99   case "+" => i"iadd"  | 
    99   case "+" => i"iadd"  | 
   100   case "-" => i"isub"  | 
   100   case "-" => i"isub"  | 
   101   case "*" => i"imul"  | 
   101   case "*" => i"imul"  | 
   102 }  | 
   102 }  | 
   103   | 
   103   | 
         | 
   104 def compile_num(i: Int) =   | 
         | 
   105   if (0 <= i && i <= 5) i"iconst_$i" else i"ldc $i"  | 
         | 
   106   | 
         | 
   107 def compile_aload(i: Int) =   | 
         | 
   108   if (0 <= i && i <= 3) i"aload_$i" else i"aload $i"  | 
         | 
   109   | 
         | 
   110 def compile_iload(i: Int) =   | 
         | 
   111   if (0 <= i && i <= 3) i"iload_$i" else i"iload $i"  | 
         | 
   112   | 
         | 
   113 def compile_istore(i: Int) =   | 
         | 
   114   if (0 <= i && i <= 3) i"istore_$i" else i"istore $i"  | 
         | 
   115   | 
   104 // arithmetic expression compilation  | 
   116 // arithmetic expression compilation  | 
   105 def compile_aexp(a: AExp, env : Env) : String = a match { | 
   117 def compile_aexp(a: AExp, env : Env) : String = a match { | 
   106   case Num(i) => i"ldc $i"  | 
   118   case Num(i) => compile_num(i)  | 
   107   case Var(s) => i"iload ${env(s)}" | 
   119   case Var(s) => compile_iload(env(s))  | 
   108   case Aop(op, a1, a2) =>   | 
   120   case Aop(op, a1, a2) =>   | 
   109     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ compile_op(op)  | 
   121     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ compile_op(op)  | 
   110   case Ref(s, a) =>  | 
   122   case Ref(s, a) =>   | 
   111     i"aload ${env(s)}" ++ compile_aexp(a, env) ++  i"iaload" | 
   123     compile_aload(env(s)) ++ compile_aexp(a, env) ++  i"iaload"  | 
   112 }  | 
   124 }  | 
         | 
   125   | 
         | 
   126 def compile_bop(op: String, jmp: String) = op match { | 
         | 
   127   case "==" => i"if_icmpne $jmp"  | 
         | 
   128   case "!=" => i"if_icmpeq $jmp"  | 
         | 
   129   case "<"  => i"if_icmpge $jmp"  | 
         | 
   130 }  | 
         | 
   131   | 
   113   | 
   132   | 
   114 // boolean expression compilation  | 
   133 // boolean expression compilation  | 
   115 def compile_bexp(b: BExp, env : Env, jmp: String) : String = b match { | 
   134 def compile_bexp(b: BExp, env : Env, jmp: String) : String = b match { | 
   116   case True => ""  | 
   135   case True => ""  | 
   117   case False => i"goto $jmp"  | 
   136   case False => i"goto $jmp"  | 
   118   case Bop("==", a1, a2) =>  | 
   137   case Bop(op, a1, a2) =>   | 
   119     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpne $jmp"  | 
   138     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ compile_bop(op, jmp)  | 
   120   case Bop("!=", a1, a2) =>  | 
         | 
   121     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpeq $jmp"  | 
         | 
   122   case Bop("<", a1, a2) =>  | 
         | 
   123     compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ i"if_icmpge $jmp"  | 
         | 
   124 }  | 
   139 }  | 
   125   | 
   140   | 
   126 // statement compilation  | 
   141 // statement compilation  | 
   127 def compile_stmt(s: Stmt, env: Env) : (String, Env) = s match { | 
   142 def compile_stmt(s: Stmt, env: Env) : (String, Env) = s match { | 
   128   case Skip => ("", env) | 
   143   case Skip => ("", env) | 
   129   case Assign(x, a) => { | 
   144   case Assign(x, a) => { | 
   130      val index = env.getOrElse(x, env.keys.size)  | 
   145      val index = env.getOrElse(x, env.keys.size) //  | 
   131     (compile_aexp(a, env) ++ i"istore $index \t\t; $x", env + (x -> index))   | 
   146     (compile_aexp(a, env) ++ compile_istore(index), env + (x -> index))   | 
   132   }   | 
   147   }   | 
   133   case If(b, bl1, bl2) => { | 
   148   case If(b, bl1, bl2) => { | 
   134     val if_else = Fresh("If_else") | 
   149     val if_else = Fresh("If_else") | 
   135     val if_end = Fresh("If_end") | 
   150     val if_end = Fresh("If_end") | 
   136     val (instrs1, env1) = compile_block(bl1, env)  | 
   151     val (instrs1, env1) = compile_block(bl1, env)  | 
   151      instrs1 ++  | 
   166      instrs1 ++  | 
   152      i"goto $loop_begin" ++  | 
   167      i"goto $loop_begin" ++  | 
   153      l"$loop_end", env1)  | 
   168      l"$loop_end", env1)  | 
   154   }  | 
   169   }  | 
   155   case Write(x) =>   | 
   170   case Write(x) =>   | 
   156     (i"iload ${env(x)} \t\t; $x" ++  | 
   171     (compile_iload(env(x)) ++  | 
   157      i"invokestatic XXX/XXX/write(I)V", env)  | 
   172      i"invokestatic XXX/XXX/write(I)V", env)  | 
   158   case Read(x) => { | 
   173   case Read(x) => { | 
   159     val index = env.getOrElse(x, env.keys.size)   | 
   174     val index = env.getOrElse(x, env.keys.size)   | 
   160     (i"invokestatic XXX/XXX/read()I" ++   | 
   175     (i"invokestatic XXX/XXX/read()I" ++       | 
   161      i"istore $index \t\t; $x", env + (x -> index))  | 
   176      compile_istore(index), env + (x -> index))  | 
   162   }  | 
   177   }  | 
   163   case ArrayDef(s: String, n: Int) => { | 
   178   case ArrayDef(s: String, n: Int) => { | 
   164     val index = if (env.isDefinedAt(s)) throw new Exception("array def error") else  | 
   179     val index = if (env.isDefinedAt(s)) throw new Exception("array def error") else  | 
   165                     env.keys.size  | 
   180                     env.keys.size  | 
   166     (i"ldc $n" ++  | 
   181     (i"ldc $n" ++  | 
   168      i"astore $index", env + (s -> index))  | 
   183      i"astore $index", env + (s -> index))  | 
   169   }  | 
   184   }  | 
   170   case AssignA(s, a1, a2) => { | 
   185   case AssignA(s, a1, a2) => { | 
   171     val index = if (env.isDefinedAt(s)) env(s) else   | 
   186     val index = if (env.isDefinedAt(s)) env(s) else   | 
   172                     throw new Exception("array not defined") | 
   187                     throw new Exception("array not defined") | 
   173     (i"aload ${env(s)}" ++ | 
   188     (compile_aload(env(s)) ++  | 
   174      compile_aexp(a1, env) ++  | 
   189      compile_aexp(a1, env) ++  | 
   175      compile_aexp(a2, env) ++  | 
   190      compile_aexp(a2, env) ++  | 
   176      i"iastore", env)  | 
   191      i"iastore", env)  | 
   177   }   | 
   192   }   | 
   178 }  | 
   193 }  | 
   241   println(s"Start compilation of $class_name")  | 
   256   println(s"Start compilation of $class_name")  | 
   242   compile_to_file(bl, class_name)  | 
   257   compile_to_file(bl, class_name)  | 
   243   println("generated .j file") | 
   258   println("generated .j file") | 
   244   (s"java -jar jvm/jasmin-2.4/jasmin.jar ${class_name}.j").!! | 
   259   (s"java -jar jvm/jasmin-2.4/jasmin.jar ${class_name}.j").!! | 
   245   println("generated .class file ") | 
   260   println("generated .class file ") | 
   246   println("Time: " + time_needed(1, (s"java ${class_name}/${class_name}").!)._1) | 
   261   println("Time: " + time_needed(3, (s"java ${class_name}/${class_name}").!)._1) | 
   247 }  | 
   262 }  | 
   248   | 
   263   | 
   249   | 
   264   | 
   250 val arr_test =   | 
   265 val arr_test =   | 
   251   List(ArrayDef("a", 10), | 
   266   List(ArrayDef("a", 10), |