added an abacus to javabyte code compiler
authorChristian Urban <christian dot urban at kcl dot ac dot uk>
Thu, 14 Mar 2013 18:46:34 +0000
changeset 225 0974c59e7029
parent 224 68324a8566c1
child 226 df455e0a9f98
added an abacus to javabyte code compiler
scala/README
scala/ex.scala
scala/ex_jvm.scala
--- a/scala/README	Thu Mar 14 18:24:06 2013 +0000
+++ b/scala/README	Thu Mar 14 18:46:34 2013 +0000
@@ -24,3 +24,13 @@
 
   rm -rf *~ lib turing abacus comp1 comp2 recs
 
+
+
+
+------------------------------
+Abacus to Javabyte compilation
+
+requires the jasmin assembler for Java
+avilable from
+
+   http://jasmin.sourceforge.net
\ No newline at end of file
--- a/scala/ex.scala	Thu Mar 14 18:24:06 2013 +0000
+++ b/scala/ex.scala	Thu Mar 14 18:46:34 2013 +0000
@@ -5,7 +5,6 @@
 import comp1._
 import comp2._
 
-print(compile_rec(S)._1.print)
 
 // Turing machine examples
 val TMCopy = TM((WBk, 5), (R, 2), (R, 3), (R, 2), (WOc, 3), 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scala/ex_jvm.scala	Thu Mar 14 18:46:34 2013 +0000
@@ -0,0 +1,110 @@
+// compiles Abacus programs directly to Javabyte code
+
+import scala.sys.process._
+import lib._
+import abacus._
+import recs._
+import comp2._
+
+
+def compile_aprog(p: AProg) : String = {
+
+  def compile_inst(i: AInst, l: Int) : List[String] = {
+    ("L" + l.toString + ":") :: (i match {
+      case Inc(n) => List("iinc " + n.toString + " 1")
+      case Dec(n, l) => List("iload " + n.toString, "ifeq L" + l.toString, "iinc " + n.toString + " -1")
+      case Goto(l) => List("goto L" + l.toString)
+    })
+  }
+  
+  val code = for ((i, l) <- p.zipWithIndex) 
+    yield compile_inst(i, l).mkString("", "\n", "\n") 
+
+  code.mkString
+}
+
+def init_regs(ns: List[Int]) : String = {
+  
+  val code = for ((n, i) <- ns.zipWithIndex)
+    yield List("bipush " + n.toString, "istore " + i.toString).mkString("", "\n", "\n") 
+  
+  code.mkString
+}
+
+def print_result(l: Int, r: Int, class_name: String) : String = {
+  List("L" + l.toString + ":", 
+       "iload " + r.toString,
+       "invokestatic " + class_name + "/" + class_name + "/write(I)V").mkString("", "\n", "\n")
+}
+  
+// compiler preludes
+def beginning(class_name: String) : String = { 
+"\n.class public " + class_name + "." + class_name + """
+.super java/lang/Object
+
+.method public <init>()V
+   aload_0
+   invokenonvirtual java/lang/Object/<init>()V
+   return
+.end method
+
+.method public static write(I)V 
+    .limit locals 5 
+    .limit stack 5 
+    iload 0 
+    getstatic java/lang/System/out Ljava/io/PrintStream; 
+    swap 
+    invokevirtual java/io/PrintStream/println(I)V 
+    return 
+.end method
+
+
+.method public static main([Ljava/lang/String;)V
+   .limit locals 200
+   .limit stack 200
+
+""" }
+
+val ending = """
+
+   return
+
+.end method
+"""
+
+
+def compile(f: Rec, ns: List[Int]) : Unit = {
+  val class_name = "LOOP"
+  val (aprog, res, max) = compile_rec(f)
+
+  val init_code = init_regs(ns.padTo(max, 0))
+  val main_code = compile_aprog(aprog.p) 
+  val fin_code = print_result(aprog.p.length, res, class_name)
+  val code = init_code.mkString + main_code.mkString + fin_code
+  
+  val assembly = beginning(class_name) ++ code ++ ending
+
+  val fw = new java.io.FileWriter(class_name + ".j") 
+  fw.write(assembly) 
+  fw.close()
+  val _ = ("java -jar jvm/jasmin-2.4/jasmin.jar " + class_name + ".j").!!
+  val start = System.nanoTime()
+  val result = ("java " + class_name + "/" + class_name).!!
+  val end = System.nanoTime()
+  println("Result: " + result + "  Time: " + (end - start) / 1.0e9)
+}
+
+
+//compile(S, List(3))
+//compile(Fact, List(11))
+//compile(Fact, List(12))
+//compile(Fact, List(13))
+//compile(Fact, List(14))
+
+for (i <- 10 to 20) {
+  println("Input:  " + i)
+  compile(Prime, List(i))
+}
+
+
+