109 |
109 |
110 // arithmetic expression compilation |
110 // arithmetic expression compilation |
111 def compile_aexp(a: AExp, env : Env) : Instrs = a match { |
111 def compile_aexp(a: AExp, env : Env) : Instrs = a match { |
112 case Num(i) => List("ldc " + i.toString + "\n") |
112 case Num(i) => List("ldc " + i.toString + "\n") |
113 case Var(s) => List("iload " + env(s) + "\n") |
113 case Var(s) => List("iload " + env(s) + "\n") |
114 case Aop("+", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("iadd\n") |
114 case Aop("+", a1, a2) => |
115 case Aop("-", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("isub\n") |
115 compile_aexp(a1, env) ++ |
116 case Aop("*", a1, a2) => compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("imul\n") |
116 compile_aexp(a2, env) ++ List("iadd\n") |
|
117 case Aop("-", a1, a2) => |
|
118 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("isub\n") |
|
119 case Aop("*", a1, a2) => |
|
120 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("imul\n") |
117 } |
121 } |
118 |
122 |
119 // boolean expression compilation |
123 // boolean expression compilation |
120 def compile_bexp(b: BExp, env : Env, jmp: String) : Instrs = b match { |
124 def compile_bexp(b: BExp, env : Env, jmp: String) : Instrs = b match { |
121 case True => Nil |
125 case True => Nil |
122 case False => List("goto " + jmp + "\n") |
126 case False => List("goto " + jmp + "\n") |
123 case Bop("=", a1, a2) => |
127 case Bop("=", a1, a2) => |
124 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpne " + jmp + "\n") |
128 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ |
|
129 List("if_icmpne " + jmp + "\n") |
125 case Bop("!=", a1, a2) => |
130 case Bop("!=", a1, a2) => |
126 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpeq " + jmp + "\n") |
131 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ |
|
132 List("if_icmpeq " + jmp + "\n") |
127 case Bop("<", a1, a2) => |
133 case Bop("<", a1, a2) => |
128 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ List("if_icmpge " + jmp + "\n") |
134 compile_aexp(a1, env) ++ compile_aexp(a2, env) ++ |
|
135 List("if_icmpge " + jmp + "\n") |
129 } |
136 } |
130 |
137 |
131 // statement compilation |
138 // statement compilation |
132 def compile_stmt(s: Stmt, env: Env) : (Instrs, Env) = s match { |
139 def compile_stmt(s: Stmt, env: Env) : (Instrs, Env) = s match { |
133 case Skip => (Nil, env) |
140 case Skip => (Nil, env) |
134 case Assign(x, a) => { |
141 case Assign(x, a) => { |
135 val index = if (env.isDefinedAt(x)) env(x) else env.keys.size.toString |
142 val index = if (env.isDefinedAt(x)) env(x) else |
|
143 env.keys.size.toString |
136 (compile_aexp(a, env) ++ |
144 (compile_aexp(a, env) ++ |
137 List("istore " + index + "\n"), env + (x -> index)) |
145 List("istore " + index + "\n"), env + (x -> index)) |
138 } |
146 } |
139 case If(b, bl1, bl2) => { |
147 case If(b, bl1, bl2) => { |
140 val if_else = Fresh("If_else") |
148 val if_else = Fresh("If_else") |
189 List(Read("n"), // read n; |
199 List(Read("n"), // read n; |
190 Assign("minus1",Num(0)), // minus1 := 0; |
200 Assign("minus1",Num(0)), // minus1 := 0; |
191 Assign("minus2",Num(1)), // minus2 := 1; |
201 Assign("minus2",Num(1)), // minus2 := 1; |
192 Assign("temp",Num(0)), // temp := 0; |
202 Assign("temp",Num(0)), // temp := 0; |
193 While(Bop("<",Num(0),Var("n")), // while n > 0 do { |
203 While(Bop("<",Num(0),Var("n")), // while n > 0 do { |
194 List(Assign("temp",Var("minus2")), // temp := minus2; |
204 List(Assign("temp",Var("minus2")), // temp := minus2; |
195 Assign("minus2",Aop("+",Var("minus1"),Var("minus2"))), // minus2 := minus1 + minus2; |
205 Assign("minus2",Aop("+",Var("minus1"),Var("minus2"))), |
196 Assign("minus1",Var("temp")), // minus1 := temp; |
206 // minus2 := minus1 + minus2; |
197 Assign("n",Aop("-",Var("n"),Num(1))))), // n := n - 1 }; |
207 Assign("minus1",Var("temp")), // minus1 := temp; |
|
208 Assign("n",Aop("-",Var("n"),Num(1))))), // n := n - 1 }; |
198 Write("minus1")) // write minus1 |
209 Write("minus1")) // write minus1 |
199 |
210 |
200 |
211 |
201 |
212 |
202 // prints out the JVM-assembly program |
213 // prints out the JVM-assembly program |