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