Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm

View file

@ -0,0 +1,22 @@
;Task:
Create a stack-based evaluator for an expression in &nbsp; [[wp:Reverse Polish notation|<u>r</u>everse <u>P</u>olish <u>n</u>otation (RPN)]] &nbsp; that also shows the changes in the stack as each individual token is processed ''as a table''.
* Assume an input of a correct, space separated, string of tokens of an RPN expression
* Test with the RPN expression generated from the &nbsp; [[Parsing/Shunting-yard algorithm]] &nbsp; task: <br>
&nbsp; &nbsp; &nbsp; &nbsp; <big><big><code> 3 4 2 * 1 5 - 2 3 ^ ^ / + </code></big></big>
* Print or display the output here
;Notes:
* &nbsp; <big><b> '''^''' </b></big> &nbsp; means exponentiation in the expression above.
* &nbsp; <big><b> '''/''' </b></big> &nbsp; means division.
;See also:
* &nbsp; [[Parsing/Shunting-yard algorithm]] for a method of generating an RPN from an infix expression.
* &nbsp; Several solutions to [[24 game/Solve]] make use of RPN evaluators (although tracing how they work is not a part of that task).
* &nbsp; [[Parsing/RPN to infix conversion]].
* &nbsp; [[Arithmetic evaluation]].
<br><br>

View file

@ -0,0 +1,16 @@
[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)

View file

@ -0,0 +1,103 @@
* 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

View file

@ -0,0 +1,143 @@
# RPN Expression evaluator - handles numbers and + - * / ^ #
# the right-hand operand for ^ is converted to an integer #
# expression terminator #
CHAR end of expression character = REPR 12;
# evaluates the specified rpn expression #
PROC evaluate = ( STRING rpn expression )VOID:
BEGIN
[ 256 ]REAL stack;
INT stack pos := 0;
# pops an element off the stack #
PROC pop = REAL:
BEGIN
stack pos -:= 1;
stack[ stack pos + 1 ]
END; # pop #
INT rpn pos := LWB rpn expression;
# evaluate tokens from the expression until we get the end of expression #
WHILE
# get the next token from the string #
STRING token type;
REAL value;
# skip spaces #
WHILE rpn expression[ rpn pos ] = " "
DO
rpn pos +:= 1
OD;
# handle the token #
IF rpn expression[ rpn pos ] = end of expression character
THEN
# no more tokens #
FALSE
ELSE
# have a token #
IF rpn expression[ rpn pos ] >= "0"
AND rpn expression[ rpn pos ] <= "9"
THEN
# have a number #
# find where the nmumber is in the expression #
INT number start = rpn pos;
WHILE ( rpn expression[ rpn pos ] >= "0"
AND rpn expression[ rpn pos ] <= "9"
)
OR rpn expression[ rpn pos ] = "."
DO
rpn pos +:= 1
OD;
# read the number from the expression #
FILE number f;
associate( number f
, LOC STRING := rpn expression[ number start : rpn pos - 1 ]
);
get( number f, ( value ) );
close( number f );
token type := "number"
ELSE
# must be an operator #
CHAR op = rpn expression[ rpn pos ];
rpn pos +:= 1;
REAL arg1 := pop;
REAL arg2 := pop;
token type := op;
value := IF op = "+"
THEN
# add the top two stack elements #
arg1 + arg2
ELIF op = "-"
THEN
# subtract the top two stack elements #
arg2 - arg1
ELIF op = "*"
THEN
# multiply the top two stack elements #
arg2 * arg1
ELIF op = "/"
THEN
# divide the top two stack elements #
arg2 / arg1
ELIF op = "^"
THEN
# raise op2 to the power of op1 #
arg2 ^ ENTIER arg1
ELSE
# unknown operator #
print( ( "Unknown operator: """ + op + """", newline ) );
0
FI
FI;
TRUE
FI
DO
# push the new value on the stack and show the new stack #
stack[ stack pos +:= 1 ] := value;
print( ( ( token type + " " )[ 1 : 8 ] ) );
FOR element FROM LWB stack TO stack pos
DO
print( ( " ", fixed( stack[ element ], 8, 4 ) ) )
OD;
print( ( newline ) )
OD;
print( ( "Result is: ", fixed( stack[ stack pos ], 12, 8 ), newline ) )
END; # evaluate #
main: (
# get the RPN expresson from the user #
STRING rpn expression;
print( ( "Enter expression: " ) );
read( ( rpn expression, newline ) );
# add a space to terminate the final token and an expression terminator #
rpn expression +:= " " + end of expression character;
# execute the expression #
evaluate( rpn expression )
)

View file

@ -0,0 +1,117 @@
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

View file

@ -0,0 +1,19 @@
grammar rpnC ;
//
// rpn Calculator
//
// Nigel Galloway - April 7th., 2012
//
@members {
Stack<Double> s = new Stack<Double>();
}
rpn : (WS* (num|op) (WS | WS* NEWLINE {System.out.println(s.pop());}))*;
num : '-'? Digit+ ('.' Digit+)? {s.push(Double.parseDouble($num.text));};
Digit : '0'..'9';
op : '-' {double x = s.pop(); s.push(s.pop() - x);}
| '/' {double x = s.pop(); s.push(s.pop() / x);}
| '*' {s.push(s.pop() * s.pop());}
| '^' {double x = s.pop(); s.push(Math.pow(s.pop(), x));}
| '+' {s.push(s.pop() + s.pop());};
WS : (' ' | '\t'){skip()};
NEWLINE : '\r'? '\n';

View file

@ -0,0 +1,128 @@
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

View file

@ -0,0 +1,68 @@
with Ada.Text_IO, Ada.Containers.Vectors;
procedure RPN_Calculator is
package IIO is new Ada.Text_IO.Float_IO(Float);
package Float_Vec is new Ada.Containers.Vectors
(Index_Type => Positive, Element_Type => Float);
Stack: Float_Vec.Vector;
Input: String := Ada.Text_IO.Get_Line;
Cursor: Positive := Input'First;
New_Cursor: Positive;
begin
loop
-- read spaces
while Cursor <= Input'Last and then Input(Cursor)=' ' loop
Cursor := Cursor + 1;
end loop;
exit when Cursor > Input'Last;
New_Cursor := Cursor;
while New_Cursor <= Input'Last and then Input(New_Cursor) /= ' ' loop
New_Cursor := New_Cursor + 1;
end loop;
-- try to read a number and push it to the stack
declare
Last: Positive;
Value: Float;
X, Y: Float;
begin
IIO.Get(From => Input(Cursor .. New_Cursor - 1),
Item => Value,
Last => Last);
Stack.Append(Value);
Cursor := New_Cursor;
exception -- if reading the number fails, try to read an operator token
when others =>
Y := Stack.Last_Element; Stack.Delete_Last; -- pick two elements
X := Stack.Last_Element; Stack.Delete_Last; -- from the stack
case Input(Cursor) is
when '+' => Stack.Append(X+Y);
when '-' => Stack.Append(X-Y);
when '*' => Stack.Append(X*Y);
when '/' => Stack.Append(X/Y);
when '^' => Stack.Append(X ** Integer(Float'Rounding(Y)));
when others => raise Program_Error with "unecpected token '"
& Input(Cursor) & "' at column" & Integer'Image(Cursor);
end case;
Cursor := New_Cursor;
end;
for I in Stack.First_Index .. Stack.Last_Index loop
Ada.Text_IO.Put(" ");
IIO.Put(Stack.Element(I), Aft => 5, Exp => 0);
end loop;
Ada.Text_IO.New_Line;
end loop;
Ada.Text_IO.Put("Result = ");
IIO.Put(Item => Stack.Last_Element, Aft => 5, Exp => 0);
end RPN_Calculator;

View file

@ -0,0 +1,35 @@
evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
evalRPN(s){
stack := []
out := "For RPN expression: '" s "'`r`n`r`nTOKEN`t`tACTION`t`t`tSTACK`r`n"
Loop Parse, s
If A_LoopField is number
t .= A_LoopField
else
{
If t
stack.Insert(t)
, out .= t "`tPush num onto top of stack`t" stackShow(stack) "`r`n"
, t := ""
If InStr("+-/*^", l := A_LoopField)
{
a := stack.Remove(), b := stack.Remove()
stack.Insert( l = "+" ? b + a
:l = "-" ? b - a
:l = "*" ? b * a
:l = "/" ? b / a
:l = "^" ? b **a
:0 )
out .= l "`tApply op " l " to top of stack`t" stackShow(stack) "`r`n"
}
}
r := stack.Remove()
out .= "`r`n The final output value is: '" r "'"
clipboard := out
return r
}
StackShow(stack){
for each, value in stack
out .= A_Space value
return subStr(out, 2)
}

View file

@ -0,0 +1,38 @@
@% = &60B
RPN$ = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
DIM Stack(1000)
SP% = 0
FOR i% = 1 TO LEN(RPN$)
Token$ = MID$(RPN$,i%,1)
IF Token$ <> " " THEN
PRINT Token$ " :";
CASE Token$ OF
WHEN "+": PROCpush(FNpop + FNpop)
WHEN "-": PROCpush(-FNpop + FNpop)
WHEN "*": PROCpush(FNpop * FNpop)
WHEN "/": n = FNpop : PROCpush(FNpop / n)
WHEN "^": n = FNpop : PROCpush(FNpop ^ n)
WHEN "0","1","2","3","4","5","6","7","8","9":
PROCpush(VALMID$(RPN$,i%))
WHILE ASCMID$(RPN$,i%)>=48 AND ASCMID$(RPN$,1)<=57
i% += 1
ENDWHILE
ENDCASE
FOR j% = SP%-1 TO 0 STEP -1 : PRINT Stack(j%); : NEXT
PRINT
ENDIF
NEXT i%
END
DEF PROCpush(n)
IF SP% > DIM(Stack(),1) ERROR 100, "Stack full"
Stack(SP%) = n
SP% += 1
ENDPROC
DEF FNpop
IF SP% = 0 ERROR 100, "Stack empty"
SP% -= 1
= Stack(SP%)

View file

@ -0,0 +1,35 @@
( ( 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
)

View file

@ -0,0 +1,53 @@
#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;
}

View file

@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Threading;
namespace RPNEvaluator
{
class RPNEvaluator
{
static void Main(string[] args)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
string rpn = "3 4 2 * 1 5 - 2 3 ^ ^ / +";
Console.WriteLine("{0}\n", rpn);
decimal result = CalculateRPN(rpn);
Console.WriteLine("\nResult is {0}", result);
}
static decimal CalculateRPN(string rpn)
{
string[] rpnTokens = rpn.Split(' ');
Stack<decimal> stack = new Stack<decimal>();
decimal number = decimal.Zero;
foreach (string token in rpnTokens)
{
if (decimal.TryParse(token, out number))
{
stack.Push(number);
}
else
{
switch (token)
{
case "^":
case "pow":
{
number = stack.Pop();
stack.Push((decimal)Math.Pow((double)stack.Pop(), (double)number));
break;
}
case "ln":
{
stack.Push((decimal)Math.Log((double)stack.Pop(), Math.E));
break;
}
case "sqrt":
{
stack.Push((decimal)Math.Sqrt((double)stack.Pop()));
break;
}
case "*":
{
stack.Push(stack.Pop() * stack.Pop());
break;
}
case "/":
{
number = stack.Pop();
stack.Push(stack.Pop() / number);
break;
}
case "+":
{
stack.Push(stack.Pop() + stack.Pop());
break;
}
case "-":
{
number = stack.Pop();
stack.Push(stack.Pop() - number);
break;
}
default:
Console.WriteLine("Error in CalculateRPN(string) Method!");
break;
}
}
PrintState(stack);
}
return stack.Pop();
}
static void PrintState(Stack<decimal> stack)
{
decimal[] arr = stack.ToArray();
for (int i = arr.Length - 1; i >= 0; i--)
{
Console.Write("{0,-8:F3}", arr[i]);
}
Console.WriteLine();
}
}
}

View file

@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void die(const char *msg)
{
fprintf(stderr, "%s", msg);
abort();
}
#define MAX_D 256
double stack[MAX_D];
int depth;
void push(double v)
{
if (depth >= MAX_D) die("stack overflow\n");
stack[depth++] = v;
}
double pop()
{
if (!depth) die("stack underflow\n");
return stack[--depth];
}
double rpn(char *s)
{
double a, b;
int i;
char *e, *w = " \t\n\r\f";
for (s = strtok(s, w); s; s = strtok(0, w)) {
a = strtod(s, &e);
if (e > s) printf(" :"), push(a);
#define binop(x) printf("%c:", *s), b = pop(), a = pop(), push(x)
else if (*s == '+') binop(a + b);
else if (*s == '-') binop(a - b);
else if (*s == '*') binop(a * b);
else if (*s == '/') binop(a / b);
else if (*s == '^') binop(pow(a, b));
#undef binop
else {
fprintf(stderr, "'%c': ", *s);
die("unknown oeprator\n");
}
for (i = depth; i-- || 0 * putchar('\n'); )
printf(" %g", stack[i]);
}
if (depth != 1) die("stack leftover\n");
return pop();
}
int main(void)
{
char s[] = " 3 4 2 * 1 5 - 2 3 ^ ^ / + ";
printf("%g\n", rpn(s));
return 0;
}

View file

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#define die(msg) fprintf(stderr, msg"\n"), abort();
double get(const char *s, const char *e, char **new_e)
{
const char *t;
double a, b;
for (e--; e >= s && isspace(*e); e--);
for (t = e; t > s && !isspace(t[-1]); t--);
if (t < s) die("underflow");
#define get2(expr) b = get(s, t, (char **)&t), a = get(s, t, (char **)&t), a = expr
a = strtod(t, (char **)&e);
if (e <= t) {
if (t[0] == '+') get2(a + b);
else if (t[0] == '-') get2(a - b);
else if (t[0] == '*') get2(a * b);
else if (t[0] == '/') get2(a / b);
else if (t[0] == '^') get2(pow(a, b));
else {
fprintf(stderr, "'%c': ", t[0]);
die("unknown token");
}
}
#undef get2
*(const char **)new_e = t;
return a;
}
double rpn(const char *s)
{
const char *e = s + strlen(s);
double v = get(s, e, (char**)&e);
while (e > s && isspace(e[-1])) e--;
if (e == s) return v;
fprintf(stderr, "\"%.*s\": ", e - s, s);
die("front garbage");
}
int main(void)
{
printf("%g\n", rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +"));
return 0;
}

View file

@ -0,0 +1,73 @@
% 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

View file

@ -0,0 +1,126 @@
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.

View file

@ -0,0 +1,44 @@
import ceylon.collection {
ArrayList
}
shared void run() {
value ops = map {
"+" -> plus<Float>,
"*" -> times<Float>,
"-" -> ((Float a, Float b) => a - b),
"/" -> ((Float a, Float b) => a / b),
"^" -> ((Float a, Float b) => a ^ b)
};
void printTableRow(String|Float token, String description, {Float*} stack) {
print("``token.string.padTrailing(8)````description.padTrailing(30)````stack``");
}
function calculate(String input) {
value stack = ArrayList<Float>();
value tokens = input.split().map((String element)
=> if(ops.keys.contains(element)) then element else parseFloat(element));
print("Token Operation Stack");
for(token in tokens.coalesced) {
if(is Float token) {
stack.push(token);
printTableRow(token, "push", stack);
} else if(exists op = ops[token], exists first = stack.pop(), exists second = stack.pop()) {
value result = op(second, first);
stack.push(result);
printTableRow(token, "perform ``token`` on ``formatFloat(second, 1, 1)`` and ``formatFloat(first, 1, 1)``", stack);
} else {
throw Exception("bad syntax");
}
}
return stack.pop();
}
print(calculate("3 4 2 * 1 5 - 2 3 ^ ^ / +"));
}

View file

@ -0,0 +1,29 @@
(ns rosettacode.parsing-rpn-calculator-algorithm
(:require clojure.math.numeric-tower
clojure.string
clojure.pprint))
(def operators
"the only allowable operators for our calculator"
{"+" +
"-" -
"*" *
"/" /
"^" clojure.math.numeric-tower/expt})
(defn rpn
"takes a string and returns a lazy-seq of all the stacks"
[string]
(letfn [(rpn-reducer [stack item] ; this takes a stack and one item and makes a new stack
(if (contains? operators item)
(let [operand-1 (peek stack) ; if we used lists instead of vectors, we could use destructuring, but stacks would look backwards
stack-1 (pop stack)] ;we're assuming that all the operators are binary
(conj (pop stack-1)
((operators item) (peek stack-1) operand-1)))
(conj stack (Long. item))))] ; if it wasn't an operator, we'll assume it's a long. Could choose bigint, or even read-line
(reductions rpn-reducer [] (clojure.string/split string #"\s+")))) ;reductions is like reduce only shows all the intermediate steps
(let [stacks (rpn "3 4 2 * 1 5 - 2 3 ^ ^ / +")] ;bind it so we can output the answer separately.
(println "stacks: ")
(clojure.pprint/pprint stacks)
(print "answer:" (->> stacks last first)))

View file

@ -0,0 +1,20 @@
(setf (symbol-function '^) #'expt) ; Make ^ an alias for EXPT
(defun print-stack (token stack)
(format T "~a: ~{~a ~}~%" token (reverse stack)))
(defun rpn (tokens &key stack verbose )
(cond
((and (not tokens) (not stack)) 0)
((not tokens) (car stack))
(T
(let* ((current (car tokens))
(next-stack (if (numberp current)
(cons current stack)
(let* ((arg2 (car stack))
(arg1 (cadr stack))
(fun (car tokens)))
(cons (funcall fun arg1 arg2) (cddr stack))))))
(when verbose
(print-stack current next-stack))
(rpn (cdr tokens) :stack next-stack :verbose verbose)))))

View file

@ -0,0 +1,26 @@
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]);
}

View file

@ -0,0 +1,116 @@
{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;

View file

@ -0,0 +1,28 @@
;; RPN (postfix) evaluator
(lib 'hash)
(define OPS (make-hash))
(hash-set OPS "^" expt)
(hash-set OPS "*" *)
(hash-set OPS "/" //) ;; float divide
(hash-set OPS "+" +)
(hash-set OPS "-" -)
(define (op? op) (hash-ref OPS op))
;; algorithm : https://en.wikipedia.org/wiki/Reverse_Polish_notation#Postfix_algorithm
(define (calculator rpn S)
(for ((token rpn))
(if (op? token)
(let [(op2 (pop S)) (op1 (pop S))]
(unless (and op1 op2) (error "cannot calculate expression at:" token))
(push S ((op? token) op1 op2))
(writeln op1 token op2 "→" (stack-top S)))
(push S (string->number token))))
(pop S))
(define (task rpn)
(define S (stack 'S))
(calculator (text-parse rpn) S ))

View file

@ -0,0 +1,42 @@
open string generic monad io
type OpType = Push | Operate
deriving Show
type Op = Op (OpType typ) input stack
deriving Show
parse str = split " " str
eval stack [] = []
eval stack (x::xs) = op :: eval nst xs
where (op, nst) = conv x stack
conv "+"@x = operate x (+)
conv "-"@x = operate x (-)
conv "*"@x = operate x (*)
conv "/"@x = operate x (/)
conv "^"@x = operate x (**)
conv x = \stack ->
let n = gread x::stack in
(Op Push x n, n)
operate input fn (x::y::ys) =
let n = (y `fn` x) :: ys in
(Op Operate input n, n)
print_line (Op typ input stack) = do
putStr input
putStr "\t"
put typ
putStr "\t\t"
putLn stack
print ((Op typ input stack)@x::xs) lv = print_line x `seq` print xs (head stack)
print [] lv = lv
print_result xs = do
putStrLn "Input\tOperation\tStack after"
res <- return $ print xs 0
putStrLn ("Result: " ++ show res)
res = parse "3 4 2 * 1 5 - 2 3 ^ ^ / +" |> eval []
print_result res ::: IO

View file

@ -0,0 +1,43 @@
-module(rpn).
-export([eval/1]).
parse(Expression) ->
parse(string:tokens(Expression," "),[]).
parse([],Expression) ->
lists:reverse(Expression);
parse(["+"|Xs],Expression) ->
parse(Xs,[fun erlang:'+'/2|Expression]);
parse(["-"|Xs],Expression) ->
parse(Xs,[fun erlang:'-'/2|Expression]);
parse(["*"|Xs],Expression) ->
parse(Xs,[fun erlang:'*'/2|Expression]);
parse(["/"|Xs],Expression) ->
parse(Xs,[fun erlang:'/'/2|Expression]);
parse(["^"|Xs],Expression) ->
parse(Xs,[fun math:pow/2|Expression]);
parse([X|Xs],Expression) ->
{N,_} = string:to_integer(X),
parse(Xs,[N|Expression]).
%% The expression should be entered as a string of numbers and
%% operators separated by spaces. No error handling is included if
%% another string format is used.
eval(Expression) ->
eval(parse(Expression),[]).
eval([],[N]) ->
N;
eval([N|Exp],Stack) when is_number(N) ->
NewStack = [N|Stack],
print(NewStack),
eval(Exp,NewStack);
eval([F|Exp],[X,Y|Stack]) ->
NewStack = [F(Y,X)|Stack],
print(NewStack),
eval(Exp,NewStack).
print(Stack) ->
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").

View file

@ -0,0 +1,23 @@
let reduce op = function
| b::a::r -> (op a b)::r
| _ -> failwith "invalid expression"
let interprete s = function
| "+" -> "add", reduce ( + ) s
| "-" -> "subtr", reduce ( - ) s
| "*" -> "mult", reduce ( * ) s
| "/" -> "divide", reduce ( / ) s
| "^" -> "exp", reduce ( ** ) s
| str -> "push", (System.Double.Parse str) :: s
let interp_and_show s inp =
let op,s'' = interprete s inp
printf "%5s%8s " inp op
List.iter (printf " %-6.3F") (List.rev s'')
printf "\n";
s''
let eval str =
printfn "Token Action Stack";
let ss = str.ToString().Split() |> Array.toList
List.fold interp_and_show [] ss

View file

@ -0,0 +1,4 @@
IN: scratchpad 3 4 2 * 1 5 - 2 3 ^ ^ / +
--- Data stack:
3+1/8192

View file

@ -0,0 +1,2 @@
{ 3 4 2 * 1 5 - 2 3 ^ ^ / + }
[ dup pprint bl 1quotation call get-datastack . ] each

View file

@ -0,0 +1,2 @@
: ^ over swap 1 ?do over * loop nip ;
s" 3 4 2 * 1 5 - 2 3 ^ ^ / +" evaluate .

View file

@ -0,0 +1,11 @@
: ^ 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 ^ ^ / +

View file

@ -0,0 +1,48 @@
REAL FUNCTION EVALRP(TEXT) !Evaluates a Reverse Polish string.
Caution: deals with single digits only.
CHARACTER*(*) TEXT !The RPN string.
INTEGER SP,STACKLIMIT !Needed for the evaluation.
PARAMETER (STACKLIMIT = 6) !This should do.
REAL*8 STACK(STACKLIMIT) !Though with ^ there's no upper limit.
INTEGER L,D !Assistants for the scan.
CHARACTER*4 DEED !A scratchpad for the annotation.
CHARACTER*1 C !The character of the moment.
WRITE (6,1) TEXT !A function that writes messages... Improper.
1 FORMAT ("Evaluation of the Reverse Polish string ",A,// !Still, it's good to see stuff.
1 "Char Token Action SP:Stack...") !Such as a heading for the trace.
SP = 0 !Commence with the stack empty.
STACK = -666 !This value should cause trouble.
DO L = 1,LEN(TEXT) !Step through the text.
C = TEXT(L:L) !Grab a character.
IF (C.LE." ") CYCLE !Boring.
D = ICHAR(C) - ICHAR("0") !Uncouth test to check for a digit.
IF (D.GE.0 .AND. D.LE.9) THEN !Is it one?
DEED = "Load" !Yes. So, load its value.
SP = SP + 1 !By going up one.
IF (SP.GT.STACKLIMIT) STOP "Stack overflow!" !Or, maybe not.
STACK(SP) = D !And stashing the value.
ELSE !Otherwise, it must be an operator.
IF (SP.LT.2) STOP "Stack underflow!" !They all require two operands.
DEED = "XEQ" !So, I'm about to do so.
SELECT CASE(C) !Which one this time?
CASE("+"); STACK(SP - 1) = STACK(SP - 1) + STACK(SP) !A + B = B + A, so it is easy.
CASE("-"); STACK(SP - 1) = STACK(SP - 1) - STACK(SP) !A is in STACK(SP - 1), B in STACK(SP)
CASE("*"); STACK(SP - 1) = STACK(SP - 1)*STACK(SP) !Again, order doesn't count.
CASE("/"); STACK(SP - 1) = STACK(SP - 1)/STACK(SP) !But for division, A/B becomes A B /
CASE("^"); STACK(SP - 1) = STACK(SP - 1)**STACK(SP) !So, this way around.
CASE DEFAULT !This should never happen!
STOP "Unknown operator!" !If the RPN script is indeed correct.
END SELECT !So much for that operator.
SP = SP - 1 !All of them take two operands and make one.
END IF !So much for that item.
WRITE (6,2) L,C,DEED,SP,STACK(1:SP) !Reveal the state now.
2 FORMAT (I4,A6,A7,I4,":",66F14.6) !Aligned with the heading of FORMAT 1.
END DO !On to the next symbol.
EVALRP = STACK(1) !The RPN string being correct, this is the result.
END !Simple enough!
PROGRAM HSILOP
REAL V
V = EVALRP("3 4 2 * 1 5 - 2 3 ^ ^ / +") !The specified example.
WRITE (6,*) "Result is...",V
END

View file

@ -0,0 +1,81 @@
#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

View file

@ -0,0 +1,19 @@
def evaluate( expr ) =
stack = []
for token <- expr.split( '''\s+''' )
case number( token )
Some( n ) ->
stack = n : stack
println( "push $token: ${stack.reversed()}" )
None ->
case {'+': (+), '-': (-), '*': (*), '/': (/), '^': (^)}.>get( token )
Some( op ) ->
stack = op( stack.tail().head(), stack.head() ) : stack.tail().tail()
println( "perform $token: ${stack.reversed()}" )
None -> error( "unrecognized operator '$token'" )
stack.head()
res = evaluate( '3 4 2 * 1 5 - 2 3 ^ ^ / +' )
println( res + (if res is Integer then '' else " or ${float(res)}") )

View file

@ -0,0 +1,76 @@
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

View file

@ -0,0 +1,43 @@
package main
import (
"fmt"
"math"
"strconv"
"strings"
)
var input = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
func main() {
fmt.Printf("For postfix %q\n", input)
fmt.Println("\nToken Action Stack")
var stack []float64
for _, tok := range strings.Fields(input) {
action := "Apply op to top of stack"
switch tok {
case "+":
stack[len(stack)-2] += stack[len(stack)-1]
stack = stack[:len(stack)-1]
case "-":
stack[len(stack)-2] -= stack[len(stack)-1]
stack = stack[:len(stack)-1]
case "*":
stack[len(stack)-2] *= stack[len(stack)-1]
stack = stack[:len(stack)-1]
case "/":
stack[len(stack)-2] /= stack[len(stack)-1]
stack = stack[:len(stack)-1]
case "^":
stack[len(stack)-2] =
math.Pow(stack[len(stack)-2], stack[len(stack)-1])
stack = stack[:len(stack)-1]
default:
action = "Push num onto top of stack"
f, _ := strconv.ParseFloat(tok, 64)
stack = append(stack, f)
}
fmt.Printf("%3s %-26s %v\n", tok, action, stack)
}
fmt.Println("\nThe final value is", stack[0])
}

View file

@ -0,0 +1,19 @@
def evaluateRPN(expression) {
def stack = [] as Stack
def binaryOp = { action -> return { action.call(stack.pop(), stack.pop()) } }
def actions = [
'+': binaryOp { a, b -> b + a },
'-': binaryOp { a, b -> b - a },
'*': binaryOp { a, b -> b * a },
'/': binaryOp { a, b -> b / a },
'^': binaryOp { a, b -> b ** a }
]
expression.split(' ').each { item ->
def action = actions[item] ?: { item as BigDecimal }
stack.push(action.call())
println "$item: $stack"
}
assert stack.size() == 1 : "Unbalanced Expression: $expression ($stack)"
stack.pop()
}

View file

@ -0,0 +1 @@
println evaluateRPN('3 4 2 * 1 5 - 2 3 ^ ^ / +')

View file

@ -0,0 +1,13 @@
calcRPN :: String -> [Double]
calcRPN = foldl interprete [] . words
interprete s x
| x `elem` ["+","-","*","/","^"] = operate x s
| otherwise = read x:s
where
operate op (x:y:s) = case op of
"+" -> x + y:s
"-" -> y - x:s
"*" -> x * y:s
"/" -> y / x:s
"^" -> y ** x:s

View file

@ -0,0 +1,6 @@
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)

View file

@ -0,0 +1,7 @@
import Control.Monad (foldM)
calcRPNIO :: String -> IO [Double]
calcRPNIO = foldM (verbose interprete) [] . words
verbose f s x = write (x ++ "\t" ++ show res ++ "\n") >> return res
where res = f s x

View file

@ -0,0 +1,10 @@
class Monad m => Logger m where
write :: String -> m ()
instance Logger IO where write = putStr
instance a ~ String => Logger (Writer a) where write = tell
verbose2 f x y = write (show x ++ " " ++
show y ++ " ==> " ++
show res ++ "\n") >> return res
where res = f x y

View file

@ -0,0 +1,2 @@
calcRPNM :: Logger m => String -> m [Double]
calcRPNM = foldM (verbose interprete) [] . words

View file

@ -0,0 +1,33 @@
procedure main()
EvalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +")
end
link printf
invocable all
procedure EvalRPN(expr) #: evaluate (and trace stack) an RPN string
stack := []
expr ? until pos(0) do {
tab(many(' ')) # consume previous seperator
token := tab(upto(' ')|0) # get token
if token := numeric(token) then { # ... numeric
push(stack,token)
printf("pushed numeric %i : %s\n",token,list2string(stack))
}
else { # ... operator
every b|a := pop(stack) # pop & reverse operands
case token of {
"+"|"-"|"*"|"^" : push(stack,token(a,b))
"/" : push(stack,token(real(a),b))
default : runerr(205,token)
}
printf("applied operator %s : %s\n",token,list2string(stack))
}
}
end
procedure list2string(L) #: format list as a string
every (s := "[ ") ||:= !L || " "
return s || "]"
end

View file

@ -0,0 +1,4 @@
a: , <;._1 ' ' , '3 4 2 * 1 5 - 2 3 ^ ^ / +'
┌┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
││3│4│2│*│1│5│-│2│3│^│^│/│+│
└┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘

View file

@ -0,0 +1,32 @@
isOp=: '_+-*/^' e.~ {.@>@{.
mo=: 1 :'(}: , u@{:) @ ['
dy=: 1 :'(_2&}. , u/@(_2&{.)) @ ['
dispatch=: (-mo)`(+dy)`(-dy)`(*dy)`(%dy)`(^dy)@.('_+-*/^' i. {.@>@])
doShift=: (<@, ".@>@{.) , }.@]
doApply=: }.@] ,~ [ <@dispatch {.@]
consume=: [: ([ smoutput@>@{.) >@{. doShift`doApply@.(isOp@]) }.
consume ^: (<:@#) a: , <;._1 ' ' , '3 4 2 * 1 5 - 2 3 ^ ^ / +'
3
3 4
3 4 2
3 8
3 8 1
3 8 1 5
3 8 _4
3 8 _4 2
3 8 _4 2 3
3 8 _4 8
3 8 65536
3 0.00012207
3.00012
┌───────┐
│3.00012│
└───────┘
consume ^: (<:@#) a: , <;._1 ' ' , '3 _ 4 +'
3
_3
_3 4
1
┌─┐
│1│
└─┘

View file

@ -0,0 +1,7 @@
rpn=: 3 :0
queue=. |.3 :'|.3 :y 0'::]each;: y
op=. 1 :'2 (u~/@:{.,}.)S:0 ,@]'
ops=. +op`(-op)`(*op)`(%op)`(^op)`(,&;)
choose=. ((;:'+-*/^')&i.@[)
,ops@.choose/queue
)

View file

@ -0,0 +1,2 @@
rpn '3 4 2 * 1 5 - 2 3 ^ ^ / +'
3.00012

View file

@ -0,0 +1,7 @@
rpnD=: 3 :0
queue=. |.3 :'|.3 :y 0'::]each;: y
op=. 1 :'2 (u~/@:{.,}.)S:0 ,@([smoutput)@]'
ops=. +op`(-op)`(*op)`(%op)`(^op)`(,&;)
choose=. ((;:'+-*/^')&i.@[)
,ops@.choose/queue
)

View file

@ -0,0 +1,10 @@
rpnD '3 4 2 * 1 5 - 2 3 ^ ^ / +'
┌─────┐
│2 4 3│
└─────┘
5 1 8 3
3 2 _4 8 3
8 _4 8 3
65536 8 3
0.00012207 3
3.00012

View file

@ -0,0 +1,55 @@
import java.util.LinkedList;
public class RPN{
public static void main(String[] args) {
evalRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +");
}
private static void evalRPN(String expr){
LinkedList<Double> stack = new LinkedList<Double>();
System.out.println("Input\tOperation\tStack after");
for (String token : expr.split("\\s")){
System.out.print(token + "\t");
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 {
System.out.print("Push\t\t");
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());
}
}

View file

@ -0,0 +1,26 @@
const e = '3 4 2 * 1 5 - 2 3 ^ ^ / +';
const s = [], tokens = e.split(' ');
for (const t of tokens) {
const n = Number(t);
if (!isNaN(n)) {
s.push(n);
} else {
if (s.length < 2) {
throw new Error(`${t}: ${s}: insufficient operands.`);
}
const o2 = s.pop(), o1 = s.pop();
switch (t) {
case '+': s.push(o1 + o2); break;
case '-': s.push(o1 - o2); break;
case '*': s.push(o1 * o2); break;
case '/': s.push(o1 / o2); break;
case '^': s.push(Math.pow(o1, o2)); break;
default: throw new Error(`Unrecognized operator: [${t}]`);
}
}
console.log(`${t}: ${s}`);
}
if (s.length > 1) {
throw new Error(`${s}: insufficient operators.`);
}

View file

@ -0,0 +1,24 @@
# Input: an array representing a stack, with .[-1] being its top.
# Output: the updated array after applying `op`
def rpn(op):
def two: .[-2:];
def update($x): (.[:-2] + [$x]);
if length<=1 then .
elif op == "+" then update(two | add)
elif op == "*" then update(two | (.[0] * .[1]))
elif op == "/" then update(two | (.[0] / .[1]))
elif op == "-" then update(two | (.[0] - .[1]))
elif op == "^" then update(two | (pow(.[0]; .[1])))
else ("ignoring unrecognized op \(op)" | debug) as $debug | .
end;
def eval:
foreach .[] as $item ([];
if ($item | type) == "number" then . + [$item]
else rpn($item)
end;
"\($item) => \(.)" ) ;
"3 4 2 * 1 5 - 2 3 ^ ^ / +"
| split(" ") | map( (try tonumber) // .)
| eval

View file

@ -0,0 +1,16 @@
function rpn(s)
stack = Any[]
for op in map(eval, map(parse, split(s)))
if isa(op, Function)
arg2 = pop!(stack)
arg1 = pop!(stack)
push!(stack, op(arg1, arg2))
else
push!(stack, op)
end
println("$op: ", join(stack, ", "))
end
length(stack) != 1 && error("invalid RPN expression $s")
return stack[1]
end
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +")

View file

@ -0,0 +1,40 @@
// version 1.1.2
fun rpnCalculate(expr: String) {
if (expr.isEmpty()) throw IllegalArgumentException("Expresssion cannot be empty")
println("For expression = $expr\n")
println("Token Action Stack")
val tokens = expr.split(' ').filter { it != "" }
val stack = mutableListOf<Double>()
for (token in tokens) {
val d = token.toDoubleOrNull()
if (d != null) {
stack.add(d)
println(" $d Push num onto top of stack $stack")
}
else if ((token.length > 1) || (token !in "+-*/^")) {
throw IllegalArgumentException("$token is not a valid token")
}
else if (stack.size < 2) {
throw IllegalArgumentException("Stack contains too few operands")
}
else {
val d1 = stack.removeAt(stack.lastIndex)
val d2 = stack.removeAt(stack.lastIndex)
stack.add(when (token) {
"+" -> d2 + d1
"-" -> d2 - d1
"*" -> d2 * d1
"/" -> d2 / d1
else -> Math.pow(d2, d1)
})
println(" $token Apply op to top of stack $stack")
}
}
println("\nThe final value is ${stack[0]}")
}
fun main(args: Array<String>) {
val expr = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
rpnCalculate(expr)
}

View file

@ -0,0 +1,79 @@
{calc 3 4 2 * 1 5 - 2 3 pow pow / +}
->
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
{def calc
{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
{def unop?
{lambda {:op}
{or {W.equal? :op sqrt} // n sqrt sqrt(n)
{W.equal? :op exp} // n exp exp(n)
{W.equal? :op log} // n log log(n)
{W.equal? :op cos} // n cos cos(n)
... and so // ...
}}}
{def binop?
{lambda {:op}
{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
a list from a string, test its emptynes and display it.
{def list
{lambda {:s}
{if {W.empty? {S.rest :s}}
then {cons {S.first :s} nil}
else {cons {S.first :s} {list {S.rest :s}}}}}}
{def empty?
{lambda {:x}
{W.equal? :x nil}}}
{def disp
{lambda {:l}
{if {empty? :l}
then
else {car :l} {disp {cdr :l}}}}}
Note that everything is exclusively built on 5 lambdatalk primitives:
- "cons, car, cdr", to create lists,
- "W.equal?" which test the equality between two words,
- and the "or" boolean function.

View file

@ -0,0 +1,85 @@
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

View file

@ -0,0 +1,52 @@
local stack = {}
function push( a ) table.insert( stack, 1, a ) end
function pop()
if #stack == 0 then return nil end
return table.remove( stack, 1 )
end
function writeStack()
for i = #stack, 1, -1 do
io.write( stack[i], " " )
end
print()
end
function operate( a )
local s
if a == "+" then
push( pop() + pop() )
io.write( a .. "\tadd\t" ); writeStack()
elseif a == "-" then
s = pop(); push( pop() - s )
io.write( a .. "\tsub\t" ); writeStack()
elseif a == "*" then
push( pop() * pop() )
io.write( a .. "\tmul\t" ); writeStack()
elseif a == "/" then
s = pop(); push( pop() / s )
io.write( a .. "\tdiv\t" ); writeStack()
elseif a == "^" then
s = pop(); push( pop() ^ s )
io.write( a .. "\tpow\t" ); writeStack()
elseif a == "%" then
s = pop(); push( pop() % s )
io.write( a .. "\tmod\t" ); writeStack()
else
push( tonumber( a ) )
io.write( a .. "\tpush\t" ); writeStack()
end
end
function calc( s )
local t, a = "", ""
print( "\nINPUT", "OP", "STACK" )
for i = 1, #s do
a = s:sub( i, i )
if a == " " then operate( t ); t = ""
else t = t .. a
end
end
if a ~= "" then operate( a ) end
print( string.format( "\nresult: %.13f", pop() ) )
end
--[[ entry point ]]--
calc( "3 4 2 * 1 5 - 2 3 ^ ^ / +" )
calc( "22 11 *" )

View file

@ -0,0 +1,36 @@
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

View file

@ -0,0 +1,9 @@
calc[rpn_] :=
Module[{tokens = StringSplit[rpn], s = "(" <> ToString@InputForm@# <> ")" &, op, steps},
op[o_, x_, y_] := ToExpression[s@x <> o <> s@y];
steps = FoldList[Switch[#2, _?DigitQ, Append[#, FromDigits[#2]],
_, Append[#[[;; -3]], op[#2, #[[-2]], #[[-1]]]]
] &, {}, tokens][[2 ;;]];
Grid[Transpose[{# <> ":" & /@ tokens,
StringRiffle[ToString[#, InputForm] & /@ #] & /@ steps}]]];
Print[calc["3 4 2 * 1 5 - 2 3 ^ ^ / +"]];

View file

@ -0,0 +1,39 @@
rmod(i, j) := mod(j, i)$
rpow(x, y) := y^x$
rpn(sexpr) := (
operands: [],
expr: charlist(sexpr),
for token in expr do (
if token = "+" then (
push(pop(operands) + pop(operands), operands)
)
elseif token = "-" then (
push(-1 * (pop(operands) - pop(operands)), operands)
)
elseif token = "*" then (
push(pop(operands) * pop(operands), operands)
)
elseif token = "/" then (
push(1 / (pop(operands) / pop(operands)), operands)
)
elseif token = "%" then (
push(rmod(pop(operands), pop(operands)), operands)
)
elseif token = "^" then (
push(rpow(pop(operands), pop(operands)), operands)
)
elseif token # " " then (
push(parse_string(token), operands)
),
if token # " " then (
print(token, " : ", operands)
)
),
pop(operands)
)$
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +"), numer;

View file

@ -0,0 +1,15 @@
(%i5) ev(rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +"),numer)
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]
/ : [1.220703125e-4, 3]
+ : [3.0001220703125]
(%o5) 3.0001220703125

View file

@ -0,0 +1,22 @@
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 ^ ^ / +")

View file

@ -0,0 +1,114 @@
.ig
RPN parser implementation in TROFF
..
.\" \(*A stack implementation
.nr Ac 0
.af Ac 1
.de APUSH
.if (\\n(Ac>=0)&(\\n(Ac<27) \{ \
. nr Ac +1
. af Ac A
. nr A\\n(Ac \\$1
. af Ac 1
\}
..
.de APOP
.if (\\n(Ac>0)&(\\n(Ac<27) \{ \
. af Ac A
. rr A\\n(Ac \\$1
. af Ac 1
. nr Ac -1
..
.\" Facility to print entire stack
.de L2
.af Ac 1
.if \\n(Li<=\\n(Ac \{ \
. af Li A
\\n(A\\n(Li
. af Li 1
. nr Li +1
. L2
\}
..
.de APRINT
.nr Li 1
.L2
.br
..
.\" Integer exponentiation algorithm
.de L1
.if \\n(Li<\\$2 \{ \
. nr Rs \\n(Rs*\\$1
. nr Li +1
. L1 \\$1 \\$2
\}
..
.de EXP
.nr Li 0
.nr Rs 1
.L1 \\$1 \\$2
..
.\" RPN Parser
.de REAP
.af Ac A
.nr O2 \\n(A\\n(Ac
.af Ac 1
.nr Ai \\n(Ac-1
.af Ai A
.nr O1 \\n(A\\n(Ai
.APOP
.APOP
..
.de RPNPUSH
.ie '\\$1'+' \{ \
. REAP
. nr Rs \\n(O1+\\n(O2
\}
.el \{ \
. ie '\\$1'-' \{ \
. REAP
. nr Rs \\n(O1-\\n(O2
\}
. el \{ \
. ie '\\$1'*' \{ \
. REAP
. nr Rs \\n(O1*\\n(O2
\}
. el \{ \
. ie '\\$1'/' \{ \
. REAP
. nr Rs \\n(O1/\\n(O2
\}
. el \{ \
. ie '\\$1'%' \{ \
. REAP
. nr Rs \\n(O1%\\n(O2
\}
. el \{ \
. ie '\\$1'^' \{ \
. REAP
. EXP \\n(O1 \\n(O2
\}
. el .nr Rs \\$1
\}
\}
\}
\}
\}
.APUSH \\n(Rs
.APRINT
..
.de RPNPRINT
.if \\n(Ac>1 .tm ERROR (rpn.roff): Malformed input expression. Evaluation stack size: \\n(Ac > 1 .
\\n(AA
..
.de RPNPARSE
.RPNPUSH \\$1
.ie \\n(.$>1 \{ \
. shift
. RPNPARSE \\$@
\}
.el .RPNPRINT
..
.RPNPARSE 3 4 2 * 1 5 - 2 3 ^ ^ / + \" Our input expression

View file

@ -0,0 +1,14 @@
3
3 4
3 4 2
3 8
3 8 1
3 8 1 5
3 8 4
3 8 4 2
3 8 4 2 3
3 8 4 8
3 8 16
3 0
3
3

View file

@ -0,0 +1,89 @@
.ig
===========================
Array implementation
===========================
..
.de end
..
.de array
. nr \\$1.c 0 1
. de \\$1.push end
. nr \\$1..\\\\n+[\\$1.c] \\\\$1
. end
. de \\$1.pop end
. if \\\\n[\\$1.c]>0 \{ \
. rr \\$1..\\\\n[\\$1.c]
. nr \\$1.c -1\
. \}
. end
. de \\$1.dump end
. nr i 0 1
. rm ou
. while \\\\n+i<=\\\\n[\\$1.c] \{ \
. as ou "\\\\n[\\$1..\\\\ni]
. \}
. tm \\\\*(ou
. rr i
. end
..
.ig
==========================
End array implementation
==========================
..
.array stack
.de hyper3
. nr rs 1
. nr i 0 1
. while \\n+i<=\\$2 .nr rs \\n(rs*\\$1
. rr i
..
.de pop2
. nr O2 \\n[\\$1..\\n[\\$1.c]]
. \\$1.pop
. nr O1 \\n[\\$1..\\n[\\$1.c]]
. \\$1.pop
..
.de rpn
. ie '\\$1'+' \{ \
. pop2 stack
. nr rs \\n(O1+\\n(O2
. \}
. el \{ \
. ie '\\$1'-' \{ \
. pop2 stack
. nr rs \\n(O1-\\n(O2
. \}
. el \{ \
. ie '\\$1'*' \{ \
. pop2 stack
. nr rs \\n(O1*\\n(O2
. \}
. el \{ \
. ie '\\$1'/' \{ \
. pop2 stack
. nr rs \\n(O1/\\n(O2
. \}
. el \{ \
. ie '\\$1'%' \{ \
. pop2 stack
. nr rs \\n(O1%\\n(O2
. \}
. el \{ \
. ie '\\$1'^' \{ \
. pop2 stack
. hyper3 \\n(O1 \\n(O2
. \}
. el .nr rs \\$1
. \}\}\}\}\}
.
. stack.push \\n(rs
. stack.dump
.
. if \\n(.$>1 \{ \
. shift
. rpn \\$@
. \}
..
.rpn 3 4 2 * 1 5 - 2 3 ^ ^ / +
.stack.dump

View file

@ -0,0 +1,14 @@
3
3 4
3 4 2
3 8
3 8 1
3 8 1 5
3 8 -4
3 8 -4 2
3 8 -4 2 3
3 8 -4 8
3 8 16
3 0
3
3

View file

@ -0,0 +1,88 @@
/* NetRexx */
options replace format comments java crossref symbols nobinary
numeric digits 20
rpnDefaultExpression = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
EODAD = '.*'
parse arg rpnString
if rpnString = '.' then rpnString = rpnDefaultExpression
if rpnString = '' then do
say 'Enter numbers or operators [to stop enter' EODAD']:'
loop label rpnloop forever
rpnval = ask
if rpnval == EODAD then leave rpnloop
rpnString = rpnString rpnval
end rpnloop
end
rpnString = rpnString.space(1)
say rpnString':' evaluateRPN(rpnString)
return
-- -----------------------------------------------------------------------------
method evaluateRPN(rpnString) public static returns Rexx
stack = LinkedList()
op = 0
L = 'L'
R = 'R'
rpnString = rpnString.strip('b')
say 'Input\tOperation\tStack after'
loop label rpn while rpnString.length > 0
parse rpnString token rest
rpnString = rest.strip('b')
say token || '\t\-'
select label tox case token
when '*' then do
say 'Operate\t\t\-'
op[R] = Rexx stack.pop()
op[L] = Rexx stack.pop()
stack.push(op[L] * op[R])
end
when '/' then do
say 'Operate\t\t\-'
op[R] = Rexx stack.pop()
op[L] = Rexx stack.pop()
stack.push(op[L] / op[R])
end
when '+' then do
say 'Operate\t\t\-'
op[R] = Rexx stack.pop()
op[L] = Rexx stack.pop()
stack.push(op[L] + op[R])
end
when '-' then do
say 'Operate\t\t\-'
op[R] = Rexx stack.pop()
op[L] = Rexx stack.pop()
stack.push(op[L] - op[R])
end
when '^' then do
say 'Operate\t\t\-'
op[R] = Rexx stack.pop()
op[L] = Rexx stack.pop()
-- If exponent is a whole number use Rexx built-in exponentiation operation, otherwise use Math.pow()
op[R] = op[R] + 0
if op[R].datatype('w') then stack.push(op[L] ** op[R])
else stack.push(Rexx Math.pow(op[L], op[R]))
end
otherwise do
if token.datatype('n') then do
say 'Push\t\t\-'
stack.push(token)
end
else do
say 'Error\t\t\-'
end
end
end tox
calc = Rexx
say stack.toString
end rpn
say
calc = stack.toString
return calc

View file

@ -0,0 +1,70 @@
import math, rdstdin, strutils, tables
type Stack = seq[float]
proc opPow(s: var Stack) =
let b = s.pop
let a = s.pop
s.add a.pow b
proc opMul(s: var Stack) =
let b = s.pop
let a = s.pop
s.add a * b
proc opDiv(s: var Stack) =
let b = s.pop
let a = s.pop
s.add a / b
proc opAdd(s: var Stack) =
let b = s.pop
let a = s.pop
s.add a + b
proc opSub(s: var Stack) =
let b = s.pop
let a = s.pop
s.add a - b
proc opNum(s: var Stack; num: float) =
s.add num
let ops = toTable({"^": opPow,
"*": opMul,
"/": opDiv,
"+": opAdd,
"-": opSub})
proc getInput(inp = ""): seq[string] =
var inp = inp
if inp.len == 0:
inp = readLineFromStdin "Expression: "
result = inp.strip.split
proc rpnCalc(tokens: seq[string]): seq[seq[string]] =
var s: Stack
result = @[@["TOKEN","ACTION","STACK"]]
for token in tokens:
var action = ""
if ops.hasKey token:
action = "Apply op to top of stack"
ops[token](s)
else:
action = "Push num onto top of stack"
s.opNum token.parseFloat
result.add(@[token, action, s.join(" ")])
let rpn = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
echo "For RPN expression: ", rpn
let rp = rpnCalc rpn.getInput
var maxColWidths = newSeq[int](rp[0].len)
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.alignLeft(maxColWidths[i])
echo ""

View file

@ -0,0 +1,27 @@
(* binop : ('a -> 'a -> 'a) -> 'a list -> 'a list *)
let binop op = function
| b::a::r -> (op a b)::r
| _ -> failwith "invalid expression"
(* interp : float list -> string -> string * float list *)
let interp s = function
| "+" -> "add", binop ( +. ) s
| "-" -> "subtr", binop ( -. ) s
| "*" -> "mult", binop ( *. ) s
| "/" -> "divide", binop ( /. ) s
| "^" -> "exp", binop ( ** ) s
| str -> "push", (float_of_string str) :: s
(* interp_and_show : float list -> string -> float list *)
let interp_and_show s inp =
let op,s' = interp s inp in
Printf.printf "%s\t%s\t" inp op;
List.(iter (Printf.printf "%F ") (rev s'));
print_newline ();
s'
(* rpn_eval : string -> float list *)
let rpn_eval str =
Printf.printf "Token\tAction\tStack\n";
let ss = Str.(split (regexp_string " ") str) in
List.fold_left interp_and_show [] ss

View file

@ -0,0 +1,63 @@
use IO;
use Struct;
bundle Default {
class RpnCalc {
function : Main(args : String[]) ~ Nil {
Caculate("3 4 2 * 1 5 - 2 3 ^ ^ / +");
}
function : native : Caculate(rpn : String) ~ Nil {
rpn->PrintLine();
tokens := rpn->Split(" ");
stack := FloatVector->New();
each(i : tokens) {
token := tokens[i]->Trim();
if(token->Size() > 0) {
if(token->Get(0)->IsDigit()) {
stack->AddBack(token->ToFloat());
}
else {
right := stack->Get(stack->Size() - 1); stack->RemoveBack();
left := stack->Get(stack->Size() - 1); stack->RemoveBack();
select(token->Get(0)) {
label '+': {
stack->AddBack(left + right);
}
label '-': {
stack->AddBack(left - right);
}
label '*': {
stack->AddBack(left * right);
}
label '/': {
stack->AddBack(left / right);
}
label '^': {
stack->AddBack(right->Power(left));
}
};
};
PrintStack(stack);
};
};
Console->Print("result: ")->PrintLine(stack->Get(0));
}
function : PrintStack(stack : FloatVector) ~ Nil {
" ["->Print();
each(i : stack) {
stack->Get(i)->Print();
if(i + 1< stack->Size()) {
", "->Print();
};
};
']'->PrintLine();
}
}
}

View file

@ -0,0 +1 @@
"3 4 2 * 1 5 - 2 3 ^ ^ / +" eval println

View file

@ -0,0 +1,3 @@
: rpn(s) { s words apply(#[ eval .l ]) }
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +")

View file

@ -0,0 +1,32 @@
/* ooRexx *************************************************************
* 10.11.2012 Walter Pachl translated from PL/I via REXX
**********************************************************************/
fid='rpl.txt'
ex=linein(fid)
Say 'Input:' ex
/* ex=' 3 4 2 * 1 5 - 2 3 ^ ^ / +' */
Numeric Digits 15
expr=''
st=.circularqueue~new(100)
Say 'Stack contents:'
do While ex<>''
Parse Var ex ch +1 ex
expr=expr||ch;
if ch<>' ' then do
If pos(ch,'0123456789')>0 Then /* a digit goes onto stack */
st~push(ch)
Else Do /* an operator */
op=st~pull /* get top element */
select /* and modify the (now) top el*/
when ch='+' Then st~push(st~pull + op)
when ch='-' Then st~push(st~pull - op)
when ch='*' Then st~push(st~pull * op)
when ch='/' Then st~push(st~pull / op)
when ch='^' Then st~push(st~pull ** op)
end;
Say st~string(' ','L') /* show stack in LIFO order */
end
end
end
Say 'The reverse polish expression = 'expr
Say 'The evaluated expression = 'st~pull

View file

@ -0,0 +1,39 @@
estack = [];
epush(x) = {
estack = vector(#estack + 1, i, if(i <= #estack, estack[i], x));
return(#estack);
};
epop() = {
local(val = estack[#estack]);
estack = vector(#estack - 1, i, estack[i]);
return(val);
};
registerRPNToken(t) = {
local(o1, o2);
if(type(t) == "t_STR",
if(t == "+", o2 = epop(); o1 = epop(); epush(o1 + o2),
if(t == "-", o2 = epop(); o1 = epop(); epush(o1 - o2),
if(t == "*", o2 = epop(); o1 = epop(); epush(o1 * o2),
if(t == "/", o2 = epop(); o1 = epop(); epush(o1 / o2),
if(t == "%", o2 = epop(); o1 = epop(); epush(o1 % o2),
if(t == "^", o2 = epop(); o1 = epop(); epush(o1 ^ o2)
)))))),
if(type(t) == "t_INT" || type(t) == "t_REAL" || type(t) == "t_FRAC",
epush(t))
);
print(estack);
};
parseRPN(s) = {
estack = [];
for(i = 1, #s, registerRPNToken(s[i]));
if(#estack > 1, error("Malformed postfix expression."));
return(estack[1]);
};
parseRPN([3, 4, 2, "*", 1, 5, "-", 2, 3, "^", "^", "/", "+"]); \\ Our input expression

View file

@ -0,0 +1,13 @@
[3]
[3, 4]
[3, 4, 2]
[3, 8]
[3, 8, 1]
[3, 8, 1, 5]
[3, 8, -4]
[3, 8, -4, 2]
[3, 8, -4, 2, 3]
[3, 8, -4, 8]
[3, 8, 65536]
[3, 1/8192]
[24577/8192]

View file

@ -0,0 +1,45 @@
<?php
function rpn($postFix){
$stack = Array();
echo "Input\tOperation\tStack\tafter\n" ;
$token = explode(" ", trim($postFix));
$count = count($token);
for($i = 0 ; $i<$count;$i++)
{
echo $token[$i] ." \t";
$tokenNum = "";
if (is_numeric($token[$i])) {
echo "Push";
array_push($stack,$token[$i]);
}
else
{
echo "Operate";
$secondOperand = end($stack);
array_pop($stack);
$firstOperand = end($stack);
array_pop($stack);
if ($token[$i] == "*")
array_push($stack,$firstOperand * $secondOperand);
else if ($token[$i] == "/")
array_push($stack,$firstOperand / $secondOperand);
else if ($token[$i] == "-")
array_push($stack,$firstOperand - $secondOperand);
else if ($token[$i] == "+")
array_push($stack,$firstOperand + $secondOperand);
else if ($token[$i] == "^")
array_push($stack,pow($firstOperand,$secondOperand));
else {
die("Error");
}
}
echo "\t\t" . implode(" ", $stack) . "\n";
}
return end($stack);
}
echo "Compute Value: " . rpn("3 4 2 * 1 5 - 2 3 ^ ^ / + ");
?>

View file

@ -0,0 +1,32 @@
Calculator: procedure options (main); /* 14 Sept. 2012 */
declare expression character (100) varying initial ('');
declare ch character (1);
declare (stack controlled, operand) float (18);
declare in file input;
open file (in) title ('/CALCULAT.DAT,type(text),recsize(100)');
on endfile (in) go to done;
put ('Stack contents:');
main_loop:
do forever;
get file (in) edit (ch) (a(1));
expression = expression || ch;
if ch = ' ' then iterate;
select (ch);
when ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')
do; allocate stack; stack = ch; iterate main_loop; end;
when ('+') do; operand = stack; free stack; stack = stack + operand; end;
when ('-') do; operand = stack; free stack; stack = stack - operand; end;
when ('*') do; operand = stack; free stack; stack = stack * operand; end;
when ('/') do; operand = stack; free stack; stack = stack / operand; end;
when ('^') do; operand = stack; free stack; stack = stack ** operand; end;
end;
call show_stack;
end;
done:
put skip list ('The reverse polish expression = ' || expression);
put skip list ('The evaluated expression = ' || stack);
end Calculator;

View file

@ -0,0 +1,46 @@
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;
/

View file

@ -0,0 +1,4 @@
begin
dbms_output.put_line(chr(10) || 'Result: ' || rpn_calc('3 4 2 * 1 5 - 2 3 ^ ^ / +'));
end;
/

View file

@ -0,0 +1,27 @@
use strict;
use warnings;
use feature 'say';
my $number = '[+-]?(?:\.\d+|\d+(?:\.\d*)?)';
my $operator = '[-+*/^]';
my @tests = ('3 4 2 * 1 5 - 2 3 ^ ^ / +');
for (@tests) {
while (
s/ \s* ((?<left>$number)) # 1st operand
\s+ ((?<right>$number)) # 2nd operand
\s+ ((?<op>$operator)) # operator
(?:\s+|$) # more to parse, or done?
/
' '.evaluate().' ' # substitute results of evaluation
/ex
) {}
say;
}
sub evaluate {
(my $a = "($+{left})$+{op}($+{right})") =~ s/\^/**/;
say $a;
eval $a;
}

View file

@ -0,0 +1,20 @@
(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">stack</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<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>
<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>
<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>
<span style="color: #008080;">switch</span> <span style="color: #000000;">op</span>
<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>
<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>
<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>
<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>
<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>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<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>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<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>
<!--

View file

@ -0,0 +1,12 @@
(de rpnCalculator (Str)
(let (^ ** Stack) # Define '^' from the built-in '**'
(prinl "Token Stack")
(for Token (str Str "*+-/\^")
(if (num? Token)
(push 'Stack @)
(set (cdr Stack)
((intern Token) (cadr Stack) (pop 'Stack)) ) )
(prin Token)
(space 6)
(println Stack) )
(println (car Stack)) ) )

View file

@ -0,0 +1,17 @@
: (rpnCalculator "3 4 2 * 1 5 - 2 3 \^ \^ / +")
Token Stack
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)
/ (0 3)
+ (3)
3
-> 3

View file

@ -0,0 +1,132 @@
function Invoke-Rpn
{
<#
.SYNOPSIS
A stack-based evaluator for an expression in reverse Polish notation.
.DESCRIPTION
A stack-based evaluator for an expression in reverse Polish notation.
All methods in the Math and Decimal classes are available.
.PARAMETER Expression
A space separated, string of tokens.
.PARAMETER DisplayState
This switch shows the changes in the stack as each individual token is processed as a table.
.EXAMPLE
Invoke-Rpn -Expression "3 4 Max"
.EXAMPLE
Invoke-Rpn -Expression "3 4 Log2"
.EXAMPLE
Invoke-Rpn -Expression "3 4 2 * 1 5 - 2 3 ^ ^ / +"
.EXAMPLE
Invoke-Rpn -Expression "3 4 2 * 1 5 - 2 3 ^ ^ / +" -DisplayState
#>
[CmdletBinding()]
Param
(
[Parameter(Mandatory=$true)]
[AllowEmptyString()]
[string]
$Expression,
[Parameter(Mandatory=$false)]
[switch]
$DisplayState
)
Begin
{
function Out-State ([System.Collections.Stack]$Stack)
{
$array = $Stack.ToArray()
[Array]::Reverse($array)
$array | ForEach-Object -Process { Write-Host ("{0,-8:F3}" -f $_) -NoNewline } -End { Write-Host }
}
function New-RpnEvaluation
{
$stack = New-Object -Type System.Collections.Stack
$shortcuts = @{
"+" = "Add"; "-" = "Subtract"; "/" = "Divide"; "*" = "Multiply"; "%" = "Remainder"; "^" = "Pow"
}
:ARGUMENT_LOOP foreach ($argument in $args)
{
if ($DisplayState -and $stack.Count)
{
Out-State $stack
}
if ($shortcuts[$argument])
{
$argument = $shortcuts[$argument]
}
try
{
$stack.Push([decimal]$argument)
continue
}
catch
{
}
$argCountList = $argument -replace "(\D+)(\d*)",$2
$operation = $argument.Substring(0, $argument.Length $argCountList.Length)
foreach($type in [Decimal],[Math])
{
if ($definition = $type::$operation)
{
if (-not $argCountList)
{
$argCountList = $definition.OverloadDefinitions |
Foreach-Object { ($_ -split ", ").Count } |
Sort-Object -Unique
}
foreach ($argCount in $argCountList)
{
try
{
$methodArguments = $stack.ToArray()[($argCount1)..0]
$result = $type::$operation.Invoke($methodArguments)
$null = 1..$argCount | Foreach-Object { $stack.Pop() }
$stack.Push($result)
continue ARGUMENT_LOOP
}
catch
{
## If error, try with the next number of arguments
}
}
}
}
}
if ($DisplayState -and $stack.Count)
{
Out-State $stack
if ($stack.Count)
{
Write-Host "`nResult = $($stack.Peek())"
}
}
else
{
$stack
}
}
}
Process
{
Invoke-Expression -Command "New-RpnEvaluation $Expression"
}
End
{
}
}
Invoke-Rpn -Expression "3 4 2 * 1 5 - 2 3 ^ ^ / +" -DisplayState

View file

@ -0,0 +1,47 @@
rpn(L) :-
writeln('Token Action Stack'),
parse(L, [],[X] ,[]),
format('~nThe final output value is ~w~n', [X]).
% skip spaces
parse([X|L], St) -->
{char_type(X, white)},
parse(L, St).
% detect operators
parse([Op|L], [Y, X | St]) -->
{ is_op(Op, X, Y, V),
writef(' %s', [[Op]]),
with_output_to(atom(Str2), writef('Apply %s on top of stack', [[Op]])),
writef(' %35l', [Str2]),
writef('%w\n', [[V | St]])},
parse(L, [V | St]).
% detect number
parse([N|L], St) -->
{char_type(N, digit)},
parse_number(L, [N], St).
% string is finished
parse([], St) --> St.
% compute numbers
parse_number([N|L], NC, St) -->
{char_type(N, digit)},
parse_number(L, [N|NC], St).
parse_number(S, NC, St) -->
{ reverse(NC, RNC),
number_chars(V, RNC),
writef('%5r', [V]),
with_output_to(atom(Str2), writef('Push num %w on top of stack', [V])),
writef(' %35l', [Str2]),
writef('%w\n', [[V | St]])},
parse(S, [V|St]).
% defining operations
is_op(42, X, Y, V) :- V is X*Y.
is_op(43, X, Y, V) :- V is X+Y.
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.

View file

@ -0,0 +1,59 @@
def op_pow(stack):
b = stack.pop(); a = stack.pop()
stack.append( a ** b )
def op_mul(stack):
b = stack.pop(); a = stack.pop()
stack.append( a * b )
def op_div(stack):
b = stack.pop(); a = stack.pop()
stack.append( a / b )
def op_add(stack):
b = stack.pop(); a = stack.pop()
stack.append( a + b )
def op_sub(stack):
b = stack.pop(); a = stack.pop()
stack.append( a - b )
def op_num(stack, num):
stack.append( num )
ops = {
'^': op_pow,
'*': op_mul,
'/': op_div,
'+': op_add,
'-': op_sub,
}
def get_input(inp = None):
'Inputs an expression and returns list of tokens'
if inp is None:
inp = input('expression: ')
tokens = inp.strip().split()
return tokens
def rpn_calc(tokens):
stack = []
table = ['TOKEN,ACTION,STACK'.split(',')]
for token in tokens:
if token in ops:
action = 'Apply op to top of stack'
ops[token](stack)
table.append( (token, action, ' '.join(str(s) for s in stack)) )
else:
action = 'Push num onto top of stack'
op_num(stack, eval(token))
table.append( (token, action, ' '.join(str(s) for s in stack)) )
return table
if __name__ == '__main__':
rpn = '3 4 2 * 1 5 - 2 3 ^ ^ / +'
print( 'For RPN expression: %r\n' % rpn )
rp = rpn_calc(get_input(rpn))
maxcolwidths = [max(len(y) for y in x) for x in zip(*rp)]
row = rp[0]
print( ' '.join('{cell:^{width}}'.format(width=width, cell=cell) for (width, cell) in zip(maxcolwidths, row)))
for row in rp[1:]:
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])

View file

@ -0,0 +1,6 @@
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

View file

@ -0,0 +1,36 @@
[ 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

View file

@ -0,0 +1,103 @@
' 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

View file

@ -0,0 +1,53 @@
/* REXX ***************************************************************
* 09.11.2012 Walter Pachl translates from PL/I
**********************************************************************/
fid='rpl.txt'
ex=linein(fid)
Say 'Input:' ex
/* ex=' 3 4 2 * 1 5 - 2 3 ^ ^ / +' */
Numeric Digits 15
expr=''
st.=0
Say 'Stack contents:'
do While ex<>''
Parse Var ex ch +1 ex
expr=expr||ch;
if ch<>' ' then do
select
When pos(ch,'0123456789')>0 Then Do
Call stack ch
Iterate
End
when ch='+' Then do; operand=getstack(); st.sti = st.sti + operand; end;
when ch='-' Then do; operand=getstack(); st.sti = st.sti - operand; end;
when ch='*' Then do; operand=getstack(); st.sti = st.sti * operand; end;
when ch='/' Then do; operand=getstack(); st.sti = st.sti / operand; end;
when ch='^' Then do; operand=getstack(); st.sti = st.sti ** operand; end;
end;
call show_stack
end
end
Say 'The reverse polish expression = 'expr
Say 'The evaluated expression = 'st.1
Exit
stack: Procedure Expose st.
/* put the argument on top of the stack */
z=st.0+1
st.z=arg(1)
st.0=z
Return
getstack: Procedure Expose st. sti
/* remove and return the stack's top element */
z=st.0
stk=st.z
st.0=st.0-1
sti=st.0
Return stk
show_stack: procedure Expose st.
/* show the stack's contents */
ol=''
do i=1 To st.0
ol=ol format(st.i,5,10)
End
Say ol
Return

View file

@ -0,0 +1,29 @@
/*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.*/
tokens=words(x) /*save the number of tokens " ". */
showSteps=1 /*set to 0 if working steps not wanted.*/
ox=x /*save the original value of X. */
do i=1 for tokens; @.i=word(x,i) /*assign the input tokens to an array. */
end /*i*/
x=space(x) /*remove any superfluous blanks in X. */
L=max(20, length(x)) /*use 20 for the minimum display width.*/
numeric digits L /*ensure enough decimal digits for ans.*/
say center('operand', L, "") center('stack', L+L, "") /*display title*/
$= /*nullify the stack (completely empty).*/
do k=1 for tokens; ?=@.k; ??=? /*process each token from the @. list.*/
#=words($) /*stack the count (the number entries).*/
if datatype(?,'N') then do; $=$ ?; call show "add to───►stack"; iterate; end
if ?=='^' then ??= "**" /*REXXify ^ ───► ** (make legal).*/
interpret 'y='word($,#-1) ?? word($,#) /*compute via the famous REXX INTERPRET*/
if datatype(y,'N') then y=y/1 /*normalize the number with ÷ by unity.*/
$=subword($, 1, #-2) y /*rebuild the stack with the answer. */
call show ? /*display steps (tracing into), maybe.*/
end /*k*/
say /*display a blank line, better perusing*/
say ' RPN input:' ox; say " answer──►"$ /*display original input; display ans.*/
parse source upper . y . /*invoked via C.L. or via a REXX pgm?*/
if y=='COMMAND' | \datatype($,"W") then exit /*stick a fork in it, we're all done. */
else exit $ /*return the answer ───► the invoker.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: if showSteps then say center(arg(1), L) left(space($), L); return

View file

@ -0,0 +1,43 @@
/*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.*/
tokens=words(x) /*save the number of tokens " ". */
showSteps=1 /*set to 0 if working steps not wanted.*/
ox=x /*save the original value of X. */
do i=1 for tokens; @.i=word(x,i) /*assign the input tokens to an array. */
end /*i*/
x=space(x) /*remove any superfluous blanks in X. */
L=max(20, length(x)) /*use 20 for the minimum display width.*/
numeric digits L /*ensure enough decimal digits for ans.*/
say center('operand', L, "") center('stack', L+L, "") /*display title*/
Dop= '/ // % ÷'; Bop='& | &&' /*division operators; binary operands.*/
Aop= '- + * ^ **' Dop Bop; Lop=Aop "||" /*arithmetic operators; legal operands.*/
$= /*nullify the stack (completely empty).*/
do k=1 for tokens; ?=@.k; ??=? /*process each token from the @. list.*/
#=words($); b=word($, max(1, #) ) /*the stack count; the last entry. */
a=word($, max(1, #-1) ) /*stack's "first" operand. */
division =wordpos(?, Dop)\==0 /*flag: doing a some kind of division.*/
arith =wordpos(?, Aop)\==0 /*flag: doing arithmetic. */
bitOp =wordpos(?, Bop)\==0 /*flag: doing some kind of binary oper*/
if datatype(?, 'N') then do; $=$ ?; call show "add to───►stack"; iterate; end
if wordpos(?, Lop)==0 then do; $=e 'illegal operator:' ?; leave; end
if w<2 then do; $=e 'illegal RPN expression.'; leave; end
if ?=='^' then ??= "**" /*REXXify ^ ──► ** (make it legal). */
if ?=='÷' then ??= "/" /*REXXify ÷ ──► / (make it legal). */
if division & b=0 then do; $=e 'division by zero.' ; leave; end
if bitOp & \isBit(a) then do; $=e "token isn't logical: " a; leave; end
if bitOp & \isBit(b) then do; $=e "token isn't logical: " b; leave; end
interpret 'y=' a ?? b /*compute with two stack operands*/
if datatype(y, 'W') then y=y/1 /*normalize the number with ÷ by unity.*/
_=subword($, 1, #-2); $=_ y /*rebuild the stack with the answer. */
call show ? /*display (possibly) a working step. */
end /*k*/
say /*display a blank line, better perusing*/
if word($,1)==e then $= /*handle the special case of errors. */
say ' RPN input:' ox; say " answer───►"$ /*display original input; display ans.*/
parse source upper . y . /*invoked via C.L. or via a REXX pgm?*/
if y=='COMMAND' | \datatype($,"W") then exit /*stick a fork in it, we're all done. */
else exit $ /*return the answer ───► the invoker.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
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

View file

@ -0,0 +1,14 @@
#lang racket
(define (calculate-RPN expr)
(for/fold ([stack '()]) ([token expr])
(printf "~a\t -> ~a~N" token stack)
(match* (token stack)
[((? number? n) s) (cons n s)]
[('+ (list x y s ___)) (cons (+ x y) s)]
[('- (list x y s ___)) (cons (- y x) s)]
[('* (list x y s ___)) (cons (* x y) s)]
[('/ (list x y s ___)) (cons (/ y x) s)]
[('^ (list x y s ___)) (cons (expt y x) s)]
[(x s) (error "calculate-RPN: Cannot calculate the expression:"
(reverse (cons x s)))])))

View file

@ -0,0 +1 @@
(calculate-RPN (in-port read (open-input-string "3.0 4 2 * 1 5 - 2 3 ^ ^ / +")))

View file

@ -0,0 +1,22 @@
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);

View file

@ -0,0 +1,2 @@
rpn = RPNExpression("3 4 2 * 1 5 - 2 3 ^ ^ / +")
value = rpn.eval

View file

@ -0,0 +1,34 @@
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

View file

@ -0,0 +1,54 @@
fn rpn(text: &str) -> f64 {
let tokens = text.split_whitespace();
let mut stack: Vec<f64> = vec![];
println!("input operation stack");
for token in tokens {
print!("{:^5} ", token);
match token.parse() {
Ok(num) => {
stack.push(num);
println!("push {:?}", stack);
}
Err(_) => {
match token {
"+" => {
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 * 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)
}
fn main() {
let text = "3 4 2 * 1 5 - 2 3 ^ ^ / +";
println!("\nresult: {}", rpn(text));
}

View file

@ -0,0 +1,40 @@
object RPN {
val PRINT_STACK_CONTENTS: Boolean = true
def main(args: Array[String]): Unit = {
val result = evaluate("3 4 2 * 1 5 - 2 3 ^ ^ / +".split(" ").toList)
println("Answer: " + result)
}
def evaluate(tokens: List[String]): Double = {
import scala.collection.mutable.Stack
val stack: Stack[Double] = new Stack[Double]
for (token <- tokens) {
if (isOperator(token)) token match {
case "+" => stack.push(stack.pop + stack.pop)
case "-" => val x = stack.pop; stack.push(stack.pop - x)
case "*" => stack.push(stack.pop * stack.pop)
case "/" => val x = stack.pop; stack.push(stack.pop / x)
case "^" => val x = stack.pop; stack.push(math.pow(stack.pop, x))
case _ => throw new RuntimeException( s""""$token" is not an operator""")
}
else stack.push(token.toDouble)
if (PRINT_STACK_CONTENTS) {
print("Input: " + token)
print(" Stack: ")
for (element <- stack.seq.reverse) print(element + " ");
println("")
}
}
stack.pop
}
def isOperator(token: String): Boolean = {
token match {
case "+" => true; case "-" => true; case "*" => true; case "/" => true; case "^" => true
case _ => false
}
}
}

Some files were not shown because too many files have changed in this diff Show more