         Edinburgh IMP77 Compiler - Version 8.4

    1  %begin
    2  %realfn eval    {evaluate sub-expression}
    3  %routinespec pushopd(%real val)
    4  %routinespec pushop(%integer op)
    5  %realfnspec popopd
    6  %integerfnspec popop
    7  %realfnspec nextopd
    8  %integerfnspec nextop
    9  %routinespec operate
   10  %constinteger plus=1,minus=2,times=3,divide=4,exp=5,assign=6,end=7,space=' '
   11  %constintegerarray prec(plus:assign)=1,1,2,2,3,0
   12  %realarray opds(0:4)    {operand stack}
   13  %integerarray ops(0:3)    {operator stack}
   14  %ownrealarray vars('a':'z')=0(*)
   15  %ownintegerarray vara('a':'z')=0(*)
   16  %integer op,opdsp,opsp,var
   17    opdsp=0 ; opsp=0    {init stack pointers}
   18    pushopd(nextopd)    {first operand}
   19    %cycle    {for each operator}
   20      op=nextop
   21      %if op=end %then %exit
   22      operate %while opsp>0 %and prec(ops(opsp))>=prec(op)
   23      %if op=assign %then %start
   24        read symbol(var)
   25        %unless 'a'<=var<='z' %or 'A'<=var<='Z' %then print symbol(var) %c
   26+         %and print string(" variable") %and %signal 15
   27        %if 'A'<=var<='Z' %then var=var-'A'+'a'
   28        vars(var)=opds(opdsp)
   29        vara(var)=1    {assigned}
   30        %continue
   31      %finish
   32      pushop(op)
   33      pushopd(nextopd)
   34    %repeat
   35    operate %while opsp>0
   36    %result=popopd
   37  !
   38  %routine pushopd(%real val)
   39    opdsp=opdsp+1
   40    opds(opdsp)=val
   41  %end
   42  !
   43  %routine pushop(%integer op)
   44    opsp=opsp+1
   45    ops(opsp)=op
   46  %end
   47  !
   48  %realfn popopd
   49  %real val
   50    val=opds(opdsp)
   51    opdsp=opdsp-1
   52    %result=val
   53  %end
   54  !
   55  %integerfn popop
   56  %integer op
   57    op=ops(opsp)
   58    opsp=opsp-1
   59    %result=op
   60  %end
   61  !
   62  %realfn nextopd
   63  %integer var
   64  %real opd
   65    skip symbol %while next symbol=space %or next symbol=nl
   66    %if '0'<=next symbol<='9' %or next symbol='-' %or next symbol='.' %c
   67+      %then read(opd) %and %result=opd
   68    %if next symbol='(' %then skip symbol %and %result=eval
   69    %if 'a'<=next symbol<='z' %or 'A'<=next symbol<='Z' %then %start
   70      read symbol(var)
   71      %if 'A'<=var<='Z' %then var=var-'A'+'a'
   72      %if vara(var)=0 %then print symbol(var) %and %c
   73+       print string(" unassigned") %and %signal 15
   74      %result=vars(var)
   75    %finish
   76    read symbol(var)
   77    print symbol(var)
   78    print string(" operand")
   79    %signal 15
   80  %end
   81  !
   82  %integerfn nextop
   83  %integer sym
   84    skip symbol %while next symbol=space
   85    read symbol(sym)
   86    %if sym='+' %then %result=plus
   87    %if sym='-' %then %result=minus
   88    %if sym='*' %then %result=times
   89    %if sym='/' %then %result=divide
   90    %if sym='^' %then %result=exp
   91    %if sym=':' %then %result=assign
   92    %if sym=')' %or sym=nl %then %result=end
   93    print symbol(sym)
   94    print string(" operator")
   95    %signal 15
   96  %end
   97  !
   98  %routine operate
   99  %real opd1,opd2
  100  %switch opn(plus:exp)
  101    opd2=popopd
  102    opd1=popopd
  103    ->opn(popop)
  104  opn(plus):pushopd(opd1+opd2) ; %return
  105  opn(minus):pushopd(opd1-opd2) ; %return
  106  opn(times):pushopd(opd1*opd2) ; %return
  107  opn(divide):%if opd2=0 %then print string("divide by zero") %and %signal 15
  108              pushopd(opd1/opd2) ; %return
  109  opn(exp):pushopd(opd1^int(opd2))
  110  %end
  111  !
  112  %end  {of eval}
  113  %real val
  114  
  115    %on %event 9,15 %start    {to trap everything}
  116  {*} %stop %if Event_Event = 9
  117      print string("?
  118+ ")
  119     ->again ; %finish
  120  
  121  select input(0); select output(0)
  122        prompt("eval:")
  123  again:val=eval
  124        %if val=int(val) %then write(int(val),0) { imp77 perms missing} {%else print(val,0,4)}
  125        newline
  126        ->again
  127  
  128  %endofprogram

  120 Statements compiled
