diff -r 06f91010fe1e -r bd25d9f9d9dc progs/inter.scala --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/progs/inter.scala Sat Sep 23 14:19:09 2017 +0100 @@ -0,0 +1,48 @@ +abstract class Exp +abstract class Stmt + +case class Plus(e1: Exp, e2: Exp) extends Exp +case class Times(e1: Exp, e2: Exp) extends Exp +case class Equ(e1: Exp, e2: Exp) extends Exp +case class Num(n: Int) extends Exp +case class Var(x: String) extends Exp + +case class Label(l: String) extends Stmt +case class Assign(x: String, e: Exp) extends Stmt +case class Goto(l: String) extends Stmt +case class Jmp(e: Exp, l: String) extends Stmt + +type Stmts = List[Stmt] +type Env = Map[String, Int] +type Snips = Map[String, Stmts] + +def preproc(sts: Stmts) : Snips = sts match { + case Nil => Map() + case Label(l)::rest => preproc(rest) + (l -> rest) + case _::rest => preproc(rest) +} + +def Prog(sts: Stmt*) = preproc(Label("")::sts.toList) + +def eval_exp(e: Exp, env: Env) : Int = e match { + case Var(x) => env(x) + case Num(n) => n + case Plus(e1, e2) => eval_exp(e1, env) + eval_exp(e2, env) + case Times(e1, e2) => eval_exp(e1, env) * eval_exp(e2, env) + case Equ(e1, e2) => + if (eval_exp(e1, env) == eval_exp(e2, env)) 1 else 0 +} + +def eval(sn: Snips) : Env = { + def eval_stmts(sts: Stmts, env: Env): Env = sts match { + case Nil => env + case Label(l)::rest => eval_stmts(rest, env) + case Assign(x, e)::rest => + eval_stmts(rest, env + (x -> eval_exp(e, env))) + case Goto(l)::rest => eval_stmts(sn(l), env) + case Jmp(b, l)::rest => + if (eval_exp(b, env) == 1) eval_stmts(sn(l), env) + else eval_stmts(rest, env) + } + eval_stmts(sn(""), Map()) +}