equal
deleted
inserted
replaced
1 // A Small Compiler for the WHILE Language |
1 // A Small Compiler for the WHILE Language |
2 // (it does not use a parser nor lexer) |
2 // (it does not use a parser nor lexer) |
3 // |
3 // |
4 // cal with |
4 // call with |
5 // |
5 // |
6 // amm compile.sc test |
6 // amm compile.sc test |
7 // amm compile.sc test2 |
7 // amm compile.sc test2 |
8 |
8 // |
|
9 // test2 includes a run of the JVM instructions. This |
|
10 // requires that jasmin.jar is present in the same |
|
11 // directory. |
9 |
12 |
10 // the abstract syntax trees |
13 // the abstract syntax trees |
11 abstract class Stmt |
14 abstract class Stmt |
12 abstract class AExp |
15 abstract class AExp |
13 abstract class BExp |
16 abstract class BExp |
31 case object False extends BExp |
34 case object False extends BExp |
32 case class Bop(o: String, a1: AExp, a2: AExp) extends BExp |
35 case class Bop(o: String, a1: AExp, a2: AExp) extends BExp |
33 |
36 |
34 |
37 |
35 // compiler headers needed for the JVM |
38 // compiler headers needed for the JVM |
36 // (contains methods for read and write) |
39 // (contains a method for write) |
37 val beginning = """ |
40 val beginning = """ |
38 .class public XXX.XXX |
41 .class public XXX.XXX |
39 .super java/lang/Object |
42 .super java/lang/Object |
40 |
43 |
41 .method public static write(I)V |
44 .method public static write(I)V |
73 x ++ "_" ++ counter.toString() |
76 x ++ "_" ++ counter.toString() |
74 } |
77 } |
75 |
78 |
76 // convenient string interpolations |
79 // convenient string interpolations |
77 // for instructions and labels |
80 // for instructions and labels |
78 import scala.language.implicitConversions |
81 |
79 import scala.language.reflectiveCalls |
82 extension (sc: StringContext) { |
80 |
|
81 implicit def sring_inters(sc: StringContext) = new { |
|
82 def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" |
83 def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" |
83 def l(args: Any*): String = sc.s(args:_*) ++ ":\n" |
84 def l(args: Any*): String = sc.s(args:_*) ++ ":\n" |
84 } |
85 } |
85 |
86 |
86 // this allows us to write things like |
87 // this allows us to write things like |
148 l"$loop_end", env1) |
149 l"$loop_end", env1) |
149 } |
150 } |
150 case Write(x) => |
151 case Write(x) => |
151 (i"iload ${env(x)} \t\t; $x" ++ |
152 (i"iload ${env(x)} \t\t; $x" ++ |
152 i"invokestatic XXX/XXX/write(I)V", env) |
153 i"invokestatic XXX/XXX/write(I)V", env) |
153 //case Read(x) => { |
|
154 // val index = env.getOrElse(x, env.keys.size) |
|
155 // (i"invokestatic XXX/XXX/read()I" ++ |
|
156 // i"istore $index \t\t; $x", env + (x -> index)) |
|
157 //} |
|
158 } |
154 } |
159 |
155 |
160 // compilation of a block (i.e. list of instructions) |
156 // compilation of a block (i.e. list of instructions) |
161 def compile_block(bl: Block, env: Env) : (String, Env) = bl match { |
157 def compile_block(bl: Block, env: Env) : (String, Env) = bl match { |
162 case Nil => ("", env) |
158 case Nil => ("", env) |
198 def test() = |
194 def test() = |
199 println(compile(fib_test, "fib")) |
195 println(compile(fib_test, "fib")) |
200 |
196 |
201 |
197 |
202 |
198 |
203 |
|
204 |
|
205 // compiling and running .j-files |
199 // compiling and running .j-files |
206 // |
200 // |
207 // JVM files can be assembled with |
201 // JVM files can be assembled with |
208 // |
202 // |
209 // java -jar jasmin.jar fib.j |
203 // java -jar jasmin.jar fib.j |
216 def run(bl: Block, class_name: String) = { |
210 def run(bl: Block, class_name: String) = { |
217 val code = compile(bl, class_name) |
211 val code = compile(bl, class_name) |
218 os.write.over(os.pwd / s"$class_name.j", code) |
212 os.write.over(os.pwd / s"$class_name.j", code) |
219 os.proc("java", "-jar", "jasmin.jar", s"$class_name.j").call() |
213 os.proc("java", "-jar", "jasmin.jar", s"$class_name.j").call() |
220 os.proc("java", s"$class_name/$class_name").call(stdout = os.Inherit, stdin = os.Inherit) |
214 os.proc("java", s"$class_name/$class_name").call(stdout = os.Inherit, stdin = os.Inherit) |
|
215 () |
221 } |
216 } |
222 |
217 |
223 |
218 |
224 @main |
219 @main |
225 def test2() = |
220 def test2() = |
264 |
259 |
265 */ |
260 */ |
266 |
261 |
267 |
262 |
268 |
263 |
269 |
|
270 |
|
271 // runs with amm2 and amm3 |
|