progs/parser-combinators/comb2-simple.sc
changeset 973 f25d338d16c9
parent 972 ebb4a40d9bae
equal deleted inserted replaced
972:ebb4a40d9bae 973:f25d338d16c9
     6 // call with
     6 // call with
     7 //
     7 //
     8 //    amm comb2-simple.sc
     8 //    amm comb2-simple.sc
     9 
     9 
    10 
    10 
       
    11 // to make sure the input has an empty-method
    11 trait IsSeq[I] {
    12 trait IsSeq[I] {
    12   extension (i: I) def isEmpty: Boolean
    13   extension (i: I) def isEmpty: Boolean
    13 }
    14 }
    14 
    15 
    15 given IsSeq[String] = _.isEmpty
    16 given IsSeq[String] = _.isEmpty
   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())