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:
parent
9364a5fbec
commit
6dbce205d1
|
@ -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.
|
||||
|
||||
|
|
1
TODO.md
1
TODO.md
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user