solutions/cw4/compiler.sc
changeset 910 b655ce68983f
parent 905 15973df32613
child 920 7af2eea19646
equal deleted inserted replaced
909:a04efdd5e7a3 910:b655ce68983f
     1 // Compiler for JVM
     1 // Compiler for JVM
       
     2 // 
       
     3 // call with 
       
     4 //
       
     5 //     amm2 compiler.sc 
       
     6 //
     2 
     7 
     3 import $file.lexer
     8 import $file.lexer
     4 import lexer._
     9 import lexer._
     5 
    10 
     6 import $file.parser
    11 import $file.parser
   107   case Var(s) => i"iload ${env(s)} \t\t; $s"
   112   case Var(s) => i"iload ${env(s)} \t\t; $s"
   108   case Aop(op, a1, a2) => 
   113   case Aop(op, a1, a2) => 
   109     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ compile_op(op)
   114     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ compile_op(op)
   110 }
   115 }
   111 
   116 
       
   117 def compile_bop(op: String) = op match {
       
   118   case "==" => "if_icmpne"
       
   119   case "!=" => "if_icmpeq"
       
   120   case "<" => "if_icmpge"
       
   121   case ">" => "if_icmple"
       
   122 }
       
   123 
   112 def compile_bexp(b: BExp, env : Env, jmp: String) : String = b match {
   124 def compile_bexp(b: BExp, env : Env, jmp: String) : String = b match {
   113   case True => ""
   125   case True => ""
   114   case False => i"goto $jmp"
   126   case False => i"goto $jmp"
   115   case And(b1, b2) => compile_bexp(b1, env, jmp) ++ compile_bexp(b2, env, jmp)
   127   case And(b1, b2) => compile_bexp(b1, env, jmp) ++ compile_bexp(b2, env, jmp)
   116   case Or(b1, b2) => {
   128   case Or(b1, b2) => {
   120     i"goto $or_end" ++
   132     i"goto $or_end" ++
   121     l"$b1_false" ++
   133     l"$b1_false" ++
   122     compile_bexp(b2, env, jmp) ++
   134     compile_bexp(b2, env, jmp) ++
   123     l"$or_end"
   135     l"$or_end"
   124   }
   136   }
   125   case Bop("==", a1, a2) => 
   137   case Bop(op, a1, a2) => 
   126     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpne $jmp"
   138     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"${compile_bop(op)} $jmp"
   127   case Bop("!=", a1, a2) => 
       
   128     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpeq $jmp"
       
   129   case Bop("<", a1, a2) => 
       
   130     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpge $jmp"
       
   131   case Bop(">", a1, a2) => 
       
   132     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmple $jmp"
       
   133 }
   139 }
   134 
   140 
   135 def compile_stmt(s: Stmt, env: Env) : (String, Env) = s match {
   141 def compile_stmt(s: Stmt, env: Env) : (String, Env) = s match {
   136   case Skip => ("", env)
   142   case Skip => ("", env)
   137   case Assign(x, a) => {
   143   case Assign(x, a) => {