scala/ex_jvm.scala
changeset 225 0974c59e7029
child 226 df455e0a9f98
equal deleted inserted replaced
224:68324a8566c1 225:0974c59e7029
       
     1 // compiles Abacus programs directly to Javabyte code
       
     2 
       
     3 import scala.sys.process._
       
     4 import lib._
       
     5 import abacus._
       
     6 import recs._
       
     7 import comp2._
       
     8 
       
     9 
       
    10 def compile_aprog(p: AProg) : String = {
       
    11 
       
    12   def compile_inst(i: AInst, l: Int) : List[String] = {
       
    13     ("L" + l.toString + ":") :: (i match {
       
    14       case Inc(n) => List("iinc " + n.toString + " 1")
       
    15       case Dec(n, l) => List("iload " + n.toString, "ifeq L" + l.toString, "iinc " + n.toString + " -1")
       
    16       case Goto(l) => List("goto L" + l.toString)
       
    17     })
       
    18   }
       
    19   
       
    20   val code = for ((i, l) <- p.zipWithIndex) 
       
    21     yield compile_inst(i, l).mkString("", "\n", "\n") 
       
    22 
       
    23   code.mkString
       
    24 }
       
    25 
       
    26 def init_regs(ns: List[Int]) : String = {
       
    27   
       
    28   val code = for ((n, i) <- ns.zipWithIndex)
       
    29     yield List("bipush " + n.toString, "istore " + i.toString).mkString("", "\n", "\n") 
       
    30   
       
    31   code.mkString
       
    32 }
       
    33 
       
    34 def print_result(l: Int, r: Int, class_name: String) : String = {
       
    35   List("L" + l.toString + ":", 
       
    36        "iload " + r.toString,
       
    37        "invokestatic " + class_name + "/" + class_name + "/write(I)V").mkString("", "\n", "\n")
       
    38 }
       
    39   
       
    40 // compiler preludes
       
    41 def beginning(class_name: String) : String = { 
       
    42 "\n.class public " + class_name + "." + class_name + """
       
    43 .super java/lang/Object
       
    44 
       
    45 .method public <init>()V
       
    46    aload_0
       
    47    invokenonvirtual java/lang/Object/<init>()V
       
    48    return
       
    49 .end method
       
    50 
       
    51 .method public static write(I)V 
       
    52     .limit locals 5 
       
    53     .limit stack 5 
       
    54     iload 0 
       
    55     getstatic java/lang/System/out Ljava/io/PrintStream; 
       
    56     swap 
       
    57     invokevirtual java/io/PrintStream/println(I)V 
       
    58     return 
       
    59 .end method
       
    60 
       
    61 
       
    62 .method public static main([Ljava/lang/String;)V
       
    63    .limit locals 200
       
    64    .limit stack 200
       
    65 
       
    66 """ }
       
    67 
       
    68 val ending = """
       
    69 
       
    70    return
       
    71 
       
    72 .end method
       
    73 """
       
    74 
       
    75 
       
    76 def compile(f: Rec, ns: List[Int]) : Unit = {
       
    77   val class_name = "LOOP"
       
    78   val (aprog, res, max) = compile_rec(f)
       
    79 
       
    80   val init_code = init_regs(ns.padTo(max, 0))
       
    81   val main_code = compile_aprog(aprog.p) 
       
    82   val fin_code = print_result(aprog.p.length, res, class_name)
       
    83   val code = init_code.mkString + main_code.mkString + fin_code
       
    84   
       
    85   val assembly = beginning(class_name) ++ code ++ ending
       
    86 
       
    87   val fw = new java.io.FileWriter(class_name + ".j") 
       
    88   fw.write(assembly) 
       
    89   fw.close()
       
    90   val _ = ("java -jar jvm/jasmin-2.4/jasmin.jar " + class_name + ".j").!!
       
    91   val start = System.nanoTime()
       
    92   val result = ("java " + class_name + "/" + class_name).!!
       
    93   val end = System.nanoTime()
       
    94   println("Result: " + result + "  Time: " + (end - start) / 1.0e9)
       
    95 }
       
    96 
       
    97 
       
    98 //compile(S, List(3))
       
    99 //compile(Fact, List(11))
       
   100 //compile(Fact, List(12))
       
   101 //compile(Fact, List(13))
       
   102 //compile(Fact, List(14))
       
   103 
       
   104 for (i <- 10 to 20) {
       
   105   println("Input:  " + i)
       
   106   compile(Prime, List(i))
       
   107 }
       
   108 
       
   109 
       
   110