79 // convenient string interpolations |
79 // convenient string interpolations |
80 // for instructions and labels |
80 // for instructions and labels |
81 |
81 |
82 extension (sc: StringContext) { |
82 extension (sc: StringContext) { |
83 def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" |
83 def i(args: Any*): String = " " ++ sc.s(args:_*) ++ "\n" |
84 def l(args: Any*): String = sc.s(args:_*) ++ ":\n" |
84 def l(args: Any*): String = sc.s(args:_*) ++ ":" |
85 } |
85 } |
86 |
86 |
87 // this allows us to write things like |
87 // this allows us to write things like |
88 // i"iadd" and l"Label" |
88 // i"iadd" and l"Label" |
89 |
89 |
129 case If(b, bl1, bl2) => { |
129 case If(b, bl1, bl2) => { |
130 val if_else = Fresh("If_else") |
130 val if_else = Fresh("If_else") |
131 val if_end = Fresh("If_end") |
131 val if_end = Fresh("If_end") |
132 val (instrs1, env1) = compile_block(bl1, env) |
132 val (instrs1, env1) = compile_block(bl1, env) |
133 val (instrs2, env2) = compile_block(bl2, env1) |
133 val (instrs2, env2) = compile_block(bl2, env1) |
134 (compile_bexp(b, env, if_else) ++ |
134 (s"""|${compile_bexp(b, env, if_else)} |
135 instrs1 ++ |
135 |${instrs1} |
136 i"goto $if_end" ++ |
136 |${i"goto $if_end"} |
137 l"$if_else" ++ |
137 |${l"$if_else"} |
138 instrs2 ++ |
138 |${instrs2} |
139 l"$if_end", env2) |
139 |${l"$if_end"}""".stripMargin, env2) |
140 } |
140 } |
141 case While(b, bl) => { |
141 case While(b, bl) => { |
142 val loop_begin = Fresh("Loop_begin") |
142 val loop_begin = Fresh("Loop_begin") |
143 val loop_end = Fresh("Loop_end") |
143 val loop_end = Fresh("Loop_end") |
144 val (instrs1, env1) = compile_block(bl, env) |
144 val (instrs1, env1) = compile_block(bl, env) |
145 (l"$loop_begin" ++ |
145 (s"""|${l"$loop_begin"} |
146 compile_bexp(b, env, loop_end) ++ |
146 |${compile_bexp(b, env, loop_end)} |
147 instrs1 ++ |
147 |$instrs1 |
148 i"goto $loop_begin" ++ |
148 |${i"goto $loop_begin"} |
149 l"$loop_end", env1) |
149 |${l"$loop_end"}""".stripMargin, env1) |
150 } |
150 } |
151 case Write(x) => |
151 case Write(x) => |
152 (i"iload ${env(x)} \t\t; $x" ++ |
152 (i"iload ${env(x)} \t\t; $x" ++ |
153 i"invokestatic XXX/XXX/write(I)V", env) |
153 i"invokestatic XXX/XXX/write(I)V", env) |
154 } |
154 } |
164 } |
164 } |
165 |
165 |
166 // main compilation function for blocks |
166 // main compilation function for blocks |
167 def compile(bl: Block, class_name: String) : String = { |
167 def compile(bl: Block, class_name: String) : String = { |
168 val instructions = compile_block(bl, Map.empty)._1 |
168 val instructions = compile_block(bl, Map.empty)._1 |
169 (beginning ++ instructions ++ ending).replaceAllLiterally("XXX", class_name) |
169 (beginning ++ instructions ++ ending).replace("XXX", class_name) |
170 } |
170 } |
171 |
171 |
172 |
172 |
173 |
173 |
174 |
174 |