189     case Aop("-", a1, a2) => eval_aexp(a1, env) - eval_aexp(a2, env) | 
   189     case Aop("-", a1, a2) => eval_aexp(a1, env) - eval_aexp(a2, env) | 
   190     case Aop("*", a1, a2) => eval_aexp(a1, env) * eval_aexp(a2, env) | 
   190     case Aop("*", a1, a2) => eval_aexp(a1, env) * eval_aexp(a2, env) | 
   191     case Aop("/", a1, a2) => eval_aexp(a1, env) / eval_aexp(a2, env) | 
   191     case Aop("/", a1, a2) => eval_aexp(a1, env) / eval_aexp(a2, env) | 
   192   }  | 
   192   }  | 
   193   | 
   193   | 
   194 def eval_bexp(b: BExp, env: Env) : Boolean =  | 
   194 def eval_bexp(b: BExp, env: Env) : Boolean = b match { | 
   195   b match { | 
         | 
   196     case True => true  | 
   195     case True => true  | 
   197     case False => false  | 
   196     case False => false  | 
   198     case Bop("==", a1, a2) => eval_aexp(a1, env) == eval_aexp(a2, env) | 
   197     case Bop("==", a1, a2) => eval_aexp(a1, env) == eval_aexp(a2, env) | 
   199     case Bop("!=", a1, a2) => !(eval_aexp(a1, env) == eval_aexp(a2, env)) | 
   198     case Bop("!=", a1, a2) => !(eval_aexp(a1, env) == eval_aexp(a2, env)) | 
   200     case Bop(">", a1, a2) => eval_aexp(a1, env) > eval_aexp(a2, env) | 
   199     case Bop(">", a1, a2) => eval_aexp(a1, env) > eval_aexp(a2, env) | 
   201     case Bop("<", a1, a2) => eval_aexp(a1, env) < eval_aexp(a2, env) | 
   200     case Bop("<", a1, a2) => eval_aexp(a1, env) < eval_aexp(a2, env) | 
   202     case And(b1, b2) => eval_bexp(b1, env) && eval_bexp(b2, env)  | 
   201     case And(b1, b2) => eval_bexp(b1, env) && eval_bexp(b2, env)  | 
   203     case Or(b1, b2) => eval_bexp(b1, env) || eval_bexp(b2, env)  | 
   202     case Or(b1, b2) => eval_bexp(b1, env) || eval_bexp(b2, env)  | 
   204   }  | 
   203   }  | 
   205   | 
   204   | 
   206 def eval_stmt(s: Stmt, env: Env) : Env =  | 
   205 def eval_stmt(s: Stmt, env: Env) : Env = s match { | 
   207   s match { | 
         | 
   208     case Skip => env  | 
   206     case Skip => env  | 
   209     case Assign(x, a) => env + (x -> eval_aexp(a, env))  | 
   207     case Assign(x, a) => env + (x -> eval_aexp(a, env))  | 
   210     case If(b, bl1, bl2) => if (eval_bexp(b, env)) eval_bl(bl1, env) else eval_bl(bl2, env)   | 
   208     case If(b, bl1, bl2) => if (eval_bexp(b, env)) eval_bl(bl1, env) else eval_bl(bl2, env)   | 
   211     case While(b, bl) =>   | 
   209     case While(b, bl) =>   | 
   212       if (eval_bexp(b, env)) eval_stmt(While(b, bl), eval_bl(bl, env))  | 
   210       if (eval_bexp(b, env)) eval_stmt(While(b, bl), eval_bl(bl, env))  | 
   213       else env  | 
   211       else env  | 
   214     case Write(x) => { println(env(x)) ; env }   | 
   212     case Write(x) => { println(env(x)) ; env }   | 
   215   }  | 
   213   }  | 
   216 def eval_bl(bl: Block, env: Env) : Env =  | 
   214 def eval_bl(bl: Block, env: Env) : Env = bl match { | 
   217   bl match { | 
         | 
   218     case Nil => env  | 
   215     case Nil => env  | 
   219     case s::bl => eval_bl(bl, eval_stmt(s, env))  | 
   216     case s::bl => eval_bl(bl, eval_stmt(s, env))  | 
   220   }  | 
   217   }  | 
   221   | 
   218   | 
   222 def eval(bl: Block) : Env = eval_bl(bl, Map())  | 
   219 def eval(bl: Block) : Env = eval_bl(bl, Map())  |