Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -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,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,86 @@
|
|||
Global stack$
|
||||
|
||||
Function RPN(expr$)
|
||||
Debug.Print "Expression:"
|
||||
Debug.Print expr$
|
||||
Debug.Print "Input", "Operation", "Stack after"
|
||||
|
||||
stack$ = ""
|
||||
token$ = "#"
|
||||
i = 1
|
||||
token$ = Split(expr$)(i - 1) 'split is base 0
|
||||
token2$ = " " + token$ + " "
|
||||
|
||||
Do
|
||||
Debug.Print "Token "; i; ": "; token$,
|
||||
'operation
|
||||
If InStr("+-*/^", token$) <> 0 Then
|
||||
Debug.Print "operate",
|
||||
op2$ = pop$()
|
||||
op1$ = pop$()
|
||||
If op1$ = "" Then
|
||||
Debug.Print "Error: stack empty for "; i; "-th token: "; token$
|
||||
End
|
||||
End If
|
||||
|
||||
op1 = Val(op1$)
|
||||
op2 = Val(op2$)
|
||||
|
||||
Select Case token$
|
||||
Case "+"
|
||||
res = CDbl(op1) + CDbl(op2)
|
||||
Case "-"
|
||||
res = CDbl(op1) - CDbl(op2)
|
||||
Case "*"
|
||||
res = CDbl(op1) * CDbl(op2)
|
||||
Case "/"
|
||||
res = CDbl(op1) / CDbl(op2)
|
||||
Case "^"
|
||||
res = CDbl(op1) ^ CDbl(op2)
|
||||
End Select
|
||||
|
||||
Call push2(str$(res))
|
||||
'default:number
|
||||
Else
|
||||
Debug.Print "push",
|
||||
Call push2(token$)
|
||||
End If
|
||||
Debug.Print "Stack: "; reverse$(stack$)
|
||||
i = i + 1
|
||||
If i > Len(Join(Split(expr, " "), "")) Then
|
||||
token$ = ""
|
||||
Else
|
||||
token$ = Split(expr$)(i - 1) 'base 0
|
||||
token2$ = " " + token$ + " "
|
||||
End If
|
||||
Loop Until token$ = ""
|
||||
|
||||
Debug.Print
|
||||
Debug.Print "Result:"; pop$()
|
||||
'extra$ = pop$()
|
||||
If stack <> "" Then
|
||||
Debug.Print "Error: extra things on a stack: "; stack$
|
||||
End If
|
||||
End
|
||||
End Function
|
||||
|
||||
'---------------------------------------
|
||||
Function reverse$(s$)
|
||||
reverse$ = ""
|
||||
token$ = "#"
|
||||
While token$ <> ""
|
||||
i = i + 1
|
||||
token$ = Split(s$, "|")(i - 1) 'split is base 0
|
||||
reverse$ = token$ & " " & reverse$
|
||||
Wend
|
||||
End Function
|
||||
'---------------------------------------
|
||||
Sub push2(s$)
|
||||
stack$ = s$ + "|" + stack$ 'stack
|
||||
End Sub
|
||||
|
||||
Function pop$()
|
||||
'it does return empty on empty stack
|
||||
pop$ = Split(stack$, "|")(0)
|
||||
stack$ = Mid$(stack$, InStr(stack$, "|") + 1)
|
||||
End Function
|
||||
Loading…
Add table
Add a link
Reference in a new issue