progs/comb2.scala
changeset 471 9476086849ad
parent 185 ea8b94d4755e
child 529 5c28e4134ee1
equal deleted inserted replaced
469:1f4e81950ab4 471:9476086849ad
       
     1 // A parser and evaluator for the while language
       
     2 // 
       
     3 
     1 import scala.language.implicitConversions
     4 import scala.language.implicitConversions
     2 import scala.language.reflectiveCalls
     5 import scala.language.reflectiveCalls
     3 
     6 
     4 abstract class Parser[I <% Seq[_], T] {
     7 abstract class Parser[I <% Seq[_], T] {
     5   def parse(ts: I): Set[(T, I)]
     8   def parse(ts: I): Set[(T, I)]
   123    IdParser ==> Var || 
   126    IdParser ==> Var || 
   124    NumParser ==> Num)
   127    NumParser ==> Num)
   125 
   128 
   126 // boolean expressions
   129 // boolean expressions
   127 lazy val BExp: Parser[String, BExp] = 
   130 lazy val BExp: Parser[String, BExp] = 
   128   ((AExp ~ "=" ~ AExp) ==> { case ((x, y), z) => Bop("=", x, z): BExp } || 
   131   ((AExp ~ "=" ~ AExp) ==> { case ((x, y), z) => Bop("=", x, z):BExp } || 
   129    (AExp ~ "!=" ~ AExp) ==> { case ((x, y), z) => Bop("!=", x, z): BExp } || 
   132    (AExp ~ "!=" ~ AExp) ==> { case ((x, y), z) => Bop("!=", x, z):BExp } || 
   130    (AExp ~ "<" ~ AExp) ==> { case ((x, y), z) => Bop("<", x, z): BExp } || 
   133    (AExp ~ "<" ~ AExp) ==> { case ((x, y), z) => Bop("<", x, z):BExp } || 
   131    (AExp ~ ">" ~ AExp) ==> { case ((x, y), z) => Bop(">", x, z): BExp } || 
   134    (AExp ~ ">" ~ AExp) ==> { case ((x, y), z) => Bop(">", x, z):BExp } || 
   132    ("true" ==> ((_) => True: BExp)) || 
   135    ("true" ==> ((_) => True:BExp )) || 
   133    ("false" ==> ((_) => False: BExp)) ||
   136    ("false" ==> ((_) => False:BExp )) ||
   134    ("(" ~ BExp ~ ")") ==> { case ((x, y), z) => y})
   137    ("(" ~ BExp ~ ")") ==> { case ((x, y), z) => y})
   135 
   138 
   136 lazy val Stmt: Parser[String, Stmt] =
   139 lazy val Stmt: Parser[String, Stmt] =
   137   (("skip" ==> ((_) => Skip: Stmt)) ||
   140   (("skip" ==> ((_) => Skip: Stmt)) ||
   138    (IdParser ~ ":=" ~ AExp) ==> { case ((x, y), z) => Assign(x, z): Stmt } ||
   141    (IdParser ~ ":=" ~ AExp) ==> { case ((x, y), z) => Assign(x, z): Stmt } ||
   147 lazy val Block: Parser[String, Block] =
   150 lazy val Block: Parser[String, Block] =
   148   (("{" ~ Stmts ~ "}") ==> { case ((x, y), z) => y} || 
   151   (("{" ~ Stmts ~ "}") ==> { case ((x, y), z) => y} || 
   149    (Stmt ==> ((s) => List(s))))
   152    (Stmt ==> ((s) => List(s))))
   150 
   153 
   151 
   154 
   152 Block.parse_all("x2:=5")
   155 Stmt.parse_all("x2:=5")
   153 Block.parse_all("{x:=5;y:=8}")
   156 Block.parse_all("{x:=5;y:=8}")
   154 Block.parse_all("if(false)then{x:=5}else{x:=10}")
   157 Block.parse_all("if(false)then{x:=5}else{x:=10}")
   155 
   158 
   156 val fib = """{n:=10;minus1:=0;minus2:=1;temp:=0;while(n>0)do{temp:=minus2;minus2:=minus1+minus2;minus1:=temp;n:=n-1};result:=minus2}"""
   159 val fib = """{n:=10;minus1:=0;minus2:=1;temp:=0;while(n>0)do{temp:=minus2;minus2:=minus1+minus2;minus1:=temp;n:=n-1};result:=minus2}"""
   157 
   160 
   191   case s::bl => eval_bl(bl, eval_stmt(s, env))
   194   case s::bl => eval_bl(bl, eval_stmt(s, env))
   192 }
   195 }
   193 
   196 
   194 def eval(bl: Block) : Env = eval_bl(bl, Map())
   197 def eval(bl: Block) : Env = eval_bl(bl, Map())
   195 
   198 
   196 eval(Block.parse_all(fib).head)("result")
   199 println(eval(Block.parse_all(fib).head)("result"))