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