Browse Source

Initial commit of RPN program

master
Wesley Kerfoot 5 years ago
commit
a926b96a5a
  1. 73
      rpn/main.pony

73
rpn/main.pony

@ -0,0 +1,73 @@
use "itertools"
class RPN
fun operate(a : I64, b : I64, op : String) : I64 =>
match op
| "+" => return a + b
| "*" => return a * b
| "/" => return a / b
| "-" => return a - b
else
0
end
fun calculate(exp : String, env : Env)? =>
let tokens = this.tokenize(exp)
let stack : Array[I64] = []
for token in tokens do
match token
| let op : String =>
try
stack.push(this.operate(stack.pop()?, stack.pop()?, op))
else
env.out.print("Error: stack underflow, exiting")
return
end
| let n : I64 =>
stack.push(n)
end
end
env.out.print(stack.apply(0)?.string())
None
fun tokenize(exp : String) : Iter[(I64 | String)] =>
// We use a union type since read_int returns (I64, USize), and we want I64 | String
Iter[String](exp.split(" ").values())
.filter({
(c) => (c != "") and (c != "\t") and (c != "\n")
})
.map[(I64 | String)]({
(n) =>
try
// ? indicates it could return an exception
match n.read_int[I64]() ?
// returns the character if no int was found
| (0, 0) => n
| (let n' : I64, let s : USize) => n'
end
else
n
end
})
new val create() =>
// Make the RPN class a val
// This means the instance is immutable
// It can be safely aliased
"""
"""
actor Main
new create(env : Env) =>
let calc = RPN.create()
let input : String = " ".join(Iter[String](env.args.values()).skip(1))
try
calc.calculate(input, env)?
else
None
end
Loading…
Cancel
Save