mirror of
https://github.com/catseye/SixtyPical.git
synced 2024-11-25 23:49:17 +00:00
Forward-reference resolution becomes increasingly general.
This commit is contained in:
parent
26a2fb448c
commit
af0e1b41c7
@ -5,6 +5,8 @@ History of SixtyPical
|
||||
----
|
||||
|
||||
* `save X, Y, Z { }` now allowed as a shortcut for nested `save`s.
|
||||
* Trying to call or goto a non-routine-typed symbol is now an
|
||||
analysis error, not a syntax error.
|
||||
* Split TODO off into own file.
|
||||
* `sixtypical` no longer writes the compiled binary to standard
|
||||
output. The `--output` command-line argument should be given
|
||||
|
@ -550,6 +550,8 @@ class Analyzer(object):
|
||||
context.invalidate_range(dest)
|
||||
elif opcode == 'call':
|
||||
type = instr.location.type
|
||||
if not isinstance(type, (RoutineType, VectorType)):
|
||||
raise TypeMismatchError(instr, instr.location)
|
||||
if isinstance(type, VectorType):
|
||||
type = type.of_type
|
||||
for ref in type.inputs:
|
||||
|
@ -115,16 +115,11 @@ class Parser(object):
|
||||
for node in program.all_children():
|
||||
if isinstance(node, SingleOp):
|
||||
instr = node
|
||||
if isinstance(instr.src, ForwardReference):
|
||||
instr.src = self.lookup(instr.src.name)
|
||||
if instr.opcode in ('call', 'goto'):
|
||||
forward_reference = instr.location
|
||||
name = forward_reference.name
|
||||
model = self.lookup(name)
|
||||
if not isinstance(model.type, (RoutineType, VectorType)):
|
||||
self.syntax_error('Illegal call of non-executable "%s"' % name)
|
||||
instr.location = model
|
||||
if instr.opcode in ('copy',):
|
||||
if isinstance(instr.src, ForwardReference):
|
||||
instr.src = self.lookup(instr.src.name)
|
||||
if isinstance(instr.location, ForwardReference):
|
||||
instr.location = self.lookup(instr.location.name)
|
||||
|
||||
return program
|
||||
|
||||
|
@ -196,6 +196,35 @@ If a routine reads or writes a user-define memory location, it needs to declare
|
||||
| }
|
||||
= ok
|
||||
|
||||
### call ###
|
||||
|
||||
You can't call a non-routine.
|
||||
|
||||
| byte up
|
||||
|
|
||||
| routine main outputs x, y trashes z, n {
|
||||
| ld x, 0
|
||||
| ld y, 1
|
||||
| call up
|
||||
| }
|
||||
? TypeMismatchError: up
|
||||
|
||||
| routine main outputs x, y trashes z, n {
|
||||
| ld x, 0
|
||||
| ld y, 1
|
||||
| call x
|
||||
| }
|
||||
? TypeMismatchError: x
|
||||
|
||||
Nor can you goto a non-routine.
|
||||
|
||||
| byte foo
|
||||
|
|
||||
| routine main {
|
||||
| goto foo
|
||||
| }
|
||||
? TypeMismatchError: foo
|
||||
|
||||
### ld ###
|
||||
|
||||
Can't `ld` from a memory location that isn't initialized.
|
||||
|
@ -404,24 +404,6 @@ Can't call routine that hasn't been defined.
|
||||
| }
|
||||
? SyntaxError
|
||||
|
||||
And you can't call a non-routine.
|
||||
|
||||
| byte up
|
||||
|
|
||||
| routine main {
|
||||
| ld x, 0
|
||||
| ld y, 1
|
||||
| call up
|
||||
| }
|
||||
? SyntaxError
|
||||
|
||||
| routine main {
|
||||
| ld x, 0
|
||||
| ld y, 1
|
||||
| call x
|
||||
| }
|
||||
? SyntaxError
|
||||
|
||||
But you can call a routine that is yet to be defined, further on.
|
||||
|
||||
| routine main {
|
||||
@ -589,13 +571,6 @@ goto.
|
||||
| }
|
||||
? SyntaxError
|
||||
|
||||
| byte foo
|
||||
|
|
||||
| routine main {
|
||||
| goto foo
|
||||
| }
|
||||
? SyntaxError
|
||||
|
||||
Buffers and pointers.
|
||||
|
||||
| buffer[2048] buf
|
||||
|
Loading…
Reference in New Issue
Block a user