mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-01-24 01:35:50 +00:00
Remove need for forward
keyword in forward reference in copy
.
This commit is contained in:
parent
08ec0e46a3
commit
f6fa1ec7d2
@ -10,8 +10,9 @@ History of SixtyPical
|
||||
* Implements the "union rule for trashes" when analyzing `if` blocks.
|
||||
* Even if we `goto` another routine, we can't trash an output.
|
||||
* `static` storage locations local to routines can now be defined within routines.
|
||||
* Small grammar change that obviates the need for parentheses in the type expression
|
||||
`vector (routine ...) table`.
|
||||
* Small grammar changes that obviate:
|
||||
* the need for parentheses in the type expression `vector (routine ...) table`#
|
||||
* the need for `forward` in forward references in source of `copy` instruction
|
||||
* Fixed bug where `trash` was not marking the location as being virtually altered.
|
||||
|
||||
0.11
|
||||
|
@ -67,7 +67,6 @@ is probably NP-complete. But doing it adeuqately is probably not that hard.
|
||||
### And at some point...
|
||||
|
||||
* `const`s that can be used in defining the size of tables, etc.
|
||||
* Remove the need for `forward` (lots of backpatching)
|
||||
* Tests, and implementation, ensuring a routine can be assigned to a vector of "wider" type
|
||||
* Check that the buffer being read or written to through pointer, appears in approporiate inputs or outputs set.
|
||||
(Associate each pointer with the buffer it points into.)
|
||||
|
@ -249,7 +249,7 @@ routine init_game
|
||||
repeat {
|
||||
copy pos, actor_pos + y
|
||||
copy word 40, actor_delta + y
|
||||
copy forward enemy_logic, actor_logic + y
|
||||
copy enemy_logic, actor_logic + y
|
||||
|
||||
st off, c
|
||||
add pos, word 7
|
||||
@ -261,7 +261,7 @@ routine init_game
|
||||
ld y, 0
|
||||
copy word 0, actor_pos + y
|
||||
copy word 0, actor_delta + y
|
||||
copy forward player_logic, actor_logic + y
|
||||
copy player_logic, actor_logic + y
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
@ -401,7 +401,7 @@ define game_state_title_screen game_state_routine
|
||||
if c {
|
||||
call clear_screen
|
||||
call init_game
|
||||
copy forward game_state_play, dispatch_game_state
|
||||
copy game_state_play, dispatch_game_state
|
||||
}
|
||||
|
||||
goto save_cinv
|
||||
@ -423,7 +423,7 @@ static byte save_x : 0
|
||||
if c {
|
||||
// Player died! Want no dead! Break out of the loop (this is a bit awkward.)
|
||||
call clear_screen
|
||||
copy forward game_state_game_over, dispatch_game_state
|
||||
copy game_state_game_over, dispatch_game_state
|
||||
ld x, 15
|
||||
} else {
|
||||
ld x, save_x
|
||||
|
@ -30,12 +30,18 @@ class Parser(object):
|
||||
self.symbols[token] = SymEntry(None, LocationRef(TYPE_BIT, token))
|
||||
self.backpatch_instrs = []
|
||||
|
||||
def lookup(self, name):
|
||||
def soft_lookup(self, name):
|
||||
if name in self.current_statics:
|
||||
return self.current_statics[name].model
|
||||
if name not in self.symbols:
|
||||
if name in self.symbols:
|
||||
return self.symbols[name].model
|
||||
return None
|
||||
|
||||
def lookup(self, name):
|
||||
model = self.soft_lookup(name)
|
||||
if model is None:
|
||||
raise SyntaxError('Undefined symbol "%s"' % name)
|
||||
return self.symbols[name].model
|
||||
return model
|
||||
|
||||
# --- grammar productions
|
||||
|
||||
@ -270,7 +276,7 @@ class Parser(object):
|
||||
accum.append(self.locexpr())
|
||||
return accum
|
||||
|
||||
def locexpr(self):
|
||||
def locexpr(self, forward=False):
|
||||
if self.scanner.token in ('on', 'off'):
|
||||
loc = ConstantRef(TYPE_BIT, 1 if self.scanner.token == 'on' else 0)
|
||||
self.scanner.scan()
|
||||
@ -285,15 +291,21 @@ class Parser(object):
|
||||
loc = ConstantRef(TYPE_WORD, int(self.scanner.token))
|
||||
self.scanner.scan()
|
||||
return loc
|
||||
elif forward:
|
||||
name = self.scanner.token
|
||||
self.scanner.scan()
|
||||
loc = self.soft_lookup(name)
|
||||
if loc is not None:
|
||||
return loc
|
||||
else:
|
||||
return name
|
||||
else:
|
||||
loc = self.lookup(self.scanner.token)
|
||||
self.scanner.scan()
|
||||
return loc
|
||||
|
||||
def indlocexpr(self):
|
||||
if self.scanner.consume('forward'):
|
||||
return self.label()
|
||||
elif self.scanner.consume('['):
|
||||
def indlocexpr(self, forward=False):
|
||||
if self.scanner.consume('['):
|
||||
loc = self.locexpr()
|
||||
self.scanner.expect(']')
|
||||
self.scanner.expect('+')
|
||||
@ -303,11 +315,12 @@ class Parser(object):
|
||||
loc = self.locexpr()
|
||||
return AddressRef(loc)
|
||||
else:
|
||||
loc = self.locexpr()
|
||||
index = None
|
||||
if self.scanner.consume('+'):
|
||||
index = self.locexpr()
|
||||
loc = IndexedRef(loc, index)
|
||||
loc = self.locexpr(forward=forward)
|
||||
if not isinstance(loc, basestring):
|
||||
index = None
|
||||
if self.scanner.consume('+'):
|
||||
index = self.locexpr()
|
||||
loc = IndexedRef(loc, index)
|
||||
return loc
|
||||
|
||||
def statics(self):
|
||||
@ -392,7 +405,7 @@ class Parser(object):
|
||||
elif self.scanner.token in ("copy",):
|
||||
opcode = self.scanner.token
|
||||
self.scanner.scan()
|
||||
src = self.indlocexpr()
|
||||
src = self.indlocexpr(forward=True)
|
||||
self.scanner.expect(',')
|
||||
dest = self.indlocexpr()
|
||||
instr = Instr(opcode=opcode, dest=dest, src=src)
|
||||
|
@ -529,6 +529,36 @@ Copy routine to vector, inside an `interrupts off` block.
|
||||
= $081A INX
|
||||
= $081B RTS
|
||||
|
||||
Copy routine (by forward reference) to vector.
|
||||
|
||||
| vector routine
|
||||
| inputs x
|
||||
| outputs x
|
||||
| trashes z, n
|
||||
| bar
|
||||
|
|
||||
| routine main
|
||||
| outputs bar
|
||||
| trashes a, n, z
|
||||
| {
|
||||
| copy foo, bar
|
||||
| }
|
||||
|
|
||||
| routine foo
|
||||
| inputs x
|
||||
| outputs x
|
||||
| trashes z, n
|
||||
| {
|
||||
| inc x
|
||||
| }
|
||||
= $080D LDA #$18
|
||||
= $080F STA $081A
|
||||
= $0812 LDA #$08
|
||||
= $0814 STA $081B
|
||||
= $0817 RTS
|
||||
= $0818 INX
|
||||
= $0819 RTS
|
||||
|
||||
Copy word to word table and back, with both `x` and `y` as indexes.
|
||||
|
||||
| word one
|
||||
|
@ -408,8 +408,9 @@ A vector can name itself in its inputs, outputs, and trashes.
|
||||
| }
|
||||
= ok
|
||||
|
||||
A routine can be copied into a vector before the routine appears in the program,
|
||||
*however*, it must be marked as such with the keyword `forward`.
|
||||
A routine can be copied into a vector before the routine appears in the program.
|
||||
This is known as a "forward reference". You are only allowed to make forward
|
||||
references in the source of a `copy` instruction.
|
||||
|
||||
| vector routine
|
||||
| inputs cinv, a
|
||||
@ -425,22 +426,6 @@ A routine can be copied into a vector before the routine appears in the program,
|
||||
| routine foo {
|
||||
| ld a, 0
|
||||
| }
|
||||
? SyntaxError: Undefined symbol
|
||||
|
||||
| vector routine
|
||||
| inputs cinv, a
|
||||
| outputs cinv, x
|
||||
| trashes a, x, z, n
|
||||
| cinv @ 788
|
||||
| routine main {
|
||||
| with interrupts off {
|
||||
| copy forward foo, cinv
|
||||
| }
|
||||
| call cinv
|
||||
| }
|
||||
| routine foo {
|
||||
| ld a, 0
|
||||
| }
|
||||
= ok
|
||||
|
||||
goto.
|
||||
|
Loading…
x
Reference in New Issue
Block a user