Parsing/RPN calculator algorithm: Difference between revisions
Content added Content deleted
(Added solution for Action!) |
|||
Line 183: | Line 183: | ||
Exec + Stack: 3 |
Exec + Stack: 3 |
||
Val= 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> |
</pre> |
||