home *** CD-ROM | disk | FTP | other *** search
- ; Written by Larry Salomon, Jr.
- ;
- ; Have at it ppl...Here is a reverse polish notation evaluator.
- ;
- ; It will accept the following operators:
- ; + plus 2 3 + equals 5
- ; - minus 3 2 - equals 1
- ; * times 3 2 * equals 6
- ; / divide 5 2 / equals 2.5
- ; < boolean less-than 5 2 < equals 0
- ; > boolean greater-than 5 2 > equals 1
- ; <= =< boolean less-than-or-equal-to 3 4 <= equals 1
- ; >= => boolean greater-than-or-equal-to 4 4 >= equals 1
- ; <> boolean not-equal-to 5 5 <> equals 0
- ; = boolean equal-to 5 5 = equals 1
- ; << shl shift left 1 3 << equals 8
- ; >> shr shift right 15 >> 3 equals 1
- ; ^ power 2 3 ^ equals 8
- ;
- ;-------------------------------------------------------
- defc calc=
- parse arg args
-
- if args='?' then
- call do_help()
- stop
- endif
-
- s_new(stack)
-
- while args/=='' do
- parse value args with val args
-
- if isnum(val) then
- s_push(stack,val)
- else
- call do_op(stack,val)
- endif
- endwhile
-
- res=s_pop(stack)
- sayerror 'The result is' res
-
- defproc do_help()
- sayerror 'Syntax: CALC reverse_polish_expression'
- sayerror 'Operators may be: + - * / < > <= >= = <> << >> int sqr'
-
- defproc do_op(var stack,op)
- if op='+' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- call s_push(stack,val2+val1)
- elseif op='-' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- call s_push(stack,val2-val1)
- elseif op='*' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- call s_push(stack,val2*val1)
- elseif op='/' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- call s_push(stack,val2/val1)
- elseif op='<' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- if val2<val1 then
- call s_push(stack,1)
- else
- call s_push(stack,0)
- endif
- elseif op='>' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- if val2>val1 then
- call s_push(stack,1)
- else
- call s_push(stack,0)
- endif
- elseif op='=' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- if val2=val1 then
- call s_push(stack,1)
- else
- call s_push(stack,0)
- endif
- elseif (op='<=') | (op='=<') then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- if val2<=val1 then
- call s_push(stack,1)
- else
- call s_push(stack,0)
- endif
- elseif (op='>=') | (op='=>') then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- if val2>=val1 then
- call s_push(stack,1)
- else
- call s_push(stack,0)
- endif
- elseif op='<>' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- if val2<>val1 then
- call s_push(stack,1)
- else
- call s_push(stack,0)
- endif
- elseif op='^' then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- call s_push(stack,power(val2,val1))
- elseif (op='<<') | (op='shl') then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- call s_push(stack,val2*power(2,val1))
- elseif (op='>>') | (op='shr') then
- val1=s_pop(stack)
- val2=s_pop(stack)
-
- call validate(2,val1,val2)
- call s_push(stack,trunc(val2/power(2,val1)))
- elseif op='int' then
- val1=s_pop(stack)
-
- call validate(1,val1)
- call s_push(stack,trunc(val1))
- elseif op='sqr' then
- val1=s_pop(stack)
-
- call validate(1,val1)
- call s_push(stack,val1*val1)
- else
- sayerror 'Invalid operator specified ("'op'").'
- stop
- endif
- return
-
- defproc validate(num)
- for i = 1 to num
- if arg(1+i)='' then
- sayerror 'Missing operand.'
- stop
- endif
- endfor
-
- defproc power(num,exp)
- if exp=0 then
- return 1
- else
- res=num
-
- while exp>1 do
- res=res*num
- exp=exp-1
- endwhile
-
- return res
- endif
-
- defproc trunc(val)
- p=pos('.',val)
-
- if p=0 then
- return val
- elseif p=1 then
- return 0
- else
- return substr(val,1,p-1)
- endif
-
- defproc s_new(var stack)
- stack=''
- return
-
- defproc s_empty(stack)
- if stack='' then
- return 1
- else
- return 0
- endif
-
- defproc s_push(var stack,val)
- stack=val stack
- return
-
- defproc s_pop(var stack)
- parse value stack with val stack
- return val
-
-