Evaluating Postfix and its Correctness
sealed abstract class Expr
case class Var(varID: String) extends Expr
case class IntLiteral(value: Int) extends Expr
case class Plus(lhs: Expr, rhs: Expr) extends Expr
case class Times(lhs: Expr, rhs: Expr) extends Expr
sealed abstract class Token
case class ID(str : String) extends Token
case class Const(c : Int) extends Token
case class Add extends Token
case class Mul extends Token
object Print {
def postfix(e : Expr) : List[Token] = e match {
case Var(id) => List(ID(id))
case IntLiteral(c) => List(Const(c))
case Plus(lhs,rhs) => postfix(lhs) ::: postfix(rhs) ::: List(Add())
case Times(lhs,rhs) => postfix(lhs) ::: postfix(rhs) ::: List(Mul())
}
}
object Eval {
// recursive interpretation of expression
def infix(env : Map[String,Int], expr : Expr) : Int = expr match {
case Var(id) => env(id)
case IntLiteral(v) => v
case Plus(e1,e2) => infix(env,e1) + infix(env,e2)
case Times(e1,e2) => infix(env,e1) * infix(env,e2)
}
// non-recursive evaluation of postfix expression
def postfix(env : Map[String,Int],
pexpr : Array[Token]) : Int = {
var stack : Array[Int] = new Array[Int](512)
var top : Int = 0
var pos : Int = 0
while (pos < pexpr.length) {
pexpr(pos) match {
case ID(v) =>
top = top + 1
stack(top) = env(v)
case Const(c) =>
top = top + 1
stack(top) = c
case Add() =>
stack(top - 1) = stack(top - 1) + stack(top)
top = top - 1
case Mul() =>
stack(top - 1) = stack(top - 1) * stack(top)
top = top - 1
}
pos = pos + 1
}
return stack(top)
}
}
object Test {
def main(args : Array[String]) = {
val expr = Plus(Var("x"),Times(Var("y"),Var("z")))
val env = Map("x"->3, "y"->4, "z"->5)
println("env = " + env)
val resInterpreted = Eval.infix(env,expr)
println("resInterpreted = " + resInterpreted)
val pexpr : Array[Token] = Print.postfix(expr).toArray
println("postfix: " + (pexpr.toList))
val resCompiled = Eval.postfix(env,pexpr)
println("resCompiled = " + resCompiled)
val theoremHolds =
(Eval.postfix(env,Print.postfix(expr).toArray) ==
Eval.infix(env,expr))
println("theoremHolds (for this case) = " + theoremHolds)
}
}