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 and lexer) |
2 // (stub for including arrays) |
3 |
3 |
4 // the abstract syntax trees |
4 // the abstract syntax trees |
5 abstract class Stmt |
5 abstract class Stmt |
6 abstract class AExp |
6 abstract class AExp |
7 abstract class BExp |
7 abstract class BExp |
10 // statements |
10 // statements |
11 case object Skip extends Stmt |
11 case object Skip extends Stmt |
12 case class If(a: BExp, bl1: Block, bl2: Block) extends Stmt |
12 case class If(a: BExp, bl1: Block, bl2: Block) extends Stmt |
13 case class While(b: BExp, bl: Block) extends Stmt |
13 case class While(b: BExp, bl: Block) extends Stmt |
14 case class Assign(s: String, a: AExp) extends Stmt |
14 case class Assign(s: String, a: AExp) extends Stmt |
15 case class Write(s: String) extends Stmt |
15 case class Write(s: String) extends Stmt // writes out a variable |
16 case class Read(s: String) extends Stmt |
|
17 |
16 |
18 // arithmetic expressions |
17 // arithmetic expressions |
19 case class Var(s: String) extends AExp |
18 case class Var(s: String) extends AExp |
20 case class Num(i: Int) extends AExp |
19 case class Num(i: Int) extends AExp |
21 case class Aop(o: String, a1: AExp, a2: AExp) extends AExp |
20 case class Aop(o: String, a1: AExp, a2: AExp) extends AExp |
43 .limit stack 2 |
42 .limit stack 2 |
44 getstatic java/lang/System/out Ljava/io/PrintStream; |
43 getstatic java/lang/System/out Ljava/io/PrintStream; |
45 iload 0 |
44 iload 0 |
46 invokevirtual java/io/PrintStream/println(I)V |
45 invokevirtual java/io/PrintStream/println(I)V |
47 return |
46 return |
48 .end method |
|
49 |
|
50 .method public static read()I |
|
51 .limit locals 10 |
|
52 .limit stack 10 |
|
53 |
|
54 ldc 0 |
|
55 istore 1 ; this will hold our final integer |
|
56 Label1: |
|
57 getstatic java/lang/System/in Ljava/io/InputStream; |
|
58 invokevirtual java/io/InputStream/read()I |
|
59 istore 2 |
|
60 iload 2 |
|
61 ldc 10 ; the newline delimiter |
|
62 isub |
|
63 ifeq Label2 |
|
64 iload 2 |
|
65 ldc 32 ; the space delimiter |
|
66 isub |
|
67 ifeq Label2 |
|
68 |
|
69 iload 2 |
|
70 ldc 48 ; we have our digit in ASCII, have to subtract it from 48 |
|
71 isub |
|
72 ldc 10 |
|
73 iload 1 |
|
74 imul |
|
75 iadd |
|
76 istore 1 |
|
77 goto Label1 |
|
78 Label2: |
|
79 ;when we come here we have our integer computed in local variable 1 |
|
80 iload 1 |
|
81 ireturn |
|
82 .end method |
47 .end method |
83 |
48 |
84 .method public static main([Ljava/lang/String;)V |
49 .method public static main([Ljava/lang/String;)V |
85 .limit locals 200 |
50 .limit locals 200 |
86 .limit stack 200 |
51 .limit stack 200 |
169 List("\n" + loop_end + ":\n\n"), env1) |
134 List("\n" + loop_end + ":\n\n"), env1) |
170 } |
135 } |
171 case Write(x) => |
136 case Write(x) => |
172 (List("iload " + env(x) + "\n" + |
137 (List("iload " + env(x) + "\n" + |
173 "invokestatic XXX/XXX/write(I)V\n"), env) |
138 "invokestatic XXX/XXX/write(I)V\n"), env) |
174 case Read(x) => { |
|
175 val index = if (env.isDefinedAt(x)) env(x) else |
|
176 env.keys.size.toString |
|
177 (List("invokestatic XXX/XXX/read()I\n" + |
|
178 "istore " + index + "\n"), env + (x -> index)) |
|
179 } |
|
180 } |
139 } |
181 |
140 |
182 // compilation of a block (i.e. list of instructions) |
141 // compilation of a block (i.e. list of instructions) |
183 def compile_block(bl: Block, env: Env) : (Instrs, Env) = bl match { |
142 def compile_block(bl: Block, env: Env) : (Instrs, Env) = bl match { |
184 case Nil => (Nil, env) |
143 case Nil => (Nil, env) |
257 |
216 |
258 |
217 |
259 compile_run(fib_test, "fib") |
218 compile_run(fib_test, "fib") |
260 |
219 |
261 |
220 |
|
221 |
|
222 val arr_test = |
|
223 List(Array("a", 10), |
|
224 Array("b", 2), |
|
225 AssignA("a", Num(0), Num(10)), |
|
226 Assign("x", Ref("a", Num(0))), |
|
227 Write("x"), |
|
228 AssignA("b", Num(1), Num(5)), |
|
229 Assign("x", Ref("b", Num(1))), |
|
230 Write("x")) |
|
231 |
|
232 //compile_run(arr_test, "a") |