home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* CALCUTIL.PAS *)
- (* Dieses Modul enthaelt die 'Laufzeit-'Fehlerbehandlung, Routinen zur *)
- (* Verwaltung der dynamischen Calc-Groessen, sowie ein paar Dinge, die das *)
- (* das Leben mit Calc erleichtern sollen. *)
-
- (* ----------------------------------------------------------------------- *)
- (* Wird von 'CalcExpression' und der Mathe-Bibliothek MATHFUNC.PAS be- *)
- (* noetigt, um bei auftretenden Fehlern nicht gleich aus dem Programm zu *)
- (* fliegen: *)
-
- PROCEDURE CalcError (ErrNum: INTEGER; Message: ErrString);
-
- BEGIN
- WriteLn; Write('*** Laufzeitfehler:'); Clreol; WriteLn;
- Write(' ');
- CASE ErrNum OF
- 1: Write('Gleitkommaueberlauf');
- 2: Write('Division durch Null');
- 3: Write('Argumentfehler in ');
- ELSE ;
- END;
- Write(' ', Message, ' !'); ClrEol;
- WriteLn; ClrEol;
- WriteLn; ClrEol;
- CalcResult := FALSE; (* Auswertung abbrechen ! *)
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Noch freien Platz im Heap ermitteln. Auf PCs wird die Anzahl noch frei- *)
- (* er Paragraphen (1 Paragr. = 16 Bytes) von MemAvail geliefert. Unter *)
- (* CP/M ergibt MemAvail einen neg. Wert, wenn mehr als 32k frei sind: *)
-
- FUNCTION HeapAvail: REAL;
- VAR temp: REAL;
-
- (* fuer MS-DOS:
- BEGIN
- temp := MemAvail;
- IF temp < 0.0 THEN temp := 65536.0 + temp;
- HeapAvail := 16.0 * temp;
- *)
-
- (* fuer CP/M: *)
- BEGIN
- temp := MemAvail;
- IF temp < 0.0 THEN temp := 65536.0 + temp;
- HeapAvail := temp;
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Ein nicht mehr benoetigtes Calc-Prog. (UPN_Queue) wieder aus dem Heap *)
- (* entfernen! Wird bei fehlerhafter Uebersetzung von 'CompileExpression' *)
- (* aufgerufen, um erzeugten 'Muell' wieder zu entfernen. Sollte vom Anwen- *)
- (* der fuer nicht mehr benoetigte, uebersetzte Ausdruecke benutzt werden, *)
- (* um keinen Heap-Ueberlauf zu provozieren! *)
-
- PROCEDURE KillExpression (VAR ExprPtr: Calc_Prog);
-
- VAR NextPtr: Calc_Prog;
-
- BEGIN
- WHILE ExprPtr <> NIL DO
- BEGIN
- NextPtr := ExprPtr^.NextInst; Dispose(ExprPtr); ExprPtr := NextPtr
- END;
- ExprPtr := NIL;
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Eine neue, leere Variablen-Tabelle im Heap anlegen. Siehe dazu Begleit- *)
- (* artikel, 'CompileExpression' und 'CalcExpression'. *)
-
- FUNCTION NewVarTab: Calc_VarTab;
-
- VAR VarTab: Calc_VarTab;
-
- BEGIN
- NewVarTab := NIL;
- IF HeapAvail > Calc_MaxVar * (Calc_OpSize+Calc_Idlen) + 100 THEN
- BEGIN
- New(VarTab); VarTab^[0].Value := 0.0; NewVarTab := VarTab
- END
- ELSE CalcError(0, 'nicht genuegend freier Speicher fuer Var.-Tabelle')
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Eine nicht mehr benoetigte Variablen-Tabelle aus dem Heap entfernen: *)
-
- PROCEDURE KillVarTab (VAR VarTab: Calc_VarTab);
-
- BEGIN if vartab <> nil THEN Dispose(VarTab); VarTab := NIL END;
-
- (* ----------------------------------------------------------------------- *)
- (* Variable mit dem Bezeichner 'Id' in Tabelle 'VarTab' suchen. Ist sie *)
- (* nicht enthalten, wird der Wert 0 zurueckgegeben, sonst der Index in *)
- (* die Tabelle. *)
-
- FUNCTION SearchVarTab (VarTab: Calc_VarTab; Id: Calc_String): INTEGER;
-
- VAR i: INTEGER;
-
- BEGIN
- if vartab <> nil THEN
- BEGIN
- FOR i := 1 to Length(id) do id[i] := upcase(id[i]);
- i := Trunc(VarTab^[0].Value); VarTab^[0].VarId := Copy(Id, 1, Calc_IdLen);
- WHILE VarTab^[i].VarId <> Id DO i := Pred(i);
- SearchVarTab := i
- END
- ELSE SearchVarTab := 0
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Variable mit dem Bezeichner 'Id' in Tabelle 'VarTab' an naechste freie *)
- (* Position aufnehmen. Zurueckgegeben wird diese Position. Ist kein Platz *)
- (* mehr in der Tabelle, wird -1 zurueckgegeben. *)
-
- FUNCTION AddToVarTab (VarTab: Calc_VarTab; Id: Calc_String): INTEGER;
-
- VAR i: INTEGER;
-
- BEGIN
- if VarTab <> nil THEN
- BEGIN
- FOR i := 1 to Length(id) do id[i] := upcase(id[i]);
- i := Trunc(VarTab^[0].Value);
- IF i < Calc_MaxVar THEN
- BEGIN
- i := Succ(i); VarTab^[0].Value := i;
- VarTab^[i].VarId := Id; VarTab^[i].Value := 0
- END
- ELSE i := -1;
- AddToVarTab := i
- END
- ELSE AddToVarTab := -1
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* Variable an der Position 'i' in einer Variablen-Tabelle den Wert 'x' *)
- (* zuweisen: *)
-
- PROCEDURE AssignVarI (VarTab: Calc_VarTab; i: INTEGER; x: Calc_Operand);
-
- BEGIN
- if vartab <> nil THEN
- BEGIN
- IF (i > 0) AND (i <= Trunc(VarTab^[0].Value)) THEN
- VarTab^[i].Value := x
- ELSE
- CalcError(0, 'Wertzuweisung an unbekannte Variable')
- END
- ELSE CalcError(0, 'Wertzuweisung an unbekannte Variable')
- END;
-
- (* ----------------------------------------------------------------------- *)
- (* ... und der Variablen mit Bezeichner 'Id': *)
-
- PROCEDURE AssignVar (VarTab: Calc_VarTab; Id: Calc_String; x: Calc_Operand);
-
- BEGIN AssignVarI(VarTab, SearchVarTab(VarTab, Id), x) END;
-
- (* ----------------------------------------------------------------------- *)
- (* es koennten noch Funktionen zur komfortablen, dialoggesteuerten Ein- *)
- (* gabe/Aenderung aller in einer Tabelle enthaltenen Calc-Variablen fol- *)
- (* gen. Hier kann der Anwender gemaess seines Problems und seiner Fan- *)
- (* tasie walten... *)
- (* ----------------------------------------------------------------------- *)
- (* Ende von CALCUTIL.PAS *)