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)