Parsing/RPN calculator algorithm: Difference between revisions

Added solution for Action!
(Added solution for Action!)
Line 183:
Exec + Stack: 3
Val= 3
</pre>
 
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
<lang Action!>INCLUDE "D2:REAL.ACT" ;from the Action! Tool Kit
 
DEFINE PTR="CARD"
DEFINE BUFFER_SIZE="60"
DEFINE ENTRY_SIZE="6"
DEFINE MAX_SIZE="10"
BYTE ARRAY stack(BUFFER_SIZE)
BYTE stackSize=[0]
 
BYTE FUNC IsEmpty()
IF stackSize=0 THEN
RETURN (1)
FI
RETURN (0)
 
PTR FUNC GetPtr(BYTE i)
RETURN (stack+i*ENTRY_SIZE)
 
PROC Push(REAL POINTER v)
REAL POINTER p
 
IF stackSize=MAX_SIZE THEN
PrintE("Error: stack is full!")
Break()
FI
p=GetPtr(stackSize)
RealAssign(v,p)
stackSize==+1
RETURN
 
PROC Pop(REAL POINTER v)
REAL POINTER p
 
IF IsEmpty() THEN
PrintE("Error: stack is empty!")
Break()
FI
stackSize==-1
p=GetPtr(stackSize)
RealAssign(p,v)
RETURN
 
PROC PrintStack()
INT i
REAL POINTER p
 
FOR i=0 TO stackSize-1
DO
p=GetPtr(i)
PrintR(p) Put(32)
OD
PutE()
RETURN
 
BYTE FUNC GetToken(CHAR ARRAY s BYTE start CHAR ARRAY t)
BYTE pos
 
pos=start
WHILE pos<=s(0) AND s(pos)#'
DO
pos==+1
OD
SCopyS(t,s,start,pos-1)
RETURN (pos)
 
PROC MyPower(REAL POINTER base,exp,res)
INT i,expI
REAL tmp
 
expI=RealToInt(exp)
IF expI<0 THEN Break() FI
 
IntToReal(1,res)
FOR i=1 TO expI
DO
RealMult(res,base,tmp)
RealAssign(tmp,res)
OD
RETURN
 
PROC Process(CHAR ARRAY s)
DEFINE Pop21="Pop(v2) Pop(v1)"
CHAR ARRAY t(100)
BYTE i,j
CHAR c
REAL v1,v2,v3
 
i=1
WHILE i<=s(0)
DO
WHILE i<=s(0) AND s(i)='
DO i==+1 OD
IF i>s(0) THEN EXIT FI
 
i=GetToken(s,i,t)
IF SCompare(t,"+")=0 THEN
Pop21 RealAdd(v1,v2,v3)
Print("calc +: ")
ELSEIF SCompare(t,"-")=0 THEN
Pop21 RealSub(v1,v2,v3)
Print("calc -: ")
ELSEIF SCompare(t,"*")=0 THEN
Pop21 RealMult(v1,v2,v3)
Print("calc *: ")
ELSEIF SCompare(t,"/")=0 THEN
Pop21 RealDiv(v1,v2,v3)
Print("calc /: ")
ELSEIF SCompare(t,"^")=0 THEN
Pop21 MyPower(v1,v2,v3)
Print("calc ^: ")
ELSE
ValR(t,v3)
PrintF("push %S: ",t)
FI
Push(v3)
PrintStack()
OD
RETURN
 
PROC Test(CHAR ARRAY s)
PrintE(s) PutE()
Process(s)
RETURN
 
PROC Main()
Put(125) PutE() ;clear the screen
Test("3 4 2 * 1 5 - 2 3 ^ ^ / +")
RETURN</lang>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/RPN_calculator_algorithm.png Screenshot from Atari 8-bit computer]
<pre>
3 4 2 * 1 5 - 2 3 ^ ^ / +
 
push 3: 3
push 4: 3 4
push 2: 3 4 2
calc *: 3 8
push 1: 3 8 1
push 5: 3 8 1 5
calc -: 3 8 -4
push 2: 3 8 -4 2
push 3: 3 8 -4 2 3
calc ^: 3 8 -4 8
calc ^: 3 8 65536
calc /: 3 1.22070312E-04
calc +: 3.00012207
</pre>
 
Anonymous user