progs/inter.scala
changeset 520 bd25d9f9d9dc
--- /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())
+}