progs/fun.scala
changeset 223 e4b29b57f6a3
parent 221 824ffbf66ab4
child 225 ef573e8fc86e
equal deleted inserted replaced
222:b712519b41d3 223:e4b29b57f6a3
    21 
    21 
    22 object RANGE {
    22 object RANGE {
    23   def apply(s: String) : RANGE = RANGE(s.toList)
    23   def apply(s: String) : RANGE = RANGE(s.toList)
    24 }
    24 }
    25 def NMTIMES(r: Rexp, n: Int, m: Int) = {
    25 def NMTIMES(r: Rexp, n: Int, m: Int) = {
    26   if(m < n) throw new IllegalArgumentException("the number m cannot be smaller than n.")
    26   if (m < n) throw new IllegalArgumentException("the number m cannot be smaller than n.")
    27   else NUPTOM(r, n, m - n)
    27   else NUPTOM(r, n, m - n)
    28 }
    28 }
    29 
    29 
    30 case class NOT(r: Rexp) extends Rexp 
    30 case class NOT(r: Rexp) extends Rexp 
    31 case class OPT(r: Rexp) extends Rexp 
    31 case class OPT(r: Rexp) extends Rexp 
   339 
   339 
   340 lazy val Prog: Parser[List[Token], List[Decl]] =
   340 lazy val Prog: Parser[List[Token], List[Decl]] =
   341   (Defn ~ T_SEMI ~ Prog) ==> { case ((x, y), z) => x :: z : List[Decl] } ||
   341   (Defn ~ T_SEMI ~ Prog) ==> { case ((x, y), z) => x :: z : List[Decl] } ||
   342   (Exp ==> ((s) => List(Main(s)) : List[Decl]))
   342   (Exp ==> ((s) => List(Main(s)) : List[Decl]))
   343 
   343 
   344 // parser examples
       
   345 
       
   346 val p12_toks = tokenizer(fromFile("defs.rec"))
       
   347 val p12_ast = Prog.parse_all(p12_toks)
       
   348 //println(p12_toks.mkString(","))
       
   349 //println(p12_ast)
       
   350 
       
   351 
       
   352 
   344 
   353 // compiler - built-in functions 
   345 // compiler - built-in functions 
   354 // copied from http://www.ceng.metu.edu.tr/courses/ceng444/link/jvm-cpm.html
   346 // copied from http://www.ceng.metu.edu.tr/courses/ceng444/link/jvm-cpm.html
   355 //
   347 //
   356 
   348 
   429     compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpge " + jmp + "\n")
   421     compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpge " + jmp + "\n")
   430   case Bop("<=", a1, a2) => 
   422   case Bop("<=", a1, a2) => 
   431     compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpgt " + jmp + "\n")
   423     compile_exp(a1, env) ++ compile_exp(a2, env) ++ List("if_icmpgt " + jmp + "\n")
   432 }
   424 }
   433 
   425 
   434 
       
   435 def compile_expT(a: Exp, env : Mem, name: String) : Instrs = a match {
       
   436   case Num(i) => List("ldc " + i.toString + "\n")
       
   437   case Var(s) => List("iload " + env(s).toString + "\n")
       
   438   case Aop("+", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("iadd\n")
       
   439   case Aop("-", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("isub\n")
       
   440   case Aop("*", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("imul\n")
       
   441   case Aop("/", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("idiv\n")
       
   442   case Aop("%", a1, a2) => compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("irem\n")
       
   443   case If(b, a1, a2) => {
       
   444     val if_else = Fresh("If_else")
       
   445     val if_end = Fresh("If_end")
       
   446     compile_bexp(b, env, if_else) ++
       
   447     compile_expT(a1, env, name) ++
       
   448     List("goto " + if_end + "\n") ++
       
   449     List("\n" + if_else + ":\n\n") ++
       
   450     compile_expT(a2, env, name) ++
       
   451     List("\n" + if_end + ":\n\n")
       
   452   }
       
   453   case Call(n, args) => if (name == n) { 
       
   454     val stores = args.zipWithIndex.map { case (x, y) => "istore " + y.toString + "\n" } 
       
   455     args.flatMap(a => compile_expT(a, env, "")) ++
       
   456     stores.reverse ++ 
       
   457     List ("goto " + n + "_Start\n") 
       
   458   } else {
       
   459     val is = "I" * args.length
       
   460     args.flatMap(a => compile_expT(a, env, "")) ++
       
   461     List ("invokestatic XXX/XXX/" + n + "(" + is + ")I\n")
       
   462   }
       
   463   case Sequ(a1, a2) => {
       
   464     compile_expT(a1, env, "") ++ List("pop\n") ++ compile_expT(a2, env, name)
       
   465   }
       
   466   case Write(a1) => {
       
   467     compile_expT(a1, env, "") ++
       
   468     List("dup\n",
       
   469          "invokestatic XXX/XXX/write(I)V\n")
       
   470   }
       
   471 }
       
   472 
       
   473 def compile_bexpT(b: BExp, env : Mem, jmp: String) : Instrs = b match {
       
   474   case Bop("==", a1, a2) => 
       
   475     compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpne " + jmp + "\n")
       
   476   case Bop("!=", a1, a2) => 
       
   477     compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpeq " + jmp + "\n")
       
   478   case Bop("<", a1, a2) => 
       
   479     compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpge " + jmp + "\n")
       
   480   case Bop("<=", a1, a2) => 
       
   481     compile_expT(a1, env, "") ++ compile_expT(a2, env, "") ++ List("if_icmpgt " + jmp + "\n")
       
   482 }
       
   483 
       
   484 
       
   485 def compile_decl(d: Decl) : Instrs = d match {
   426 def compile_decl(d: Decl) : Instrs = d match {
   486   case Def(name, args, a) => { 
   427   case Def(name, args, a) => { 
   487     val env = args.zipWithIndex.toMap
   428     val env = args.zipWithIndex.toMap
   488     val is = "I" * args.length
   429     val is = "I" * args.length
   489     List(".method public static " + name + "(" + is + ")I \n",
   430     List(".method public static " + name + "(" + is + ")I \n",
   490          ".limit locals " + args.length.toString + "\n",
   431          ".limit locals " + args.length.toString + "\n",
   491          ".limit stack " + (1 + max_stack_exp(a)).toString + "\n",
   432          ".limit stack " + (1 + max_stack_exp(a)).toString + "\n",
   492          name + "_Start:\n") ++   
   433          name + "_Start:\n") ++   
   493     //compile_exp(a, env) ++
   434     compile_exp(a, env) ++
   494     compile_expT(a, env, name) ++
       
   495     List("ireturn\n",
   435     List("ireturn\n",
   496          ".end method \n\n")
   436          ".end method \n\n")
   497   }
   437   }
   498   case Main(a) => {
   438   case Main(a) => {
   499     val main_begin = 
   439     List(".method public static main([Ljava/lang/String;)V\n",
   500       List(".method public static main([Ljava/lang/String;)V\n",
   440          ".limit locals 200\n",
   501            ".limit locals 200\n",
   441          ".limit stack 200\n") ++
   502            ".limit stack 200\n")
   442     compile_exp(a, Map()) ++
   503     val main_end = 
   443     List("invokestatic XXX/XXX/write(I)V\n",
   504       List("invokestatic XXX/XXX/write(I)V\n",
   444          "return\n",
   505            "return\n",
   445          ".end method\n")
   506            ".end method\n")
       
   507     main_begin ++ compile_exp(a, Map()) ++ main_end
       
   508   }
   446   }
   509 }
   447 }
   510 
   448 
   511 def compile(class_name: String, input: String) : String = {
   449 def compile(class_name: String, input: String) : String = {
   512   val tks = tokenizer(input)
   450   val tks = tokenizer(input)