rpnthing.pas 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. program RPNThing;
  2. {
  3. $ id: $
  4. Copyright (c) 2000 by Marco van de Voort([email protected])
  5. member of the Free Pascal development team
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright. (LGPL)
  8. Much too simplistic program to test some basic features of Symbolic unit.
  9. It is the very rough skeleton of a symbolic RPN calculator like a HP48.
  10. Since there are no exception conditions in the parser or evaluator,
  11. please enter valid expressions.
  12. Don't use 5E6 notation, it is not implemented yet. You can enter
  13. symbolic expressions using x, integer constants and half the math
  14. unit's function.
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18. }
  19. {$ifdef FPC}
  20. {$Mode ObjFpc}
  21. {$endif}
  22. Uses Symbolic,Crt;
  23. function GetKey:char;
  24. begin
  25. repeat
  26. while keypressed DO ;
  27. result:=ReadKey;
  28. if result=#0 then {Make sure control codes are skipped apropiately}
  29. begin
  30. result:=readKey;
  31. result:=#0;
  32. end;
  33. until result IN ['X','x','O','o','q','Q',' ','+','-','*','/','^','e','E','d','D','T','t'];
  34. end;
  35. VAR Stack : array[0..100] of TExpression;
  36. I,StackPtr : Integer;
  37. InputC : Char;
  38. S : String;
  39. Flag : Boolean;
  40. Procedure Redraw;
  41. var I : Integer;
  42. begin
  43. for I:=1 to 20 DO
  44. begin
  45. GotoXY(1,I);
  46. Write(' ':79);
  47. GotoXY(1,I);
  48. IF (StackPtr>(20-I)) then
  49. begin
  50. IF NOT Assigned(stack[20-I]) then
  51. begin
  52. gotoXY(1,1); write(' ':50);
  53. gotoxy(1,1); writeln(I,' ',20-I);
  54. Writeln(stackptr);
  55. HALT;
  56. end;
  57. Writeln(stack[StackPtr-(21-I)].InfixExpr);
  58. end
  59. else
  60. write('-');
  61. end;
  62. GotoXY(1,21);
  63. Write(' ':80);
  64. end;
  65. begin
  66. Writeln(' + - / * ^ : perform the RPN operation');
  67. Writeln(' [space],'#39' : get a "prompt" to input a number or infix expression');
  68. Writeln(' E,e : Try to simplify/evaluate the expression. ');
  69. Writeln(' For now this is restricted to constant values only');
  70. Writeln(' D,d : Drop 1 value from the stack');
  71. Writeln(' Q,q : By pressing this key you agree this program is great');
  72. Writeln(' O,o : Derive the expression with respect to X');
  73. Writeln(' T,t : Taylor polynomal. Also with respect to X, and to 2nd ');
  74. writeln(' stacklevel degree');
  75. Writeln;
  76. Writeln('Press enter to start calculating');
  77. ReadLn;
  78. ClrScr;
  79. StackPtr:=0;
  80. repeat
  81. InputC:=GetKey;
  82. Case InputC OF
  83. '+','-','*','/','^' : if stackPtr>1 then
  84. begin
  85. Dec(StackPtr);
  86. case InputC of {Double case is ugly but short}
  87. '+' : Stack[StackPtr-1].AddTo(Stack[StackPtr]);
  88. '-' : Stack[StackPtr-1].SubFrom(Stack[StackPtr]);
  89. '*' : Stack[StackPtr-1].Times(Stack[StackPtr]);
  90. '/' : Stack[StackPtr-1].DivBy(Stack[StackPtr]);
  91. '^' : Stack[StackPtr-1].RaiseTo(Stack[StackPtr]);
  92. end;
  93. Stack[StackPtr].free;
  94. Redraw;
  95. end;
  96. 'E','e' : If Stackptr>0 then
  97. begin
  98. Stack[StackPtr-1].SimplifyConstants;
  99. Redraw;
  100. end;
  101. 'T','t' : If StackPtr>1 then {Stackptr-1=function. Stackptr-2=degree
  102. x is assumed, and x0 is substed}
  103. begin
  104. Flag:=True;
  105. Try
  106. i:=Stack[StackPtr-2].ValueAsInteger;
  107. except
  108. on ENotInt do
  109. begin
  110. GotoXY(1,1);
  111. WritelN('This constant doesn''t evaluate to an integer');
  112. Flag:=False;
  113. end;
  114. end;
  115. If I<0 then
  116. begin
  117. GotoXY(1,1);
  118. WritelN('I never heard of negative terms in a Taylor polynomal');
  119. end
  120. else
  121. If Flag then
  122. begin
  123. Stack[StackPtr-2].Free;
  124. Stack[StackPtr-2]:=Stack[StackPtr-1];
  125. Stack[StackPtr-1]:=Stack[StackPtr-2].Taylor(I,'X','0.0');
  126. Redraw;
  127. end;
  128. end;
  129. 'O','o' : if StackPtr>0 then
  130. begin
  131. Stack[StackPtr]:=Stack[StackPtr-1].Derive('X');
  132. Inc(StackPtr);
  133. Redraw;
  134. end;
  135. 'D','d' : If StackPtr>0 Then
  136. begin
  137. Stack[StackPtr-1].free;
  138. Dec(StackPtr);
  139. Redraw;
  140. end;
  141. ' ',#39 : If Stackptr<100 then
  142. begin
  143. GotoXY(1,1); Writeln(' ':60);
  144. gotoxy(1,1); write('Enter expr. : '); readln(s);
  145. s:=upcase(S);
  146. stack[StackPtr]:=TExpression.Create(S);
  147. Stack[StackPtr].Simplificationlevel:=2; {Don't add reals to integer. Only evaluates
  148. (integer op integer) and (real op real) and
  149. function(real)}
  150. Inc(Stackptr);
  151. Redraw;
  152. end;
  153. 'X','x' : begin
  154. ClrScr;
  155. Writeln(stdout,stack[StackPtr-1].InfixExpr);
  156. Writeln;
  157. Writeln(stdout,stack[StackPtr-1].RPNExpr);
  158. inputC:='q';
  159. end;
  160. end;
  161. until (InputC IN ['q','Q']);
  162. If StackPtr>0 THEN
  163. For I:=0 To StackPtr-1 Do
  164. Stack[I].Free;
  165. end.