home *** CD-ROM | disk | FTP | other *** search
/ Vectronix 2 / VECTRONIX2.iso / FILES_07 / HISPEED1.ZIP / DOSDEMO / MINICALC.PAS < prev    next >
Pascal/Delphi Source File  |  1991-07-02  |  6KB  |  209 lines

  1. Program MiniCalc;
  2. {$I-
  3.   Calculator by Christen Fihl 1990,
  4.   Example of use:   * P=22/7 ; 2+3 ; p*5 ; sin(pi*45/180)
  5.                     * 22/7 ; P ; 2+3
  6. }
  7. Type Real=Double; {Choose your own precision (Single/Double/Extended}
  8.  
  9. Const NextIsError=#1; NextIsValue=#2; NextIsName=#3; NextIsEOF=#4;
  10.  
  11. Type  TStr   =     String[80];
  12.       TSaved =     Array['A'..'Z'] of Real;
  13.  
  14. Var   xx: real;
  15.       Saved:       TSaved;                           {26 Memory cells}
  16.       InputLine:   TStr;
  17.       Position,n:  Integer;                    {Position on InputLine}
  18.       ErrPos:      Integer;
  19.       LastPos:     Integer;
  20.       CmdLine:     TStr;
  21.       NextName:    TStr;       {Returned by Next when  Ch=NextIsName}
  22.       NextVal,R:   Real;   {Value returned by Next when Ch=NextIsVal}
  23.       Ch,LastCh:   Char;
  24.  
  25. procedure Next;                                      {Return Ch:=Last}
  26. var p,e: integer;
  27. procedure NextCh;
  28. begin
  29.   if Position<=Length(InputLine) then inc(Position);
  30.   if Position>Length(InputLine) then Ch:=NextIsEOF
  31.   else Ch:=UpCase(InputLine[Position]);
  32. end;
  33. procedure PrevCh;
  34. begin
  35.   dec(Position)
  36. end;
  37.  
  38. begin {procedure Next}
  39.   LastCh:=Ch; LastPos:=Position;
  40.   repeat NextCh until Ch<>' ';
  41.   ErrPos:=Position;
  42.   case Ch of
  43.   '0'..'9','.':                                               {Number}
  44.     begin
  45.       p:=Position;
  46.       repeat NextCh until not (Ch in ['0'..'9','.']);
  47.       if UpCase(Ch)='E' then begin                        {look for E}
  48.         NextCh;
  49.         if Ch in ['+','-'] then NextCh;
  50.         while Ch in ['0'..'9'] do NextCh;
  51.       end;
  52.       Val(Copy(InputLine,p,Position-p),NextVal,e);
  53.       if e<>0 then begin Position:=p+e-1; Ch:=NextIsError end;
  54.       PrevCh; Ch:=NextIsValue;
  55.     end;
  56.   'A'..'Z':                                                     {Name}
  57.     begin
  58.       NextName:='';
  59.       while (Ch in ['A'..'Z']) do begin NextName:=NextName+Ch; NextCh end;
  60.       PrevCh; Ch:=NextIsName;
  61.     end;
  62.   end;
  63. end;
  64.  
  65. function AddExpr: Real; FORWARD;
  66.  
  67. function Factor: Real;
  68. function FindAndSkip(What: TStr): Boolean;
  69. begin
  70.   if NextName=What then begin
  71.     Next;  FindAndSkip:=True;
  72.   end else FindAndSkip:=False;
  73. end;
  74.  
  75. begin
  76.   case Ch of
  77.   NextIsValue:
  78.     begin
  79.       Factor:=NextVal;
  80.       Next;
  81.     end;
  82.   NextIsName:                                      {SIN(10) or SIN 10}
  83.     begin
  84.     {Add your own here}
  85.       if FindAndSkip('PI')   then Factor:=PI             else 
  86.       if FindAndSkip('SQR')  then Factor:=sqr(Factor)    else 
  87.       if FindAndSkip('SQRT') then Factor:=sqrt(Factor)   else  
  88.       if FindAndSkip('ABS')  then Factor:=abs(Factor)    else 
  89.       if FindAndSkip('SIN')  then Factor:=sin(Factor)    else 
  90.       if FindAndSkip('COS')  then Factor:=cos(Factor)    else 
  91.       if FindAndSkip('ARCTAN') then Factor:=arctan(Factor) else  
  92.       if FindAndSkip('LOG')  then Factor:=ln(Factor)/ln(10) else 
  93.       if FindAndSkip('LN')   then Factor:=ln(Factor)     else 
  94.       if FindAndSkip('EXP')  then Factor:=exp(Factor)    else   
  95.       if FindAndSkip('MIN')  then begin          {User defined rutine}
  96.         if Saved['X']<Saved['Y'] then Factor:=Saved['X']    {Min(x,y)}
  97.         else                          Factor:=Saved['Y']
  98.       end else
  99.       if Length(NextName)=1 then begin
  100.         Factor:=Saved[NextName[1]];
  101.         Next;
  102.       end else Ch:=NextIsError
  103.     end;
  104.   '(':                                                 {fx X=3+(4*5)}
  105.     begin
  106.       Next;
  107.       Factor:=AddExpr;                               {recursiv call!}
  108.       if Ch<>')' then Ch:=NextIsError
  109.       else Next;
  110.     end;
  111.   else {Error}
  112.     Ch:=NextIsError; Factor:=0;
  113.   end;
  114. end;
  115.  
  116. function SignedFactor: Real; {SignedFactor ::= (+|-| ) SignedFactor}
  117. begin
  118.   case Ch of
  119.   '-': begin Next; SignedFactor:=-SignedFactor; end;
  120.   '+': begin Next; SignedFactor:=+SignedFactor; end;
  121.   else
  122.     SignedFactor:=Factor;
  123.   end;
  124. end;
  125.  
  126. function Term: Real;         {Term ::= (^| ) SignedFactor}
  127. var   R: Real;
  128. begin
  129.   R:=SignedFactor;
  130.   while Ch='^' do begin
  131.     Next; R:=exp(ln(R)*SignedFactor);
  132.   end;
  133.   Term:=R;
  134. end;
  135.  
  136. function MulExpr: Real;      {MulExpr ::= Term (*|/| ) Term}
  137. var   R: Real;
  138. begin
  139.   R:=Term;
  140.   while Ch in ['*','/'] do begin
  141.     Next;
  142.     case LastCh of
  143.     '*': R:=R*Term;
  144.     '/': R:=R/Term;
  145.     end;
  146.   end;
  147.   MulExpr:=R;
  148. end;
  149.  
  150. function AddExpr: Real;       {AddExpr ::= MulExpr (+|-| ) MulExpr}
  151. var   R: Real;
  152. begin
  153.   R:=MulExpr;
  154.   while Ch in ['+','-'] do begin
  155.     Next;
  156.     case LastCh of
  157.     '+': R:=R+MulExpr;
  158.     '-': R:=R-MulExpr;
  159.     end;
  160.   end;
  161.   AddExpr:=R;
  162. end;
  163.  
  164. function AssignStmt: Boolean;  {AssignStmt ::= ID=AddExpr}
  165. var ID: Char; Pos2: Integer;
  166. begin
  167.   AssignStmt:=False;
  168.   if Ch=NextIsName then begin
  169.     Pos2:=LastPos; ID:=NextName[1];
  170.     Next; if Ch='=' then begin
  171.       Next;
  172.       Saved[ID]:=AddExpr;
  173.       AssignStmt:=True;
  174.     end else begin
  175.       Position:=Pos2; Next;
  176.     end;
  177.   end;
  178. end;
  179.  
  180. Label Exit;
  181. begin {Main program}
  182.   FillChar(Saved,SizeOf(Saved),0);
  183.   writeln('MiniCalc for Atari');
  184.   repeat
  185.     write('* '); readln(CmdLine); if CmdLine='' then goto Exit;
  186.     repeat
  187.       Position:=Pos(';',CmdLine+';');
  188.       InputLine:=Copy(CmdLine,1,Position-1);
  189.       Delete(CmdLine,1,Position);
  190.       Position:=0; Next;
  191.       if (Ch<>NextIsEOF) then begin
  192.         if not AssignStmt then begin
  193.           R:=AddExpr;
  194.           if Ch=NextIsEOF then begin
  195.             write('= ');
  196.             if abs(R)>1 then                  {Chose your own format}
  197.               writeln(R:10:5)
  198.             else
  199.               if R=0 then writeln(0) else writeln(R);
  200.           end;
  201.         end;
  202.         if Ch<>NextIsEOF then
  203.           writeln(InputLine,#13#10'^ fejl':ErrPos+8);
  204.       end;
  205.     until (CmdLine='');
  206.   until false;
  207. Exit:
  208. end.
  209.