progs/parser-combinators/comb2.sc
changeset 973 f25d338d16c9
parent 972 ebb4a40d9bae
child 977 1e6eca42d90b
equal deleted inserted replaced
972:ebb4a40d9bae 973:f25d338d16c9
    14 // it allows writing nested patterns as
    14 // it allows writing nested patterns as
    15 // case x ~ y ~ z => ...
    15 // case x ~ y ~ z => ...
    16 
    16 
    17 case class ~[+A, +B](x: A, y: B)
    17 case class ~[+A, +B](x: A, y: B)
    18 
    18 
    19 
    19 // to make sure the input has an empty-method
    20 trait IsSeq[I] {
    20 trait IsSeq[I] {
    21   extension (i: I) def isEmpty: Boolean
    21   extension (i: I) def isEmpty: Boolean
    22 }
    22 }
    23 
    23 
    24 given IsSeq[String] = _.isEmpty
    24 given IsSeq[String] = _.isEmpty
   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())