home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
epmsmp.zip
/
RPN.E
< prev
next >
Wrap
Text File
|
1992-08-26
|
5KB
|
218 lines
; 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