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

goto is no longer restricted to appearing in tail position.

This commit is contained in:
Chris Pressey 2018-11-27 14:25:43 +00:00
parent 9364a5fbec
commit 6dbce205d1
4 changed files with 52 additions and 16 deletions

View File

@ -5,6 +5,8 @@ History of SixtyPical
----
* Syntactically, `goto` may only appear at the end of a block.
It need no longer be the final instruction in a routine,
as long as the type context is consistent at every exit.
* Fixed pathological memory use in the lexical scanner - should
be much less inefficient now when parsing large source files.

View File

@ -69,7 +69,6 @@ error.
If a block ends in a `call` can that be converted to end in a `goto`? Why not? I think it can,
if the block is in tail position. The constraints should iron out the same both ways.
And - once we have this - why do we need `goto` to be in tail position, strictly?
As long as the routine has consistent type context every place it exits, that should be fine.
### "Include" directives

View File

@ -433,9 +433,6 @@ class Analyzer(object):
dest = instr.dest
src = instr.src
if context.encountered_gotos():
raise IllegalJumpError(instr, instr)
if opcode == 'ld':
if isinstance(src, IndexedRef):
context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
@ -735,6 +732,9 @@ class Analyzer(object):
if instr.src is not None:
context.assert_meaningful(instr.src)
if context.encountered_gotos():
raise IllegalJumpError(instr, instr)
def analyze_for(self, instr, context):
context.assert_meaningful(instr.dest)
context.assert_writeable(instr.dest)

View File

@ -2280,7 +2280,7 @@ But only if they are bytes.
| }
? TypeMismatchError
A `goto` cannot appear within a `save` block, even if it is otherwise in tail position.
A `goto` cannot appear within a `save` block.
| define other routine
| trashes a, z, n
@ -2325,8 +2325,7 @@ A `goto` cannot appear within a `save` block, even if it is otherwise in tail po
| }
= ok
A `goto` cannot appear within a `with interrupts` block, even if it is
otherwise in tail position.
A `goto` cannot appear within a `with interrupts` block.
| vector routine
| inputs x
@ -2973,7 +2972,26 @@ Calling the vector does indeed trash the things the vector says it does.
| }
? UnmeaningfulOutputError: x
`goto`, if present, must be in tail position (the final instruction in a routine.)
For now at least, you cannot have a `goto` inside a loop.
| define bar routine trashes x, z, n {
| ld x, 200
| }
|
| define main routine trashes x, z, n {
| ld x, 0
| repeat {
| inc x
| goto bar
| } until z
| }
? IllegalJumpError
`goto`, as a matter of syntax, can only appear at the end
of a block; but it need not be the final instruction in a
routine. It is only important that the type context at every
`goto` is compatible with the type context at the end of
the routine.
| define bar routine trashes x, z, n {
| ld x, 200
@ -2995,9 +3013,8 @@ Calling the vector does indeed trash the things the vector says it does.
| ld x, 1
| goto bar
| }
| ld x, 0
| }
? IllegalJumpError
= ok
| define bar routine trashes x, z, n {
| ld x, 200
@ -3009,6 +3026,7 @@ Calling the vector does indeed trash the things the vector says it does.
| ld x, 1
| goto bar
| }
| goto bar
| }
= ok
@ -3024,7 +3042,7 @@ Calling the vector does indeed trash the things the vector says it does.
| }
| ld x, 0
| }
? IllegalJumpError
= ok
| define bar routine trashes x, z, n {
| ld x, 200
@ -3057,7 +3075,21 @@ Calling the vector does indeed trash the things the vector says it does.
| }
= ok
For the purposes of `goto`, the end of a loop is never tail position.
| define bar routine trashes x, z, n {
| ld x, 200
| }
|
| define main routine trashes x, z, n {
| ld x, 0
| if z {
| ld x, 1
| goto bar
| } else {
| ld x, 0
| }
| ld x, 0
| }
= ok
| define bar routine trashes x, z, n {
| ld x, 200
@ -3065,12 +3097,15 @@ For the purposes of `goto`, the end of a loop is never tail position.
|
| define main routine trashes x, z, n {
| ld x, 0
| repeat {
| inc x
| if z {
| ld x, 1
| goto bar
| } until z
| } else {
| ld x, 0
| }
| goto bar
| }
? IllegalJumpError
= ok
Can't `goto` a routine that outputs or trashes more than the current routine.