progs/compile_arr.scala
changeset 709 c112a6cb5e52
parent 708 4980f421b3b0
child 710 183663740fb7
equal deleted inserted replaced
708:4980f421b3b0 709:c112a6cb5e52
    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),
   508 bf_run(bf2, "fibs")
   523 bf_run(bf2, "fibs")
   509 
   524 
   510 // Mandelbrot Set
   525 // Mandelbrot Set
   511 //----------------
   526 //----------------
   512 //
   527 //
   513 // Note: Parsing of the generated WHILE program (around 60K in size)
   528 // Note: Parsing of the generated WHILE program (around 56K in size)
   514 // takes approximately 10 minutes
   529 // takes approximately 10 minutes. The final class file runs
       
   530 // for around 23 seconds.
   515 
   531 
   516 bf_run("""A mandelbrot set fractal viewer in brainf*** written by Erik Bosman
   532 bf_run("""A mandelbrot set fractal viewer in brainf*** written by Erik Bosman
   517 +++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
   533 +++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
   518 >>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
   534 >>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
   519 <<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
   535 <<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>