34 lines
1.2 KiB
Plaintext
34 lines
1.2 KiB
Plaintext
require "queue"
|
|
local fmt = require "fmt"
|
|
|
|
local function rpn_calculate(expr)
|
|
assert(#expr > 0, "expression cannot be empty")
|
|
print($"For expression = {expr}\n")
|
|
print("Token Action Stack")
|
|
local tokens = expr:split(" "):filter(|t| -> #t > 0):reorder()
|
|
local stk = new stack()
|
|
for tokens as token do
|
|
local d = tonumber(token)
|
|
if d then
|
|
stk:push(d)
|
|
fmt.print(" %d Push num onto top of stack %s", d, fmt.swrite(stk:toarray()))
|
|
elseif #token > 1 or !(token in "+-*/^") then
|
|
error($"{token} is not a valid token.")
|
|
elseif stk:size() < 2 then
|
|
error("Stack contains too few operands.")
|
|
else
|
|
local d1 = stk:pop()
|
|
local d2 = stk:pop()
|
|
stk:push(token == "+" ? d2 + d1 :
|
|
token == "-" ? d2 - d1 :
|
|
token == "*" ? d2 * d1 :
|
|
token == "/" ? d2 / d1 : d2 ^ d1)
|
|
fmt.print(" %s Apply op to top of stack %s", token, fmt.swrite(stk:toarray()))
|
|
end
|
|
end
|
|
fmt.print("\nThe final value is %0.14g", stk:pop())
|
|
end
|
|
|
|
local expr = "3 4 2 * 1 5 - 2 3 ^ ^ / +"
|
|
rpn_calculate(expr)
|