1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-06-07 22:29:27 +00:00

Introducing a new pseudo-opcode is rarely an elegant solution.

This commit is contained in:
Chris Pressey 2017-12-12 14:09:17 +00:00
parent dbbd99ffe5
commit b7b28830d7
4 changed files with 40 additions and 5 deletions

View File

@ -5,6 +5,7 @@ History of SixtyPical
----
* Can `call` and `goto` routines that are defined further down in the source code.
* `assign`, a form of `copy` that can copy (to a vector) a routine that is defined further down.
0.9
---

View File

@ -46,11 +46,6 @@ Finish the little demo "game" where you can move a block around the screen with
the joystick (i.e. bring it up to par with the original demo game that was written
for SixtyPical)
### `copy` (to vectors) routines that are defined further down in the source code
We might have a graph of states that refer to each other and that want to `goto`
each other. Thus we need this. We have it for other things.
### Allow branches to diverge in what they touch
For example, if the routine inputs and outputs `foo`, and one branch of an `if`

View File

@ -64,6 +64,14 @@ class Parser(object):
if not isinstance(self.symbols[name].model.type, ExecutableType):
raise SyntaxError('Illegal call of non-executable "%s"' % name)
instr.location = self.symbols[name].model
if instr.opcode in ('assign',):
name = instr.src
if name not in self.symbols:
raise SyntaxError('Undefined routine "%s"' % name)
if not isinstance(self.symbols[name].model.type, ExecutableType):
raise SyntaxError('Illegal assign of non-executable "%s"' % name)
instr.src = self.symbols[name].model
instr.opcode = 'copy'
return Program(defns=defns, routines=routines)
@ -286,6 +294,15 @@ class Parser(object):
self.scanner.expect(',')
dest = self.indlocexpr()
return Instr(opcode=opcode, dest=dest, src=src)
elif self.scanner.token == 'assign':
opcode = self.scanner.token
self.scanner.scan()
src = self.label()
self.scanner.expect(',')
dest = self.indlocexpr()
instr = Instr(opcode=opcode, dest=dest, src=src)
self.backpatch_instrs.append(instr)
return instr
elif self.scanner.consume("with"):
self.scanner.expect("interrupts")
self.scanner.expect("off")

View File

@ -356,6 +356,28 @@ 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*, in order to do this currently, one needs to use the special opcode
form `assign`, which is equivalent to `copy` except that the routine need not
have already appeared in the program.
| vector cinv
| inputs cinv, a
| outputs cinv, x
| trashes a, x, z, n
| @ 788
|
| routine main {
| with interrupts off {
| assign foo, cinv
| }
| call cinv
| }
| routine foo {
| ld a, 0
| }
= ok
goto.
| routine foo {