home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TPTOOL4.ZIP / RPNCALC.INC < prev   
Encoding:
Text File  |  1987-03-28  |  4.8 KB  |  185 lines

  1.  
  2. const rpncalc_tag: string[90]
  3.    = #0'@(#)CURRENT_FILE LAST_UPDATE Post-fix calculator library 1.0'#0;
  4. #log Post-fix calculator library 1.0
  5.  
  6. (*
  7.  * MISC_rpn_calc - post-fix calculator
  8.  *
  9.  * This is a utility library to implement a simple post-fix (rpn)
  10.  * calculator that can be used when runtime defined calculations
  11.  * need to be made.
  12.  *
  13.  *)
  14.  
  15. function MISC_rpn_calc (initial_value:      real;
  16.                         formula:            anystring): real;
  17.                            {apply RPN calculator to formula with initial_value
  18.                              on top of stack. returns final top of stack}
  19.  
  20. const
  21.    stack_limit =       10;    {maximum stack depth}
  22.  
  23.  
  24. var
  25.    stack:              array [1.. stack_limit] of real;
  26.    top:                integer;
  27.    word:               anystring;
  28.    c:                  char;
  29.    i:                  integer;
  30.    code:               integer;
  31.    v1,
  32.    v2:                 real;
  33.  
  34.  
  35.    procedure push (v:                  real);
  36.                               {push v on top of the stack}
  37.    begin
  38.       top := top + 1;
  39.  
  40.       if top > stack_limit then
  41.       begin
  42.          MISC_fatal_error('RPN Stack overflow, formula: ' + formula);
  43.          top := top -1;
  44.       end;
  45.  
  46.       stack[top]:= v;
  47.    end;
  48.  
  49.  
  50.    function pop: real;        {pop a value off the top of stack}
  51.    begin
  52.  
  53.       if top < 1 then
  54.       begin
  55.          MISC_fatal_error('RPN Stack underflow, formula: ' + formula);
  56.          top := top + 1;
  57.       end;
  58.  
  59.       pop := stack [top];
  60.       top := top - 1;
  61.    end;
  62.  
  63.    function scannum(word: anystring; radix: integer): real;
  64.    var
  65.       i:  integer;
  66.       n:  real;
  67.       d:  integer;
  68.  
  69.    begin
  70.       n := 0.0;
  71.       for i := 2 to length(word) do
  72.       begin
  73.          d := ord(upcase(word[i])) - ord('0');
  74.          if d > 9 then
  75.             d := d - 7;
  76.          n := n * int(radix) + int(d);
  77.       end;
  78.  
  79.       scannum := n;
  80.    end;
  81.  
  82.    function binval(word: anystring): real;
  83.    begin
  84.       binval := scannum(word,2);
  85.    end;
  86.  
  87.    function hexval(word: anystring): real;
  88.    begin
  89.       hexval := scannum(word,16);
  90.    end;
  91.  
  92.    function tan(r: real): real;
  93.    begin
  94.       tan := sin(r) / cos(r);
  95.    end;
  96.  
  97. begin                         {MISC_rpn_calc}
  98.  
  99.    top := 0;
  100.    push(initial_value);
  101.    word := '';
  102.  
  103.    for i := 1 to length (formula) do
  104.                               {scan the formula string}
  105.    begin
  106.       c := formula [i];
  107.  
  108.       if c <> ' ' then
  109.          word := word + upcase(c);
  110.  
  111.       if (c = ' ') or (i = length (formula)) then
  112.                                  {if at the end of a word or at the end
  113.                                    of the formula}
  114.       begin
  115.  
  116.          case word [1] of       {check for and process each operator}
  117.  
  118.             '+':  push(pop + pop);
  119.  
  120.             '*':  push(pop * pop);
  121.  
  122.             '-':  begin
  123.                      if (length(word) > 1) and (word[2] in ['0'..'9']) then
  124.                      begin
  125.                         val(word, v1, code);
  126.                         push(v1);
  127.                      end
  128.                      else
  129.                      begin
  130.                         v1 := pop;
  131.                         v2 := pop;
  132.                         push(v2 - v1);
  133.                      end;
  134.                   end;
  135.  
  136.             '/':  begin
  137.                      v1 := pop;
  138.                      v2 := pop;
  139.                      push(v2 / v1);
  140.                   end;
  141.  
  142.             '\':  begin
  143.                      v1 := pop;
  144.                      if v1 <> 0.0 then
  145.                         push(1.0 / v1)
  146.                      else
  147.                         push(0.0);
  148.                   end;
  149.  
  150.             'H':  push(hexval(word));
  151.  
  152.             'B':  push(binval(word));
  153.  
  154.             '.','0'..'9':              {numbers are pushed on the stack}
  155.                   begin
  156.                      val(word, v1, code);
  157.                      push(v1);
  158.                   end;
  159.  
  160.             else
  161.                if word = 'PI'   then push(pi)        else
  162.                if word = 'SIN'  then push(sin(pop))  else
  163.                if word = 'COS'  then push(cos(pop))  else
  164.                if word = 'TAN'  then push(tan(pop))  else
  165.                if word = 'EXP'  then push(exp(pop))  else
  166.                if word = 'INT'  then push(int(pop))  else
  167.                if word = 'SQRT' then push(sqrt(pop)) else
  168.                if word = 'LN'   then push(ln(pop))   else
  169.                if word = 'E'    then push(exp(1.0))
  170.                else
  171.                   MISC_fatal_error('Unknown RPN word: ' + word +
  172.                                    ' in formula: ' + formula);
  173.          end;
  174.  
  175.          word := '';                {consume the word and scan for more
  176.                                       words}
  177.  
  178.       end;
  179.    end;
  180.  
  181.    MISC_rpn_calc := pop;
  182.  
  183. end;                       {MISC_rpn_calc}
  184.  
  185.