git @ Cat's Eye Technologies SixtyPical / f6fa1ec
Remove need for `forward` keyword in forward reference in `copy`. Chris Pressey 3 years ago
6 changed file(s) with 67 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
99 * Implements the "union rule for trashes" when analyzing `if` blocks.
1010 * Even if we `goto` another routine, we can't trash an output.
1111 * `static` storage locations local to routines can now be defined within routines.
12 * Small grammar change that obviates the need for parentheses in the type expression
13 `vector (routine ...) table`.
12 * Small grammar changes that obviate:
13 * the need for parentheses in the type expression `vector (routine ...) table`#
14 * the need for `forward` in forward references in source of `copy` instruction
1415 * Fixed bug where `trash` was not marking the location as being virtually altered.
1516
1617 0.11
6666 ### And at some point...
6767
6868 * `const`s that can be used in defining the size of tables, etc.
69 * Remove the need for `forward` (lots of backpatching)
7069 * Tests, and implementation, ensuring a routine can be assigned to a vector of "wider" type
7170 * Check that the buffer being read or written to through pointer, appears in approporiate inputs or outputs set.
7271 (Associate each pointer with the buffer it points into.)
248248 repeat {
249249 copy pos, actor_pos + y
250250 copy word 40, actor_delta + y
251 copy forward enemy_logic, actor_logic + y
251 copy enemy_logic, actor_logic + y
252252
253253 st off, c
254254 add pos, word 7
260260 ld y, 0
261261 copy word 0, actor_pos + y
262262 copy word 0, actor_delta + y
263 copy forward player_logic, actor_logic + y
263 copy player_logic, actor_logic + y
264264 }
265265
266266 // ----------------------------------------------------------------
400400 if c {
401401 call clear_screen
402402 call init_game
403 copy forward game_state_play, dispatch_game_state
403 copy game_state_play, dispatch_game_state
404404 }
405405
406406 goto save_cinv
422422 if c {
423423 // Player died! Want no dead! Break out of the loop (this is a bit awkward.)
424424 call clear_screen
425 copy forward game_state_game_over, dispatch_game_state
425 copy game_state_game_over, dispatch_game_state
426426 ld x, 15
427427 } else {
428428 ld x, save_x
2929 self.symbols[token] = SymEntry(None, LocationRef(TYPE_BIT, token))
3030 self.backpatch_instrs = []
3131
32 def lookup(self, name):
32 def soft_lookup(self, name):
3333 if name in self.current_statics:
3434 return self.current_statics[name].model
35 if name not in self.symbols:
35 if name in self.symbols:
36 return self.symbols[name].model
37 return None
38
39 def lookup(self, name):
40 model = self.soft_lookup(name)
41 if model is None:
3642 raise SyntaxError('Undefined symbol "%s"' % name)
37 return self.symbols[name].model
43 return model
3844
3945 # --- grammar productions
4046
269275 accum.append(self.locexpr())
270276 return accum
271277
272 def locexpr(self):
278 def locexpr(self, forward=False):
273279 if self.scanner.token in ('on', 'off'):
274280 loc = ConstantRef(TYPE_BIT, 1 if self.scanner.token == 'on' else 0)
275281 self.scanner.scan()
284290 loc = ConstantRef(TYPE_WORD, int(self.scanner.token))
285291 self.scanner.scan()
286292 return loc
293 elif forward:
294 name = self.scanner.token
295 self.scanner.scan()
296 loc = self.soft_lookup(name)
297 if loc is not None:
298 return loc
299 else:
300 return name
287301 else:
288302 loc = self.lookup(self.scanner.token)
289303 self.scanner.scan()
290304 return loc
291305
292 def indlocexpr(self):
293 if self.scanner.consume('forward'):
294 return self.label()
295 elif self.scanner.consume('['):
306 def indlocexpr(self, forward=False):
307 if self.scanner.consume('['):
296308 loc = self.locexpr()
297309 self.scanner.expect(']')
298310 self.scanner.expect('+')
302314 loc = self.locexpr()
303315 return AddressRef(loc)
304316 else:
305 loc = self.locexpr()
306 index = None
307 if self.scanner.consume('+'):
308 index = self.locexpr()
309 loc = IndexedRef(loc, index)
317 loc = self.locexpr(forward=forward)
318 if not isinstance(loc, basestring):
319 index = None
320 if self.scanner.consume('+'):
321 index = self.locexpr()
322 loc = IndexedRef(loc, index)
310323 return loc
311324
312325 def statics(self):
391404 elif self.scanner.token in ("copy",):
392405 opcode = self.scanner.token
393406 self.scanner.scan()
394 src = self.indlocexpr()
407 src = self.indlocexpr(forward=True)
395408 self.scanner.expect(',')
396409 dest = self.indlocexpr()
397410 instr = Instr(opcode=opcode, dest=dest, src=src)
528528 = $081A INX
529529 = $081B RTS
530530
531 Copy routine (by forward reference) to vector.
532
533 | vector routine
534 | inputs x
535 | outputs x
536 | trashes z, n
537 | bar
538 |
539 | routine main
540 | outputs bar
541 | trashes a, n, z
542 | {
543 | copy foo, bar
544 | }
545 |
546 | routine foo
547 | inputs x
548 | outputs x
549 | trashes z, n
550 | {
551 | inc x
552 | }
553 = $080D LDA #$18
554 = $080F STA $081A
555 = $0812 LDA #$08
556 = $0814 STA $081B
557 = $0817 RTS
558 = $0818 INX
559 = $0819 RTS
560
531561 Copy word to word table and back, with both `x` and `y` as indexes.
532562
533563 | word one
407407 | }
408408 = ok
409409
410 A routine can be copied into a vector before the routine appears in the program,
411 *however*, it must be marked as such with the keyword `forward`.
410 A routine can be copied into a vector before the routine appears in the program.
411 This is known as a "forward reference". You are only allowed to make forward
412 references in the source of a `copy` instruction.
412413
413414 | vector routine
414415 | inputs cinv, a
424425 | routine foo {
425426 | ld a, 0
426427 | }
427 ? SyntaxError: Undefined symbol
428
429 | vector routine
430 | inputs cinv, a
431 | outputs cinv, x
432 | trashes a, x, z, n
433 | cinv @ 788
434 | routine main {
435 | with interrupts off {
436 | copy forward foo, cinv
437 | }
438 | call cinv
439 | }
440 | routine foo {
441 | ld a, 0
442 | }
443428 = ok
444429
445430 goto.