Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
2
Task/Parsing-RPN-calculator-algorithm/00-META.yaml
Normal file
2
Task/Parsing-RPN-calculator-algorithm/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Parsing/RPN_calculator_algorithm
|
||||
22
Task/Parsing-RPN-calculator-algorithm/00-TASK.txt
Normal file
22
Task/Parsing-RPN-calculator-algorithm/00-TASK.txt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
;Task:
|
||||
Create a stack-based evaluator for an expression in [[wp:Reverse Polish notation|<u>r</u>everse <u>P</u>olish <u>n</u>otation (RPN)]] 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 [[Parsing/Shunting-yard algorithm]] task: <br>
|
||||
<big><big><code> 3 4 2 * 1 5 - 2 3 ^ ^ / + </code></big></big>
|
||||
* Print or display the output here
|
||||
|
||||
|
||||
;Notes:
|
||||
* <big><b> '''^''' </b></big> means exponentiation in the expression above.
|
||||
* <big><b> '''/''' </b></big> means division.
|
||||
|
||||
|
||||
;See also:
|
||||
* [[Parsing/Shunting-yard algorithm]] for a method of generating an RPN from an infix expression.
|
||||
* Several solutions to [[24 game/Solve]] make use of RPN evaluators (although tracing how they work is not a part of that task).
|
||||
* [[Parsing/RPN to infix conversion]].
|
||||
* [[Arithmetic evaluation]].
|
||||
<br><br>
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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 )
|
||||
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
@ -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';
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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%)
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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 ^ ^ / +"));
|
||||
}
|
||||
|
|
@ -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)))
|
||||
|
|
@ -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)))))
|
||||
|
|
@ -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]);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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 ))
|
||||
|
|
@ -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
|
||||
|
|
@ -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").
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
IN: scratchpad 3 4 2 * 1 5 - 2 3 ^ ^ / +
|
||||
|
||||
--- Data stack:
|
||||
3+1/8192
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
{ 3 4 2 * 1 5 - 2 3 ^ ^ / + }
|
||||
[ dup pprint bl 1quotation call get-datastack . ] each
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
: ^ over swap 1 ?do over * loop nip ;
|
||||
s" 3 4 2 * 1 5 - 2 3 ^ ^ / +" evaluate .
|
||||
|
|
@ -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 ^ ^ / +
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)}") )
|
||||
|
|
@ -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
|
||||
|
|
@ -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])
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
println evaluateRPN('3 4 2 * 1 5 - 2 3 ^ ^ / +')
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
calcRPNM :: Logger m => String -> m [Double]
|
||||
calcRPNM = foldM (verbose interprete) [] . words
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
a: , <;._1 ' ' , '3 4 2 * 1 5 - 2 3 ^ ^ / +'
|
||||
┌┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
|
||||
││3│4│2│*│1│5│-│2│3│^│^│/│+│
|
||||
└┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
|
||||
|
|
@ -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│
|
||||
└─┘
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
rpn '3 4 2 * 1 5 - 2 3 ^ ^ / +'
|
||||
3.00012
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -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
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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.`);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ^ ^ / +")
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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 *" )
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ^ ^ / +"]];
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ^ ^ / +")
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ""
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
"3 4 2 * 1 5 - 2 3 ^ ^ / +" eval println
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
: rpn(s) { s words apply(#[ eval .l ]) }
|
||||
|
||||
rpn("3 4 2 * 1 5 - 2 3 ^ ^ / +")
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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]
|
||||
|
|
@ -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 ^ ^ / + ");
|
||||
?>
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
/
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
begin
|
||||
dbms_output.put_line(chr(10) || 'Result: ' || rpn_calc('3 4 2 * 1 5 - 2 3 ^ ^ / +'));
|
||||
end;
|
||||
/
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>
|
||||
<!--
|
||||
|
|
@ -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)) ) )
|
||||
|
|
@ -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
|
||||
|
|
@ -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()[($argCount–1)..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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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])
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)))])))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(calculate-RPN (in-port read (open-input-string "3.0 4 2 * 1 5 - 2 3 ^ ^ / +")))
|
||||
|
|
@ -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);
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
rpn = RPNExpression("3 4 2 * 1 5 - 2 3 ^ ^ / +")
|
||||
value = rpn.eval
|
||||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue