Parsing/RPN calculator algorithm: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
 
(48 intermediate revisions by 31 users not shown)
Line 22:
*   [[Arithmetic evaluation]].
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">[Float] a
[String = ((Float, Float) -> Float)] b
b[‘+’] = (x, y) -> y + x
b[‘-’] = (x, y) -> y - x
b[‘*’] = (x, y) -> y * x
b[‘/’] = (x, y) -> y / x
b[‘^’] = (x, y) -> y ^ x
 
L(c) ‘3 4 2 * 1 5 - 2 3 ^ ^ / +’.split(‘ ’)
I c C b
V first = a.pop()
V second = a.pop()
a.append(b[c](first, second))
E
a.append(Float(c))
print(c‘ ’a)</syntaxhighlight>
 
{{out}}
<pre>
3 [3]
4 [3, 4]
2 [3, 4, 2]
* [3, 8]
1 [3, 8, 1]
5 [3, 8, 1, 5]
- [3, 8, -4]
2 [3, 8, -4, 2]
3 [3, 8, -4, 2, 3]
^ [3, 8, -4, 8]
^ [3, 8, 65536]
/ [3, 0.00012207]
+ [3.00012207]
</pre>
 
=={{header|360 Assembly}}==
{{trans|FORTRAN}}
For concision, only integer arithmetic is handled, but input numbers can be of any length. The formal task is not completed, but the spirit of it is.
<syntaxhighlight lang="360asm">* RPN calculator RC 25/01/2019
REVPOL CSECT
USING REVPOL,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) save previous context
ST R13,4(R15) link backward
ST R15,8(R13) link forward
LR R13,R15 set addressability
XPRNT TEXT,L'TEXT print expression !?
L R4,0 js=0 offset in stack
LA R5,0 ns=0 number of stack items
LA R6,0 jt=0 offset in text
LA R7,TEXT r7=@text
MVC CC,0(R7) cc first char of token
DO WHILE=(CLI,CC,NE,X'00') do while cc<>'0'x
MVC CTOK,=CL5' ' ctok=''
MVC CTOK(1),CC ctok=cc
CLI CC,C' ' if cc=' '
BE ITERATE then goto iterate
IF CLI,CC,GE,C'0',AND,CLI,CC,LE,C'9' THEN
MVC DEED,=C'Load' deed='Load'
XDECI R2,0(R7) r2=cint(text); r1=@text
ST R2,STACK(R4) stack(js)=cc
SR R1,R7 lt length of token
BCTR R1,0 lt-1
EX R1,MVCV MVC CTOK("R1"),0(R7)
AR R6,R1 jt+=lt-1
AR R7,R1 @text+=lt-1
LA R4,4(R4) js+=4
LA R5,1(R5) ns++
ELSE , else
MVC DEED,=C'Exec' deed='Exec'
LA R9,STACK-8(R4) @stack(j-1)
IF CLI,CC,EQ,C'+' THEN if cc='+' then
L R1,STACK-8(R4) stack(j-1)
A R1,STACK-4(R4) stack(j-1)+stack(j)
ST R1,0(R9) stack(j-1)=stack(j-1)+stack(j)
ENDIF , endif
IF CLI,CC,EQ,C'-' THEN if cc='-' then
L R1,STACK-8(R4) stack(j-1)
S R1,STACK-4(R4) stack(j-1)-stack(j)
ST R1,0(R9) stack(j-1)=stack(j-1)-stack(j)
ENDIF , endif
IF CLI,CC,EQ,C'*' THEN if cc='*' then
L R3,STACK-8(R4) stack(j-1)
M R2,STACK-4(R4) stack(j-1)*stack(j)
ST R3,0(R9) stack(j-1)=stack(j-1)*stack(j)
ENDIF , endif
IF CLI,CC,EQ,C'/' THEN if cc='/' then
L R2,STACK-8(R4) stack(j-1)
SRDA R2,32 for sign propagation
D R2,STACK-4(R4) stack(j-1)/stack(j)
ST R3,0(R9) stack(j-1)=stack(j-1)/stack(j)
ENDIF , endif
IF CLI,CC,EQ,C'^' THEN if cc='^' then
LA R3,1 r3=1
L R0,STACK-4(R4) r0=stack(j) [loop count]
EXPONENT M R2,STACK-8(R4) r3=r3*stack(j-1)
BCT R0,EXPONENT if r0--<>0 then goto exponent
ST R3,0(R9) stack(j-1)=stack(j-1)^stack(j)
ENDIF , endif
S R4,=F'4' js-=4
BCTR R5,0 ns--
ENDIF , endif
MVC PG,=CL80' ' clean buffer
MVC PG(4),DEED output deed
MVC PG+5(5),CTOK output cc
MVC PG+11(6),=C'Stack:' output
LA R2,1 i=1
LA R3,STACK @stack
LA R9,PG+18 @buffer
DO WHILE=(CR,R2,LE,R5) do i=1 to ns
L R1,0(R3) stack(i)
XDECO R1,XDEC edit stack(i)
MVC 0(5,R9),XDEC+7 output stack(i)
LA R2,1(R2) i=i+1
LA R3,4(R3) @stack+=4
LA R9,6(R9) @buffer+=6
ENDDO , enddo
XPRNT PG,L'PG print
ITERATE LA R6,1(R6) jt++
LA R7,1(R7) @text++
MVC CC,0(R7) cc next char
ENDDO , enddo
L R1,STACK stack(1)
XDECO R1,XDEC edit stack(1)
MVC XDEC(4),=C'Val=' output
XPRNT XDEC,L'XDEC print stack(1)
L R13,4(0,R13) restore previous savearea pointer
LM R14,R12,12(R13) restore previous context
XR R15,R15 rc=0
BR R14 exit
MVCV MVC CTOK(0),0(R7) patern mvc
TEXT DC C'3 4 2 * 1 5 - 2 3 ^ ^ / +',X'00'
STACK DS 16F stack(16)
DEED DS CL4
CC DS C
CTOK DS CL5
PG DS CL80
XDEC DS CL12
YREGS
END REVPOL</syntaxhighlight>
{{out}}
<pre>
3 4 2 * 1 5 - 2 3 ^ ^ / +
Load 3 Stack: 3
Load 4 Stack: 3 4
Load 2 Stack: 3 4 2
Exec * Stack: 3 8
Load 1 Stack: 3 8 1
Load 5 Stack: 3 8 1 5
Exec - Stack: 3 8 -4
Load 2 Stack: 3 8 -4 2
Load 3 Stack: 3 8 -4 2 3
Exec ^ Stack: 3 8 -4 8
Exec ^ Stack: 3 8 65536
Exec / Stack: 3 0
Exec + Stack: 3
Val= 3
</pre>
 
=={{header|Action!}}==
{{libheader|Action! Tool Kit}}
<syntaxhighlight 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</syntaxhighlight>
{{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>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Containers.Vectors;
 
procedure RPN_Calculator is
Line 91 ⟶ 403:
 
 
end RPN_Calculator;</langsyntaxhighlight>
 
{{out}}
Line 109 ⟶ 421:
3.00012
Result = 3.00012</pre>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.win32}}
<langsyntaxhighlight lang="algol68"># RPN Expression evaluator - handles numbers and + - * / ^ #
# the right-hand operand for ^ is converted to an integer #
 
Line 253 ⟶ 566:
evaluate( rpn expression )
 
)</langsyntaxhighlight>
{{out}}
<pre>
Line 272 ⟶ 585:
Result is: +3.00012207
</pre>
=={{header|ANSI Standard BASIC}}==
<lang ANSI Standard BASIC>1000 DECLARE EXTERNAL SUB rpn
1010 PUBLIC NUMERIC R(64) ! stack
1020 PUBLIC STRING expn$ ! for keyboard input
1030 PUBLIC NUMERIC i, lenn, n, true, false ! global values
1040 LET true = -1
1050 LET false = 0
1060 DO
1070 PRINT "enter an RPN expression:"
1080 INPUT expn$
1090 IF LEN( expn$ ) = 0 THEN EXIT DO
1100 PRINT "expn: ";expn$
1110 CALL rpn( expn$ )
1120 LOOP
1130 END
1140 !
1150 ! interpret reverse polish (postfix) expression
1160 EXTERNAL SUB rpn( expn$ )
1170 DECLARE EXTERNAL FUNCTION is_digit, get_number
1180 DECLARE EXTERNAL SUB print_stack
1190 DECLARE STRING ch$
1200 LET expn$ = expn$ & " " ! must terminate line with space
1210 LET lenn = LEN( expn$ )
1220 LET i = 0
1230 LET n = 1
1240 LET R(n) = 0.0 ! push zero for unary operations
1250 DO
1260 IF i >= lenn THEN EXIT DO ! at end of line
1270 LET i = i + 1
1280 IF expn$(i:i) <> " " THEN ! skip white spaces
1290 IF is_digit( expn$(i:i) ) = true THEN ! push number onto stack
1300 LET n = n + 1
1310 LET R(n) = get_number
1320 CALL print_stack
1330 ELSEIF expn$(i:i) = "+" then ! add and pop stack
1340 IF n < 2 THEN
1350 PRINT "stack underflow"
1360 ELSE
1370 LET R(n-1) = R(n-1) + R(n)
1380 LET n = n - 1
1390 CALL print_stack
1400 END IF
1410 ELSEIF expn$(i:i) = "-" then ! subtract and pop stack
1420 IF n < 2 THEN
1430 PRINT "stack underflow"
1440 ELSE
1450 LET R(n-1) = R(n-1) - R(n)
1460 LET n = n - 1
1470 CALL print_stack
1480 END IF
1490 ELSEIF expn$(i:i) = "*" then ! multiply and pop stack
1500 IF n < 2 THEN
1510 PRINT "stack underflow"
1520 ELSE
1530 LET R(n-1) = R(n-1) * R(n)
1540 LET n = n - 1
1550 CALL print_stack
1560 END IF
1570 ELSEIF expn$(i:i) = "/" THEN ! divide and pop stack
1580 IF n < 2 THEN
1590 PRINT "stack underflow"
1600 ELSE
1610 LET R(n-1) = R(n-1) / R(n)
1620 LET n = n - 1
1630 CALL print_stack
1640 END IF
1650 ELSEIF expn$(i:i) = "^" THEN ! raise to power and pop stack
1660 IF n < 2 THEN
1670 PRINT "stack underflow"
1680 ELSE
1690 LET R(n-1) = R(n-1) ^ R(n)
1700 LET n = n - 1
1710 CALL print_stack
1720 END IF
1730 ELSE
1740 PRINT REPEAT$( " ", i+5 ); "^ error"
1750 EXIT DO
1760 END IF
1770 END IF
1780 LOOP
1790 PRINT "result: "; R(n) ! end of main program
1800 END SUB
1810 !
1820 ! extract a number from a string
1830 EXTERNAL FUNCTION get_number
1840 DECLARE EXTERNAL FUNCTION is_digit
1850 LET j = 1 ! start of number string
1860 DECLARE STRING number$ ! buffer for conversion
1870 DO ! get integer part
1880 LET number$(j:j) = expn$(i:i)
1890 LET i = i + 1
1900 LET j = j + 1
1910 IF is_digit( expn$(i:i) ) = false THEN
1920 IF expn$(i:i) = "." then
1930 LET number$(j:j) = expn$(i:i) ! include decimal point
1940 LET i = i + 1
1950 LET j = j + 1
1960 DO WHILE is_digit( expn$(i:i) ) = true ! get fractional part
1970 LET number$(j:j) = expn$(i:i)
1980 LET i = i + 1
1990 LET j = j + 1
2000 LOOP
2010 END IF
2020 EXIT DO
2030 END IF
2040 LOOP
2050 LET get_number = VAL( number$ )
2060 END FUNCTION
2070 !
2080 ! check for digit character
2090 EXTERNAL FUNCTION is_digit( ch$ )
2100 IF "0" <= expn$(i:i) AND expn$(i:i) <= "9" THEN
2110 LET is_digit = true
2120 ELSE
2130 LET is_digit = false
2140 END IF
2150 END FUNCTION
2160 !
2170 EXTERNAL SUB print_stack
2180 PRINT expn$(i:i);" ";
2190 FOR ptr=n TO 2 STEP -1
2200 PRINT USING "-----%.####":R(ptr);
2210 NEXT ptr
2220 PRINT
2230 END SUB</lang>
 
=={{header|ANTLR}}==
Line 404 ⟶ 592:
<br clear=both>
===Java===
<langsyntaxhighlight lang="java">
grammar rpnC ;
//
Line 424 ⟶ 612:
WS : (' ' | '\t'){skip()};
NEWLINE : '\r'? '\n';
</syntaxhighlight>
</lang>
Produces:
<pre>
Line 436 ⟶ 624:
{{works with|AutoHotkey_L}}
Output is in clipboard.
<langsyntaxhighlight AHKlang="ahk">evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
evalRPN(s){
stack := []
Line 470 ⟶ 658:
out .= A_Space value
return subStr(out, 2)
}</langsyntaxhighlight>
{{out}}
<pre>For RPN expression: '3 4 2 * 1 5 - 2 3 ^ ^ / +'
Line 491 ⟶ 679:
The final output value is: '3.000122'</pre>
 
=={{header|BBC BASIC}}==
==={{header|ANSI BASIC}}===
<lang bbcbasic> @% = &60B
{{works with|Decimal BASIC}}
<syntaxhighlight lang="basic">1000 DECLARE EXTERNAL SUB rpn
1010 PUBLIC NUMERIC R(64) ! stack
1020 PUBLIC STRING expn$ ! for keyboard input
1030 PUBLIC NUMERIC i, lenn, n, true, false ! global values
1040 LET true = -1
1050 LET false = 0
1060 DO
1070 PRINT "enter an RPN expression:"
1080 INPUT expn$
1090 IF LEN( expn$ ) = 0 THEN EXIT DO
1100 PRINT "expn: ";expn$
1110 CALL rpn( expn$ )
1120 LOOP
1130 END
1140 !
1150 ! interpret reverse polish (postfix) expression
1160 EXTERNAL SUB rpn( expn$ )
1170 DECLARE EXTERNAL FUNCTION is_digit, get_number
1180 DECLARE EXTERNAL SUB print_stack
1190 DECLARE STRING ch$
1200 LET expn$ = expn$ & " " ! must terminate line with space
1210 LET lenn = LEN( expn$ )
1220 LET i = 0
1230 LET n = 1
1240 LET R(n) = 0.0 ! push zero for unary operations
1250 DO
1260 IF i >= lenn THEN EXIT DO ! at end of line
1270 LET i = i + 1
1280 IF expn$(i:i) <> " " THEN ! skip white spaces
1290 IF is_digit( expn$(i:i) ) = true THEN ! push number onto stack
1300 LET n = n + 1
1310 LET R(n) = get_number
1320 CALL print_stack
1330 ELSEIF expn$(i:i) = "+" then ! add and pop stack
1340 IF n < 2 THEN
1350 PRINT "stack underflow"
1360 ELSE
1370 LET R(n-1) = R(n-1) + R(n)
1380 LET n = n - 1
1390 CALL print_stack
1400 END IF
1410 ELSEIF expn$(i:i) = "-" then ! subtract and pop stack
1420 IF n < 2 THEN
1430 PRINT "stack underflow"
1440 ELSE
1450 LET R(n-1) = R(n-1) - R(n)
1460 LET n = n - 1
1470 CALL print_stack
1480 END IF
1490 ELSEIF expn$(i:i) = "*" then ! multiply and pop stack
1500 IF n < 2 THEN
1510 PRINT "stack underflow"
1520 ELSE
1530 LET R(n-1) = R(n-1) * R(n)
1540 LET n = n - 1
1550 CALL print_stack
1560 END IF
1570 ELSEIF expn$(i:i) = "/" THEN ! divide and pop stack
1580 IF n < 2 THEN
1590 PRINT "stack underflow"
1600 ELSE
1610 LET R(n-1) = R(n-1) / R(n)
1620 LET n = n - 1
1630 CALL print_stack
1640 END IF
1650 ELSEIF expn$(i:i) = "^" THEN ! raise to power and pop stack
1660 IF n < 2 THEN
1670 PRINT "stack underflow"
1680 ELSE
1690 LET R(n-1) = R(n-1) ^ R(n)
1700 LET n = n - 1
1710 CALL print_stack
1720 END IF
1730 ELSE
1740 PRINT REPEAT$( " ", i+5 ); "^ error"
1750 EXIT DO
1760 END IF
1770 END IF
1780 LOOP
1790 PRINT "result: "; R(n) ! end of main program
1800 END SUB
1810 !
1820 ! extract a number from a string
1830 EXTERNAL FUNCTION get_number
1840 DECLARE EXTERNAL FUNCTION is_digit
1850 LET i1 = i ! start of number substring
1860 DO ! get integer part
1870 LET i = i + 1
1880 IF is_digit( expn$(i:i) ) = false THEN
1890 IF expn$(i:i) = "." THEN
1900 LET i = i + 1
1910 DO WHILE is_digit( expn$(i:i) ) = true ! get fractional part
1920 LET i = i + 1
1930 LOOP
1940 END IF
1950 EXIT DO
1960 END IF
1970 LOOP
1980 LET get_number = VAL( expn$(i1:i - 1) )
1990 END FUNCTION
2000 !
2010 ! check for digit character
2020 EXTERNAL FUNCTION is_digit( ch$ )
2030 IF "0" <= ch$ AND ch$ <= "9" THEN
2040 LET is_digit = true
2050 ELSE
2060 LET is_digit = false
2070 END IF
2080 END FUNCTION
2090 !
2100 EXTERNAL SUB print_stack
2110 PRINT expn$(i:i);" ";
2120 FOR ptr=n TO 2 STEP -1
2130 PRINT USING "-----%.####":R(ptr);
2140 NEXT ptr
2150 PRINT
2160 END SUB</syntaxhighlight>
{{out}}
<pre>
enter an RPN expression:
? 3 4 2 * 1 5 - 2 3 ^ ^ / +
expn: 3 4 2 * 1 5 - 2 3 ^ ^ / +
3.0000
4.0000 3.0000
2.0000 4.0000 3.0000
* 8.0000 3.0000
1.0000 8.0000 3.0000
5.0000 1.0000 8.0000 3.0000
- -4.0000 8.0000 3.0000
2.0000 -4.0000 8.0000 3.0000
3.0000 2.0000 -4.0000 8.0000 3.0000
^ 8.0000 -4.0000 8.0000 3.0000
^ 65536.0000 8.0000 3.0000
/ 0.0001 3.0000
+ 3.0001
result: 3.0001220703125
enter an RPN expression:
?
 
</pre>
 
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> @% = &60B
RPN$ = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
Line 529 ⟶ 861:
IF SP% = 0 ERROR 100, "Stack empty"
SP% -= 1
= Stack(SP%)</langsyntaxhighlight>
{{out}}
<pre>
Line 546 ⟶ 878:
+ : 3.00012
</pre>
 
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">#define NULL 0
 
type node
'implement the stack as a linked list
n as double
p as node ptr
end type
 
function spctok( byref s as string ) as string
'returns everything in the string up to the first space
'modifies the original string to begin at the fist non-space char after the first space
dim as string r
dim as double i = 1
while mid(s,i,1)<>" " and i<=len(s)
r += mid(s,i,1)
i+=1
wend
do
i+=1
loop until mid(s,i,1)<>" " or i >= len(s)
s = right(s,len(s)-i+1)
return r
end function
 
sub print_stack( byval S as node ptr )
'display everything on the stack
print "Stack <--- ";
while S->p <> NULL
S = S->p
print S->n;" ";
wend
print
end sub
 
sub push( byval S as node ptr, v as double )
'push a value onto the stack
dim as node ptr x
x = allocate(sizeof(node))
x->n = v
x->p = S->p
S->p = x
end sub
 
function pop( byval S as node ptr ) as double
'pop a value from the stack
if s->P = NULL then return -99999
dim as double r = S->p->n
dim as node ptr junk = S->p
S->p = S->p->p
deallocate(junk)
return r
end function
 
dim as string s = "3 4 2 * 1 5 - 2 3 ^ ^ / +", c
dim as node StackHead
 
while len(s) > 0
c = spctok(s)
print "Token: ";c;" ";
select case c
case "+"
push(@StackHead, pop(@StackHead) + pop(@StackHead))
print "Operation + ";
case "-"
push(@StackHead, -(pop(@StackHead) - pop(@StackHead)))
print "Operation - ";
case "/"
push(@StackHead, 1./(pop(@StackHead) / pop(@StackHead)))
print "Operation / ";
case "*"
push(@StackHead, pop(@StackHead) * pop(@StackHead))
print "Operation * ";
case "^"
push(@StackHead, pop(@StackHead) ^ pop(@StackHead))
print "Operation ^ ";
case else
push(@StackHead, val(c))
print "Operation push ";
end select
print_stack(@StackHead)
wend</syntaxhighlight>
{{out}}<pre>
Token: 3 Operation push Stack <--- 3
Token: 4 Operation push Stack <--- 4 3
Token: 2 Operation push Stack <--- 2 4 3
Token: * Operation * Stack <--- 8 3
Token: 1 Operation push Stack <--- 1 8 3
Token: 5 Operation push Stack <--- 5 1 8 3
Token: - Operation - Stack <--- -4 8 3
Token: 2 Operation push Stack <--- 2 -4 8 3
Token: 3 Operation push Stack <--- 3 2 -4 8 3
Token: ^ Operation ^ Stack <--- 8 -4 8 3
Token: ^ Operation ^ Stack <--- 65536 8 3
Token: / Operation / Stack <--- 0.0001220703125 3
Token: + Operation + Stack <--- 3.0001220703125
</pre>
 
=== {{header|GW-BASIC}} ===
{{trans|QuickBASIC}}
Supports multi-digit numbers and negative numbers.
{{works with|BASICA}}
<syntaxhighlight lang="gwbasic">
10 REM Parsing/RPN calculator algorithm
20 MAX.INDEX% = 63
30 REM Stack
40 REM TOP.INDEX% - top index of the stack
50 DIM ELEMS(MAX.INDEX%)
60 EXPR$ = "3 4 2 * 1 5 - 2 3 ^ ^ / +": GOSUB 200
70 END
190 REM ** Evaluate the expression in RPN
200 GOSUB 1000
210 PRINT "Input", "Operation", "Stack after"
220 REM SP% - start position of token, DP% - position of delimiter
230 DP% = 0
240 REM Loop: do ... until DP% = 0
250 SP% = DP% + 1
260 DP% = INSTR(DP% + 1, EXPR$, " ")
270 IF DP% = 0 THEN TOKEN$ = MID$(EXPR$, SP%, LEN(EXPR$) - SP% + 1) ELSE TE% = DP% - 1: TOKEN$ = MID$(EXPR$, SP%, DP% - SP%)
280 PRINT TOKEN$,
290 IF TOKEN$ <> "*" THEN 350
300 PRINT "Operate",
310 GOSUB 1060: SECOND = POP
320 GOSUB 1060: FIRST = POP
330 X = FIRST * SECOND: GOSUB 1160
340 GOTO 610
350 IF TOKEN$ <> "/" THEN 410
360 PRINT "Operate",
370 GOSUB 1060: SECOND = POP
380 GOSUB 1060: FIRST = POP
390 X = FIRST / SECOND: GOSUB 1160
400 GOTO 610
410 IF TOKEN$ <> "-" THEN 470
420 PRINT "Operate",
430 GOSUB 1060: SECOND = POP
440 GOSUB 1060: FIRST = POP
450 X = FIRST - SECOND: GOSUB 1160
460 GOTO 610
470 IF TOKEN$ <> "+" THEN 530
480 PRINT "Operate",
490 GOSUB 1060: SECOND = POP
500 GOSUB 1060: FIRST = POP
510 X = FIRST + SECOND: GOSUB 1160
520 GOTO 610
530 IF TOKEN$ <> "^" THEN 590
540 PRINT "Operate",
550 GOSUB 1060: SECOND = POP
560 GOSUB 1060: FIRST = POP
570 X = FIRST ^ SECOND: GOSUB 1160
580 GOTO 610
590 PRINT "Push",
600 X = VAL(TOKEN$): GOSUB 1160
610 GOSUB 1100
620 IF DP% <> 0 THEN 250
630 GOSUB 1060:
640 PRINT "Final answer: "; POP
650 GOSUB 1030
660 IF NOT EMPTY% THEN PRINT "Error, too many operands: "; : GOSUB 1100: STOP
670 RETURN
980 REM ** Operations on the stack
990 REM ** Make the stack empty
1000 TOP.INDEX% = MAX.INDEX% + 1
1010 RETURN
1020 REM ** Is the stack empty?
1030 EMPTY% = TOP.INDEX% > MAX.INDEX%
1040 RETURN
1050 REM ** Pop from the stack
1060 GOSUB 1030
1070 IF NOT EMPTY% THEN POP = ELEMS(TOP.INDEX%): TOP.INDEX% = TOP.INDEX% + 1 ELSE PRINT "The stack is empty.": STOP
1080 RETURN
1090 REM ** Print the stack
1100 FOR PTR% = TOP.INDEX% TO MAX.INDEX%
1110 PRINT USING "######.###"; ELEMS(PTR%);
1120 NEXT PTR%
1130 PRINT
1140 RETURN
1150 REM ** Push to the stack
1160 IF TOP.INDEX% > 0 THEN TOP.INDEX% = TOP.INDEX% - 1: ELEMS(TOP.INDEX%) = X ELSE PRINT "The stack is full.": STOP
1170 RETURN
</syntaxhighlight>
{{out}}
<pre>
Input Operation Stack after
3 Push 3.000
4 Push 4.000 3.000
2 Push 2.000 4.000 3.000
* Operate 8.000 3.000
1 Push 1.000 8.000 3.000
5 Push 5.000 1.000 8.000 3.000
- Operate -4.000 8.000 3.000
2 Push 2.000 -4.000 8.000 3.000
3 Push 3.000 2.000 -4.000 8.000 3.000
^ Operate 8.000 -4.000 8.000 3.000
^ Operate 65536.000 8.000 3.000
/ Operate 0.000 3.000
+ Operate 3.000
Final answer: 3.000122
</pre>
 
==={{header|Liberty BASIC}}===
{{works with|Just BASIC}}
<syntaxhighlight lang="lb">
global stack$
 
expr$ = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
print "Expression:"
print expr$
print
 
print "Input","Operation","Stack after"
 
stack$=""
token$ = "#"
i = 1
token$ = word$(expr$, i)
token2$ = " "+token$+" "
 
do
print "Token ";i;": ";token$,
select case
'operation
case instr("+-*/^",token$)<>0
print "operate",
op2$=pop$()
op1$=pop$()
if op1$="" then
print "Error: stack empty for ";i;"-th token: ";token$
end
end if
 
op1=val(op1$)
op2=val(op2$)
 
select case token$
case "+"
res = op1+op2
case "-"
res = op1-op2
case "*"
res = op1*op2
case "/"
res = op1/op2
case "^"
res = op1^op2
end select
 
call push str$(res)
'default:number
case else
print "push",
call push token$
end select
print "Stack: ";reverse$(stack$)
i = i+1
token$ = word$(expr$, i)
token2$ = " "+token$+" "
loop until token$ =""
 
res$=pop$()
print
print "Result:" ;res$
extra$=pop$()
if extra$<>"" then
print "Error: extra things on a stack: ";extra$
end if
end
 
'---------------------------------------
function reverse$(s$)
reverse$ = ""
token$="#"
while token$<>""
i=i+1
token$=word$(s$,i,"|")
reverse$ = token$;" ";reverse$
wend
end function
'---------------------------------------
sub push s$
stack$=s$+"|"+stack$ 'stack
end sub
 
function pop$()
'it does return empty on empty stack
pop$=word$(stack$,1,"|")
stack$=mid$(stack$,instr(stack$,"|")+1)
end function
</syntaxhighlight>
 
{{out}}
<pre>
Expression:
3 4 2 * 1 5 - 2 3 ^ ^ / +
 
Input Operation Stack after
Token 1: 3 push Stack: 3
Token 2: 4 push Stack: 3 4
Token 3: 2 push Stack: 3 4 2
Token 4: * operate Stack: 3 8
Token 5: 1 push Stack: 3 8 1
Token 6: 5 push Stack: 3 8 1 5
Token 7: - operate Stack: 3 8 -4
Token 8: 2 push Stack: 3 8 -4 2
Token 9: 3 push Stack: 3 8 -4 2 3
Token 10: ^ operate Stack: 3 8 -4 8
Token 11: ^ operate Stack: 3 8 65536
Token 12: / operate Stack: 3 0.12207031e-3
Token 13: + operate Stack: 3.00012207
 
Result:3.00012207
</pre>
 
==={{header|QuickBASIC}}===
{{trans|Java|In fact, stack and tokenizing had to be implemented. Converting string to numbers is based on the <code>VAL</code> function in BASIC.}}
Supports multi-digit numbers and negative numbers.
<syntaxhighlight lang="qbasic">
' Parsing/RPN calculator algorithm
DECLARE SUB MakeEmpty (S AS ANY)
DECLARE SUB Push (X AS SINGLE, S AS ANY)
DECLARE SUB PrintStack (S AS ANY)
DECLARE SUB EvalRPN (Expr$)
DECLARE FUNCTION Empty% (S AS ANY)
DECLARE FUNCTION Pop! (S AS ANY)
 
CONST MAXINDEX = 63
 
TYPE TNumStack
TopIndex AS INTEGER
Elems(MAXINDEX) AS SINGLE
END TYPE
 
EvalRPN ("3 4 2 * 1 5 - 2 3 ^ ^ / +")
END
 
FUNCTION Empty% (S AS TNumStack)
Empty% = S.TopIndex > MAXINDEX
END FUNCTION
 
SUB EvalRPN (Expr$)
DIM S AS TNumStack
MakeEmpty S
PRINT "Input", "Operation", "Stack after"
' SP% - start position of token
' DP% - position of delimiter
DP% = 0
DO
SP% = DP% + 1
DP% = INSTR(DP% + 1, Expr$, " ")
IF DP% <> 0 THEN
TE% = DP% - 1
Token$ = MID$(Expr$, SP%, DP% - SP%)
ELSE
Token$ = MID$(Expr$, SP%, LEN(Expr$) - SP% + 1)
END IF
PRINT Token$,
IF Token$ = "*" THEN
PRINT "Operate",
Second = Pop(S): First = Pop(S)
Push First * Second, S
ELSEIF Token$ = "/" THEN
PRINT "Operate",
Second = Pop(S): First = Pop(S)
Push First / Second, S
ELSEIF Token$ = "-" THEN
PRINT "Operate",
Second = Pop(S): First = Pop(S)
Push First - Second, S
ELSEIF Token$ = "+" THEN
PRINT "Operate",
Second = Pop(S): First = Pop(S)
Push First + Second, S
ELSEIF Token$ = "^" THEN
PRINT "Operate",
Second = Pop(S): First = Pop(S)
Push First ^ Second, S
ELSE
PRINT "Push",
Push VAL(Token$), S
END IF
PrintStack S
LOOP UNTIL DP% = 0
PRINT "Final answer: "; Pop(S)
IF NOT Empty(S) THEN
PRINT "Error, too many operands: ";
PrintStack S
STOP
END IF
END SUB
 
SUB MakeEmpty (S AS TNumStack)
S.TopIndex = MAXINDEX + 1
END SUB
 
FUNCTION Pop (S AS TNumStack)
IF Empty%(S) THEN
PRINT "The stack is empty."
STOP
ELSE
Pop = S.Elems(S.TopIndex)
S.TopIndex = S.TopIndex + 1
END IF
END FUNCTION
 
SUB PrintStack (S AS TNumStack)
FOR Ptr% = S.TopIndex% TO MAXINDEX
PRINT USING "######.###"; S.Elems(Ptr%);
NEXT Ptr%
PRINT
END SUB
 
SUB Push (X AS SINGLE, S AS TNumStack)
IF S.TopIndex = 0 THEN
PRINT "The stack is full."
STOP
ELSE
S.TopIndex = S.TopIndex - 1
S.Elems(S.TopIndex) = X
END IF
END SUB
</syntaxhighlight>
{{out}}
<pre>
Input Operation Stack after
3 Push 3.000
4 Push 4.000 3.000
2 Push 2.000 4.000 3.000
* Operate 8.000 3.000
1 Push 1.000 8.000 3.000
5 Push 5.000 1.000 8.000 3.000
- Operate -4.000 8.000 3.000
2 Push 2.000 -4.000 8.000 3.000
3 Push 3.000 2.000 -4.000 8.000 3.000
^ Operate 8.000 -4.000 8.000 3.000
^ Operate 65536.000 8.000 3.000
/ Operate 0.000 3.000
+ Operate 3.000
Final answer: 3.000122
</pre>
 
==={{header|Run BASIC}}===
<syntaxhighlight lang="runbasic">prn$ = "3 4 2 * 1 5 - 2 3 ^ ^ / + "
 
j = 0
while word$(prn$,i + 1," ") <> ""
i = i + 1
n$ = word$(prn$,i," ")
if n$ < "0" or n$ > "9" then
num1 = val(word$(stack$,s," "))
num2 = val(word$(stack$,s-1," "))
n = op(n$,num2,num1)
s = s - 1
stack$ = stk$(stack$,s -1,str$(n))
print "Push Opr ";n$;" to stack: ";stack$
else
s = s + 1
stack$ = stack$ + n$ + " "
print "Push Num ";n$;" to stack: ";stack$
end if
wend
 
function stk$(stack$,s,a$)
for i = 1 to s
stk$ = stk$ + word$(stack$,i," ") + " "
next i
stk$ = stk$ + a$ + " "
end function
 
FUNCTION op(op$,a,b)
if op$ = "*" then op = a * b
if op$ = "/" then op = a / b
if op$ = "^" then op = a ^ b
if op$ = "+" then op = a + b
if op$ = "-" then op = a - b
end function</syntaxhighlight>
<pre>Push Num 3 to stack: 3
Push Num 4 to stack: 3 4
Push Num 2 to stack: 3 4 2
Push Opr * to stack: 3 8
Push Num 1 to stack: 3 8 1
Push Num 5 to stack: 3 8 1 5
Push Opr - to stack: 3 8 -4
Push Num 2 to stack: 3 8 -4 2
Push Num 3 to stack: 3 8 -4 2 3
Push Opr ^ to stack: 3 8 -4 8
Push Opr ^ to stack: 3 8 65536
Push Opr / to stack: 3 1.22070312e-4
Push Opr + to stack: 3.00012207</pre>
 
==={{header|Sinclair ZX81 BASIC}}===
If you only have 1k of RAM, this program will correctly evaluate the test expression with fewer than 10 bytes to spare. (I know that because I tried running it with the first line modified to allow a stack depth of 7, i.e. allocating space for two more 40-bit floats, and it crashed with an "out of memory" error code before it could print the result of the final addition.) If we desperately needed a few extra bytes there are ways they could be shaved out of the current program; but this version works, and editing a program that takes up almost all your available RAM isn't very comfortable, and to make it really useful for practical purposes you would still want to have 2k or more anyway.
 
The ZX81 character set doesn't include <code>^</code>, so we have to use <code>**</code> instead. Note that this is not two separate stars, although that's what it looks like: you have to enter it by typing <code>SHIFT</code>+<code>H</code>.
 
No attempt is made to check for invalid syntax, stack overflow or underflow, etc.
 
<syntaxhighlight lang="basic"> 10 DIM S(5)
20 LET P=1
30 INPUT E$
40 LET I=0
50 LET I=I+1
60 IF E$(I)=" " THEN GOTO 110
70 IF I<LEN E$ THEN GOTO 50
80 LET W$=E$
90 GOSUB 150
100 STOP
110 LET W$=E$( TO I-1)
120 LET E$=E$(I+1 TO )
130 GOSUB 150
140 GOTO 40
150 IF W$="+" OR W$="-" OR W$="*" OR W$="/" OR W$="**" THEN GOTO 250
160 LET S(P)=VAL W$
170 LET P=P+1
180 PRINT W$;
190 PRINT ":";
200 FOR I=P-1 TO 1 STEP -1
210 PRINT " ";S(I);
220 NEXT I
230 PRINT
240 RETURN
250 IF W$="**" THEN LET S(P-2)=ABS S(P-2)
260 LET S(P-2)=VAL (STR$ S(P-2)+W$+STR$ S(P-1))
270 LET P=P-1
280 GOTO 180</syntaxhighlight>
{{in}}
<pre>3 4 2 * 1 5 - 2 3 ** ** / +</pre>
{{out}}
<pre>3: 3
4: 4 3
2: 2 4 3
*: 8 3
1: 1 8 3
5: 5 1 8 3
-: -4 8 3
2: 2 -4 8 3
3: 3 2 -4 8 3
**: 8 -4 8 3
**: 65536 8 3
/: .00012207031 3
+: 3.0001221</pre>
 
==={{header|VBA}}===
{{trans|Liberty BASIC}}
<syntaxhighlight lang="vba">Global stack$
Function RPN(expr$)
Debug.Print "Expression:"
Debug.Print expr$
Debug.Print "Input", "Operation", "Stack after"
stack$ = ""
token$ = "#"
i = 1
token$ = Split(expr$)(i - 1) 'split is base 0
token2$ = " " + token$ + " "
Do
Debug.Print "Token "; i; ": "; token$,
'operation
If InStr("+-*/^", token$) <> 0 Then
Debug.Print "operate",
op2$ = pop$()
op1$ = pop$()
If op1$ = "" Then
Debug.Print "Error: stack empty for "; i; "-th token: "; token$
End
End If
op1 = Val(op1$)
op2 = Val(op2$)
Select Case token$
Case "+"
res = CDbl(op1) + CDbl(op2)
Case "-"
res = CDbl(op1) - CDbl(op2)
Case "*"
res = CDbl(op1) * CDbl(op2)
Case "/"
res = CDbl(op1) / CDbl(op2)
Case "^"
res = CDbl(op1) ^ CDbl(op2)
End Select
Call push2(str$(res))
'default:number
Else
Debug.Print "push",
Call push2(token$)
End If
Debug.Print "Stack: "; reverse$(stack$)
i = i + 1
If i > Len(Join(Split(expr, " "), "")) Then
token$ = ""
Else
token$ = Split(expr$)(i - 1) 'base 0
token2$ = " " + token$ + " "
End If
Loop Until token$ = ""
Debug.Print
Debug.Print "Result:"; pop$()
'extra$ = pop$()
If stack <> "" Then
Debug.Print "Error: extra things on a stack: "; stack$
End If
End
End Function
'---------------------------------------
Function reverse$(s$)
reverse$ = ""
token$ = "#"
While token$ <> ""
i = i + 1
token$ = Split(s$, "|")(i - 1) 'split is base 0
reverse$ = token$ & " " & reverse$
Wend
End Function
'---------------------------------------
Sub push2(s$)
stack$ = s$ + "|" + stack$ 'stack
End Sub
Function pop$()
'it does return empty on empty stack
pop$ = Split(stack$, "|")(0)
stack$ = Mid$(stack$, InStr(stack$, "|") + 1)
End Function</syntaxhighlight>
 
{{out}}
<pre>?RPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
Expression:
3 4 2 * 1 5 - 2 3 ^ ^ / +
Input Operation Stack after
Token 1 : 3 push Stack: 3
Token 2 : 4 push Stack: 3 4
Token 3 : 2 push Stack: 3 4 2
Token 4 : * operate Stack: 3 8
Token 5 : 1 push Stack: 3 8 1
Token 6 : 5 push Stack: 3 8 1 5
Token 7 : - operate Stack: 3 8 -4
Token 8 : 2 push Stack: 3 8 -4 2
Token 9 : 3 push Stack: 3 8 -4 2 3
Token 10 : ^ operate Stack: 3 8 -4 8
Token 11 : ^ operate Stack: 3 8 65536
Token 12 : / operate Stack: 3 .0001220703125
Token 13 : + operate Stack: 3.0001220703125
 
Result: 3.0001220703125</pre>
 
==={{header|Xojo}}===
{{trans|VBA}}
<syntaxhighlight lang="xojo">
Function RPN(expr As String) As String
Dim tokenArray() As String
Dim stack() As String
Dim Wert1 As Double
Dim Wert2 As Double
'Initialize array (removed later)
ReDim tokenArray(1)
ReDim stack(1)
tokenArray = Split(expr, " ")
Dim i As integer
i = 0
 
While i <= tokenArray.Ubound
If tokenArray(i) = "+" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1+Wert2))
ElseIf tokenArray(i) = "-" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1-Wert2))
ElseIf tokenArray(i) = "*" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1*Wert2))
ElseIf tokenArray(i) = "/" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1/Wert2))
ElseIf tokenArray(i) = "^" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(pow(Wert1,Wert2)))
Else
stack.Append(tokenArray(i))
End If
i = i +1
Wend
Return stack(2)
End Function</syntaxhighlight>
 
 
 
{{out}}
<pre>?RPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
Expression:
3 4 2 * 1 5 - 2 3 ^ ^ / +
 
Input Operation Stack after
Token 1 : 3 push Stack: 3
Token 2 : 4 push Stack: 3 4
Token 3 : 2 push Stack: 3 4 2
Token 4 : * operate Stack: 3 8
Token 5 : 1 push Stack: 3 8 1
Token 6 : 5 push Stack: 3 8 1 5
Token 7 : - operate Stack: 3 8 -4
Token 8 : 2 push Stack: 3 8 -4 2
Token 9 : 3 push Stack: 3 8 -4 2 3
Token 10 : ^ operate Stack: 3 8 -4 8
Token 11 : ^ operate Stack: 3 8 65536
Token 12 : / operate Stack: 3 .000122
Token 13 : + operate Stack: 3.000122
 
Result: 3.000122</pre>
 
=={{header|Bracmat}}==
<syntaxhighlight lang="bracmat">( ( show
= line a
. \n:?line
& whl
' (!arg:%?a ?arg&!a " " !line:?line)
& put$(str$!line)
)
& :?stack
& map
$ ( (
= a b
. show$(!arg !stack)
& ( !arg
: ( "+"
| "-"
| "*"
| "/"
| "^"
)
& !stack:%?a %?b ?stack
& ( !arg:"+"&!a+!b
| !arg:"-"&-1*!a+!b
| !arg:"*"&!a*!b
| !arg:"/"&!a*!b^-1
| !a^!b
)
| !arg
)
!stack
: ?stack
)
. vap$((=.!arg).get'(,STR)." ")
)
& out$!stack
)</syntaxhighlight>
Input from keyboard:
<pre>3 4 2 * 1 5 - 2 3 ^ ^ / +</pre>
Output:
<pre>3
3 4
3 4 2
3 4 2 *
3 8 1
3 8 1 5
3 8 1 5 -
3 8 -4 2
3 8 -4 2 3
3 8 -4 2 3 ^
3 8 -4 9 ^
3 8 1/6561 /
3 1/52488 +
157465/52488
{!} 157465/52488</pre>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 609 ⟶ 1,721:
printf("%g\n", rpn(s));
return 0;
}</langsyntaxhighlight>
 
It's also possible to parse RPN string backwards and recursively; good luck printing out your token stack ''as a table'': there isn't one.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
Line 664 ⟶ 1,776:
printf("%g\n", rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +"));
return 0;
}</langsyntaxhighlight>
 
=={{header|C++}}==
<lang cpp>#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <cstdlib>
 
double rpn(const std::string &expr){
std::istringstream iss(expr);
std::vector<double> stack;
std::cout << "Input\tOperation\tStack after" << std::endl;
std::string token;
while (iss >> token) {
std::cout << token << "\t";
double tokenNum;
if (std::istringstream(token) >> tokenNum) {
std::cout << "Push\t\t";
stack.push_back(tokenNum);
} else {
std::cout << "Operate\t\t";
double secondOperand = stack.back();
stack.pop_back();
double firstOperand = stack.back();
stack.pop_back();
if (token == "*")
stack.push_back(firstOperand * secondOperand);
else if (token == "/")
stack.push_back(firstOperand / secondOperand);
else if (token == "-")
stack.push_back(firstOperand - secondOperand);
else if (token == "+")
stack.push_back(firstOperand + secondOperand);
else if (token == "^")
stack.push_back(std::pow(firstOperand, secondOperand));
else { //just in case
std::cerr << "Error" << std::endl;
std::exit(1);
}
}
std::copy(stack.begin(), stack.end(), std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
}
return stack.back();
}
 
int main() {
std::string s = " 3 4 2 * 1 5 - 2 3 ^ ^ / + ";
std::cout << "Final answer: " << rpn(s) << std::endl;
return 0;
}</lang>
{{out}}
<pre>
Input Operation Stack after
3 Push 3
4 Push 3 4
2 Push 3 4 2
* Operate 3 8
1 Push 3 8 1
5 Push 3 8 1 5
- Operate 3 8 -4
2 Push 3 8 -4 2
3 Push 3 8 -4 2 3
^ Operate 3 8 -4 8
^ Operate 3 8 65536
/ Operate 3 0.00012207
+ Operate 3.00012
Final answer: 3.00012
</pre>
 
=={{header|C sharp|C#}}==
<langsyntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
Line 839 ⟶ 1,878:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 859 ⟶ 1,898:
 
Result is 3.0001220703125
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <vector>
#include <string>
#include <sstream>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <iterator>
#include <cstdlib>
 
double rpn(const std::string &expr){
std::istringstream iss(expr);
std::vector<double> stack;
std::cout << "Input\tOperation\tStack after" << std::endl;
std::string token;
while (iss >> token) {
std::cout << token << "\t";
double tokenNum;
if (std::istringstream(token) >> tokenNum) {
std::cout << "Push\t\t";
stack.push_back(tokenNum);
} else {
std::cout << "Operate\t\t";
double secondOperand = stack.back();
stack.pop_back();
double firstOperand = stack.back();
stack.pop_back();
if (token == "*")
stack.push_back(firstOperand * secondOperand);
else if (token == "/")
stack.push_back(firstOperand / secondOperand);
else if (token == "-")
stack.push_back(firstOperand - secondOperand);
else if (token == "+")
stack.push_back(firstOperand + secondOperand);
else if (token == "^")
stack.push_back(std::pow(firstOperand, secondOperand));
else { //just in case
std::cerr << "Error" << std::endl;
std::exit(1);
}
}
std::copy(stack.begin(), stack.end(), std::ostream_iterator<double>(std::cout, " "));
std::cout << std::endl;
}
return stack.back();
}
 
int main() {
std::string s = " 3 4 2 * 1 5 - 2 3 ^ ^ / + ";
std::cout << "Final answer: " << rpn(s) << std::endl;
return 0;
}</syntaxhighlight>
{{out}}
<pre>
Input Operation Stack after
3 Push 3
4 Push 3 4
2 Push 3 4 2
* Operate 3 8
1 Push 3 8 1
5 Push 3 8 1 5
- Operate 3 8 -4
2 Push 3 8 -4 2
3 Push 3 8 -4 2 3
^ Operate 3 8 -4 8
^ Operate 3 8 65536
/ Operate 3 0.00012207
+ Operate 3.00012
Final answer: 3.00012
</pre>
 
=={{header|Ceylon}}==
<syntaxhighlight lang="text">import ceylon.collection {
 
ArrayList
Line 905 ⟶ 2,017:
print(calculate("3 4 2 * 1 5 - 2 3 ^ ^ / +"));
}</langsyntaxhighlight>
{{out}}
<pre>Token Operation Stack
Line 926 ⟶ 2,038:
=={{header|Clojure}}==
This would be a lot simpler and generic if we were allowed to use something other than ^ for exponentiation. ^ isn't a legal clojure symbol.
<langsyntaxhighlight lang="clojure">
(ns rosettacode.parsing-rpn-calculator-algorithm
(:require clojure.math.numeric-tower
Line 956 ⟶ 2,068:
(clojure.pprint/pprint stacks)
(print "answer:" (->> stacks last first)))
</syntaxhighlight>
</lang>
{{out}}
stacks:
Line 974 ⟶ 2,086:
[24577/8192])
answer: 24577/8192
 
=={{header|CLU}}==
<syntaxhighlight lang="clu">% Split string by whitespace
split = iter (expr: string) yields (string)
own whitespace: string := " \r\n\t"
cur: array[char] := array[char]$[]
for c: char in string$chars(expr) do
if string$indexc(c, whitespace) = 0 then
array[char]$addh(cur, c)
else
if array[char]$empty(cur) then continue end
yield(string$ac2s(cur))
cur := array[char]$[]
end
end
if ~array[char]$empty(cur) then
yield(string$ac2s(cur))
end
end split
 
% Tokenize a RPN expression
token = oneof[number: real, op: char]
tokens = iter (expr: string) yields (token) signals (parse_error(string))
own operators: string := "+-*/^"
for t: string in split(expr) do
if string$size(t) = 1 cand string$indexc(t[1], operators)~=0 then
yield(token$make_op(t[1]))
else
yield(token$make_number(real$parse(t)))
except when bad_format:
signal parse_error(t)
end
end
end
end tokens
 
% Print the stack
print_stack = proc (stack: array[real])
po: stream := stream$primary_output()
for num: real in array[real]$elements(stack) do
stream$puts(po, f_form(num, 5, 5) || " ")
end
stream$putl(po, "")
end print_stack
 
% Evaluate an expression, printing the stack at each point
evaluate_rpn = proc (expr: string) returns (real) signals (parse_error(string), bounds)
stack: array[real] := array[real]$[]
for t: token in tokens(expr) do
tagcase t
tag number (n: real): array[real]$addh(stack, n)
tag op (f: char):
r: real := array[real]$remh(stack)
l: real := array[real]$remh(stack)
n: real
if f='+' then n := l+r
elseif f='-' then n := l-r
elseif f='*' then n := l*r
elseif f='/' then n := l/r
elseif f='^' then n := l**r
end
array[real]$addh(stack, n)
end
print_stack(stack)
end resignal parse_error
return(array[real]$reml(stack))
end evaluate_rpn
start_up = proc ()
po: stream := stream$primary_output()
expr: string := "3 4 2 * 1 5 - 2 3 ^ ^ / +"
stream$putl(po, "Expression: " || expr)
stream$putl(po, "Result: " || f_form(evaluate_rpn(expr), 5, 5))
end start_up</syntaxhighlight>
{{out}}
<pre>Expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
3.00000
3.00000 4.00000
3.00000 4.00000 2.00000
3.00000 8.00000
3.00000 8.00000 1.00000
3.00000 8.00000 1.00000 5.00000
3.00000 8.00000 -4.00000
3.00000 8.00000 -4.00000 2.00000
3.00000 8.00000 -4.00000 2.00000 3.00000
3.00000 8.00000 -4.00000 8.00000
3.00000 8.00000 65535.99240
3.00000 0.00012
3.00012
Result: 3.00012</pre>
 
 
=={{header|COBOL}}==
<syntaxhighlight lang="cobol">
IDENTIFICATION DIVISION.
PROGRAM-ID. RPN.
AUTHOR. Bill Gunshannon.
INSTALLATION.
DATE-WRITTEN. 9 Feb 2020.
************************************************************
** Program Abstract:
** Create a stack-based evaluator for an expression in
** reverse Polish notation (RPN) that also shows the
** changes in the stack as each individual token is
** processed as a table.
************************************************************
DATA DIVISION.
WORKING-STORAGE SECTION.
01 LineIn PIC X(25).
01 IP PIC 99
VALUE 1.
01 CInNum PIC XXXX.
 
01 Stack PIC S999999V9999999
OCCURS 50 times.
01 SP PIC 99
VALUE 1.
01 Operator PIC X.
01 Value1 PIC S999999V9999999.
01 Value2 PIC S999999V9999999.
01 Result PIC S999999V9999999.
01 Idx PIC 99.
01 FormatNum PIC ZZZZZZ9.9999999.
01 Zip PIC X.
PROCEDURE DIVISION.
Main-Program.
DISPLAY "Enter the RPN Equation: "
WITH NO ADVANCING.
ACCEPT LineIn.
 
PERFORM UNTIL IP GREATER THAN
FUNCTION STORED-CHAR-LENGTH(LineIn)
 
 
UNSTRING LineIn DELIMITED BY SPACE INTO CInNum
WITH POINTER IP
 
MOVE CInNum TO Operator
 
PERFORM Do-Operation
 
PERFORM Show-Stack
 
END-PERFORM.
 
DISPLAY "End Result: " FormatNum
 
STOP RUN.
Do-Operation.
 
EVALUATE Operator
WHEN "+"
PERFORM Pop
Compute Result = Value2 + Value1
PERFORM Push
 
WHEN "-"
PERFORM Pop
Compute Result = Value2 - Value1
PERFORM Push
 
WHEN "*"
PERFORM Pop
Compute Result = Value2 * Value1
PERFORM Push
 
WHEN "/"
PERFORM Pop
Compute Result = Value2 / Value1
PERFORM Push
 
WHEN "^"
PERFORM Pop
Compute Result = Value2 ** Value1
PERFORM Push
 
WHEN NUMERIC
MOVE Operator TO Result
PERFORM Push
END-EVALUATE.
 
 
Show-Stack.
 
DISPLAY "STACK: " WITH NO ADVANCING.
MOVE 1 TO Idx.
PERFORM UNTIL (Idx = SP)
MOVE Stack(Idx) TO FormatNum
IF Stack(Idx) IS NEGATIVE
THEN
DISPLAY " -" FUNCTION TRIM(FormatNum)
WITH NO ADVANCING
ELSE
DISPLAY FormatNum WITH NO ADVANCING
END-IF
ADD 1 to Idx
END-PERFORM.
DISPLAY " ".
 
Push.
 
MOVE Result TO Stack(SP)
ADD 1 TO SP.
 
Pop.
 
SUBTRACT 1 FROM SP
MOVE Stack(SP) TO Value1
SUBTRACT 1 FROM SP
MOVE Stack(SP) TO Value2.
 
 
END-PROGRAM.
</syntaxhighlight>
{{out}}
<pre>
Enter the RPN Equation: 3 4 2 * 1 5 - 2 3 ^ ^ / +
STACK: 3.0000000
STACK: 3.0000000 4.0000000
STACK: 3.0000000 4.0000000 2.0000000
STACK: 3.0000000 8.0000000
STACK: 3.0000000 8.0000000 1.0000000
STACK: 3.0000000 8.0000000 1.0000000 5.0000000
STACK: 3.0000000 8.0000000 -4.0000000
STACK: 3.0000000 8.0000000 -4.0000000 2.0000000
STACK: 3.0000000 8.0000000 -4.0000000 2.0000000 3.0000000
STACK: 3.0000000 8.0000000 -4.0000000 8.0000000
STACK: 3.0000000 8.0000000 65536.0000000
STACK: 3.0000000 0.0001220
STACK: 3.0001220
End Result: 3.0001220
</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(setf (symbol-function '^) #'expt) ; Make ^ an alias for EXPT
 
(defun print-stack (token stack)
Line 995 ⟶ 2,348:
(when verbose
(print-stack current next-stack))
(rpn (cdr tokens) :stack next-stack :verbose verbose)))))</langsyntaxhighlight>
 
{{Out}}
Line 1,019 ⟶ 2,372:
+: 24577/8192
24577/8192</pre>
 
=={{header|D}}==
{{trans|Go}}
<syntaxhighlight lang="d">import std.stdio, std.string, std.conv, std.typetuple;
 
void main() {
auto input = "3 4 2 * 1 5 - 2 3 ^ ^ / +";
writeln("For postfix expression: ", input);
writeln("\nToken Action Stack");
real[] stack;
foreach (tok; input.split()) {
auto action = "Apply op to top of stack";
switch (tok) {
foreach (o; TypeTuple!("+", "-", "*", "/", "^")) {
case o:
mixin("stack[$ - 2]" ~
(o == "^" ? "^^" : o) ~ "=stack[$ - 1];");
stack.length--;
break;
}
break;
default:
action = "Push num onto top of stack";
stack ~= to!real(tok);
}
writefln("%3s %-26s %s", tok, action, stack);
}
writeln("\nThe final value is ", stack[0]);
}</syntaxhighlight>
{{out}}
<pre>For postfix expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
 
Token Action Stack
3 Push num onto top of stack [3]
4 Push num onto top of stack [3, 4]
2 Push num onto top of stack [3, 4, 2]
* Apply op to top of stack [3, 8]
1 Push num onto top of stack [3, 8, 1]
5 Push num onto top of stack [3, 8, 1, 5]
- Apply op to top of stack [3, 8, -4]
2 Push num onto top of stack [3, 8, -4, 2]
3 Push num onto top of stack [3, 8, -4, 2, 3]
^ Apply op to top of stack [3, 8, -4, 8]
^ Apply op to top of stack [3, 8, 65536]
/ Apply op to top of stack [3, 0.00012207]
+ Apply op to top of stack [3.00012]
 
The final value is 3.00012</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
This is a good example of creating s simple object to create a stakc for use in parsing the data.
 
<syntaxhighlight lang="Delphi">
{This code normally exists in a library, but is presented here for clarity}
 
function ExtractToken(S: string; Sep: char; var P: integer): string;
{Extract token from S, starting at P up to but not including Sep}
{Terminates with P pointing past Sep or past end of string}
var C: char;
begin
Result:='';
while P<=Length(S) do
begin
C:=S[P]; Inc(P);
if C=Sep then break
else Result:=Result+C;
end;
end;
 
{Create stack object to handle parsing}
 
type TRealStack = class(TObject)
private
Data: array of double;
protected
public
function GetStackStr: string;
procedure Push(D: double);
function Pop: double;
end;
 
procedure TRealStack.Push(D: double);
{Push double on stack}
begin
SetLength(Data,Length(Data)+1);
Data[High(Data)]:=D;
end;
 
 
function TRealStack.Pop: double;
{Pop double off stack, raises exception if stack empty}
begin
if Length(Data)<1 then raise exception.Create('Stack Empty');
Result:=Data[High(Data)];
SetLength(Data,Length(Data)-1);
end;
 
 
function TRealStack.GetStackStr: string;
{Get string representation of stack data}
var I: integer;
begin
Result:='';
for I:=0 to High(Data) do
begin
if I<>0 then Result:=Result+', ';
Result:=Result+FloatToStrF(Data[I],ffGeneral,18,4);
end;
end;
 
 
 
procedure RPNParser(Memo: TMemo; S: string);
{Parse RPN string and display all operations}
var I: integer;
var Stack: TRealStack;
var Token: string;
var D: double;
 
 
function HandleOperator(S: string): boolean;
{Handle numerical operator command}
var Arg1,Arg2: double;
begin
Result:=False;
{Empty comand string? }
if Length(S)>1 then exit;
{Invalid command? }
if not (S[1] in ['+','-','*','/','^']) then exit;
{Get arguments off stack}
Arg1:=Stack.Pop; Arg2:=Stack.Pop;
Result:=True;
{Decode command}
case S[1] of
'+': Stack.Push(Arg2 + Arg1);
'-': Stack.Push(Arg2 - Arg1);
'*': Stack.Push(Arg2 * Arg1);
'/': Stack.Push(Arg2 / Arg1);
'^': Stack.Push(Power(Arg2,Arg1));
else Result:=False;
end;
end;
 
 
begin
Stack:=TRealStack.Create;
try
I:=1;
while true do
begin
{Extract one token from string}
Token:=ExtractToken(S,' ',I);
{Exit if no more data}
if Token='' then break;
{If token is a number convert it to a double otherwise, process an operator}
if Token[1] in ['0'..'9'] then Stack.Push(StrToFloat(Token))
else if not HandleOperator(Token) then raise Exception.Create('Illegal Token: '+Token);
Memo.Lines.Add(Token+' ['+Stack.GetStackStr+']');
end;
finally Stack.Free; end;
end;
 
 
procedure ShowRPNParser(Memo: TMemo);
var S: string;
begin
S:='3 4 2 * 1 5 - 2 3 ^ ^ / + ';
RPNParser(Memo,S);
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
3 [3]
4 [3, 4]
2 [3, 4, 2]
* [3, 8]
1 [3, 8, 1]
5 [3, 8, 1, 5]
- [3, 8, -4]
2 [3, 8, -4, 2]
3 [3, 8, -4, 2, 3]
^ [3, 8, -4, 8]
^ [3, 8, 65536]
/ [3, 0.0001220703125]
+ [3.0001220703125]
Elapsed Time: 16.409 ms.
 
</pre>
 
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
;; RPN (postfix) evaluator
 
Line 1,050 ⟶ 2,596:
(define S (stack 'S))
(calculator (text-parse rpn) S ))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,077 ⟶ 2,623:
→ 24577/8192
</pre>
 
 
=={{header|Ela}}==
<langsyntaxhighlight lang="ela">open string generic monad io
 
type OpType = Push | Operate
Line 1,121 ⟶ 2,666:
 
res = parse "3 4 2 * 1 5 - 2 3 ^ ^ / +" |> eval []
print_result res ::: IO</langsyntaxhighlight>
 
{{out}}
Line 1,139 ⟶ 2,684:
+ Operate [3.000122f]
Result: 3.000122f</pre>
 
=={{header|D}}==
{{trans|Go}}
<lang d>import std.stdio, std.string, std.conv, std.typetuple;
 
void main() {
auto input = "3 4 2 * 1 5 - 2 3 ^ ^ / +";
writeln("For postfix expression: ", input);
writeln("\nToken Action Stack");
real[] stack;
foreach (tok; input.split()) {
auto action = "Apply op to top of stack";
switch (tok) {
foreach (o; TypeTuple!("+", "-", "*", "/", "^")) {
case o:
mixin("stack[$ - 2]" ~
(o == "^" ? "^^" : o) ~ "=stack[$ - 1];");
stack.length--;
break;
}
break;
default:
action = "Push num onto top of stack";
stack ~= to!real(tok);
}
writefln("%3s %-26s %s", tok, action, stack);
}
writeln("\nThe final value is ", stack[0]);
}</lang>
{{out}}
<pre>For postfix expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
 
Token Action Stack
3 Push num onto top of stack [3]
4 Push num onto top of stack [3, 4]
2 Push num onto top of stack [3, 4, 2]
* Apply op to top of stack [3, 8]
1 Push num onto top of stack [3, 8, 1]
5 Push num onto top of stack [3, 8, 1, 5]
- Apply op to top of stack [3, 8, -4]
2 Push num onto top of stack [3, 8, -4, 2]
3 Push num onto top of stack [3, 8, -4, 2, 3]
^ Apply op to top of stack [3, 8, -4, 8]
^ Apply op to top of stack [3, 8, 65536]
/ Apply op to top of stack [3, 0.00012207]
+ Apply op to top of stack [3.00012]
 
The final value is 3.00012</pre>
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">-module(rpn).
-export([eval/1]).
 
Line 1,231 ⟶ 2,728:
lists:map(fun (X) when is_integer(X) -> io:format("~12.12b ",[X]);
(X) when is_float(X) -> io:format("~12f ",[X]) end, Stack),
io:format("~n").</langsyntaxhighlight>
 
{{out}}
Line 1,253 ⟶ 2,750:
{{trans|OCaml}}
<p>As interactive script</p>
<langsyntaxhighlight lang="fsharp">let reduce op = function
| b::a::r -> (op a b)::r
| _ -> failwith "invalid expression"
Line 1,275 ⟶ 2,772:
printfn "Token Action Stack";
let ss = str.ToString().Split() |> Array.toList
List.fold interp_and_show [] ss</langsyntaxhighlight>
{{out}}
<pre>> eval "3 4 2 * 1 5 - 2 3 ^ ^ / +";;
Line 1,296 ⟶ 2,793:
=={{header|Factor}}==
Factor <i>is</i> a stack-based evaluator for an expression in reverse Polish notation. In the listener:
<langsyntaxhighlight lang="factor">IN: scratchpad 3 4 2 * 1 5 - 2 3 ^ ^ / +
 
--- Data stack:
3+1/8192</langsyntaxhighlight>
 
To show intermediate steps:
<langsyntaxhighlight lang="factor">{ 3 4 2 * 1 5 - 2 3 ^ ^ / + } [ 1quotation ] map
[ dup pprint bl 1quotation call get-datastack . ] each</langsyntaxhighlight>
{{out}}
<pre>
[ 3 ] { 3 }
[ 4 ] { 3 4 }
[ 2 ] { 3 4 2 }
[ * ] { 3 8 }
[ 1 ] { 3 8 1 }
[ 5 ] { 3 8 1 5 }
[ - ] { 3 8 -4 }
[ 2 ] { 3 8 -4 2 }
[ 3 ] { 3 8 -4 2 3 }
[ ^ ] { 3 8 -4 8 }
[ ^ ] { 3 8 65536 }
[ / ] { 3 1/8192 }
[ + ] { 3+1/8192 }
</pre>
 
 
=={{header|Forth}}==
 
{{works with|gforth|0.7.3}}
Forth is stack-based, so evaluation is direct:
<syntaxhighlight lang="forth">: ^ over swap 1 ?do over * loop nip ;
s" 3 4 2 * 1 5 - 2 3 ^ ^ / +" evaluate .</syntaxhighlight>
 
To show intermediate steps:
<syntaxhighlight lang="forth">: ^ over swap 1 ?do over * loop nip ;
: detail
begin
cr ." stack: " .s
bl word count dup
0<> while
." , read: " 2dup type evaluate
repeat
2drop
;
detail 3 4 2 * 1 5 - 2 3 ^ ^ / +</syntaxhighlight>
 
{{out}}
<pre>stack: <0> , read: 3
stack: <1> 3 , read: 4
stack: <2> 3 4 , read: 2
stack: <3> 3 4 2 , read: *
stack: <2> 3 8 , read: 1
stack: <3> 3 8 1 , read: 5
stack: <4> 3 8 1 5 , read: -
stack: <3> 3 8 -4 , read: 2
stack: <4> 3 8 -4 2 , read: 3
stack: <5> 3 8 -4 2 3 , read: ^
stack: <4> 3 8 -4 8 , read: ^
stack: <3> 3 8 65536 , read: /
stack: <2> 3 0 , read: +
stack: <1> 3 ok</pre>
 
 
 
=={{header|Fortran}}==
Line 1,326 ⟶ 2,862:
The method is simple (the whole point of RPN) and the function prints a schedule of actions at each step. Possibly this semi-tabular output is what is meant by "as a table". Conveniently, all the operators take two operands and return one, so the SP accountancy can be shared. Unlike ! for example.
 
The source style is essentially F77 except for the trivial use of the PARAMETER statement, and CYCLE to GO TO the end of the loop when a space is encountered. With the introduction of unfixed-format source style came also the possible use of semicolons to cram more than one statement part on a line so that the CASE and its action statement can be spread across the page rather than use two lines in alternation: for this case a tabular layout results that is easier to read and check. Because the F90 MODULE protocol is not used, the function's type should be declared in the calling routine but the default type suffices.<langsyntaxhighlight Fortranlang="fortran"> REAL FUNCTION EVALRP(TEXT) !Evaluates a Reverse Polish string.
Caution: deals with single digits only.
CHARACTER*(*) TEXT !The RPN string.
Line 1,373 ⟶ 2,909:
V = EVALRP("3 4 2 * 1 5 - 2 3 ^ ^ / +") !The specified example.
WRITE (6,*) "Result is...",V
END</langsyntaxhighlight>
 
Output...
Line 1,396 ⟶ 2,932:
 
=={{header|FunL}}==
<langsyntaxhighlight lang="funl">def evaluate( expr ) =
stack = []
 
Line 1,414 ⟶ 2,950:
 
res = evaluate( '3 4 2 * 1 5 - 2 3 ^ ^ / +' )
println( res + (if res is Integer then '' else " or ${float(res)}") )</langsyntaxhighlight>
 
{{out}}
Line 1,437 ⟶ 2,973:
=={{header|Go}}==
No error checking.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,479 ⟶ 3,015:
}
fmt.Println("\nThe final value is", stack[0])
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,503 ⟶ 3,039:
 
=={{header|Groovy}}==
<langsyntaxhighlight lang="groovy">def evaluateRPN(expression) {
def stack = [] as Stack
def binaryOp = { action -> return { action.call(stack.pop(), stack.pop()) } }
Line 1,521 ⟶ 3,057:
assert stack.size() == 1 : "Unbalanced Expression: $expression ($stack)"
stack.pop()
}</langsyntaxhighlight>
Test
<langsyntaxhighlight lang="groovy">println evaluateRPN('3 4 2 * 1 5 - 2 3 ^ ^ / +')</langsyntaxhighlight>
{{out}}
<pre>3: [3]
Line 1,542 ⟶ 3,078:
=={{header|Haskell}}==
Pure RPN calculator
<langsyntaxhighlight Haskelllang="haskell">calcRPN :: String -> [Double]
calcRPN = foldl interprete [] . words
 
Line 1,554 ⟶ 3,090:
"*" -> x * y:s
"/" -> y / x:s
"^" -> y ** x:s</langsyntaxhighlight>
 
<pre>λ> calcRPN "3 4 +"
Line 1,567 ⟶ 3,103:
''Pure logging''. Log as well as a result could be used as a data.
 
<langsyntaxhighlight lang="haskell">calcRPNLog :: String -> ([Double],[(String, [Double])])
calcRPNLog input = mkLog $ zip commands $ tail result
where result = scanl interprete [] commands
commands = words input
mkLog [] = ([], [])
mkLog res = (snd $ last res, res)</langsyntaxhighlight>
 
<pre>λ> calcRPNLog "3 4 +"
Line 1,593 ⟶ 3,129:
 
''Logging as a side effect.'' Calculator returns result in IO context:
<langsyntaxhighlight lang="haskell">import Control.Monad (foldM)
 
calcRPNIO :: String -> IO [Double]
Line 1,599 ⟶ 3,135:
 
verbose f s x = write (x ++ "\t" ++ show res ++ "\n") >> return res
where res = f s x</langsyntaxhighlight>
 
<pre>λ> calcRPNIO "3 4 +"
Line 1,626 ⟶ 3,162:
 
Some universal definitions:
<langsyntaxhighlight lang="haskell">class Monad m => Logger m where
write :: String -> m ()
 
Line 1,635 ⟶ 3,171:
show y ++ " ==> " ++
show res ++ "\n") >> return res
where res = f x y</langsyntaxhighlight>
 
The use case:
<langsyntaxhighlight lang="haskell">calcRPNM :: Logger m => String -> m [Double]
calcRPNM = foldM (verbose interprete) [] . words</langsyntaxhighlight>
 
{{out}} in REPL
Line 1,662 ⟶ 3,198:
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">procedure main()
EvalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
end
Line 1,694 ⟶ 3,230:
every (s := "[ ") ||:= !L || " "
return s || "]"
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 1,720 ⟶ 3,256:
 
Our implementation will be a monadic verb: it will take a single argument, which contains both the accumulated stack and the tokens to be processed. First, create initial state of the input:
<langsyntaxhighlight Jlang="j"> a: , <;._1 ' ' , '3 4 2 * 1 5 - 2 3 ^ ^ / +'
┌┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
││3│4│2│*│1│5│-│2│3│^│^│/│+│
└┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘</langsyntaxhighlight>
As an example, let's also add monadic operation _ which inverses the sign of the stack top element.
 
Line 1,739 ⟶ 3,275:
As a side effect, "consume" is going to print the resulting stack,
so running "consume" once for each token will produce intermediate states of the stack.
<langsyntaxhighlight Jlang="j"> isOp=: '_+-*/^' e.~ {.@>@{.
mo=: 1 :'(}: , u@{:) @ ['
dy=: 1 :'(_2&}. , u/@(_2&{.)) @ ['
Line 1,770 ⟶ 3,306:
┌─┐
│1│
└─┘</langsyntaxhighlight>
 
=== Alternate Implementation ===
 
<langsyntaxhighlight Jlang="j">rpn=: 3 :0
queue=. |.3 :'|.3 :y 0'::]each;: y
op=. 1 :'2 (u~/@:{.,}.)S:0 ,@]'
Line 1,780 ⟶ 3,316:
choose=. ((;:'+-*/^')&i.@[)
,ops@.choose/queue
)</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight Jlang="j"> rpn '3 4 2 * 1 5 - 2 3 ^ ^ / +'
3.00012</langsyntaxhighlight>
 
To see intermediate result stacks, use this variant (the only difference is the definition of 'op'):
 
<langsyntaxhighlight Jlang="j">rpnD=: 3 :0
queue=. |.3 :'|.3 :y 0'::]each;: y
op=. 1 :'2 (u~/@:{.,}.)S:0 ,@([smoutput)@]'
Line 1,795 ⟶ 3,331:
choose=. ((;:'+-*/^')&i.@[)
,ops@.choose/queue
)</langsyntaxhighlight>
 
In other words:
 
<langsyntaxhighlight Jlang="j"> rpnD '3 4 2 * 1 5 - 2 3 ^ ^ / +'
┌─────┐
│2 4 3│
Line 1,808 ⟶ 3,344:
65536 8 3
0.00012207 3
3.00012</langsyntaxhighlight>
 
Note that the seed stack is boxed while computed stacks are not.
Line 1,818 ⟶ 3,354:
{{works with|Java|1.5+}}
Supports multi-digit numbers and negative numbers.
<syntaxhighlight lang="java5">
<lang java5>import java.util.LinkedList;
import java.util.LinkedList;
 
public class RPN{
public static void evalRPNmain(String[] exprargs) {
evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +");
String cleanExpr = cleanExpr(expr);
}
 
private static void evalRPN(String expr){
LinkedList<Double> stack = new LinkedList<Double>();
System.out.println("Input\tOperation\tStack after");
for (String token :cleanExpr expr.split("\\s")){
System.out.print(token + "\t");
if (token.equals("*")) {
Double tokenNum = null;
try{
tokenNum = Double.parseDouble(token);
}catch(NumberFormatException e){}
if(tokenNum != null){
System.out.print("Push\t\t");
stack.push(Double.parseDouble(token+""));
}else if(token.equals("*")){
System.out.print("Operate\t\t");
double secondOperand = stack.pop();
double firstOperand = stack.pop();
stack.push(firstOperand * secondOperand);
} else if (token.equals("/")) {
System.out.print("Operate\t\t");
double secondOperand = stack.pop();
double firstOperand = stack.pop();
stack.push(firstOperand / secondOperand);
} else if (token.equals("-")) {
System.out.print("Operate\t\t");
double secondOperand = stack.pop();
double firstOperand = stack.pop();
stack.push(firstOperand - secondOperand);
} else if (token.equals("+")) {
System.out.print("Operate\t\t");
double secondOperand = stack.pop();
double firstOperand = stack.pop();
stack.push(firstOperand + secondOperand);
} else if (token.equals("^")) {
System.out.print("Operate\t\t");
double secondOperand = stack.pop();
double firstOperand = stack.pop();
stack.push(Math.pow(firstOperand, secondOperand));
} else{//just in case{
System.out.printlnprint("ErrorPush\t\t");
return;try {
stack.push(Double.parseDouble(token+""));
} catch (NumberFormatException e) {
System.out.println("\nError: invalid token " + token);
return;
}
}
System.out.println(stack);
}
if (stack.size() > 1) {
System.out.println("Error, too many operands: " + stack);
return;
}
System.out.println("Final answer: " + stack.pop());
}
}
</syntaxhighlight>
private static String cleanExpr(String expr){
//remove all non-operators, non-whitespace, and non digit chars
return expr.replaceAll("[^\\^\\*\\+\\-\\d/\\s]", "");
}
public static void main(String[] args){
evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +");
}
}</lang>
{{out}}
<pre>Input Operation Stack after
Line 1,895 ⟶ 3,429:
 
=={{header|JavaScript}}==
<syntaxhighlight lang ="javascript">var e = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
const e = '3 4 2 * 1 5 - 2 3 ^ ^ / +';
var s=[], e=e.split(' ')
const s = [], tokens = e.split(' ');
for (var i in e) {
for (const t of tokens) {
var t=e[i], n=+t
if ( const n == Number(t);
if (!isNaN(n)) {
s.push(n)
s.push(n);
else {
} else {
var o2=s.pop(), o1=s.pop()
if (s.length < 2) {
switch (t) {
throw new Error(`${t}: ${s}: insufficient operands.`);
case '+': s.push(o1+o2); break;
}
case '-': s.push(o1-o2); break;
const o2 = s.pop(), o1 = s.pop();
case '*': s.push(o1*o2); break;
switch (t) {
case '/': s.push(o1/o2); break;
case '^+': s.push(Math.pow(o1, + o2)); break;
case '-': s.push(o1 - o2); break;
}
case '*': s.push(o1 * o2); break;
}
case '/': s.push(o1 / o2); break;
document.write(t, ': ', s, '<br>')
case '^': s.push(Math.pow(o1, o2)); break;
}</lang>
default: throw new Error(`Unrecognized operator: [${t}]`);
}
}
console.log(`${t}: ${s}`);
}
 
if (s.length > 1) {
throw new Error(`${s}: insufficient operators.`);
}
</syntaxhighlight>
{{out}}
<pre>
Line 1,929 ⟶ 3,473:
+: 3.0001220703125
</pre>
 
==== With checks and messages ====
=={{header|jq}}==
<lang javascript>var e = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
{{works with|jq}}
eval: {
'''Also works with gojq, the Go implementation of jq, and with jackson-jq and fq.'''
document.write(e, '<br>')
<syntaxhighlight lang=jq>
var s=[], e=e.split(' ')
# Input: an array representing a stack, with .[-1] being its top.
for (var i in e) {
# Output: the updated array after applying `op`
var t=e[i], n=+t
def rpn(op):
if (!t) continue
def two: .[-2:];
if (n == t)
def update($x): (.[:-2] + [$x]);
s.push(n)
if length<=1 then .
else {
elif op == "+" then update(two | add)
if ('+-*/^'.indexOf(t) == -1) {
elif op == "*" then update(two | (.[0] * .[1]))
document.write(t, ': ', s, '<br>', 'Unknown operator!<br>')
elif op == "/" then update(two | (.[0] / .[1]))
break eval
elif op == "-" then update(two | (.[0] - .[1]))
}
elif op == "^" then update(two | (pow(.[0]; .[1])))
if (s.length<2) {
else ("ignoring unrecognized op \(op)" | debug) as $debug | .
document.write(t, ': ', s, '<br>', 'Insufficient operands!<br>')
end;
break eval
 
}
def eval:
var o2=s.pop(), o1=s.pop()
foreach .[] as $item ([];
switch (t) {
if ($item | type) == "number" then . + [$item]
case '+': s.push(o1+o2); break
else rpn($item)
case '-': s.push(o1-o2); break
end;
case '*': s.push(o1*o2); break
"\($item) => \(.)" ) ;
case '/': s.push(o1/o2); break
 
case '^': s.push(Math.pow(o1,o2))
"3 4 2 * 1 5 - 2 3 ^ ^ / +"
}
| split(" ") | map( (try tonumber) // .)
}
| eval
document.write(t, ': ', s, '<br>')
</syntaxhighlight>
}
''Invocation:'' jq -nr -f rpn.jq
if (s.length>1) {
{{output}}
document.write('Insufficient operators!<br>')
}
}</lang>
{{out}}
<pre>
3 => [3]
3 4 2 * 1 5 - 2 3 ^ ^ / +
4 => [3,4]
3: 3
4:2 => [3,4,2]
2:* => [3,4,28]
*:1 => [3,8,1]
1:5 => [3,8,1,5]
5:- => [3,8,1,5-4]
-:2 => [3,8,-4,2]
2:3 => [3,8,-4,2,3]
3:^ => [3,8,-4,2,38]
^: => [3,8,-4,865536]
/ => [3,0.0001220703125]
^: 3,8,65536
/:+ => [3,0.0001220703125]
+: 3.0001220703125
</pre>
 
=={{header|Julia}}==
(This code takes advantage of the fact that all of the operands and functions in the specified RPN syntax are valid Julia expressions, so we can use the built-in <code>parse</code> and <code>eval</code> functions to turn them into numbers and the corresponding Julia functions.)
<langsyntaxhighlight lang="julia">function rpn(s)
stack = Any[]
for op in map(eval, map(parse, split(s)))
Line 1,998 ⟶ 3,538:
return stack[1]
end
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +")</langsyntaxhighlight>
{{out}}
<pre>3: 3
Line 2,016 ⟶ 3,556:
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
fun rpnCalculate(expr: String) {
Line 2,055 ⟶ 3,595:
val expr = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
rpnCalculate(expr)
}</langsyntaxhighlight>
 
{{out}}
Line 2,079 ⟶ 3,619:
</pre>
 
=={{[[header|Liberty BASIC}}Lambdatalk]]==
<syntaxhighlight lang="scheme">
<lang lb>
{calc 3 4 2 * 1 5 - 2 3 pow pow / +}
global stack$
->
3:
4: 3
2: 4 3
*: 2 4 3
1: 8 3
5: 1 8 3
-: 5 1 8 3
2: -4 8 3
3: 2 -4 8 3
pow: 3 2 -4 8 3
pow: 8 -4 8 3
/: 65536 8 3
+: 0.0001220703125 3
-> 3.0001220703125
 
where
expr$ = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
print "Expression:"
print expr$
print
 
{def calc
print "Input","Operation","Stack after"
{def calc.r
{lambda {:x :s}
{if {empty? :x}
then -> {car :s}
else {car :x}: {disp :s}{br}
{calc.r {cdr :x}
{if {unop? {car :x}}
then {cons {{car :x} {car :s}} {cdr :s}}
else {if {binop? {car :x}}
then {cons {{car :x} {car {cdr :s}} {car :s}} {cdr {cdr :s}}}
else {cons {car :x} :s}} }}}}}
{lambda {:s}
{calc.r {list :s} nil}}}
 
using the unop? & binop? functions to test unary and binary operators
stack$=""
token$ = "#"
i = 1
token$ = word$(expr$, i)
token2$ = " "+token$+" "
 
{def unop?
do
{lambda {:op}
print "Token ";i;": ";token$,
{or {W.equal? :op sqrt} // n sqrt sqrt(n)
select case
{W.equal? :op exp} // n exp exp(n)
'operation
{W.equal? :op log} // n log log(n)
case instr("+-*/^",token$)<>0
{W.equal? :op cos} // n cos cos(n)
print "operate",
... and op2$=pop$()so // ...
}}}
op1$=pop$()
if op1$="" then
print "Error: stack empty for ";i;"-th token: ";token$
end
end if
 
{def binop?
op1=val(op1$)
{lambda {:op}
op2=val(op2$)
{or {W.equal? :op +} // m n + m+n
{W.equal? :op -} // m n - m-n
{W.equal? :op *} // m n * m*n
{W.equal? :op /} // m n / m/n
{W.equal? :op %} // m n % m%n
{W.equal? :op pow} // m n pow m^n
... and so on // ...
}}}
 
and the list, empty? and disp functions to create
select case token$
a list from a string, test its emptynes and display it.
case "+"
res = op1+op2
case "-"
res = op1-op2
case "*"
res = op1*op2
case "/"
res = op1/op2
case "^"
res = op1^op2
end select
 
{def list
call push str$(res)
{lambda {:s}
'default:number
{if {W.empty? {S.rest :s}}
case else
then {cons {S.first :s} nil}
print "push",
else {cons {S.first :s} {list {S.rest :s}}}}}}
call push token$
end select
print "Stack: ";reverse$(stack$)
i = i+1
token$ = word$(expr$, i)
token2$ = " "+token$+" "
loop until token$ =""
 
{def empty?
res$=pop$()
{lambda {:x}
print
{W.equal? :x nil}}}
print "Result:" ;res$
extra$=pop$()
if extra$<>"" then
print "Error: extra things on a stack: ";extra$
end if
end
 
{def disp
'---------------------------------------
{lambda {:l}
function reverse$(s$)
{if {empty? :l}
reverse$ = ""
token$="#"then
else {car :l} {disp {cdr :l}}}}}
while token$<>""
i=i+1
token$=word$(s$,i,"|")
reverse$ = token$;" ";reverse$
wend
end function
'---------------------------------------
sub push s$
stack$=s$+"|"+stack$ 'stack
end sub
 
Note that everything is exclusively built on 5 lambdatalk primitives:
function pop$()
- "cons, car, cdr", to create lists,
'it does return empty on empty stack
- "W.equal?" which test the equality between two words,
pop$=word$(stack$,1,"|")
- and the "or" boolean function.
stack$=mid$(stack$,instr(stack$,"|")+1)
</syntaxhighlight>
end function
</lang>
 
{{out}}
<pre>
Expression:
3 4 2 * 1 5 - 2 3 ^ ^ / +
 
Input Operation Stack after
Token 1: 3 push Stack: 3
Token 2: 4 push Stack: 3 4
Token 3: 2 push Stack: 3 4 2
Token 4: * operate Stack: 3 8
Token 5: 1 push Stack: 3 8 1
Token 6: 5 push Stack: 3 8 1 5
Token 7: - operate Stack: 3 8 -4
Token 8: 2 push Stack: 3 8 -4 2
Token 9: 3 push Stack: 3 8 -4 2 3
Token 10: ^ operate Stack: 3 8 -4 8
Token 11: ^ operate Stack: 3 8 65536
Token 12: / operate Stack: 3 0.12207031e-3
Token 13: + operate Stack: 3.00012207
 
Result:3.00012207
</pre>
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">
local stack = {}
function push( a ) table.insert( stack, 1, a ) end
Line 2,243 ⟶ 3,755:
--[[ entry point ]]--
calc( "3 4 2 * 1 5 - 2 3 ^ ^ / +" )
calc( "22 11 *" )</langsyntaxhighlight>
{{out}}
<pre>
Line 2,270 ⟶ 3,782:
result: 242.0000000000000</pre>
 
=={{header|MathematicaM2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Rpn_Calc {
Rem Form 80,60
function rpn_calc(a$) {
def m=0
dim token$()
token$()=piece$(a$," ")
l=len(token$())
dim type(l)=0, reg(l)
where=-1
for i=0 to l-1
c=val(token$(i),"",m)
if m>-1 then
where++
reg(where)=c
else
reg(where-1)=eval(str$(reg(where-1))+token$(i)+str$(reg(where)))
where--
end if
inf=each(reg(),1, where+1)
while inf
export$<=token$(i)+" ["+str$(inf^,"")+"] "+ str$(array(inf))+{
}
token$(i)=" "
end while
next i
=reg(0)
}
Global export$
document export$
example1=rpn_calc("3 4 2 * 1 5 - 2 3 ^ ^ / +")
example2=rpn_calc("1 2 + 3 4 + ^ 5 6 + ^")
Print example1, example2
Rem Print #-2, Export$
ClipBoard Export$
}
Rpn_Calc
</syntaxhighlight>
 
{{out}}
<pre style="height:30ex;overflow:scroll">
3 [0] 3
4 [0] 3
[1] 4
2 [0] 3
[1] 4
[2] 2
* [0] 3
[1] 8
1 [0] 3
[1] 8
[2] 1
5 [0] 3
[1] 8
[2] 1
[3] 5
- [0] 3
[1] 8
[2] -4
2 [0] 3
[1] 8
[2] -4
[3] 2
3 [0] 3
[1] 8
[2] -4
[3] 2
[4] 3
^ [0] 3
[1] 8
[2] -4
[3] 8
^ [0] 3
[1] 8
[2] 65536
/ [0] 3
[1] .0001220703125
+ [0] 3.0001220703125
1 [0] 1
2 [0] 1
[1] 2
+ [0] 3
3 [0] 3
[1] 3
4 [0] 3
[1] 3
[2] 4
+ [0] 3
[1] 7
^ [0] 2187
5 [0] 2187
[1] 5
6 [0] 2187
[1] 5
[2] 6
+ [0] 2187
[1] 11
^ [0] 5.47440108942022E+36
 
</pre >
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
(This code takes advantage of the fact that all of the operands and functions in the specified RPN syntax can be used to form valid Mathematica expressions, so we can use the built-in ToExpression function to turn them into numbers and the corresponding Mathematica functions. Note that we need to add braces around arguments, otherwise "-4^8" would be parsed as "-(4^8)" instead of "(-4)^8".)
<langsyntaxhighlight Mathematicalang="mathematica">calc[rpn_] :=
Module[{tokens = StringSplit[rpn], s = "(" <> ToString@InputForm@# <> ")" &, op, steps},
op[o_, x_, y_] := ToExpression[s@x <> o <> s@y];
Line 2,280 ⟶ 3,894:
Grid[Transpose[{# <> ":" & /@ tokens,
StringRiffle[ToString[#, InputForm] & /@ #] & /@ steps}]]];
Print[calc["3 4 2 * 1 5 - 2 3 ^ ^ / +"]];</langsyntaxhighlight>
{{out}}
<pre>3: 3
Line 2,310 ⟶ 3,924:
=={{header|Maxima}}==
 
<langsyntaxhighlight Maximalang="maxima">rmod(i, j) := mod(j, i)$
rpow(x, y) := y^x$
 
Line 2,348 ⟶ 3,962:
)$
 
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +"), numer;</langsyntaxhighlight>
 
===Output===
<syntaxhighlight lang="text">(%i5) ev(rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +"),numer)
3 : [3]
4 : [4, 3]
Line 2,365 ⟶ 3,979:
/ : [1.220703125e-4, 3]
+ : [3.0001220703125]
(%o5) 3.0001220703125</langsyntaxhighlight>
 
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">RPN = function(inputText)
tokens = inputText.split
stack = []
while tokens
tok = tokens.pull
if "+-*/^".indexOf(tok) != null then
b = stack.pop
a = stack.pop
if tok == "+" then stack.push a + b
if tok == "-" then stack.push a - b
if tok == "*" then stack.push a * b
if tok == "/" then stack.push a / b
if tok == "^" then stack.push a ^ b
else
stack.push val(tok)
end if
print tok + " --> " + stack
end while
return stack[0]
end function
 
print RPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")</syntaxhighlight>
 
{{out}}
<pre>3 --> [3]
4 --> [3, 4]
2 --> [3, 4, 2]
* --> [3, 8]
1 --> [3, 8, 1]
5 --> [3, 8, 1, 5]
- --> [3, 8, -4]
2 --> [3, 8, -4, 2]
3 --> [3, 8, -4, 2, 3]
^ --> [3, 8, -4, 8]
^ --> [3, 8, 65536]
/ --> [3, 0.000122]
+ --> [3.000122]
3.000122</pre>
 
=={{header|N/t/roff}}==
Line 2,372 ⟶ 4,026:
 
{{works with|GNU TROFF|1.22.2}}
<langsyntaxhighlight Nlang="n/t/roff">.ig
RPN parser implementation in TROFF
Originally written on November 21, 2017.
Modified for Rosettacode on December 3, 2017.
 
Stephanie Björk (Katt) <katt16777216@gmail.com>
..
.\" \(*A stack implementation
Line 2,489 ⟶ 4,139:
.el .RPNPRINT
..
.RPNPARSE 3 4 2 * 1 5 - 2 3 ^ ^ / + \" Our input expression</langsyntaxhighlight>
 
====Output====
<syntaxhighlight lang="text"> 3
3 4
3 4 2
Line 2,505 ⟶ 4,155:
3 0
3
3</langsyntaxhighlight>
 
===Modern version===
Line 2,512 ⟶ 4,162:
{{works with|GNU Troff|1.22.2}}
 
<langsyntaxhighlight Nlang="n/t/roff">.ig
===========================
Array implementation
Line 2,600 ⟶ 4,250:
..
.rpn 3 4 2 * 1 5 - 2 3 ^ ^ / +
.stack.dump</langsyntaxhighlight>
 
====Output====
<syntaxhighlight lang="text">3
3 4
3 4 2
Line 2,616 ⟶ 4,266:
3 0
3
3</langsyntaxhighlight>
 
=={{header|NetRexx}}==
{{trans|Java}}
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref symbols nobinary
 
Line 2,708 ⟶ 4,358:
calc = stack.toString
return calc
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,732 ⟶ 4,382:
=={{header|Nim}}==
{{trans|Python}}
<langsyntaxhighlight lang="nim">import math, rdstdin, strutils, tables
 
type Stack = seq[float]
 
proc lalign(s, x): string =
s & repeatChar(x - s.len, ' ')
 
proc opPow(s: var Stack) =
Line 2,764 ⟶ 4,411:
s.add a - b
 
proc opNum(s: var Stack,; num: float) = s.add num
s.add num
 
let ops = toTable({"^": opPow,
Line 2,778 ⟶ 4,426:
result = inp.strip.split
 
proc rpnCalc(tokens: seq[string]): autoseq[seq[string]] =
var s: Stack = @[]
result = @[@["TOKEN","ACTION","STACK"]]
for token in tokens:
Line 2,789 ⟶ 4,437:
action = "Push num onto top of stack"
s.opNum token.parseFloat
result.add(@[token, action, s.map(proc (x: float): string = $x).join(" ")])
 
let rpn = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
Line 2,798 ⟶ 4,446:
for i in 0 .. rp[0].high:
for x in rp:
maxColWidths[i] = max(maxColWidths[i], x[i].len + 3)
 
for x in rp:
for i, y in x:
stdout.write y.lalignalignLeft(maxColWidths[i]), " "
echo ""</langsyntaxhighlight>
 
{{out}}
<pre>For RPN expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
TOKEN ACTION STACK
3 Push num onto top of stack 3.0
4 Push num onto top of stack 3.0 4.0
2 Push num onto top of stack 3.0 4.0 2.0
* Apply op to top of stack 3.0 8.0
1 Push num onto top of stack 3.0 8.0 1.0
5 Push num onto top of stack 3.0 8.0 1.0 5.0
- Apply op to top of stack 3.0 8.0 -4.0
2 Push num onto top of stack 3.0 8.0 -4.0 2.0
3 Push num onto top of stack 3.0 8.0 -4.0 2.0 3.0
^ Apply op to top of stack 3.0 8.0 -4.0 8.0
^ Apply op to top of stack 3.0 8.0 65536.0
/ Apply op to top of stack 3.0 0.0001220703125
+ Apply op to top of stack 3.0001220703125 </pre>
 
=={{header|Objeck}}==
<langsyntaxhighlight lang="objeck">
use IO;
use Struct;
Line 2,886 ⟶ 4,535:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,908 ⟶ 4,557:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">(* binop : ('a -> 'a -> 'a) -> 'a list -> 'a list *)
let binop op = function
| b::a::r -> (op a b)::r
Line 2,934 ⟶ 4,583:
Printf.printf "Token\tAction\tStack\n";
let ss = Str.(split (regexp_string " ") str) in
List.fold_left interp_and_show [] ss</langsyntaxhighlight>
 
Evaluation of the test expression:
Line 2,960 ⟶ 4,609:
Oforth uses RPN and natively parse RPN.
 
<langsyntaxhighlight Oforthlang="oforth">"3 4 2 * 1 5 - 2 3 ^ ^ / +" eval println</langsyntaxhighlight>
 
{{out}}
Line 2,969 ⟶ 4,618:
To show the changes in the stack, we can use .l after evaluating each word :
 
<langsyntaxhighlight Oforthlang="oforth">: rpn(s) { s words apply(#[ eval .l ]) }
 
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +")</langsyntaxhighlight>
 
{{out}}
Line 2,991 ⟶ 4,640:
 
=={{header|ooRexx}}==
<langsyntaxhighlight ooRexxlang="oorexx">/* ooRexx *************************************************************
* 10.11.2012 Walter Pachl translated from PL/I via REXX
**********************************************************************/
Line 3,022 ⟶ 4,671:
end
Say 'The reverse polish expression = 'expr
Say 'The evaluated expression = 'st~pull</langsyntaxhighlight>
{{out}}
<pre>
Line 3,035 ⟶ 4,684:
The reverse polish expression = 3 4 2 * 1 5 - 2 3 ^ ^ / +
The evaluated expression = 3.0001220703125
</pre>
 
=={{header|PARI/GP}}==
Due to the nature of the language, it is not trivial to process an expression as a simple space-separated string. Though, this could be done if one calls an external shell program such as <code>sed</code> and pipes the result back hither.
 
<langsyntaxhighlight lang="parigp">estack = [];
 
epush(x) = {
Line 3,078 ⟶ 4,727:
};
 
parseRPN([3, 4, 2, "*", 1, 5, "-", 2, 3, "^", "^", "/", "+"]); \\ Our input expression</langsyntaxhighlight>
 
===Output===
<syntaxhighlight lang="text">[3]
[3, 4]
[3, 4, 2]
Line 3,093 ⟶ 4,742:
[3, 8, 65536]
[3, 1/8192]
[24577/8192]</langsyntaxhighlight>
 
Whenever possible, PARI/GP tries to manipulate and return results in the simplest form it can. In this case, it deems fractions the most suitable form of output. Nonetheless, converting the fraction <code>24577/8192</code> yields <code>3.0001220703125</code> as expected.
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
<lang Perl>
use warnings;
# RPN calculator
use feature 'say';
#
# Nigel Galloway April 2nd., 2012
#
$WSb = '(?:^|\s+)';
$WSa = '(?:\s+|$)';
$num = '([+-/]?(?:\.\d+|\d+(?:\.\d*)?))';
$op = '([-+*/^])';
sub myE {
my $a = '('.$1.')'.$3.'('.$2.')';
$a =~ s/\^/**/;
return eval($a);
}
while (<>) {
while (s/$WSb$num\s+$num\s+$op$WSa/' '.myE().' '/e) {}
print ($_, "\n");
}
</lang>
Produces:
<pre>
>rpnC.pl
3 4 2 * 1 5 - 2 3 ^ ^ / +
3.0001220703125
</pre>
 
my $number = '[+-]?(?:\.\d+|\d+(?:\.\d*)?)';
=={{header|Perl 6}}==
my $operator = '[-+*/^]';
{{works with|rakudo|2015-09-25}}
<lang perl6>my $proggie = '3 4 2 * 1 5 - 2 3 ^ ^ / +';
 
my @tests = ('3 4 2 * 1 5 - 2 3 ^ ^ / +');
class RPN is Array {
 
for (@tests) {
method binop(&op) { self.push: self.pop R[&op] self.pop }
while (
 
s/ \s* ((?<left>$number)) # 1st operand
method run($p) {
for \s+ ((?<right>$p.wordsnumber)) # 2nd {operand
say "$_\s+ ({self}(?<op>$operator)";) # operator
(?:\s+|$) when /\d/ { self.push: $_ } # more to parse, or done?
when '+' { self.binop: &[+] }/
when' '-.evaluate().' ' { self.binop: &[-] } # substitute results of evaluation
when '*' { self.binop: &[*] }/ex
) {}
when '/' { self.binop: &[/] }
say;
when '^' { self.binop: &[**] }
default { die "$_ is bogus" }
}
say self;
}
}
 
sub evaluate {
RPN.new.run($proggie);</lang>
(my $a = "($+{left})$+{op}($+{right})") =~ s/\^/**/;
say $a;
eval $a;
}</syntaxhighlight>
{{out}}
<pre>3 (4)*(2)
4 (31)-(5)
(2 )**(3 4)
* (3 -4 2)**(8)
(8)/(65536)
1 (3 8)
(3)+(0.0001220703125)
5 (3 8 1)
3.0001220703125</pre>
- (3 8 1 5)
2 (3 8 -4)
3 (3 8 -4 2)
^ (3 8 -4 2 3)
^ (3 8 -4 8)
/ (3 8 65536)
+ (3 0.0001220703125)
3.0001220703125</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>procedure evalRPN(string s)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence stack = {}
<span style="color: #008080;">procedure</span> <span style="color: #000000;">evalRPN</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
sequence ops = split(s)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
for i=1 to length(ops) do
<span style="color: #000000;">ops</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
string op = ops[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ops</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
switch op
<span style="color: #004080;">string</span> <span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ops</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
case "+": stack[-2] = stack[-2]+stack[-1]; stack = stack[1..-2]
<span style="color: #008080;">switch</span> <span style="color: #000000;">op</span>
case "-": stack[-2] = stack[-2]-stack[-1]; stack = stack[1..-2]
<span style="color: #008080;">case</span> <span style="color: #008000;">"+"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">];</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
case "*": stack[-2] = stack[-2]*stack[-1]; stack = stack[1..-2]
<span style="color: #008080;">case</span> <span style="color: #008000;">"-"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">];</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
case "/": stack[-2] = stack[-2]/stack[-1]; stack = stack[1..-2]
<span style="color: #008080;">case</span> <span style="color: #008000;">"*"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">];</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
case "^": stack[-2] = power(stack[-2],stack[-1]); stack = stack[1..-2]
<span style="color: #008080;">case</span> <span style="color: #008000;">"/"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]/</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">];</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
default : stack = append(stack,scanf(op,"%d")[1][1])
<span style="color: #008080;">case</span> <span style="color: #008000;">"^"</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]);</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">stack</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
end switch
<span style="color: #008080;">default</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">scanf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">)[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
?{op,stack}
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
end for
<span style="color: #0000FF;">?{</span><span style="color: #000000;">op</span><span style="color: #0000FF;">,</span><span style="color: #000000;">stack</span><span style="color: #0000FF;">}</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">evalRPN</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"3 4 2 * 1 5 - 2 3 ^ ^ / +"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
"started"
{"3",{3}}
{"4",{3,4}}
Line 3,196 ⟶ 4,817:
{"^",{3,8,-4,8}}
{"^",{3,8,65536}}
{"/",{3,0.00012207031250001220703}}
{"+",{3.00012207}}
</pre>
 
=={{header|PHP}}==
<langsyntaxhighlight lang="php">
<?php
function rpn($postFix){
Line 3,247 ⟶ 4,868:
echo "Compute Value: " . rpn("3 4 2 * 1 5 - 2 3 ^ ^ / + ");
?>
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,269 ⟶ 4,890:
=={{header|PicoLisp}}==
This is an integer-only calculator:
<langsyntaxhighlight PicoLisplang="picolisp">(de rpnCalculator (Str)
(let (^ ** Stack) # Define '^' from the built-in '**'
(prinl "Token Stack")
Line 3,280 ⟶ 4,901:
(space 6)
(println Stack) )
(println (car Stack)) ) )</langsyntaxhighlight>
Test (note that the top-of-stack is in the left-most position):
<langsyntaxhighlight PicoLisplang="picolisp">: (rpnCalculator "3 4 2 * 1 5 - 2 3 \^ \^ / +")
Token Stack
3 (3)
Line 3,298 ⟶ 4,919:
+ (3)
3
-> 3</langsyntaxhighlight>
 
=={{header|PL/I}}==
<langsyntaxhighlight PLlang="pl/Ii">Calculator: procedure options (main); /* 14 Sept. 2012 */
declare expression character (100) varying initial ('');
declare ch character (1);
Line 3,332 ⟶ 4,953:
put skip list ('The evaluated expression = ' || stack);
 
end Calculator;</langsyntaxhighlight>
<pre>
Stack contents:
Line 3,358 ⟶ 4,979:
end;
end show_stack;</pre>
 
=={{header|PL/SQL}}==
<syntaxhighlight lang="plsql">create or replace function rpn_calc(str varchar2) return number as
type num_aa is table of number index by pls_integer;
type num_stack is record (a num_aa, top pls_integer default 0);
ns num_stack;
pos1 integer := 1;
pos2 integer;
token varchar2(100);
op2 number;
procedure push(s in out nocopy num_stack, x number) is
begin
s.top := s.top + 1;
s.a(s.top) := x;
end;
function pop(s in out nocopy num_stack) return number is
x number;
begin
x := s.a(s.top);
s.top := s.top - 1;
return x;
end;
procedure print_stack(s num_stack) is -- for debugging only; remove from final version
ps varchar2(4000);
begin
for i in 1 .. s.top loop
ps := ps || s.a(i) || ' ';
end loop;
dbms_output.put_line('Stack: ' || rtrim(ps));
end;
begin
while pos1 <= length(str) loop
pos2 := instr(str || ' ', ' ', pos1);
token := substr(str, pos1, pos2 - pos1);
pos1 := pos2 + 1;
case token
when '+' then push(ns, pop(ns) + pop(ns));
when '-' then op2 := pop(ns); push(ns, pop(ns) - op2);
when '*' then push(ns, pop(ns) * pop(ns));
when '/' then op2 := pop(ns); push(ns, pop(ns) / op2);
when '^' then op2 := pop(ns); push(ns, power(pop(ns), op2));
else push(ns, to_number(token));
end case;
print_stack(ns); -- for debugging purposes only
end loop;
return pop(ns);
end rpn_calc;
/</syntaxhighlight>
 
Testing:
 
<syntaxhighlight lang="plsql">begin
dbms_output.put_line(chr(10) || 'Result: ' || rpn_calc('3 4 2 * 1 5 - 2 3 ^ ^ / +'));
end;
/</syntaxhighlight>
 
Output:
 
<pre>
Stack: 3
Stack: 3 4
Stack: 3 4 2
Stack: 3 8
Stack: 3 8 1
Stack: 3 8 1 5
Stack: 3 8 -4
Stack: 3 8 -4 2
Stack: 3 8 -4 2 3
Stack: 3 8 -4 8
Stack: 3 8 65536
Stack: 3 .0001220703125
Stack: 3.0001220703125
 
Result: 3.0001220703125
 
 
PL/SQL procedure successfully completed.
</pre>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Invoke-Rpn
{
Line 3,493 ⟶ 5,192:
 
Invoke-Rpn -Expression "3 4 2 * 1 5 - 2 3 ^ ^ / +" -DisplayState
</syntaxhighlight>
</lang>
 
{{Out}}
Line 3,517 ⟶ 5,216:
=={{header|Prolog}}==
Works with SWI-Prolog.
<langsyntaxhighlight Prologlang="prolog">rpn(L) :-
writeln('Token Action Stack'),
parse(L, [],[X] ,[]),
Line 3,563 ⟶ 5,262:
is_op(45, X, Y, V) :- V is X-Y.
is_op(47, X, Y, V) :- V is X/Y.
is_op(94, X, Y, V) :- V is X**Y.</langsyntaxhighlight>
{{out}}
<pre>5 ?- rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +").
Line 3,586 ⟶ 5,285:
=={{header|Python}}==
=== Version 1 ===
<langsyntaxhighlight lang="python">def op_pow(stack):
b = stack.pop(); a = stack.pop()
stack.append( a ** b )
Line 3,644 ⟶ 5,343:
print( ' '.join('{cell:<{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))
 
print('\n The final output value is: %r' % rp[-1][2])</langsyntaxhighlight>
 
{{out}}
Line 3,668 ⟶ 5,367:
=== Version 2 ===
 
<langsyntaxhighlight lang="python">a=[]
b={'+': lambda x,y: y+x, '-': lambda x,y: y-x, '*': lambda x,y: y*x,'/': lambda x,y:y/x,'^': lambda x,y:y**x}
for c in '3 4 2 * 1 5 - 2 3 ^ ^ / +'.split():
if c in b: a.append(b[c](a.pop(),a.pop()))
else: a.append(float(c))
print c, a</langsyntaxhighlight>
 
{{out}}
Line 3,689 ⟶ 5,388:
/ [3.0, 0.0001220703125]
+ [3.0001220703125]</pre>
 
=={{header|Quackery}}==
 
On an historical note, the first step in developing the language Quackery, as is the case with many stack based/reverse Polish/concatenative languages, was coding an RP calculator much like this one. With the minor difference that the exponentiation operator in Quackery is <code>**</code> rather than <code>^</code> (which is bitwise xor) the test string <code>"3 4 2 * 1 5 - 2 3 ^ ^ / +"</code> ''is'' Quackery code, and could be compiled and evaluated (in the Quackery vernacular, "built and done") by passing it to the Quackery word <code>quackery</code>, which is defined in Quackery as
 
<code>[ build do ] is quackery ( $ --> [ )</code>, which neatly sums up the language.
 
Here we interpret rather than compile the code, using a <code>switch</code> statement (not actually defined in Quackery, so the code to define it is included), and using the provided ancillary stack <code>temp</code> to make the stack activity explicit.
 
(If the gentle gatekeepers will permit a moment of shameless self-promotion… If you are interested in stack processors or concatenative languages, you may wish to consider that Quackery was designed with the intent of being an entry level language suitable for educational and hobbyist use, accessible at the code level by virtue of being coded in (mostly) non-idiomatic Python (24k source) and Quackery (another 24k of course) with the Python code emphasising a straightforward approach and the use of simple algorithms for the sake of legibility in preference to efficiency.)
 
<syntaxhighlight lang="quackery">
[ stack ] is switch.arg ( --> [ )
 
[ switch.arg put ] is switch ( x --> )
 
[ switch.arg release ] is otherwise ( --> )
 
[ switch.arg share
!= iff ]else[ done
otherwise
]'[ do ]done[ ] is case ( x --> )
 
[ say "Applying: "
swap echo$ sp
temp take
temp take
swap rot do
temp put ] is apply ( $ x --> )
 
[ say "Pushing: " dup echo$ sp
$->n drop temp put ] is isnumber ( $ --> )
 
[ temp copy echo cr ] is display ( --> )
 
[ nest$ witheach
[ dup switch
[ $ '+' case [ ' + apply ]
$ '-' case [ ' - apply ]
$ '*' case [ ' * apply ]
$ '/' case [ ' / apply ]
$ '^' case [ ' ** apply ]
otherwise [ isnumber ] ]
display ]
temp take ] is rpncalc ( $ --> n )
 
$ "3 4 2 * 1 5 - 2 3 ^ ^ / +" rpncalc
say "Result: " echo</syntaxhighlight>
 
{{out}}
 
<pre>Pushing: 3 [ stack 3 ]
Pushing: 4 [ stack 3 4 ]
Pushing: 2 [ stack 3 4 2 ]
Applying: * [ stack 3 8 ]
Pushing: 1 [ stack 3 8 1 ]
Pushing: 5 [ stack 3 8 1 5 ]
Applying: - [ stack 3 8 -4 ]
Pushing: 2 [ stack 3 8 -4 2 ]
Pushing: 3 [ stack 3 8 -4 2 3 ]
Applying: ^ [ stack 3 8 -4 8 ]
Applying: ^ [ stack 3 8 65536 ]
Applying: / [ stack 3 0 ]
Applying: + [ stack 3 ]
Result: 3</pre>
 
=={{header|Racket}}==
 
<langsyntaxhighlight lang="racket">
#lang racket
Line 3,708 ⟶ 5,472:
(reverse (cons x s)))])))
 
</syntaxhighlight>
</lang>
Test case
<pre>
Line 3,729 ⟶ 5,493:
 
Reading from a string:
<langsyntaxhighlight lang="racket">
(calculate-RPN (in-port read (open-input-string "3.0 4 2 * 1 5 - 2 3 ^ ^ / +")))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2015-09-25}}
<syntaxhighlight lang="raku" line>my $proggie = '3 4 2 * 1 5 - 2 3 ^ ^ / +';
 
class RPN is Array {
 
method binop(&op) { self.push: self.pop R[&op] self.pop }
 
method run($p) {
for $p.words {
say "$_ ({self})";
when /\d/ { self.push: $_ }
when '+' { self.binop: &[+] }
when '-' { self.binop: &[-] }
when '*' { self.binop: &[*] }
when '/' { self.binop: &[/] }
when '^' { self.binop: &[**] }
default { die "$_ is bogus" }
}
say self;
}
}
 
RPN.new.run($proggie);</syntaxhighlight>
{{out}}
<pre>3 ()
4 (3)
2 (3 4)
* (3 4 2)
1 (3 8)
5 (3 8 1)
- (3 8 1 5)
2 (3 8 -4)
3 (3 8 -4 2)
^ (3 8 -4 2 3)
^ (3 8 -4 8)
/ (3 8 65536)
+ (3 0.0001220703125)
3.0001220703125</pre>
 
=={{header|REXX}}==
===version 1===
<langsyntaxhighlight lang="rexx">/* REXX ***************************************************************
* 09.11.2012 Walter Pachl translates from PL/I
**********************************************************************/
Line 3,787 ⟶ 5,592:
End
Say ol
Return</langsyntaxhighlight>
{{out}}
<pre>
Line 3,806 ⟶ 5,611:
:::: <big><big> 3.0 &nbsp; .4e1 &nbsp; 2e0 &nbsp; * &nbsp; +1. &nbsp; 5 &nbsp; - &nbsp; 2 &nbsp; 3 &nbsp; ** &nbsp; ** &nbsp; / &nbsp; + </big></big>
which is the essentially the same as the default used by the REXX program.
<langsyntaxhighlight REXXlang="rexx">/*REXX program evaluates a ═════ Reverse Polish notation (RPN) ═════ expression. */
parse arg x /*obtain optional arguments from the CL*/
if x='' then x= "3 4 2 * 1 5 - 2 3 ^ ^ / +" /*Not specified? Then use the default.*/
Line 3,834 ⟶ 5,639:
else exit $ /*return the answer ───► the invoker.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: if showSteps then say center(arg(1), L) left(space($), L); return</langsyntaxhighlight>
'''output''' &nbsp; when using the default input:
<pre>
Line 3,869 ⟶ 5,674:
::* &nbsp; allows remainder division &nbsp; <big>//</big>
::* &nbsp; allows concatenation &nbsp; <big>||</big>
<langsyntaxhighlight REXXlang="rexx">/*REXX program evaluates a ═════ Reverse Polish notation (RPN) ═════ expression. */
parse arg x /*obtain optional arguments from the CL*/
if x='' then x= "3 4 2 * 1 5 - 2 3 ^ ^ / +" /*Not specified? Then use the default.*/
Line 3,911 ⟶ 5,716:
/*──────────────────────────────────────────────────────────────────────────────────────*/
isBit: return arg(1)==0 | arg(1)==1 /*returns 1 if arg1 is a binary bit*/
show: if showSteps then say center(arg(1), L) left(space($), L); return</langsyntaxhighlight>
'''output''' &nbsp; is identical to the 2<sup>nd</sup> REXX version.
<br><br>
 
=={{header|RPL}}==
'''Straightforward '''
"3 4 2 * 1 5 - 2 3 ^ ^ / +" STR→
{{out}}
<pre>
1: 3.00012207031
</pre>
 
'''Step-by-step'''
 
<code>LEXER</code> is defined at [[Parsing/Shunting-yard algorithm#RPL|Parsing/Shunting-yard algorithm]]
{{works with|Halcyon Calc|4.2.7}}
≪ <span style="color:blue">LEXER</span> "" { } 0 → postfix token steps depth
≪ 1 postfix SIZE '''FOR''' j
postfix j GET 'token' STO
'''IF''' token TYPE '''THEN'''
"≪" token + "≫" + STR→ EVAL
depth 1 - ‘depth’ STO
'''ELSE'''
token
depth 1 + ‘depth’ STO
'''END'''
depth DUPN depth →LIST
steps "Token " token →STR + " → " + ROT →STR +
+ ‘steps’ STO
'''NEXT''' steps
≫ ≫ '<span style="color:blue">CALC</span>' STO
 
"3 4 2 * 1 5 - 2 3 ^ ^ / +" <span style="color:blue">CALC</span>
{{out}}
<pre>
2: 3.00012207031
1: { "Token 3 → { 3 }"
"Token 4 → { 3 4 }"
"Token 2 → { 3 4 2 }"
"Token * → { 3 8 }"
"Token 1 → { 3 8 1 }"
"Token 5 → { 3 8 1 5 }"
"Token - → { 3 8 -4 }"
"Token 2 → { 3 8 -4 2 }"
"Token 3 → { 3 8 -4 2 3 }"
"Token ^ → { 3 8 -4 8 }"
"Token ^ → { 3 8 65536 }"
"Token / → { 3 1.220703125E-04 }"
"Token + → { 3.00012207031 }" }
</pre>
Additional spaces and CR characters have been added to the above output to enhance readability.
 
=={{header|Ruby}}==
See [[Parsing/RPN/Ruby]]
<langsyntaxhighlight lang="ruby">rpn = RPNExpression("3 4 2 * 1 5 - 2 3 ^ ^ / +")
value = rpn.eval</langsyntaxhighlight>
{{out}}
<pre>for RPN expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Line 3,937 ⟶ 5,790:
Value = 3.0001220703125</pre>
 
=={{header|Run BASICRust}}==
<syntaxhighlight lang="rust">fn rpn(text: &str) -> f64 {
<lang runbasic>prn$ = "3 4 2 * 1 5 - 2 3 ^ ^ / + "
let tokens = text.split_whitespace();
let mut stack: Vec<f64> = vec![];
println!("input operation stack");
 
for token in tokens {
j = 0
print!("{:^5} ", token);
while word$(prn$,i + 1," ") <> ""
match token.parse() {
i = i + 1
Ok(num) => {
n$ = word$(prn$,i," ")
if n$ < "0" or n$ > "9" then stack.push(num);
num1 = val(word$ println!(stack$,s,"push {:?}", stack));
num2 = val(word$(stack$,s-1," ")) }
n = op Err(n$,num2,num1_) => {
s = s - 1 match token {
"+" => {
stack$ = stk$(stack$,s -1,str$(n))
let b = stack.pop().expect("missing first operand");
print "Push Opr ";n$;" to stack: ";stack$
let a = stack.pop().expect("missing second operand");
else
stack.push(a + b);
s = s + 1
stack$ = stack$ + n$ + " " }
print "Push Num ";n$;" to stack: ";stack$-" => {
let b = stack.pop().expect("missing first operand");
end if
let a = stack.pop().expect("missing second operand");
wend
stack.push(a - b);
}
"*" => {
let b = stack.pop().expect("missing first operand");
let a = stack.pop().expect("missing second operand");
stack.push(a * b);
}
"/" => {
let b = stack.pop().expect("missing first operand");
let a = stack.pop().expect("missing second operand");
stack.push(a / b);
}
"^" => {
let b = stack.pop().expect("missing first operand");
let a = stack.pop().expect("missing second operand");
stack.push(a.powf(b));
}
_ => panic!("unknown operator {}", token),
}
println!("calculate {:?}", stack);
}
}
}
 
stack.pop().unwrap_or(0.0)
function stk$(stack$,s,a$)
}
for i = 1 to s
 
stk$ = stk$ + word$(stack$,i," ") + " "
fn main() {
next i
let text = "3 4 2 * 1 5 - 2 3 ^ ^ / +";
stk$ = stk$ + a$ + " "
end function
 
println!("\nresult: {}", rpn(text));
FUNCTION op(op$,a,b)
}</syntaxhighlight>
if op$ = "*" then op = a * b
{{out}}
if op$ = "/" then op = a / b
<pre>input operation stack
if op$ = "^" then op = a ^ b
if op$ =3 "+" then oppush = a + b [3.0]
if op$ =4 "-" then oppush = a - b [3.0, 4.0]
2 push [3.0, 4.0, 2.0]
end function</lang>
* calculate [3.0, 8.0]
<pre>Push Num 3 to stack: 3
1 push [3.0, 8.0, 1.0]
Push Num 4 to stack: 3 4
5 push [3.0, 8.0, 1.0, 5.0]
Push Num 2 to stack: 3 4 2
Push Opr *- to stack: calculate [3.0, 8.0, -4.0]
Push Num 12 to stack: push [3.0, 8.0, 1-4.0, 2.0]
Push Num 53 to stack: push [3.0, 8.0, 1-4.0, 52.0, 3.0]
Push Opr -^ to stack: calculate [3.0, 8.0, -4.0, 8.0]
^ calculate [3.0, 8.0, 65536.0]
Push Num 2 to stack: 3 8 -4 2
/ calculate [3.0, 0.0001220703125]
Push Num 3 to stack: 3 8 -4 2 3
+ calculate [3.0001220703125]
Push Opr ^ to stack: 3 8 -4 8
 
Push Opr ^ to stack: 3 8 65536
result: 3.0001220703125
Push Opr / to stack: 3 1.22070312e-4
</pre>
Push Opr + to stack: 3.00012207</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">object RPN {
val PRINT_STACK_CONTENTS: Boolean = true
 
Line 4,026 ⟶ 5,904:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 4,045 ⟶ 5,923:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">var proggie = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
 
class RPN(arr=[]) {
Line 4,078 ⟶ 5,956:
}
 
RPN.new.run(proggie)</langsyntaxhighlight>
{{out}}
<pre>
Line 4,096 ⟶ 5,974:
3.0001220703125
</pre>
 
=={{header|Sinclair ZX81 BASIC}}==
If you only have 1k of RAM, this program will correctly evaluate the test expression with fewer than 10 bytes to spare. (I know that because I tried running it with the first line modified to allow a stack depth of 7, i.e. allocating space for two more 40-bit floats, and it crashed with an "out of memory" error code before it could print the result of the final addition.) If we desperately needed a few extra bytes there are ways they could be shaved out of the current program; but this version works, and editing a program that takes up almost all your available RAM isn't very comfortable, and to make it really useful for practical purposes you would still want to have 2k or more anyway.
 
The ZX81 character set doesn't include <code>^</code>, so we have to use <code>**</code> instead. Note that this is not two separate stars, although that's what it looks like: you have to enter it by typing <code>SHIFT</code>+<code>H</code>.
 
No attempt is made to check for invalid syntax, stack overflow or underflow, etc.
 
<lang basic> 10 DIM S(5)
20 LET P=1
30 INPUT E$
40 LET I=0
50 LET I=I+1
60 IF E$(I)=" " THEN GOTO 110
70 IF I<LEN E$ THEN GOTO 50
80 LET W$=E$
90 GOSUB 150
100 STOP
110 LET W$=E$( TO I-1)
120 LET E$=E$(I+1 TO )
130 GOSUB 150
140 GOTO 40
150 IF W$="+" OR W$="-" OR W$="*" OR W$="/" OR W$="**" THEN GOTO 250
160 LET S(P)=VAL W$
170 LET P=P+1
180 PRINT W$;
190 PRINT ":";
200 FOR I=P-1 TO 1 STEP -1
210 PRINT " ";S(I);
220 NEXT I
230 PRINT
240 RETURN
250 IF W$="**" THEN LET S(P-2)=ABS S(P-2)
260 LET S(P-2)=VAL (STR$ S(P-2)+W$+STR$ S(P-1))
270 LET P=P-1
280 GOTO 180</lang>
{{in}}
<pre>3 4 2 * 1 5 - 2 3 ** ** / +</pre>
{{out}}
<pre>3: 3
4: 4 3
2: 2 4 3
*: 8 3
1: 1 8 3
5: 5 1 8 3
-: -4 8 3
2: 2 -4 8 3
3: 3 2 -4 8 3
**: 8 -4 8 3
**: 65536 8 3
/: .00012207031 3
+: 3.0001221</pre>
 
=={{header|Swift}}==
{{trans|Go}}
<langsyntaxhighlight Swiftlang="swift">let opa = [
"^": (prec: 4, rAssoc: true),
"*": (prec: 3, rAssoc: false),
Line 4,208 ⟶ 6,034:
input = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"
"infix: \(input)"
"postfix: \(parseInfix(input))"</langsyntaxhighlight>
{{out}}
<pre>"postfix: 3 4 2 * 1 5 - 2 3 ^ ^ / +"</pre>
 
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl"># Helper
proc pop stk {
upvar 1 $stk s
Line 4,262 ⟶ 6,087:
}
 
puts [evaluate {3 4 2 * 1 5 - 2 3 ^ ^ / +}]</langsyntaxhighlight>
{{out}}
<pre>
Line 4,286 ⟶ 6,111:
Technically, this implementation uses a string to represent a stack and lines to delimit each item of the stack, not spaces as you might expect. However, the input is parsed pretty much as a space-separated argument string, but only with the asterisk quoted.
 
<langsyntaxhighlight lang="bash">#!/bin/sh
 
exp() {
Line 4,350 ⟶ 6,175:
}
 
rpn 3 4 2 '*' 1 5 '-' 2 3 '^' '^' '/' '+'</langsyntaxhighlight>
 
===Output===
<syntaxhighlight lang="text">3 : 3
4 : 3 4
2 : 3 4 2
Line 4,366 ⟶ 6,191:
/ : 3 0
+ : 3
3</langsyntaxhighlight>
 
=={{header|VBAV (Vlang)}}==
{{trans|C}}
Updated to V (Vlang) version 0.2.2
<syntaxhighlight lang="go">import math
 
const (
{{trans|Liberty BASIC}}
supported_operations = ['+', '-', '*', '/', '^']
max_depth = 256
)
 
struct Stack {
<lang VBA>Global stack$
mut:
data []f32 = [f32(0)].repeat(max_depth)
Function RPN(expr$)
depth int
Debug.Print "Expression:"
}
Debug.Print expr$
Debug.Print "Input", "Operation", "Stack after"
stack$ = ""
token$ = "#"
i = 1
token$ = Split(expr$)(i - 1) 'split is base 0
token2$ = " " + token$ + " "
Do
Debug.Print "Token "; i; ": "; token$,
'operation
If InStr("+-*/^", token$) <> 0 Then
Debug.Print "operate",
op2$ = pop$()
op1$ = pop$()
If op1$ = "" Then
Debug.Print "Error: stack empty for "; i; "-th token: "; token$
End
End If
op1 = Val(op1$)
op2 = Val(op2$)
Select Case token$
Case "+"
res = CDbl(op1) + CDbl(op2)
Case "-"
res = CDbl(op1) - CDbl(op2)
Case "*"
res = CDbl(op1) * CDbl(op2)
Case "/"
res = CDbl(op1) / CDbl(op2)
Case "^"
res = CDbl(op1) ^ CDbl(op2)
End Select
Call push2(str$(res))
'default:number
Else
Debug.Print "push",
Call push2(token$)
End If
Debug.Print "Stack: "; reverse$(stack$)
i = i + 1
If i > Len(Join(Split(expr, " "), "")) Then
token$ = ""
Else
token$ = Split(expr$)(i - 1) 'base 0
token2$ = " " + token$ + " "
End If
Loop Until token$ = ""
Debug.Print
Debug.Print "Result:"; pop$()
'extra$ = pop$()
If stack <> "" Then
Debug.Print "Error: extra things on a stack: "; stack$
End If
End
End Function
'---------------------------------------
Function reverse$(s$)
reverse$ = ""
token$ = "#"
While token$ <> ""
i = i + 1
token$ = Split(s$, "|")(i - 1) 'split is base 0
reverse$ = token$ & " " & reverse$
Wend
End Function
'---------------------------------------
Sub push2(s$)
stack$ = s$ + "|" + stack$ 'stack
End Sub
Function pop$()
'it does return empty on empty stack
pop$ = Split(stack$, "|")(0)
stack$ = Mid$(stack$, InStr(stack$, "|") + 1)
End Function</lang>
 
fn (mut stack Stack) push(value f32) {
{{out}}
if stack.depth >= max_depth {
<pre>?RPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
println('Stack Overflow!!')
Expression:
return
3 4 2 * 1 5 - 2 3 ^ ^ / +
}
Input Operation Stack after
stack.data[stack.depth] = value
Token 1 : 3 push Stack: 3
stack.depth++
Token 2 : 4 push Stack: 3 4
}
Token 3 : 2 push Stack: 3 4 2
Token 4 : * operate Stack: 3 8
Token 5 : 1 push Stack: 3 8 1
Token 6 : 5 push Stack: 3 8 1 5
Token 7 : - operate Stack: 3 8 -4
Token 8 : 2 push Stack: 3 8 -4 2
Token 9 : 3 push Stack: 3 8 -4 2 3
Token 10 : ^ operate Stack: 3 8 -4 8
Token 11 : ^ operate Stack: 3 8 65536
Token 12 : / operate Stack: 3 .0001220703125
Token 13 : + operate Stack: 3.0001220703125
 
fn (mut stack Stack) pop() ?f32 {
Result: 3.0001220703125</pre>
if stack.depth > 0 {
stack.depth--
result := stack.data[stack.depth]
return result
}
return error('Stack Underflow!!')
}
 
fn (stack Stack) peek() ?f32 {
if stack.depth > 0 {
result := stack.data[0]
return result
}
return error('Out of Bounds...')
}
 
fn (mut stack Stack) rpn(input string) ?f32 {
println('Input: $input')
tokens := input.split(' ')
mut a := f32(0)
mut b := f32(0)
println('Token Stack')
for token in tokens {
if token.str.is_digit() {
stack.push(token.f32())
} else if token in supported_operations {
b = stack.pop() or { f32(0) }
a = stack.pop() or { f32(0) }
match token {
'+' {
stack.push(a + b)
}
'-' {
stack.push(a - b)
}
'*' {
stack.push(a * b)
}
'/' {
stack.push(a / b)
}
'^' {
stack.push(f32(math.pow(a, b)))
}
else {
println('Oofffff')
}
}
}
print('${token:5s} ')
for i := 0; i < stack.depth; i++ {
if i == stack.depth - 1 {
println('${stack.data[i]:0.6f} |>')
} else {
print('${stack.data[i]:0.6f}, ')
}
}
}
return stack.peek()
}
 
fn main() {
=={{header|Xojo}}==
mut calc := Stack{}
result := calc.rpn('3 4 2 * 1 5 - 2 3 ^ ^ / +') or { return }
println('\nResult: $result')
}
</syntaxhighlight>
{{out}}
<pre>Input: 3 4 2 * 1 5 - 2 3 ^ ^ / +
Token Stack
3 3.000000 |>
4 3.000000, 4.000000 |>
2 3.000000, 4.000000, 2.000000 |>
* 3.000000, 8.000000 |>
1 3.000000, 8.000000, 1.000000 |>
5 3.000000, 8.000000, 1.000000, 5.000000 |>
- 3.000000, 8.000000, -4.000000 |>
2 3.000000, 8.000000, -4.000000, 2.000000 |>
3 3.000000, 8.000000, -4.000000, 2.000000, 3.000000 |>
^ 3.000000, 8.000000, -4.000000, 8.000000 |>
^ 3.000000, 8.000000, 65536.000000 |>
/ 3.000000, 0.000122 |>
+ 3.000122 |>
 
Result: 3.000122</pre>
{{trans|VBA}}
 
=={{header|Wren}}==
<lang Xojo>
{{trans|Kotlin}}
{{libheader|Wren-seq}}
Function RPN(expr As String) As String
<syntaxhighlight lang="wren">import "./seq" for Stack
 
Dim tokenArray() As String
Dim stack() As String
Dim Wert1 As Double
Dim Wert2 As Double
'Initialize array (removed later)
ReDim tokenArray(1)
ReDim stack(1)
tokenArray = Split(expr, " ")
Dim i As integer
i = 0
While i <= tokenArray.Ubound
If tokenArray(i) = "+" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1+Wert2))
ElseIf tokenArray(i) = "-" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1-Wert2))
ElseIf tokenArray(i) = "*" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1*Wert2))
ElseIf tokenArray(i) = "/" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(Wert1/Wert2))
ElseIf tokenArray(i) = "^" Then
Wert2 = Val(stack.pop)
Wert1 = Val(stack.pop)
stack.Append(Str(pow(Wert1,Wert2)))
Else
stack.Append(tokenArray(i))
End If
i = i +1
Wend
Return stack(2)
End Function</lang>
 
var rpnCalculate = Fn.new { |expr|
if (expr == "") Fiber.abort("Expression cannot be empty.")
System.print("For expression = %(expr)\n")
System.print("Token Action Stack")
var tokens = expr.split(" ").where { |t| t != "" }
var stack = Stack.new()
for (token in tokens) {
var d = Num.fromString(token)
if (d) {
stack.push(d)
System.print(" %(d) Push num onto top of stack %(stack)")
} else if ((token.count > 1) || !"+-*/^".contains(token)) {
Fiber.abort("%(token) is not a valid token.")
} else if (stack.count < 2) {
Fiber.abort("Stack contains too few operands.")
} else {
var d1 = stack.pop()
var d2 = stack.pop()
stack.push(token == "+" ? d2 + d1 :
token == "-" ? d2 - d1 :
token == "*" ? d2 * d1 :
token == "/" ? d2 / d1 : d2.pow(d1))
System.print(" %(token) Apply op to top of stack %(stack)")
}
}
System.print("\nThe final value is %(stack.pop())")
}
 
var expr = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
rpnCalculate.call(expr)</syntaxhighlight>
 
{{out}}
<pre>
<pre>?RPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
For expression = 3 4 2 * 1 5 - 2 3 ^ ^ / +
Expression:
3 4 2 * 1 5 - 2 3 ^ ^ / +
 
InputToken Operation Action Stack after Stack
Token 1 : 3 push Push num onto top of stack Stack: [3 ]
Token 2 : 4 push Push num onto top of stack Stack: [3, 4 ]
Token 3 : 2 push Push num onto top of stack Stack: [3, 4, 2 ]
Token * 4 : * Apply operateop to top of stack Stack: [3 , 8 ]
Token 5 : 1 push Push num onto top of stack Stack: [3 , 8, 1 ]
Token 6 : 5 push Push num onto top of stack Stack: [3 , 8, 1, 5 ]
Token - 7 : - Apply operateop to top of stack Stack: [3 , 8, -4 ]
Token 8 : 2 push Push num onto top of stack Stack: [3 , 8, -4, 2 ]
Token 9 : 3 push Push num onto top of stack Stack: [3 , 8, -4, 2, 3 ]
Token ^ 10 : ^ operateApply op to top of stack Stack: [3 , 8, -4 , 8 ]
Token ^ 11 : ^ operateApply op to top of stack Stack: [3 , 8 , 65536 ]
Token / 12 : / operateApply op to top of stack Stack: [3, 0.0001220001220703125]
Token + 13 : + operate Apply op to top of stack Stack: [3.0001220001220703125]
 
The final value is 3.0001220703125
Result: 3.000122</pre>
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">real Stack(10);
int SP;
 
proc Push(X);
real X;
[Stack(SP):= X; SP:= SP+1];
 
func real Pop;
[SP:= SP-1; return Stack(SP)];
 
char Str; real Top; int Token, I;
[Str:= "3 4 2 * 1 5 - 2 3 ^^ ^^ / + ";
SP:= 0;
Format(6, 8);
loop [repeat Token:= Str(0); Str:= Str+1;
until Token # ^ ; \skip space characters
case Token of
^+: [Top:= Pop; Push(Pop+Top)];
^-: [Top:= Pop; Push(Pop-Top)];
^*: [Top:= Pop; Push(Pop*Top)];
^/: [Top:= Pop; Push(Pop/Top)];
^^: [Top:= Pop; Push(Pow(Pop, Top))];
$A0: quit \space with MSB set
other [Push(float(Token-^0))]; \single digit number
ChOut(0, Token);
for I:= 0 to SP-1 do \show stack
RlOut(0, Stack(I));
CrLf(0);
];
]</syntaxhighlight>
{{out}}
<pre>
3 3.00000000
4 3.00000000 4.00000000
2 3.00000000 4.00000000 2.00000000
* 3.00000000 8.00000000
1 3.00000000 8.00000000 1.00000000
5 3.00000000 8.00000000 1.00000000 5.00000000
- 3.00000000 8.00000000 -4.00000000
2 3.00000000 8.00000000 -4.00000000 2.00000000
3 3.00000000 8.00000000 -4.00000000 2.00000000 3.00000000
^ 3.00000000 8.00000000 -4.00000000 8.00000000
^ 3.00000000 8.00000000 65536.00000000
/ 3.00000000 0.00012207
+ 3.00012207
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">var ops=D("^",True, "*",'*, "/",'/, "+",'+, "-",'-);
 
fcn parseRPN(e){
Line 4,590 ⟶ 6,429:
}
println("result: ", stack[0])
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">tests:=T("3 4 2 * 1 5 - 2 3 ^ ^ / +");
foreach t in (tests) { parseRPN(t) }</langsyntaxhighlight>
{{out}}
<pre>
9,477

edits