git @ Cat's Eye Technologies SixtyPical / 31a16ed
Merge pull request #7 from catseye/routine-static-storage Routine static storage Chris Pressey authored 3 years ago GitHub committed 3 years ago
8 changed file(s) with 281 addition(s) and 88 deletion(s). Raw diff Collapse all Expand all
7373
7474 ### And at some point...
7575
76 * `const`s, that can be used in defining the size of tables, etc
77 * Remove the need for `forward` and `vector () table` (make grammar changes)
78 * Tests, and implementation, ensuring a routine can be assigned to a vector of "wider" type
7679 * Check that the buffer being read or written to through pointer, appears in approporiate inputs or outputs set.
7780 * `interrupt` routines -- to indicate that "the supervisor" has stored values on the stack, so we can trash them.
7881 * error messages that include the line number of the source code
7982 * add absolute addressing in shl/shr, absolute-indexed for add, sub, etc.
8083 * automatic tail-call optimization (could be tricky, w/constraints?)
81 * `st a, [ptr] + y`, possibly `ld x, [ptr] + y`, possibly `st x, [ptr] + y`
84 * possibly `ld x, [ptr] + y`, possibly `st x, [ptr] + y`
8285 * Maybe even `copy [ptra] + y, [ptrb] + y`, which can be compiled to indirect LDA then indirect STA!
8386
8487 Things it will not do
5050
5151 class IncompatibleConstraintsError(ConstraintsError):
5252 pass
53
54
55 def routine_has_static(routine, ref):
56 if not hasattr(routine, 'statics'):
57 return False
58 return ref in [static.location for static in routine.statics]
5359
5460
5561 class Context(object):
111117 def assert_meaningful(self, *refs, **kwargs):
112118 exception_class = kwargs.get('exception_class', UnmeaningfulReadError)
113119 for ref in refs:
120 # statics are always meaningful
121 if routine_has_static(self.routine, ref):
122 continue
114123 if ref.is_constant() or ref in self.routines:
115124 pass
116125 elif isinstance(ref, LocationRef):
128137 def assert_writeable(self, *refs, **kwargs):
129138 exception_class = kwargs.get('exception_class', ForbiddenWriteError)
130139 for ref in refs:
140 # statics are always writeable
141 if routine_has_static(self.routine, ref):
142 continue
131143 if ref not in self._writeable:
132144 message = '%s in %s' % (ref.name, self.routine.name)
133145 if kwargs.get('message'):
230242 for ref in type_.outputs:
231243 context.assert_meaningful(ref, exception_class=UnmeaningfulOutputError)
232244 for ref in context.each_touched():
233 if ref not in type_.outputs and ref not in type_.trashes:
245 if ref not in type_.outputs and ref not in type_.trashes and not routine_has_static(routine, ref):
234246 message = '%s in %s' % (ref.name, routine.name)
235247 raise ForbiddenWriteError(message)
236248 self.current_routine = None
2727 class Compiler(object):
2828 def __init__(self, emitter):
2929 self.emitter = emitter
30 self.routines = {}
31 self.labels = {}
32 self.trampolines = {} # Location -> Label
30 self.routines = {} # routine.name -> Routine
31 self.routine_statics = {} # routine.name -> { static.name -> Label }
32 self.labels = {} # global.name -> Label ("global" includes routines)
33 self.trampolines = {} # Location -> Label
34 self.current_routine = None
3335
3436 # helper methods
3537
4143 else:
4244 raise NotImplementedError(index)
4345
46 def compute_length_of_defn(self, defn):
47 length = None
48 type_ = defn.location.type
49 if type_ == TYPE_BYTE:
50 length = 1
51 elif type_ == TYPE_WORD or isinstance(type_, (PointerType, VectorType)):
52 length = 2
53 elif isinstance(type_, TableType):
54 length = type_.size * (1 if type_.of_type == TYPE_BYTE else 2)
55 elif isinstance(type_, BufferType):
56 length = type_.size
57 if length is None:
58 raise NotImplementedError("Need size for type {}".format(type_))
59 return length
60
61 def get_label(self, name):
62 if self.current_routine:
63 static_label = self.routine_statics.get(self.current_routine.name, {}).get(name)
64 if static_label:
65 return static_label
66 return self.labels[name]
67
4468 # visitor methods
4569
4670 def compile_program(self, program):
4771 assert isinstance(program, Program)
4872
73 defn_labels = []
74
4975 for defn in program.defns:
50 # compute length of memory pointed to. this is awful.
51 length = None
52 type_ = defn.location.type
53 if type_ == TYPE_BYTE:
54 length = 1
55 elif type_ == TYPE_WORD or isinstance(type_, (PointerType, VectorType)):
56 length = 2
57 elif isinstance(type_, TableType):
58 length = type_.size * (1 if type_.of_type == TYPE_BYTE else 2)
59 elif isinstance(type_, BufferType):
60 length = type_.size
61 if length is None:
62 raise NotImplementedError("Need size for type {}".format(type_))
63 self.labels[defn.name] = Label(defn.name, addr=defn.addr, length=length)
76 length = self.compute_length_of_defn(defn)
77 label = Label(defn.name, addr=defn.addr, length=length)
78 self.labels[defn.name] = label
79 defn_labels.append((defn, label))
6480
6581 for routine in program.routines:
6682 self.routines[routine.name] = routine
6985 label.set_addr(routine.addr)
7086 self.labels[routine.name] = label
7187
88 if hasattr(routine, 'statics'):
89 static_labels = {}
90 for defn in routine.statics:
91 length = self.compute_length_of_defn(defn)
92 label = Label(defn.name, addr=defn.addr, length=length)
93 static_labels[defn.name] = label
94 defn_labels.append((defn, label))
95 self.routine_statics[routine.name] = static_labels
96
7297 self.compile_routine(self.routines['main'])
7398 for routine in program.routines:
7499 if routine.name != 'main':
76101
77102 for location, label in self.trampolines.iteritems():
78103 self.emitter.resolve_label(label)
79 self.emitter.emit(JMP(Indirect(self.labels[location.name])))
104 self.emitter.emit(JMP(Indirect(self.get_label(location.name))))
80105 self.emitter.emit(RTS())
81106
82107 # initialized data
83 for defn in program.defns:
108 for defn, label in defn_labels:
84109 if defn.initial is not None:
85 label = self.labels[defn.name]
86110 initial_data = None
87111 type_ = defn.location.type
88112 if type_ == TYPE_BYTE:
98122 self.emitter.emit(initial_data)
99123
100124 # uninitialized, "BSS" data
101 for defn in program.defns:
125 for defn, label in defn_labels:
102126 if defn.initial is None and defn.addr is None:
103 label = self.labels[defn.name]
104127 self.emitter.resolve_bss_label(label)
105128
106
107129 def compile_routine(self, routine):
130 self.current_routine = routine
108131 assert isinstance(routine, Routine)
109132 if routine.block:
110 self.emitter.resolve_label(self.labels[routine.name])
133 self.emitter.resolve_label(self.get_label(routine.name))
111134 self.compile_block(routine.block)
112135 self.emitter.emit(RTS())
136 self.current_routine = None
113137
114138 def compile_block(self, block):
115139 assert isinstance(block, Block)
131155 elif isinstance(src, ConstantRef):
132156 self.emitter.emit(LDA(Immediate(Byte(src.value))))
133157 elif isinstance(src, IndexedRef) and src.index == REG_X:
134 self.emitter.emit(LDA(AbsoluteX(self.labels[src.name])))
158 self.emitter.emit(LDA(AbsoluteX(self.get_label(src.name))))
135159 elif isinstance(src, IndexedRef) and src.index == REG_Y:
136 self.emitter.emit(LDA(AbsoluteY(self.labels[src.name])))
160 self.emitter.emit(LDA(AbsoluteY(self.get_label(src.name))))
137161 elif isinstance(src, IndirectRef) and isinstance(src.ref.type, PointerType):
138 self.emitter.emit(LDA(IndirectY(self.labels[src.ref.name])))
139 else:
140 self.emitter.emit(LDA(Absolute(self.labels[src.name])))
162 self.emitter.emit(LDA(IndirectY(self.get_label(src.ref.name))))
163 else:
164 self.emitter.emit(LDA(Absolute(self.get_label(src.name))))
141165 elif dest == REG_X:
142166 if src == REG_A:
143167 self.emitter.emit(TAX())
144168 elif isinstance(src, ConstantRef):
145169 self.emitter.emit(LDX(Immediate(Byte(src.value))))
146170 elif isinstance(src, IndexedRef) and src.index == REG_Y:
147 self.emitter.emit(LDX(AbsoluteY(self.labels[src.name])))
148 else:
149 self.emitter.emit(LDX(Absolute(self.labels[src.name])))
171 self.emitter.emit(LDX(AbsoluteY(self.get_label(src.name))))
172 else:
173 self.emitter.emit(LDX(Absolute(self.get_label(src.name))))
150174 elif dest == REG_Y:
151175 if src == REG_A:
152176 self.emitter.emit(TAY())
153177 elif isinstance(src, ConstantRef):
154178 self.emitter.emit(LDY(Immediate(Byte(src.value))))
155179 elif isinstance(src, IndexedRef) and src.index == REG_X:
156 self.emitter.emit(LDY(AbsoluteX(self.labels[src.name])))
157 else:
158 self.emitter.emit(LDY(Absolute(self.labels[src.name])))
180 self.emitter.emit(LDY(AbsoluteX(self.get_label(src.name))))
181 else:
182 self.emitter.emit(LDY(Absolute(self.get_label(src.name))))
159183 else:
160184 raise UnsupportedOpcodeError(instr)
161185 elif opcode == 'st':
175199 REG_X: AbsoluteX,
176200 REG_Y: AbsoluteY,
177201 }[dest.index]
178 label = self.labels[dest.ref.name]
202 label = self.get_label(dest.ref.name)
179203 elif isinstance(dest, IndirectRef) and isinstance(dest.ref.type, PointerType):
180204 mode_cls = IndirectY
181 label = self.labels[dest.ref.name]
205 label = self.get_label(dest.ref.name)
182206 else:
183207 mode_cls = Absolute
184 label = self.labels[dest.name]
208 label = self.get_label(dest.name)
185209
186210 if op_cls is None or mode_cls is None:
187211 raise UnsupportedOpcodeError(instr)
191215 if isinstance(src, ConstantRef):
192216 self.emitter.emit(ADC(Immediate(Byte(src.value))))
193217 else:
194 self.emitter.emit(ADC(Absolute(self.labels[src.name])))
218 self.emitter.emit(ADC(Absolute(self.get_label(src.name))))
195219 elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
196220 if isinstance(src, ConstantRef):
197 dest_label = self.labels[dest.name]
221 dest_label = self.get_label(dest.name)
198222 self.emitter.emit(LDA(Absolute(dest_label)))
199223 self.emitter.emit(ADC(Immediate(Byte(src.low_byte()))))
200224 self.emitter.emit(STA(Absolute(dest_label)))
202226 self.emitter.emit(ADC(Immediate(Byte(src.high_byte()))))
203227 self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
204228 elif isinstance(src, LocationRef):
205 src_label = self.labels[src.name]
206 dest_label = self.labels[dest.name]
229 src_label = self.get_label(src.name)
230 dest_label = self.get_label(dest.name)
207231 self.emitter.emit(LDA(Absolute(dest_label)))
208232 self.emitter.emit(ADC(Absolute(src_label)))
209233 self.emitter.emit(STA(Absolute(dest_label)))
214238 raise UnsupportedOpcodeError(instr)
215239 elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and isinstance(dest.type, PointerType):
216240 if isinstance(src, ConstantRef):
217 dest_label = self.labels[dest.name]
241 dest_label = self.get_label(dest.name)
218242 self.emitter.emit(LDA(ZeroPage(dest_label)))
219243 self.emitter.emit(ADC(Immediate(Byte(src.low_byte()))))
220244 self.emitter.emit(STA(ZeroPage(dest_label)))
222246 self.emitter.emit(ADC(Immediate(Byte(src.high_byte()))))
223247 self.emitter.emit(STA(ZeroPage(Offset(dest_label, 1))))
224248 elif isinstance(src, LocationRef):
225 src_label = self.labels[src.name]
226 dest_label = self.labels[dest.name]
249 src_label = self.get_label(src.name)
250 dest_label = self.get_label(dest.name)
227251 self.emitter.emit(LDA(ZeroPage(dest_label)))
228252 self.emitter.emit(ADC(Absolute(src_label)))
229253 self.emitter.emit(STA(ZeroPage(dest_label)))
239263 if isinstance(src, ConstantRef):
240264 self.emitter.emit(SBC(Immediate(Byte(src.value))))
241265 else:
242 self.emitter.emit(SBC(Absolute(self.labels[src.name])))
266 self.emitter.emit(SBC(Absolute(self.get_label(src.name))))
243267 elif isinstance(dest, LocationRef) and src.type == TYPE_WORD and dest.type == TYPE_WORD:
244268 if isinstance(src, ConstantRef):
245 dest_label = self.labels[dest.name]
269 dest_label = self.get_label(dest.name)
246270 self.emitter.emit(LDA(Absolute(dest_label)))
247271 self.emitter.emit(SBC(Immediate(Byte(src.low_byte()))))
248272 self.emitter.emit(STA(Absolute(dest_label)))
250274 self.emitter.emit(SBC(Immediate(Byte(src.high_byte()))))
251275 self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
252276 elif isinstance(src, LocationRef):
253 src_label = self.labels[src.name]
254 dest_label = self.labels[dest.name]
277 src_label = self.get_label(src.name)
278 dest_label = self.get_label(dest.name)
255279 self.emitter.emit(LDA(Absolute(dest_label)))
256280 self.emitter.emit(SBC(Absolute(src_label)))
257281 self.emitter.emit(STA(Absolute(dest_label)))
268292 elif dest == REG_Y:
269293 self.emitter.emit(INY())
270294 else:
271 self.emitter.emit(INC(Absolute(self.labels[dest.name])))
295 self.emitter.emit(INC(Absolute(self.get_label(dest.name))))
272296 elif opcode == 'dec':
273297 if dest == REG_X:
274298 self.emitter.emit(DEX())
275299 elif dest == REG_Y:
276300 self.emitter.emit(DEY())
277301 else:
278 self.emitter.emit(DEC(Absolute(self.labels[dest.name])))
302 self.emitter.emit(DEC(Absolute(self.get_label(dest.name))))
279303 elif opcode == 'cmp':
280304 cls = {
281305 'a': CMP,
287311 if isinstance(src, ConstantRef):
288312 self.emitter.emit(cls(Immediate(Byte(src.value))))
289313 else:
290 self.emitter.emit(cls(Absolute(self.labels[src.name])))
314 self.emitter.emit(cls(Absolute(self.get_label(src.name))))
291315 elif opcode in ('and', 'or', 'xor',):
292316 cls = {
293317 'and': AND,
298322 if isinstance(src, ConstantRef):
299323 self.emitter.emit(cls(Immediate(Byte(src.value))))
300324 else:
301 self.emitter.emit(cls(Absolute(self.labels[src.name])))
325 self.emitter.emit(cls(Absolute(self.get_label(src.name))))
302326 else:
303327 raise UnsupportedOpcodeError(instr)
304328 elif opcode in ('shl', 'shr'):
312336 raise UnsupportedOpcodeError(instr)
313337 elif opcode == 'call':
314338 location = instr.location
315 label = self.labels[instr.location.name]
339 label = self.get_label(instr.location.name)
316340 if isinstance(location.type, RoutineType):
317341 self.emitter.emit(JSR(Absolute(label)))
318342 elif isinstance(location.type, VectorType):
324348 raise NotImplementedError
325349 elif opcode == 'goto':
326350 location = instr.location
327 label = self.labels[instr.location.name]
351 label = self.get_label(instr.location.name)
328352 if isinstance(location.type, RoutineType):
329353 self.emitter.emit(JMP(Absolute(label)))
330354 elif isinstance(location.type, VectorType):
382406 if isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndirectRef):
383407 if src.type == TYPE_BYTE and isinstance(dest.ref.type, PointerType):
384408 if isinstance(src, ConstantRef):
385 dest_label = self.labels[dest.ref.name]
409 dest_label = self.get_label(dest.ref.name)
386410 self.emitter.emit(LDA(Immediate(Byte(src.value))))
387411 self.emitter.emit(STA(IndirectY(dest_label)))
388412 elif isinstance(src, LocationRef):
389 src_label = self.labels[src.name]
390 dest_label = self.labels[dest.ref.name]
413 src_label = self.get_label(src.name)
414 dest_label = self.get_label(dest.ref.name)
391415 self.emitter.emit(LDA(Absolute(src_label)))
392416 self.emitter.emit(STA(IndirectY(dest_label)))
393417 else:
396420 raise NotImplementedError((src, dest))
397421 elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef):
398422 if dest.type == TYPE_BYTE and isinstance(src.ref.type, PointerType):
399 src_label = self.labels[src.ref.name]
400 dest_label = self.labels[dest.name]
423 src_label = self.get_label(src.ref.name)
424 dest_label = self.get_label(dest.name)
401425 self.emitter.emit(LDA(IndirectY(src_label)))
402426 self.emitter.emit(STA(Absolute(dest_label)))
403427 else:
404428 raise NotImplementedError((src, dest))
405429 elif isinstance(src, AddressRef) and isinstance(dest, LocationRef) and \
406430 isinstance(src.ref.type, BufferType) and isinstance(dest.type, PointerType):
407 src_label = self.labels[src.ref.name]
408 dest_label = self.labels[dest.name]
431 src_label = self.get_label(src.ref.name)
432 dest_label = self.get_label(dest.name)
409433 self.emitter.emit(LDA(Immediate(HighAddressByte(src_label))))
410434 self.emitter.emit(STA(ZeroPage(dest_label)))
411435 self.emitter.emit(LDA(Immediate(LowAddressByte(src_label))))
412436 self.emitter.emit(STA(ZeroPage(Offset(dest_label, 1))))
413437 elif isinstance(src, LocationRef) and isinstance(dest, IndexedRef):
414438 if src.type == TYPE_WORD and TableType.is_a_table_type(dest.ref.type, TYPE_WORD):
415 src_label = self.labels[src.name]
416 dest_label = self.labels[dest.ref.name]
439 src_label = self.get_label(src.name)
440 dest_label = self.get_label(dest.ref.name)
417441 self.emitter.emit(LDA(Absolute(src_label)))
418442 self.emitter.emit(STA(self.addressing_mode_for_index(dest.index)(dest_label)))
419443 self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
420444 self.emitter.emit(STA(self.addressing_mode_for_index(dest.index)(Offset(dest_label, 256))))
421445 elif isinstance(src.type, VectorType) and isinstance(dest.ref.type, TableType) and isinstance(dest.ref.type.of_type, VectorType):
422446 # FIXME this is the exact same as above - can this be simplified?
423 src_label = self.labels[src.name]
424 dest_label = self.labels[dest.ref.name]
447 src_label = self.get_label(src.name)
448 dest_label = self.get_label(dest.ref.name)
425449 self.emitter.emit(LDA(Absolute(src_label)))
426450 self.emitter.emit(STA(self.addressing_mode_for_index(dest.index)(dest_label)))
427451 self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
428452 self.emitter.emit(STA(self.addressing_mode_for_index(dest.index)(Offset(dest_label, 256))))
429453 elif isinstance(src.type, RoutineType) and isinstance(dest.ref.type, TableType) and isinstance(dest.ref.type.of_type, VectorType):
430 src_label = self.labels[src.name]
431 dest_label = self.labels[dest.ref.name]
454 src_label = self.get_label(src.name)
455 dest_label = self.get_label(dest.ref.name)
432456 self.emitter.emit(LDA(Immediate(HighAddressByte(src_label))))
433457 self.emitter.emit(STA(self.addressing_mode_for_index(dest.index)(dest_label)))
434458 self.emitter.emit(LDA(Immediate(LowAddressByte(src_label))))
437461 raise NotImplementedError
438462 elif isinstance(src, ConstantRef) and isinstance(dest, IndexedRef):
439463 if src.type == TYPE_WORD and TableType.is_a_table_type(dest.ref.type, TYPE_WORD):
440 dest_label = self.labels[dest.ref.name]
464 dest_label = self.get_label(dest.ref.name)
441465 self.emitter.emit(LDA(Immediate(Byte(src.low_byte()))))
442466 self.emitter.emit(STA(self.addressing_mode_for_index(dest.index)(dest_label)))
443467 self.emitter.emit(LDA(Immediate(Byte(src.high_byte()))))
446470 raise NotImplementedError
447471 elif isinstance(src, IndexedRef) and isinstance(dest, LocationRef):
448472 if TableType.is_a_table_type(src.ref.type, TYPE_WORD) and dest.type == TYPE_WORD:
449 src_label = self.labels[src.ref.name]
450 dest_label = self.labels[dest.name]
473 src_label = self.get_label(src.ref.name)
474 dest_label = self.get_label(dest.name)
451475 self.emitter.emit(LDA(self.addressing_mode_for_index(src.index)(src_label)))
452476 self.emitter.emit(STA(Absolute(dest_label)))
453477 self.emitter.emit(LDA(self.addressing_mode_for_index(src.index)(Offset(src_label, 256))))
454478 self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
455479 elif isinstance(dest.type, VectorType) and isinstance(src.ref.type, TableType) and isinstance(src.ref.type.of_type, VectorType):
456480 # FIXME this is the exact same as above - can this be simplified?
457 src_label = self.labels[src.ref.name]
458 dest_label = self.labels[dest.name]
481 src_label = self.get_label(src.ref.name)
482 dest_label = self.get_label(dest.name)
459483 self.emitter.emit(LDA(self.addressing_mode_for_index(src.index)(src_label)))
460484 self.emitter.emit(STA(Absolute(dest_label)))
461485 self.emitter.emit(LDA(self.addressing_mode_for_index(src.index)(Offset(src_label, 256))))
469493 if isinstance(src, ConstantRef):
470494 raise NotImplementedError
471495 else:
472 src_label = self.labels[src.name]
473 dest_label = self.labels[dest.name]
496 src_label = self.get_label(src.name)
497 dest_label = self.get_label(dest.name)
474498 self.emitter.emit(LDA(Absolute(src_label)))
475499 self.emitter.emit(STA(Absolute(dest_label)))
476500 elif src.type == TYPE_WORD and dest.type == TYPE_WORD:
477501 if isinstance(src, ConstantRef):
478 dest_label = self.labels[dest.name]
502 dest_label = self.get_label(dest.name)
479503 self.emitter.emit(LDA(Immediate(Byte(src.low_byte()))))
480504 self.emitter.emit(STA(Absolute(dest_label)))
481505 self.emitter.emit(LDA(Immediate(Byte(src.high_byte()))))
482506 self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
483507 else:
484 src_label = self.labels[src.name]
485 dest_label = self.labels[dest.name]
508 src_label = self.get_label(src.name)
509 dest_label = self.get_label(dest.name)
486510 self.emitter.emit(LDA(Absolute(src_label)))
487511 self.emitter.emit(STA(Absolute(dest_label)))
488512 self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
489513 self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
490514 elif isinstance(src.type, VectorType) and isinstance(dest.type, VectorType):
491 src_label = self.labels[src.name]
492 dest_label = self.labels[dest.name]
515 src_label = self.get_label(src.name)
516 dest_label = self.get_label(dest.name)
493517 self.emitter.emit(LDA(Absolute(src_label)))
494518 self.emitter.emit(STA(Absolute(dest_label)))
495519 self.emitter.emit(LDA(Absolute(Offset(src_label, 1))))
496520 self.emitter.emit(STA(Absolute(Offset(dest_label, 1))))
497521 elif isinstance(src.type, RoutineType) and isinstance(dest.type, VectorType):
498 src_label = self.labels[src.name]
499 dest_label = self.labels[dest.name]
522 src_label = self.get_label(src.name)
523 dest_label = self.get_label(dest.name)
500524 self.emitter.emit(LDA(Immediate(HighAddressByte(src_label))))
501525 self.emitter.emit(STA(Absolute(dest_label)))
502526 self.emitter.emit(LDA(Immediate(LowAddressByte(src_label))))
144144 # just to be sure.
145145 equal = isinstance(other, self.__class__) and other.name == self.name
146146 if equal:
147 assert other.type == self.type
147 assert other.type == self.type, repr((self, other))
148148 return equal
149149
150150 def __hash__(self):
1313 self.ast_node = ast_node
1414 self.model = model
1515
16 def __repr__(self):
17 return "%s(%r, %r)" % (self.__class__.__name__, self.ast_node, self.model)
18
1619
1720 class Parser(object):
1821 def __init__(self, text):
1922 self.scanner = Scanner(text)
20 self.symbols = {} # token -> SymEntry
21 self.typedefs = {} # token -> Type AST
23 self.symbols = {} # token -> SymEntry
24 self.current_statics = {} # token -> SymEntry
25 self.typedefs = {} # token -> Type AST
2226 for token in ('a', 'x', 'y'):
2327 self.symbols[token] = SymEntry(None, LocationRef(TYPE_BYTE, token))
2428 for token in ('c', 'z', 'n', 'v'):
2630 self.backpatch_instrs = []
2731
2832 def lookup(self, name):
33 if name in self.current_statics:
34 return self.current_statics[name].model
2935 if name not in self.symbols:
3036 raise SyntaxError('Undefined symbol "%s"' % name)
3137 return self.symbols[name].model
208214 type_ = self.defn_type()
209215 if not isinstance(type_, RoutineType):
210216 raise SyntaxError("Can only define a routine, not %r" % type_)
217 statics = []
211218 if self.scanner.consume('@'):
212219 self.scanner.check_type('integer literal')
213220 block = None
214221 addr = int(self.scanner.token)
215222 self.scanner.scan()
216223 else:
224 statics = self.statics()
225
226 self.current_statics = self.compose_statics_dict(statics)
217227 block = self.block()
228 self.current_statics = {}
229
218230 addr = None
219231 location = LocationRef(type_, name)
220232 return Routine(
221233 name=name, block=block, addr=addr,
222 location=location
234 location=location, statics=statics
223235 )
236
237 def compose_statics_dict(self, statics):
238 c = {}
239 for defn in statics:
240 name = defn.name
241 if name in self.symbols or name in self.current_statics:
242 raise SyntaxError('Symbol "%s" already declared' % name)
243 c[name] = SymEntry(defn, defn.location)
244 return c
224245
225246 def labels(self):
226247 accum = []
282303 index = self.locexpr()
283304 loc = IndexedRef(loc, index)
284305 return loc
306
307 def statics(self):
308 defns = []
309 while self.scanner.consume('static'):
310 defn = self.defn()
311 if defn.initial is None:
312 raise SyntaxError("Static definition {} must have initial value".format(defn))
313 defns.append(defn)
314 return defns
285315
286316 def block(self):
287317 instrs = []
22822282 | copy foo, vec
22832283 | }
22842284 = ok
2285
2286 ### static ###
2287
2288 When memory locations are defined static to a routine, they cannot be
2289 directly input, nor directly output; and since they are always initialized,
2290 they cannot be trashed. Thus, they really don't participate in the analysis.
2291
2292 | define foo routine
2293 | inputs x
2294 | outputs x
2295 | trashes z, n
2296 | static byte t : 0
2297 | {
2298 | st x, t
2299 | inc t
2300 | ld x, t
2301 | }
2302 |
2303 | define main routine
2304 | trashes a, x, z, n
2305 | static byte t : 0
2306 | {
2307 | ld x, t
2308 | call foo
2309 | }
2310 = ok
945945 = $080D TAX
946946 = $080E LDA #$00
947947 = $0810 RTS
948
949 ### static ###
950
951 Memory locations defined static to a routine are allocated
952 just the same as initialized global storage locations are.
953
954 | define foo routine
955 | inputs x
956 | outputs x
957 | trashes z, n
958 | static byte t : 255
959 | {
960 | st x, t
961 | inc t
962 | ld x, t
963 | }
964 |
965 | define main routine
966 | trashes a, x, z, n
967 | static byte t : 7
968 | {
969 | ld x, t
970 | call foo
971 | }
972 = $080D LDX $081F
973 = $0810 JSR $0814
974 = $0813 RTS
975 = $0814 STX $081E
976 = $0817 INC $081E
977 = $081A LDX $081E
978 = $081D RTS
979 = $081E .byte $FF
980 = $081F .byte $07
528528 | ld a, 0
529529 | }
530530 ? SyntaxError
531
532 Memory locations can be defined static to a routine.
533
534 | define foo routine
535 | inputs x
536 | outputs x
537 | trashes z, n
538 | static byte t : 0
539 | {
540 | st x, t
541 | inc t
542 | ld x, t
543 | }
544 |
545 | define main routine
546 | trashes a, x, z, n
547 | static byte t : 0
548 | {
549 | ld x, t
550 | call foo
551 | }
552 = ok
553
554 Static memory locations must always be given an initial value.
555
556 | define main routine
557 | inputs x
558 | outputs x
559 | trashes z, n
560 | static byte t
561 | {
562 | st x, t
563 | inc t
564 | ld x, t
565 | }
566 ? SyntaxError
567
568 Name of a static cannot shadow an existing global or static.
569
570 | byte t
571 |
572 | define main routine
573 | inputs x
574 | outputs x
575 | trashes z, n
576 | static byte t
577 | {
578 | st x, t
579 | inc t
580 | ld x, t
581 | }
582 ? SyntaxError
583
584 | define main routine
585 | inputs x
586 | outputs x
587 | trashes z, n
588 | static byte t
589 | static byte t
590 | {
591 | st x, t
592 | inc t
593 | ld x, t
594 | }
595 ? SyntaxError