| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721 |
- {
- $ id: $
- Copyright (c) 2000 by Marco van de Voort ([email protected])
- member of the Free Pascal development team
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright. (LGPL)
- Evaluator class implementation. Evaluates a parsetree expression in
- a way optimized for fast repeated evaluations of the same expression
- with different variables and constants.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************
- }
- {$IFDEF DebugDump}
- procedure TEvaluator.WriteVliw(p:VLIWEvalWord); forward;
- {$ENDIF}
- Procedure TEvalInternalError(A,B:ArbInt);
- VAR S,S2 : ShortString;
- begin
- Str(ORD(A),S);
- Str(ORD(B),S2);
- Raise TEvaluatorIE.Create(SEvalIE+S+' '+S2);
- end;
- CONSTRUCTOR TEvaluator.Create(VariableList:TStringList;Expression:pnode);
- {Constructor. Stringlist to set the order of variables in the function while
- xconverting the pnode tree to a TEvaluator structure. This avoids any string
- parsing during a real evaluation, and moves all stringparsing to the setup.
- So for Func(x,y,z) Variablelist contains ('x','y','z') in that order.
- }
- begin
- VariableName:=VariableList;
- ConstantNames:=TStringList.Create;
- ConstantValue:=TList.Create;
- Getmem(VLIWRPnExpr,SIZEOF(VLIWEvalWord)*VLIWIncr);
- VLIWCount:=0;
- VLIWAlloc:=VLIWIncr;
- MaxStack :=0;
- TreeToVLIWRPN(Expression);
- end;
- CONSTRUCTOR TEvaluator.Create(VariableList:TStringList;Expression:TExpression);
- {Overloaded, same as other constructor. (which it even calls), except that
- it has a TExpression as argument.
- Besides that it gets the pnode from the TExpression, it sets the
- TExpression.Evaluator to self, and a flag to set in the TExpression that its
- assiociated TEvaluator is up to date with the TExpression.
- }
- begin
- Self.Create(VariableList,Expression.ExprTree);
- Expression.Evaluator:=Self;
- Expression.EvaluatorUpToDate:=TRUE;
- end;
- DESTRUCTOR TEvaluator.Destroy;
- VAR I : LONGINT;
- TmpList : Tlist;
- begin
- VariableName.Free;
- ConstantNames.Free;
- IF ConstantValue.Count>0 THEN
- FOR I:=0 to ConstantValue.Count -1 DO
- begin
- TmpList:=TList(ConstantValue[I]);
- TmpList.Free;
- end;
- ConstantValue.Free;
- If VLIWAlloc>0 THEN
- FreeMem(VLIWRPNExpr,VLIWAlloc*SIZEOF(VLIWEvalWord));
- inherited Destroy;
- end;
- PROCEDURE TEvaluator.SetConstant(Name:ShortString;Value:ArbFloat);
- Var Ind,I : Longint;
- TmpList : TList;
- begin
- Ind:=ConstantNames.IndexOf(Name);
- If Ind<>-1 THEN
- begin
- TmpList:=TList(ConstantValue[Ind]);
- I:=TmpList.Count;
- If I>0 Then
- For I:=0 TO TmpList.Count-1 DO
- begin
- PVLIWEvalWord(TmpList[I])^.VLIWEntity:=AfConstant;
- PVLIWEvalWord(TmpList[I])^.Value:=Value;
- end;
- end;
- end;
- procedure TEvaluator.TreeToVLIWRPN(expr:pnode);
- procedure CheckVLIWArr;
- begin
- if VLIWCount=VLIWAlloc then
- begin
- ReAllocMem(VLIWRPNExpr,(VLIWAlloc+VLIWIncr)*SIZEOF(VLIWEvalWord));
- Inc(VLIWAlloc,VLIWIncr);
- end;
- end;
- procedure searchTree(Tree:pnode);
- var Ind : ArbInt;
- TmpList : TList;
- begin
- if tree<>nil then
- case Tree^.nodetype of
- VarNode : begin
- {some variable or constant. First: Variable?}
- Ind:=VariableName.IndexOf(Tree^.Variable);
- If Ind<>-1 then
- begin {We have identified a variable}
- CheckVLIWArr; {Make sure there is at least room for one variable}
- WITH VLIWRPNExpr[VLIWCount] do
- begin
- VLIWEntity:=AVariable;
- IndexOfVar:=Ind;
- end;
- {$IFDEF DebugDump}
- WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
- {$ENDIF}
- inc(VLIWCount);
- end
- else
- begin {We have a constant}
- ind:=ConstantNames.IndexOf(Tree^.Variable);
- if Ind=-1 then
- begin {That doesn't exist. Make sure it exists}
- ConstantNames.Add(Tree^.Variable);
- TmpList:=TList.Create;
- ConstantValue.Add(TmpList);
- end
- else
- begin
- TmpList:=tlist(ConstantValue[Ind]);
- end;
- {Create the VLIW record}
- CheckVLIWArr;
- WITH VLIWRPNExpr[VLIWCount] do
- begin
- VLIWEntity:=Placeholder;
- IndexOfConstant:=255;
- end;
- {$IFDEF DebugDump}
- WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
- {$ENDIF}
- {Store a pointer to the VLIW record to be able to change the
- constant}
- TmpList.Add(pointer(VLIWCount)); {Can't pick pointer here, due to realloc}
- inc(VLIWCount);
- end; {Ind<>-1}
- end;
- ConstNode: begin
- CheckVLIWArr;
- WITH VLIWRPNExpr[VLIWCount] do
- begin
- VLIWEntity:=AfConstant;
- Value:=tree^.value;
- end;
- {$IFDEF DebugDump}
- WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
- {$ENDIF}
- inc(VLIWCount);
- end;
- iconstnode: begin
- CheckVLIWArr;
- WITH VLIWRPNExpr[VLIWCount] do
- begin
- VLIWEntity:=AiConstant;
- IValue:=tree^.ivalue;
- end;
- {$IFDEF DebugDump}
- WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
- {$ENDIF}
- inc(VLIWCount);
- end;
- CalcNode : begin
- CheckVLIWArr;
- WITH VLIWRPNExpr[VLIWCount] do
- begin
- VLIWEntity:=AnOperation;
- op:=vliwop2(ord(Tree^.op));
- end;
- {$IFDEF DebugDump}
- WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
- {$ENDIF}
- inc(VLIWCount);
- SearchTree(tree^.left);
- SearchTree(tree^.right);
- end;
- FuncNode: begin
- CheckVLIWArr;
- WITH VLIWRPNExpr[VLIWCount] do
- begin
- VLIWEntity:=AFunction;
- fun1:=Tree^.fun;
- end;
- {$IFDEF DebugDump}
- WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
- {$ENDIF}
- inc(VLIWCount);
- SearchTree(tree^.son);
- end;
- Func2Node: begin
- CheckVLIWArr;
- WITH VLIWRPNExpr[VLIWCount] do
- begin
- VLIWEntity:=AnOperation;
- if tree^.fun2=powerx then
- op:=VLIWOp2(powo)
- else
- if tree^.fun2 >powerx then
- op:=vliwop2(ord(powv)+ord(tree^.fun2)-ord(arctan2x))
- else
- op:=vliwop2(1+ord(powv)+ord(tree^.fun2)-ord(arctan2x))
- end;
- {$IFDEF DebugDump}
- WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
- {$ENDIF}
- inc(VLIWCount);
- SearchTree(tree^.son2left);
- SearchTree(tree^.son2right);
- end
- else
- TEvalInternalError(4,ORD(Tree^.nodetype ));
- end;
- end;
- Procedure FixLists;
- {We added constants as VLIWCount indexes. To speed up we convert them to
- pointers. We couldn't do that directly as a consequence of the ReAlloc.}
- VAR I,J : Longint;
- TmpList : TList;
- begin
- I:=ConstantValue.Count;
- IF I>0 THEN
- FOR J:=0 TO I-1 DO
- begin
- TmpList:=TList(ConstantValue[J]);
- IF (Tmplist<>NIL) and (TmpList.Count>0) then
- for I:=0 TO TmpList.Count-1 DO
- TmpList[I]:=@VLIWRPNExpr[longint(TmpList[I])];
- end;
- end;
- begin
- VLIWCount:=0;
- SearchTree(expr);
- FixLists;
- end;
- function TEvaluator.Evaluate(const variables:Array of ArbFloat):ArbFloat;
- {The one that does the work}
- CONST StackDepth=50;
- var TheArray : pVLIWEvalWord;
- VLIWRecs : Longint;
- RPNStack : ARRAY[0..StackDepth] OF ArbFloat;
- I,
- RPNPointer : Longint;
- // S : ansiString;
- procedure push(Val:ArbFloat); {$IFDEF FPC} InLine; {$endif}
- begin
- IF RPNPointer=StackDepth THEN
- RAISE TEvaluatorStackException.Create(SEvalStackDepthExceeded);
- RPNStack[RpnPointer]:=Val;
- INC(RPNPointer);
- end;
- begin
- VLIWRecs:=VariableName.Count;
- if (High(Variables)+1)<>VLIWRecs then
- Raise TEvaluatorNotEnoughVariables.Create(SeValBadNumberOfVars);
- RPNPointer:=0;
- VliwRecs:=VliwCount-1;
- TheArray:=@VLIWRPNExpr[VLIWRecs];
- REPEAT
- {$IFDEF DebugMe}
- Writeln(VliwRecs,' ',ord(TheArray^.VLIWEntity));
- {$ENDIF}
- TheArray:=@VLIWRPNExpr[VLIWRecs];
- CASE TheArray^.VLIWEntity OF
- AVariable : begin
- {$IFDEF DebugMe}
- Writeln('var:', TheArray^.IndexOfVar);
- {$ENDIF}
- Push(Variables[TheArray^.IndexOfVar]);
- end;
- AfConstant : begin
- {$IFDEF DebugMe}
- Writeln('FP value:', TheArray^.value);
- {$ENDIF}
- Push(TheArray^.Value);
- end;
- AiConstant : begin
- {$IFDEF DebugMe}
- Writeln('Int value:', TheArray^.ivalue);
- {$ENDIF}
- Push(TheArray^.iValue);
- end;
- Placeholder: begin
- // RAISE TEvaluatorBadConstant.Create(ConstantNames[TheArray^.IndexOfConstant]);
- end;
- AnOperation: begin
- {$IFDEF DebugMe}
- Writeln('Operator value:', ord(TheArray^.op));
- {$ENDIF}
- Case TheArray^.Op of
- addv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]+RPNStack[RPNPointer-1];
- end;
- subv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]-RPNStack[RPNPointer-1];
- end;
- mulv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]*RPNStack[RPNPointer-1];
- end;
- dvdv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]/RPNStack[RPNPointer-1];
- end;
- powv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=Power(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- arctan2v : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=ArcTan2(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- stepv : begin
- Dec(RPNPointer);
- If RPNStack[RPNPointer-1]>RPNStack[RPNPOINTER] THEN
- RPNStack[RPNPointer-1]:=1.0
- else
- RPNStack[RPNPointer-1]:=0.0;
- end;
- hypotv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=hypot(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- lognv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=logn(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- else
- TEvalInternalError(1,ORD(TheArray^.op));
- end;
- end;
- AFunction : begin
- {$IFDEF DebugMe}
- Writeln('function value:', ord(TheArray^.fun1));
- {$ENDIF}
- Case TheArray^.Fun1 of
- cosx: RPNStack[RPNPointer-1]:=cos(RPNStack[RPNPointer-1]);
- sinx: RPNStack[RPNPointer-1]:=sin(RPNStack[RPNPointer-1]);
- tanx: RPNStack[RPNPointer-1]:=tan(RPNStack[RPNPointer-1]);
- sqrx: RPNStack[RPNPointer-1]:=sqr(RPNStack[RPNPointer-1]);
- sqrtx: RPNStack[RPNPointer-1]:=sqrt(RPNStack[RPNPointer-1]);
- expx: RPNStack[RPNPointer-1]:=exp(RPNStack[RPNPointer-1]);
- lnx: RPNStack[RPNPointer-1]:=ln(RPNStack[RPNPointer-1]);
- invx: RPNStack[RPNPointer-1]:=1/RPNStack[RPNPointer-1];
- minus: RPNStack[RPNPointer-1]:=-RPNStack[RPNPointer-1];
- cotanx: RPNStack[RPNPointer-1]:=cotan(RPNStack[RPNPointer-1]);
- arcsinx: RPNStack[RPNPointer-1]:=arcsin(RPNStack[RPNPointer-1]);
- arccosx: RPNStack[RPNPointer-1]:=arccos(RPNStack[RPNPointer-1]);
- arctanx: RPNStack[RPNPointer-1]:=arctan(RPNStack[RPNPointer-1]);
- sinhx: RPNStack[RPNPointer-1]:=sinh(RPNStack[RPNPointer-1]);
- coshx: RPNStack[RPNPointer-1]:=cosh(RPNStack[RPNPointer-1]);
- tanhx: RPNStack[RPNPointer-1]:=tanh(RPNStack[RPNPointer-1]);
- arcsinhx: RPNStack[RPNPointer-1]:=ArcSinh(RPNStack[RPNPointer-1]);
- arccoshx: RPNStack[RPNPointer-1]:=ArcCosh(RPNStack[RPNPointer-1]);
- arctanhx: RPNStack[RPNPointer-1]:=ArcTanh(RPNStack[RPNPointer-1]);
- log10x: RPNStack[RPNPointer-1]:=Log10(RPNStack[RPNPointer-1]);
- log2x: RPNStack[RPNPointer-1]:=Log2(RPNStack[RPNPointer-1]);
- lnxpix: RPNStack[RPNPointer-1]:=lnxp1(RPNStack[RPNPointer-1]);
- else
- TEvalInternalError(2,ORD(TheArray^.fun1));
- end;
- end;
- else
- TEvalInternalError(3,ORD(TheArray^.VLIWEntity));
- end;
- {$Ifdef DebugDump}
- Writeln('RecordNo: ',VliwRecs);
- IF RPNPointer>0 then
- begin
- Writeln('RPN stack');
- for I:=0 TO RpnPointer-1 DO
- Writeln(I:2,' ',RpnStack[I]);
- end;
- {$Endif}
- dec(TheArray);
- dec(VliwRecs);
- UNTIL VliwRecs<0;
- Result:=RPNStack[0];
- end;
- {
- function TEvaluator.i387Evaluate(const variables:Array of ArbFloat):ArbFloat;
- {This should become the really *cool* one in time.
- Still experimental though.
- Current status:
- - Can be entirely FP, but isn't allowed to use more that 4 stack-pos then.
- - Math's ARCCOS ARCCOSH ARCSIN ARCSINH ARCTAN2 ARCTANH COSH COTAN HYPOT LNXP1 LOG10
- LOG2 LOGN POWER SINH TAN TANH
- and System.Exp are forbidden because they use stackroom internally.
- This is a problem, because specially Exp() is much too common.
- }
- CONST StackDepth=50;
- var TheArray : pVLIWEvalWord;
- VLIWRecs : Longint;
- RPNStack : ARRAY[0..StackDepth] OF ArbFloat;
- I,
- RPNPointer : Longint;
- procedure push(Val:ArbFloat); {$IFDEF FPC} InLine; {$endif}
- begin
- IF RPNPointer=StackDepth THEN
- RAISE TEvaluatorStackException.Create(SEvalStackDepthExceeded);
- RPNStack[RpnPointer]:=Val;
- INC(RPNPointer);
- end;
- begin
- VLIWRecs:=VariableName.Count;
- if (High(Variables)+1)<>VLIWRecs then
- Raise TEvaluatorNotEnoughVariables.Create(SeValBadNumberOfVars);
- RPNPointer:=0;
- VliwRecs:=VliwCount-1;
- TheArray:=@VLIWRPNExpr[VLIWRecs];
- REPEAT
- {$IFDEF DebugMe}
- Writeln(VliwRecs,' ',ord(TheArray^.VLIWEntity));
- {$ENDIF}
- TheArray:=@VLIWRPNExpr[VLIWRecs];
- CASE TheArray^.VLIWEntity OF
- AVariable : begin
- {$IFDEF DebugMe}
- Writeln('var:', TheArray^.IndexOfVar);
- {$ENDIF}
- Push(Variables[TheArray^.IndexOfVar]);
- end;
- AfConstant : begin
- {$IFDEF DebugMe}
- Writeln('FP value:', TheArray^.value);
- {$ENDIF}
- Push(TheArray^.Value);
- end;
- AiConstant : begin
- {$IFDEF DebugMe}
- Writeln('Int value:', TheArray^.ivalue);
- {$ENDIF}
- Push(TheArray^.iValue);
- end;
- Placeholder: begin
- // RAISE TEvaluatorBadConstant.Create(ConstantNames[TheArray^.IndexOfConstant]);
- end;
- AnOperation: begin
- {$IFDEF DebugMe}
- Writeln('Operator value:', ord(TheArray^.op));
- {$ENDIF}
- Case TheArray^.Op of
- addv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]+RPNStack[RPNPointer-1];
- end;
- subv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]-RPNStack[RPNPointer-1];
- end;
- mulv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]*RPNStack[RPNPointer-1];
- end;
- dvdv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]/RPNStack[RPNPointer-1];
- end;
- powv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=Power(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- arctan2v : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=ArcTan2(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- stepv : begin
- Dec(RPNPointer);
- If RPNStack[RPNPointer-1]>RPNStack[RPNPOINTER] THEN
- RPNStack[RPNPointer-1]:=1.0
- else
- RPNStack[RPNPointer-1]:=0.0;
- end;
- hypotv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=hypot(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- lognv : begin
- Dec(RPNPointer);
- RPNStack[RPNPointer-1]:=logn(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
- end;
- else
- TEvalInternalError(1,ORD(TheArray^.op));
- end;
- end;
- AFunction : begin
- {$IFDEF DebugMe}
- Writeln('function value:', ord(TheArray^.fun1));
- {$ENDIF}
- Case TheArray^.Fun1 of
- cosx: RPNStack[RPNPointer-1]:=cos(RPNStack[RPNPointer-1]);
- sinx: RPNStack[RPNPointer-1]:=sin(RPNStack[RPNPointer-1]);
- tanx: RPNStack[RPNPointer-1]:=tan(RPNStack[RPNPointer-1]);
- sqrx: RPNStack[RPNPointer-1]:=sqr(RPNStack[RPNPointer-1]);
- sqrtx: RPNStack[RPNPointer-1]:=sqrt(RPNStack[RPNPointer-1]);
- expx: RPNStack[RPNPointer-1]:=exp(RPNStack[RPNPointer-1]);
- lnx: RPNStack[RPNPointer-1]:=ln(RPNStack[RPNPointer-1]);
- invx: RPNStack[RPNPointer-1]:=1/RPNStack[RPNPointer-1];
- minus: RPNStack[RPNPointer-1]:=-RPNStack[RPNPointer-1];
- cotanx: RPNStack[RPNPointer-1]:=cotan(RPNStack[RPNPointer-1]);
- arcsinx: RPNStack[RPNPointer-1]:=arcsin(RPNStack[RPNPointer-1]);
- arccosx: RPNStack[RPNPointer-1]:=arccos(RPNStack[RPNPointer-1]);
- arctanx: RPNStack[RPNPointer-1]:=arctan(RPNStack[RPNPointer-1]);
- sinhx: RPNStack[RPNPointer-1]:=sinh(RPNStack[RPNPointer-1]);
- coshx: RPNStack[RPNPointer-1]:=cosh(RPNStack[RPNPointer-1]);
- tanhx: RPNStack[RPNPointer-1]:=tanh(RPNStack[RPNPointer-1]);
- arcsinhx: RPNStack[RPNPointer-1]:=ArcSinh(RPNStack[RPNPointer-1]);
- arccoshx: RPNStack[RPNPointer-1]:=ArcCosh(RPNStack[RPNPointer-1]);
- arctanhx: RPNStack[RPNPointer-1]:=ArcTanh(RPNStack[RPNPointer-1]);
- log10x: RPNStack[RPNPointer-1]:=Log10(RPNStack[RPNPointer-1]);
- log2x: RPNStack[RPNPointer-1]:=Log2(RPNStack[RPNPointer-1]);
- lnxpix: RPNStack[RPNPointer-1]:=lnxp1(RPNStack[RPNPointer-1]);
- else
- TEvalInternalError(2,ORD(TheArray^.fun1));
- end;
- end;
- else
- TEvalInternalError(3,ORD(TheArray^.VLIWEntity));
- end;
- {$Ifdef DebugDump}
- Writeln('RecordNo: ',VliwRecs);
- IF RPNPointer>0 then
- begin
- Writeln('RPN stack');
- for I:=0 TO RpnPointer-1 DO
- Writeln(I:2,' ',RpnStack[I]);
- end;
- {$Endif}
- dec(TheArray);
- dec(VliwRecs);
- UNTIL VliwRecs<0;
- Result:=RPNStack[0];
- end;
- }
- function TEvaluator.Evaldepth:longint;
- {estimate stackdepth}
- var TheArray : pVLIWEvalWord;
- VLIWRecs : Longint;
- Deepest : Longint;
- RPNPointer : Longint;
- begin
- RPNPointer:=0;
- Deepest:=0;
- VliwRecs:=VliwCount-1;
- TheArray:=@VLIWRPNExpr[VLIWRecs];
- REPEAT
- TheArray:=@VLIWRPNExpr[VLIWRecs];
- CASE TheArray^.VLIWEntity OF
- AVariable,
- afconstant,
- aiconstant, {a placeholder always changes into a push}
- placeholder : Inc(rpnpointer);
- AnOperation : Dec(rpnpointer); {take two args, put one back}
- { AFunction : Doesn't do anything}
- end;
- If Deepest<RPNPointer then
- Deepest:=RPNPointer;
- dec(TheArray);
- dec(VliwRecs);
- UNTIL VliwRecs<0;
- Result:=deepest;
- end;
- {$IFDEF DebugDump}
- CONST VLIWOPNames : array[addv..lognv] of String[9] =
- ('add','sub','mul','dd','pow',
- 'arctan2','step','hypot','logn');
- procedure TEvaluator.WriteVliw(p:VLIWEvalWord);
- begin
- Write('writevliw ',(ord(p.vliwentity)-ORD(AVariable)):2,' ');
- CASE p.VLIWEntity OF
- AVariable : Writeln('variable : ', VariableName[p.IndexOfVar]);
- AfConstant : Writeln('FP value : ', p.value);
- AiConstant : Writeln('Int value: ', p.ivalue);
- Placeholder: begin
- writeln('placeholder');
- end;
- AnOperation: begin
- Write('Operator : ');
- IF not (p.OP IN [addv..lognv]) then
- Writeln('Bad OPERATOR!')
- ELSE
- Writeln(VLIWOpNames[p.op]);
- end;
- AFunction : begin
- Write('Function: ');
- IF not (p.fun1 IN [cosx..lognx]) then
- Writeln('xBad function')
- ELSE
- Writeln(FunctionNames[p.fun1]);
- end;
- else
- Writeln('xBAD Entity');
- end;
- end;
- procedure TEvaluator.debugger;
- {Dump the VLIWArray in textual form for debugging}
- var TheArray : pVLIWEvalWord;
- VLIWRecs : Longint;
- {$IFNDEF GoUp}
- {$DEFINE GoDown}
- {$ENDIF}
- begin
- VLIWRecs:=VariableName.Count;
- Writeln('Variables : ',VLIWRecs);
- Writeln('Constants : ',ConstantNames.Count);
- VliwRecs:=VliwCount-1;
- Writeln('VLIWCount : ',VLIWCOUNT);
- {$IFDEF GoDown}
- TheArray:=@VLIWRPNExpr[VLIWRecs-1];
- {$ELSE}
- TheArray:=VLIWRPNExpr;
- {$ENDIF}
- REPEAT
- {$IFDEF GoDown}
- Writeln(VliwRecs,' ',ord(TheArray^.VLIWEntity));
- {$ELSE}
- Writeln(VLIWCount-VliwRecs,' ',ord(TheArray^.VLIWEntity));
- {$ENDIF}
- Writeln('------------------------------------------------------');
- WriteVliw(TheArray^);
- {$IFDEF GoDown}
- dec(TheArray);
- {$ELSE}
- INC(TheArray);
- {$ENDIF}
- dec(VliwRecs);
- UNTIL VliwRecs<0;
- end;
- {$ENDIF}
- {
- $Log$
- Revision 1.1 2002/12/15 21:01:28 marco
- Initial revision
- }
|