teval.inc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. {
  2. $ id: $
  3. Copyright (c) 2000 by Marco van de Voort ([email protected])
  4. member of the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright. (LGPL)
  7. Evaluator class implementation. Evaluates a parsetree expression in
  8. a way optimized for fast repeated evaluations of the same expression
  9. with different variables and constants.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************
  14. }
  15. {$IFDEF DebugDump}
  16. procedure TEvaluator.WriteVliw(p:VLIWEvalWord); forward;
  17. {$ENDIF}
  18. Procedure TEvalInternalError(A,B:ArbInt);
  19. VAR S,S2 : ShortString;
  20. begin
  21. Str(ORD(A),S);
  22. Str(ORD(B),S2);
  23. Raise TEvaluatorIE.Create(SEvalIE+S+' '+S2);
  24. end;
  25. CONSTRUCTOR TEvaluator.Create(VariableList:TStringList;Expression:pnode);
  26. {Constructor. Stringlist to set the order of variables in the function while
  27. xconverting the pnode tree to a TEvaluator structure. This avoids any string
  28. parsing during a real evaluation, and moves all stringparsing to the setup.
  29. So for Func(x,y,z) Variablelist contains ('x','y','z') in that order.
  30. }
  31. begin
  32. VariableName:=VariableList;
  33. ConstantNames:=TStringList.Create;
  34. ConstantValue:=TList.Create;
  35. Getmem(VLIWRPnExpr,SIZEOF(VLIWEvalWord)*VLIWIncr);
  36. VLIWCount:=0;
  37. VLIWAlloc:=VLIWIncr;
  38. MaxStack :=0;
  39. TreeToVLIWRPN(Expression);
  40. end;
  41. CONSTRUCTOR TEvaluator.Create(VariableList:TStringList;Expression:TExpression);
  42. {Overloaded, same as other constructor. (which it even calls), except that
  43. it has a TExpression as argument.
  44. Besides that it gets the pnode from the TExpression, it sets the
  45. TExpression.Evaluator to self, and a flag to set in the TExpression that its
  46. assiociated TEvaluator is up to date with the TExpression.
  47. }
  48. begin
  49. Self.Create(VariableList,Expression.ExprTree);
  50. Expression.Evaluator:=Self;
  51. Expression.EvaluatorUpToDate:=TRUE;
  52. end;
  53. DESTRUCTOR TEvaluator.Destroy;
  54. VAR I : LONGINT;
  55. TmpList : Tlist;
  56. begin
  57. VariableName.Free;
  58. ConstantNames.Free;
  59. IF ConstantValue.Count>0 THEN
  60. FOR I:=0 to ConstantValue.Count -1 DO
  61. begin
  62. TmpList:=TList(ConstantValue[I]);
  63. TmpList.Free;
  64. end;
  65. ConstantValue.Free;
  66. If VLIWAlloc>0 THEN
  67. FreeMem(VLIWRPNExpr,VLIWAlloc*SIZEOF(VLIWEvalWord));
  68. inherited Destroy;
  69. end;
  70. PROCEDURE TEvaluator.SetConstant(Name:ShortString;Value:ArbFloat);
  71. Var Ind,I : Longint;
  72. TmpList : TList;
  73. begin
  74. Ind:=ConstantNames.IndexOf(Name);
  75. If Ind<>-1 THEN
  76. begin
  77. TmpList:=TList(ConstantValue[Ind]);
  78. I:=TmpList.Count;
  79. If I>0 Then
  80. For I:=0 TO TmpList.Count-1 DO
  81. begin
  82. PVLIWEvalWord(TmpList[I])^.VLIWEntity:=AfConstant;
  83. PVLIWEvalWord(TmpList[I])^.Value:=Value;
  84. end;
  85. end;
  86. end;
  87. procedure TEvaluator.TreeToVLIWRPN(expr:pnode);
  88. procedure CheckVLIWArr;
  89. begin
  90. if VLIWCount=VLIWAlloc then
  91. begin
  92. ReAllocMem(VLIWRPNExpr,(VLIWAlloc+VLIWIncr)*SIZEOF(VLIWEvalWord));
  93. Inc(VLIWAlloc,VLIWIncr);
  94. end;
  95. end;
  96. procedure searchTree(Tree:pnode);
  97. var Ind : ArbInt;
  98. TmpList : TList;
  99. begin
  100. if tree<>nil then
  101. case Tree^.nodetype of
  102. VarNode : begin
  103. {some variable or constant. First: Variable?}
  104. Ind:=VariableName.IndexOf(Tree^.Variable);
  105. If Ind<>-1 then
  106. begin {We have identified a variable}
  107. CheckVLIWArr; {Make sure there is at least room for one variable}
  108. WITH VLIWRPNExpr[VLIWCount] do
  109. begin
  110. VLIWEntity:=AVariable;
  111. IndexOfVar:=Ind;
  112. end;
  113. {$IFDEF DebugDump}
  114. WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
  115. {$ENDIF}
  116. inc(VLIWCount);
  117. end
  118. else
  119. begin {We have a constant}
  120. ind:=ConstantNames.IndexOf(Tree^.Variable);
  121. if Ind=-1 then
  122. begin {That doesn't exist. Make sure it exists}
  123. ConstantNames.Add(Tree^.Variable);
  124. TmpList:=TList.Create;
  125. ConstantValue.Add(TmpList);
  126. end
  127. else
  128. begin
  129. TmpList:=tlist(ConstantValue[Ind]);
  130. end;
  131. {Create the VLIW record}
  132. CheckVLIWArr;
  133. WITH VLIWRPNExpr[VLIWCount] do
  134. begin
  135. VLIWEntity:=Placeholder;
  136. IndexOfConstant:=255;
  137. end;
  138. {$IFDEF DebugDump}
  139. WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
  140. {$ENDIF}
  141. {Store a pointer to the VLIW record to be able to change the
  142. constant}
  143. TmpList.Add(pointer(VLIWCount)); {Can't pick pointer here, due to realloc}
  144. inc(VLIWCount);
  145. end; {Ind<>-1}
  146. end;
  147. ConstNode: begin
  148. CheckVLIWArr;
  149. WITH VLIWRPNExpr[VLIWCount] do
  150. begin
  151. VLIWEntity:=AfConstant;
  152. Value:=tree^.value;
  153. end;
  154. {$IFDEF DebugDump}
  155. WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
  156. {$ENDIF}
  157. inc(VLIWCount);
  158. end;
  159. iconstnode: begin
  160. CheckVLIWArr;
  161. WITH VLIWRPNExpr[VLIWCount] do
  162. begin
  163. VLIWEntity:=AiConstant;
  164. IValue:=tree^.ivalue;
  165. end;
  166. {$IFDEF DebugDump}
  167. WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
  168. {$ENDIF}
  169. inc(VLIWCount);
  170. end;
  171. CalcNode : begin
  172. CheckVLIWArr;
  173. WITH VLIWRPNExpr[VLIWCount] do
  174. begin
  175. VLIWEntity:=AnOperation;
  176. op:=vliwop2(ord(Tree^.op));
  177. end;
  178. {$IFDEF DebugDump}
  179. WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
  180. {$ENDIF}
  181. inc(VLIWCount);
  182. SearchTree(tree^.left);
  183. SearchTree(tree^.right);
  184. end;
  185. FuncNode: begin
  186. CheckVLIWArr;
  187. WITH VLIWRPNExpr[VLIWCount] do
  188. begin
  189. VLIWEntity:=AFunction;
  190. fun1:=Tree^.fun;
  191. end;
  192. {$IFDEF DebugDump}
  193. WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
  194. {$ENDIF}
  195. inc(VLIWCount);
  196. SearchTree(tree^.son);
  197. end;
  198. Func2Node: begin
  199. CheckVLIWArr;
  200. WITH VLIWRPNExpr[VLIWCount] do
  201. begin
  202. VLIWEntity:=AnOperation;
  203. if tree^.fun2=powerx then
  204. op:=VLIWOp2(powo)
  205. else
  206. if tree^.fun2 >powerx then
  207. op:=vliwop2(ord(powv)+ord(tree^.fun2)-ord(arctan2x))
  208. else
  209. op:=vliwop2(1+ord(powv)+ord(tree^.fun2)-ord(arctan2x))
  210. end;
  211. {$IFDEF DebugDump}
  212. WriteVliw(VLIWRPNExpr[VLIWCOUNT]);
  213. {$ENDIF}
  214. inc(VLIWCount);
  215. SearchTree(tree^.son2left);
  216. SearchTree(tree^.son2right);
  217. end
  218. else
  219. TEvalInternalError(4,ORD(Tree^.nodetype ));
  220. end;
  221. end;
  222. Procedure FixLists;
  223. {We added constants as VLIWCount indexes. To speed up we convert them to
  224. pointers. We couldn't do that directly as a consequence of the ReAlloc.}
  225. VAR I,J : Longint;
  226. TmpList : TList;
  227. begin
  228. I:=ConstantValue.Count;
  229. IF I>0 THEN
  230. FOR J:=0 TO I-1 DO
  231. begin
  232. TmpList:=TList(ConstantValue[J]);
  233. IF (Tmplist<>NIL) and (TmpList.Count>0) then
  234. for I:=0 TO TmpList.Count-1 DO
  235. TmpList[I]:=@VLIWRPNExpr[longint(TmpList[I])];
  236. end;
  237. end;
  238. begin
  239. VLIWCount:=0;
  240. SearchTree(expr);
  241. FixLists;
  242. end;
  243. function TEvaluator.Evaluate(const variables:Array of ArbFloat):ArbFloat;
  244. {The one that does the work}
  245. CONST StackDepth=50;
  246. var TheArray : pVLIWEvalWord;
  247. VLIWRecs : Longint;
  248. RPNStack : ARRAY[0..StackDepth] OF ArbFloat;
  249. I,
  250. RPNPointer : Longint;
  251. // S : ansiString;
  252. procedure push(Val:ArbFloat); {$IFDEF FPC} InLine; {$endif}
  253. begin
  254. IF RPNPointer=StackDepth THEN
  255. RAISE TEvaluatorStackException.Create(SEvalStackDepthExceeded);
  256. RPNStack[RpnPointer]:=Val;
  257. INC(RPNPointer);
  258. end;
  259. begin
  260. VLIWRecs:=VariableName.Count;
  261. if (High(Variables)+1)<>VLIWRecs then
  262. Raise TEvaluatorNotEnoughVariables.Create(SeValBadNumberOfVars);
  263. RPNPointer:=0;
  264. VliwRecs:=VliwCount-1;
  265. TheArray:=@VLIWRPNExpr[VLIWRecs];
  266. REPEAT
  267. {$IFDEF DebugMe}
  268. Writeln(VliwRecs,' ',ord(TheArray^.VLIWEntity));
  269. {$ENDIF}
  270. TheArray:=@VLIWRPNExpr[VLIWRecs];
  271. CASE TheArray^.VLIWEntity OF
  272. AVariable : begin
  273. {$IFDEF DebugMe}
  274. Writeln('var:', TheArray^.IndexOfVar);
  275. {$ENDIF}
  276. Push(Variables[TheArray^.IndexOfVar]);
  277. end;
  278. AfConstant : begin
  279. {$IFDEF DebugMe}
  280. Writeln('FP value:', TheArray^.value);
  281. {$ENDIF}
  282. Push(TheArray^.Value);
  283. end;
  284. AiConstant : begin
  285. {$IFDEF DebugMe}
  286. Writeln('Int value:', TheArray^.ivalue);
  287. {$ENDIF}
  288. Push(TheArray^.iValue);
  289. end;
  290. Placeholder: begin
  291. // RAISE TEvaluatorBadConstant.Create(ConstantNames[TheArray^.IndexOfConstant]);
  292. end;
  293. AnOperation: begin
  294. {$IFDEF DebugMe}
  295. Writeln('Operator value:', ord(TheArray^.op));
  296. {$ENDIF}
  297. Case TheArray^.Op of
  298. addv : begin
  299. Dec(RPNPointer);
  300. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]+RPNStack[RPNPointer-1];
  301. end;
  302. subv : begin
  303. Dec(RPNPointer);
  304. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]-RPNStack[RPNPointer-1];
  305. end;
  306. mulv : begin
  307. Dec(RPNPointer);
  308. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]*RPNStack[RPNPointer-1];
  309. end;
  310. dvdv : begin
  311. Dec(RPNPointer);
  312. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]/RPNStack[RPNPointer-1];
  313. end;
  314. powv : begin
  315. Dec(RPNPointer);
  316. RPNStack[RPNPointer-1]:=Power(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  317. end;
  318. arctan2v : begin
  319. Dec(RPNPointer);
  320. RPNStack[RPNPointer-1]:=ArcTan2(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  321. end;
  322. stepv : begin
  323. Dec(RPNPointer);
  324. If RPNStack[RPNPointer-1]>RPNStack[RPNPOINTER] THEN
  325. RPNStack[RPNPointer-1]:=1.0
  326. else
  327. RPNStack[RPNPointer-1]:=0.0;
  328. end;
  329. hypotv : begin
  330. Dec(RPNPointer);
  331. RPNStack[RPNPointer-1]:=hypot(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  332. end;
  333. lognv : begin
  334. Dec(RPNPointer);
  335. RPNStack[RPNPointer-1]:=logn(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  336. end;
  337. else
  338. TEvalInternalError(1,ORD(TheArray^.op));
  339. end;
  340. end;
  341. AFunction : begin
  342. {$IFDEF DebugMe}
  343. Writeln('function value:', ord(TheArray^.fun1));
  344. {$ENDIF}
  345. Case TheArray^.Fun1 of
  346. cosx: RPNStack[RPNPointer-1]:=cos(RPNStack[RPNPointer-1]);
  347. sinx: RPNStack[RPNPointer-1]:=sin(RPNStack[RPNPointer-1]);
  348. tanx: RPNStack[RPNPointer-1]:=tan(RPNStack[RPNPointer-1]);
  349. sqrx: RPNStack[RPNPointer-1]:=sqr(RPNStack[RPNPointer-1]);
  350. sqrtx: RPNStack[RPNPointer-1]:=sqrt(RPNStack[RPNPointer-1]);
  351. expx: RPNStack[RPNPointer-1]:=exp(RPNStack[RPNPointer-1]);
  352. lnx: RPNStack[RPNPointer-1]:=ln(RPNStack[RPNPointer-1]);
  353. invx: RPNStack[RPNPointer-1]:=1/RPNStack[RPNPointer-1];
  354. minus: RPNStack[RPNPointer-1]:=-RPNStack[RPNPointer-1];
  355. cotanx: RPNStack[RPNPointer-1]:=cotan(RPNStack[RPNPointer-1]);
  356. arcsinx: RPNStack[RPNPointer-1]:=arcsin(RPNStack[RPNPointer-1]);
  357. arccosx: RPNStack[RPNPointer-1]:=arccos(RPNStack[RPNPointer-1]);
  358. arctanx: RPNStack[RPNPointer-1]:=arctan(RPNStack[RPNPointer-1]);
  359. sinhx: RPNStack[RPNPointer-1]:=sinh(RPNStack[RPNPointer-1]);
  360. coshx: RPNStack[RPNPointer-1]:=cosh(RPNStack[RPNPointer-1]);
  361. tanhx: RPNStack[RPNPointer-1]:=tanh(RPNStack[RPNPointer-1]);
  362. arcsinhx: RPNStack[RPNPointer-1]:=ArcSinh(RPNStack[RPNPointer-1]);
  363. arccoshx: RPNStack[RPNPointer-1]:=ArcCosh(RPNStack[RPNPointer-1]);
  364. arctanhx: RPNStack[RPNPointer-1]:=ArcTanh(RPNStack[RPNPointer-1]);
  365. log10x: RPNStack[RPNPointer-1]:=Log10(RPNStack[RPNPointer-1]);
  366. log2x: RPNStack[RPNPointer-1]:=Log2(RPNStack[RPNPointer-1]);
  367. lnxpix: RPNStack[RPNPointer-1]:=lnxp1(RPNStack[RPNPointer-1]);
  368. else
  369. TEvalInternalError(2,ORD(TheArray^.fun1));
  370. end;
  371. end;
  372. else
  373. TEvalInternalError(3,ORD(TheArray^.VLIWEntity));
  374. end;
  375. {$Ifdef DebugDump}
  376. Writeln('RecordNo: ',VliwRecs);
  377. IF RPNPointer>0 then
  378. begin
  379. Writeln('RPN stack');
  380. for I:=0 TO RpnPointer-1 DO
  381. Writeln(I:2,' ',RpnStack[I]);
  382. end;
  383. {$Endif}
  384. dec(TheArray);
  385. dec(VliwRecs);
  386. UNTIL VliwRecs<0;
  387. Result:=RPNStack[0];
  388. end;
  389. {
  390. function TEvaluator.i387Evaluate(const variables:Array of ArbFloat):ArbFloat;
  391. {This should become the really *cool* one in time.
  392. Still experimental though.
  393. Current status:
  394. - Can be entirely FP, but isn't allowed to use more that 4 stack-pos then.
  395. - Math's ARCCOS ARCCOSH ARCSIN ARCSINH ARCTAN2 ARCTANH COSH COTAN HYPOT LNXP1 LOG10
  396. LOG2 LOGN POWER SINH TAN TANH
  397. and System.Exp are forbidden because they use stackroom internally.
  398. This is a problem, because specially Exp() is much too common.
  399. }
  400. CONST StackDepth=50;
  401. var TheArray : pVLIWEvalWord;
  402. VLIWRecs : Longint;
  403. RPNStack : ARRAY[0..StackDepth] OF ArbFloat;
  404. I,
  405. RPNPointer : Longint;
  406. procedure push(Val:ArbFloat); {$IFDEF FPC} InLine; {$endif}
  407. begin
  408. IF RPNPointer=StackDepth THEN
  409. RAISE TEvaluatorStackException.Create(SEvalStackDepthExceeded);
  410. RPNStack[RpnPointer]:=Val;
  411. INC(RPNPointer);
  412. end;
  413. begin
  414. VLIWRecs:=VariableName.Count;
  415. if (High(Variables)+1)<>VLIWRecs then
  416. Raise TEvaluatorNotEnoughVariables.Create(SeValBadNumberOfVars);
  417. RPNPointer:=0;
  418. VliwRecs:=VliwCount-1;
  419. TheArray:=@VLIWRPNExpr[VLIWRecs];
  420. REPEAT
  421. {$IFDEF DebugMe}
  422. Writeln(VliwRecs,' ',ord(TheArray^.VLIWEntity));
  423. {$ENDIF}
  424. TheArray:=@VLIWRPNExpr[VLIWRecs];
  425. CASE TheArray^.VLIWEntity OF
  426. AVariable : begin
  427. {$IFDEF DebugMe}
  428. Writeln('var:', TheArray^.IndexOfVar);
  429. {$ENDIF}
  430. Push(Variables[TheArray^.IndexOfVar]);
  431. end;
  432. AfConstant : begin
  433. {$IFDEF DebugMe}
  434. Writeln('FP value:', TheArray^.value);
  435. {$ENDIF}
  436. Push(TheArray^.Value);
  437. end;
  438. AiConstant : begin
  439. {$IFDEF DebugMe}
  440. Writeln('Int value:', TheArray^.ivalue);
  441. {$ENDIF}
  442. Push(TheArray^.iValue);
  443. end;
  444. Placeholder: begin
  445. // RAISE TEvaluatorBadConstant.Create(ConstantNames[TheArray^.IndexOfConstant]);
  446. end;
  447. AnOperation: begin
  448. {$IFDEF DebugMe}
  449. Writeln('Operator value:', ord(TheArray^.op));
  450. {$ENDIF}
  451. Case TheArray^.Op of
  452. addv : begin
  453. Dec(RPNPointer);
  454. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]+RPNStack[RPNPointer-1];
  455. end;
  456. subv : begin
  457. Dec(RPNPointer);
  458. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]-RPNStack[RPNPointer-1];
  459. end;
  460. mulv : begin
  461. Dec(RPNPointer);
  462. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]*RPNStack[RPNPointer-1];
  463. end;
  464. dvdv : begin
  465. Dec(RPNPointer);
  466. RPNStack[RPNPointer-1]:=RPNStack[RPNPointer]/RPNStack[RPNPointer-1];
  467. end;
  468. powv : begin
  469. Dec(RPNPointer);
  470. RPNStack[RPNPointer-1]:=Power(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  471. end;
  472. arctan2v : begin
  473. Dec(RPNPointer);
  474. RPNStack[RPNPointer-1]:=ArcTan2(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  475. end;
  476. stepv : begin
  477. Dec(RPNPointer);
  478. If RPNStack[RPNPointer-1]>RPNStack[RPNPOINTER] THEN
  479. RPNStack[RPNPointer-1]:=1.0
  480. else
  481. RPNStack[RPNPointer-1]:=0.0;
  482. end;
  483. hypotv : begin
  484. Dec(RPNPointer);
  485. RPNStack[RPNPointer-1]:=hypot(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  486. end;
  487. lognv : begin
  488. Dec(RPNPointer);
  489. RPNStack[RPNPointer-1]:=logn(RPNStack[RPNPointer],RPNStack[RPNPointer-1]);
  490. end;
  491. else
  492. TEvalInternalError(1,ORD(TheArray^.op));
  493. end;
  494. end;
  495. AFunction : begin
  496. {$IFDEF DebugMe}
  497. Writeln('function value:', ord(TheArray^.fun1));
  498. {$ENDIF}
  499. Case TheArray^.Fun1 of
  500. cosx: RPNStack[RPNPointer-1]:=cos(RPNStack[RPNPointer-1]);
  501. sinx: RPNStack[RPNPointer-1]:=sin(RPNStack[RPNPointer-1]);
  502. tanx: RPNStack[RPNPointer-1]:=tan(RPNStack[RPNPointer-1]);
  503. sqrx: RPNStack[RPNPointer-1]:=sqr(RPNStack[RPNPointer-1]);
  504. sqrtx: RPNStack[RPNPointer-1]:=sqrt(RPNStack[RPNPointer-1]);
  505. expx: RPNStack[RPNPointer-1]:=exp(RPNStack[RPNPointer-1]);
  506. lnx: RPNStack[RPNPointer-1]:=ln(RPNStack[RPNPointer-1]);
  507. invx: RPNStack[RPNPointer-1]:=1/RPNStack[RPNPointer-1];
  508. minus: RPNStack[RPNPointer-1]:=-RPNStack[RPNPointer-1];
  509. cotanx: RPNStack[RPNPointer-1]:=cotan(RPNStack[RPNPointer-1]);
  510. arcsinx: RPNStack[RPNPointer-1]:=arcsin(RPNStack[RPNPointer-1]);
  511. arccosx: RPNStack[RPNPointer-1]:=arccos(RPNStack[RPNPointer-1]);
  512. arctanx: RPNStack[RPNPointer-1]:=arctan(RPNStack[RPNPointer-1]);
  513. sinhx: RPNStack[RPNPointer-1]:=sinh(RPNStack[RPNPointer-1]);
  514. coshx: RPNStack[RPNPointer-1]:=cosh(RPNStack[RPNPointer-1]);
  515. tanhx: RPNStack[RPNPointer-1]:=tanh(RPNStack[RPNPointer-1]);
  516. arcsinhx: RPNStack[RPNPointer-1]:=ArcSinh(RPNStack[RPNPointer-1]);
  517. arccoshx: RPNStack[RPNPointer-1]:=ArcCosh(RPNStack[RPNPointer-1]);
  518. arctanhx: RPNStack[RPNPointer-1]:=ArcTanh(RPNStack[RPNPointer-1]);
  519. log10x: RPNStack[RPNPointer-1]:=Log10(RPNStack[RPNPointer-1]);
  520. log2x: RPNStack[RPNPointer-1]:=Log2(RPNStack[RPNPointer-1]);
  521. lnxpix: RPNStack[RPNPointer-1]:=lnxp1(RPNStack[RPNPointer-1]);
  522. else
  523. TEvalInternalError(2,ORD(TheArray^.fun1));
  524. end;
  525. end;
  526. else
  527. TEvalInternalError(3,ORD(TheArray^.VLIWEntity));
  528. end;
  529. {$Ifdef DebugDump}
  530. Writeln('RecordNo: ',VliwRecs);
  531. IF RPNPointer>0 then
  532. begin
  533. Writeln('RPN stack');
  534. for I:=0 TO RpnPointer-1 DO
  535. Writeln(I:2,' ',RpnStack[I]);
  536. end;
  537. {$Endif}
  538. dec(TheArray);
  539. dec(VliwRecs);
  540. UNTIL VliwRecs<0;
  541. Result:=RPNStack[0];
  542. end;
  543. }
  544. function TEvaluator.Evaldepth:longint;
  545. {estimate stackdepth}
  546. var TheArray : pVLIWEvalWord;
  547. VLIWRecs : Longint;
  548. Deepest : Longint;
  549. RPNPointer : Longint;
  550. begin
  551. RPNPointer:=0;
  552. Deepest:=0;
  553. VliwRecs:=VliwCount-1;
  554. TheArray:=@VLIWRPNExpr[VLIWRecs];
  555. REPEAT
  556. TheArray:=@VLIWRPNExpr[VLIWRecs];
  557. CASE TheArray^.VLIWEntity OF
  558. AVariable,
  559. afconstant,
  560. aiconstant, {a placeholder always changes into a push}
  561. placeholder : Inc(rpnpointer);
  562. AnOperation : Dec(rpnpointer); {take two args, put one back}
  563. { AFunction : Doesn't do anything}
  564. end;
  565. If Deepest<RPNPointer then
  566. Deepest:=RPNPointer;
  567. dec(TheArray);
  568. dec(VliwRecs);
  569. UNTIL VliwRecs<0;
  570. Result:=deepest;
  571. end;
  572. {$IFDEF DebugDump}
  573. CONST VLIWOPNames : array[addv..lognv] of String[9] =
  574. ('add','sub','mul','dd','pow',
  575. 'arctan2','step','hypot','logn');
  576. procedure TEvaluator.WriteVliw(p:VLIWEvalWord);
  577. begin
  578. Write('writevliw ',(ord(p.vliwentity)-ORD(AVariable)):2,' ');
  579. CASE p.VLIWEntity OF
  580. AVariable : Writeln('variable : ', VariableName[p.IndexOfVar]);
  581. AfConstant : Writeln('FP value : ', p.value);
  582. AiConstant : Writeln('Int value: ', p.ivalue);
  583. Placeholder: begin
  584. writeln('placeholder');
  585. end;
  586. AnOperation: begin
  587. Write('Operator : ');
  588. IF not (p.OP IN [addv..lognv]) then
  589. Writeln('Bad OPERATOR!')
  590. ELSE
  591. Writeln(VLIWOpNames[p.op]);
  592. end;
  593. AFunction : begin
  594. Write('Function: ');
  595. IF not (p.fun1 IN [cosx..lognx]) then
  596. Writeln('xBad function')
  597. ELSE
  598. Writeln(FunctionNames[p.fun1]);
  599. end;
  600. else
  601. Writeln('xBAD Entity');
  602. end;
  603. end;
  604. procedure TEvaluator.debugger;
  605. {Dump the VLIWArray in textual form for debugging}
  606. var TheArray : pVLIWEvalWord;
  607. VLIWRecs : Longint;
  608. {$IFNDEF GoUp}
  609. {$DEFINE GoDown}
  610. {$ENDIF}
  611. begin
  612. VLIWRecs:=VariableName.Count;
  613. Writeln('Variables : ',VLIWRecs);
  614. Writeln('Constants : ',ConstantNames.Count);
  615. VliwRecs:=VliwCount-1;
  616. Writeln('VLIWCount : ',VLIWCOUNT);
  617. {$IFDEF GoDown}
  618. TheArray:=@VLIWRPNExpr[VLIWRecs-1];
  619. {$ELSE}
  620. TheArray:=VLIWRPNExpr;
  621. {$ENDIF}
  622. REPEAT
  623. {$IFDEF GoDown}
  624. Writeln(VliwRecs,' ',ord(TheArray^.VLIWEntity));
  625. {$ELSE}
  626. Writeln(VLIWCount-VliwRecs,' ',ord(TheArray^.VLIWEntity));
  627. {$ENDIF}
  628. Writeln('------------------------------------------------------');
  629. WriteVliw(TheArray^);
  630. {$IFDEF GoDown}
  631. dec(TheArray);
  632. {$ELSE}
  633. INC(TheArray);
  634. {$ENDIF}
  635. dec(VliwRecs);
  636. UNTIL VliwRecs<0;
  637. end;
  638. {$ENDIF}
  639. {
  640. $Log$
  641. Revision 1.1 2002/12/15 21:01:28 marco
  642. Initial revision
  643. }