progs/inter.scala
changeset 520 bd25d9f9d9dc
equal deleted inserted replaced
519:06f91010fe1e 520:bd25d9f9d9dc
       
     1 abstract class Exp
       
     2 abstract class Stmt
       
     3 
       
     4 case class Plus(e1: Exp, e2: Exp) extends Exp
       
     5 case class Times(e1: Exp, e2: Exp) extends Exp
       
     6 case class Equ(e1: Exp, e2: Exp) extends Exp
       
     7 case class Num(n: Int) extends Exp
       
     8 case class Var(x: String) extends Exp
       
     9 
       
    10 case class Label(l: String) extends Stmt
       
    11 case class Assign(x: String, e: Exp) extends Stmt
       
    12 case class Goto(l: String) extends Stmt
       
    13 case class Jmp(e: Exp, l: String) extends Stmt
       
    14 
       
    15 type Stmts = List[Stmt]
       
    16 type Env = Map[String, Int]
       
    17 type Snips = Map[String, Stmts] 
       
    18 
       
    19 def preproc(sts: Stmts) : Snips = sts match {
       
    20   case Nil => Map()
       
    21   case Label(l)::rest => preproc(rest) + (l -> rest) 
       
    22   case _::rest => preproc(rest)
       
    23 } 
       
    24 
       
    25 def Prog(sts: Stmt*) = preproc(Label("")::sts.toList)
       
    26 
       
    27 def eval_exp(e: Exp, env: Env) : Int = e match {
       
    28   case Var(x) => env(x)
       
    29   case Num(n) => n
       
    30   case Plus(e1, e2) => eval_exp(e1, env) + eval_exp(e2, env)
       
    31   case Times(e1, e2) => eval_exp(e1, env) * eval_exp(e2, env)
       
    32   case Equ(e1, e2) => 
       
    33     if (eval_exp(e1, env) == eval_exp(e2, env)) 1 else 0
       
    34 }
       
    35 
       
    36 def eval(sn: Snips) : Env = {
       
    37   def eval_stmts(sts: Stmts, env: Env): Env = sts match {
       
    38     case Nil => env
       
    39     case Label(l)::rest => eval_stmts(rest, env)
       
    40     case Assign(x, e)::rest => 
       
    41       eval_stmts(rest, env + (x -> eval_exp(e, env)))
       
    42     case Goto(l)::rest => eval_stmts(sn(l), env)
       
    43     case Jmp(b, l)::rest => 
       
    44       if (eval_exp(b, env) == 1) eval_stmts(sn(l), env) 
       
    45       else eval_stmts(rest, env)
       
    46   }
       
    47   eval_stmts(sn(""), Map())
       
    48 }