progs/inter.scala
author Christian Urban <christian dot urban at kcl dot ac dot uk>
Tue, 26 Sep 2017 12:35:32 +0100
changeset 537 72dbf4154173
parent 520 bd25d9f9d9dc
permissions -rw-r--r--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
520
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     1
abstract class Exp
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     2
abstract class Stmt
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     3
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     4
case class Plus(e1: Exp, e2: Exp) extends Exp
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     5
case class Times(e1: Exp, e2: Exp) extends Exp
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     6
case class Equ(e1: Exp, e2: Exp) extends Exp
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     7
case class Num(n: Int) extends Exp
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     8
case class Var(x: String) extends Exp
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
     9
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    10
case class Label(l: String) extends Stmt
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    11
case class Assign(x: String, e: Exp) extends Stmt
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    12
case class Goto(l: String) extends Stmt
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    13
case class Jmp(e: Exp, l: String) extends Stmt
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    14
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    15
type Stmts = List[Stmt]
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    16
type Env = Map[String, Int]
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    17
type Snips = Map[String, Stmts] 
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    18
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    19
def preproc(sts: Stmts) : Snips = sts match {
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    20
  case Nil => Map()
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    21
  case Label(l)::rest => preproc(rest) + (l -> rest) 
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    22
  case _::rest => preproc(rest)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    23
} 
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    24
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    25
def Prog(sts: Stmt*) = preproc(Label("")::sts.toList)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    26
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    27
def eval_exp(e: Exp, env: Env) : Int = e match {
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    28
  case Var(x) => env(x)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    29
  case Num(n) => n
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    30
  case Plus(e1, e2) => eval_exp(e1, env) + eval_exp(e2, env)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    31
  case Times(e1, e2) => eval_exp(e1, env) * eval_exp(e2, env)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    32
  case Equ(e1, e2) => 
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    33
    if (eval_exp(e1, env) == eval_exp(e2, env)) 1 else 0
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    34
}
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    35
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    36
def eval(sn: Snips) : Env = {
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    37
  def eval_stmts(sts: Stmts, env: Env): Env = sts match {
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    38
    case Nil => env
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    39
    case Label(l)::rest => eval_stmts(rest, env)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    40
    case Assign(x, e)::rest => 
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    41
      eval_stmts(rest, env + (x -> eval_exp(e, env)))
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    42
    case Goto(l)::rest => eval_stmts(sn(l), env)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    43
    case Jmp(b, l)::rest => 
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    44
      if (eval_exp(b, env) == 1) eval_stmts(sn(l), env) 
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    45
      else eval_stmts(rest, env)
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    46
  }
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    47
  eval_stmts(sn(""), Map())
bd25d9f9d9dc updated
Christian Urban <urbanc@in.tum.de>
parents:
diff changeset
    48
}