Simplify and improve Emitter abstraction.
Chris Pressey
3 years ago
8 | 8 | TableType, PointerType, RoutineType, VectorType, |
9 | 9 | REG_A, REG_X, REG_Y, FLAG_C |
10 | 10 | ) |
11 | from sixtypical.emitter import Byte, Word, Table, Label, Offset, LowAddressByte, HighAddressByte, Emitter | |
11 | from sixtypical.emitter import Byte, Word, Table, Label, Offset, LowAddressByte, HighAddressByte | |
12 | 12 | from sixtypical.gen6502 import ( |
13 | 13 | Immediate, Absolute, AbsoluteX, AbsoluteY, ZeroPage, Indirect, IndirectY, Relative, |
14 | 14 | LDA, LDX, LDY, STA, STX, STY, |
159 | 159 | assert isinstance(routine, Routine) |
160 | 160 | |
161 | 161 | self.current_routine = routine |
162 | saved_emitter = self.emitter | |
163 | self.emitter = Emitter(saved_emitter.addr) | |
162 | ||
164 | 163 | if routine.block: |
165 | 164 | self.emitter.resolve_label(self.get_label(routine.name)) |
166 | 165 | self.compile_block(routine.block) |
167 | 166 | |
168 | 167 | needs_rts = True |
169 | if self.emitter.accum: | |
170 | last_op = self.emitter.accum[-1] | |
171 | if isinstance(last_op, JMP): | |
172 | needs_rts = False | |
173 | if isinstance(last_op.operand, Absolute): | |
174 | if isinstance(last_op.operand.value, Label): | |
175 | if next_routine and last_op.operand.value.name == next_routine.name: | |
176 | self.emitter.retract() | |
168 | last_op = self.emitter.get_tail() | |
169 | if isinstance(last_op, JMP): | |
170 | needs_rts = False | |
171 | if isinstance(last_op.operand, Absolute): | |
172 | if isinstance(last_op.operand.value, Label): | |
173 | if next_routine and last_op.operand.value.name == next_routine.name: | |
174 | self.emitter.retract() | |
177 | 175 | |
178 | 176 | if needs_rts: |
179 | 177 | self.emitter.emit(RTS()) |
180 | 178 | |
181 | saved_emitter.emit(*self.emitter.accum) | |
182 | self.emitter = saved_emitter | |
183 | 179 | self.current_routine = None |
184 | 180 | |
185 | 181 | def compile_block(self, block): |