|    184  |    185  | 
|    185  |    186  | 
|    186 // an interpreter for the WHILE language |    187 // an interpreter for the WHILE language | 
|    187 type Env = Map[String, Int] |    188 type Env = Map[String, Int] | 
|    188  |    189  | 
|    189 def eval_aexp(a: AExp, env: Env) : Int = |    190 def eval_aexp(a: AExp, env: Env) : Int = a match { | 
|    190   a match { |         | 
|    191     case Num(i) => i |    191     case Num(i) => i | 
|    192     case Var(s) => env(s) |    192     case Var(s) => env(s) | 
|    193     case Aop("+", a1, a2) => eval_aexp(a1, env) + eval_aexp(a2, env) |    193     case Aop("+", a1, a2) => eval_aexp(a1, env) + eval_aexp(a2, env) | 
|    194     case Aop("-", a1, a2) => eval_aexp(a1, env) - eval_aexp(a2, env) |    194     case Aop("-", a1, a2) => eval_aexp(a1, env) - eval_aexp(a2, env) | 
|    195     case Aop("*", a1, a2) => eval_aexp(a1, env) * eval_aexp(a2, env) |    195     case Aop("*", a1, a2) => eval_aexp(a1, env) * eval_aexp(a2, env) | 
|    196     case Aop("/", a1, a2) => eval_aexp(a1, env) / eval_aexp(a2, env) |    196     case Aop("/", a1, a2) => eval_aexp(a1, env) / eval_aexp(a2, env) | 
|    197   } |    197   } | 
|    198  |    198  | 
|    199 def eval_bexp(b: BExp, env: Env) : Boolean = |    199 def eval_bexp(b: BExp, env: Env) : Boolean = b match { | 
|    200   b match { |         | 
|    201     case True => true |    200     case True => true | 
|    202     case False => false |    201     case False => false | 
|    203     case Bop("==", a1, a2) => eval_aexp(a1, env) == eval_aexp(a2, env) |    202     case Bop("==", a1, a2) => eval_aexp(a1, env) == eval_aexp(a2, env) | 
|    204     case Bop("!=", a1, a2) => !(eval_aexp(a1, env) == eval_aexp(a2, env)) |    203     case Bop("!=", a1, a2) => !(eval_aexp(a1, env) == eval_aexp(a2, env)) | 
|    205     case Bop(">", a1, a2) => eval_aexp(a1, env) > eval_aexp(a2, env) |    204     case Bop(">", a1, a2) => eval_aexp(a1, env) > eval_aexp(a2, env) | 
|    206     case Bop("<", a1, a2) => eval_aexp(a1, env) < eval_aexp(a2, env) |    205     case Bop("<", a1, a2) => eval_aexp(a1, env) < eval_aexp(a2, env) | 
|    207     case And(b1, b2) => eval_bexp(b1, env) && eval_bexp(b2, env) |    206     case And(b1, b2) => eval_bexp(b1, env) && eval_bexp(b2, env) | 
|    208     case Or(b1, b2) => eval_bexp(b1, env) || eval_bexp(b2, env) |    207     case Or(b1, b2) => eval_bexp(b1, env) || eval_bexp(b2, env) | 
|    209   } |    208   } | 
|    210  |    209  | 
|    211 def eval_stmt(s: Stmt, env: Env) : Env = |    210 def eval_stmt(s: Stmt, env: Env) : Env = s match { | 
|    212   s match { |         | 
|    213     case Skip => env |    211     case Skip => env | 
|    214     case Assign(x, a) => env + (x -> eval_aexp(a, env)) |    212     case Assign(x, a) => env + (x -> eval_aexp(a, env)) | 
|    215     case If(b, bl1, bl2) => if (eval_bexp(b, env)) eval_bl(bl1, env) else eval_bl(bl2, env)  |    213     case If(b, bl1, bl2) => if (eval_bexp(b, env)) eval_bl(bl1, env) else eval_bl(bl2, env)  | 
|    216     case While(b, bl) =>  |    214     case While(b, bl) =>  | 
|    217       if (eval_bexp(b, env)) eval_stmt(While(b, bl), eval_bl(bl, env)) |    215       if (eval_bexp(b, env)) eval_stmt(While(b, bl), eval_bl(bl, env)) | 
|    218       else env |    216       else env | 
|    219     case Write(x) => { println(env(x)) ; env }   |    217     case Write(x) => { println(env(x)) ; env }   | 
|    220   } |    218   } | 
|    221 def eval_bl(bl: Block, env: Env) : Env = |    219 def eval_bl(bl: Block, env: Env) : Env = bl match { | 
|    222   bl match { |         | 
|    223     case Nil => env |    220     case Nil => env | 
|    224     case s::bl => eval_bl(bl, eval_stmt(s, env)) |    221     case s::bl => eval_bl(bl, eval_stmt(s, env)) | 
|    225   } |    222   } | 
|    226  |    223  | 
|    227 def eval(bl: Block) : Env = eval_bl(bl, Map()) |    224 def eval(bl: Block) : Env = eval_bl(bl, Map()) |