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())  |