diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index 6dd1ea4..da96c30 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -9,7 +9,7 @@ from sixtypical.model import ( ) from sixtypical.emitter import Byte, Label, Offset from sixtypical.gen6502 import ( - Immediate, Absolute, AbsoluteX, AbsoluteY, Relative, + Immediate, Absolute, AbsoluteX, AbsoluteY, Indirect, Relative, LDA, LDX, LDY, STA, STX, STY, TAX, TAY, TXA, TYA, CLC, SEC, ADC, SBC, ROL, ROR, @@ -193,8 +193,16 @@ class Compiler(object): else: raise UnsupportedOpcodeError(instr) elif opcode == 'call': + location = instr.location label = self.labels[instr.location.name] - self.emitter.emit(JSR(Absolute(label))) + if isinstance(location.type, RoutineType): + self.emitter.emit(JSR(Absolute(label))) + elif isinstance(location.type, VectorType): + # XXX NOT QUITE RIGHT, IS IT? + # We need to simulate an indirect JSR! + self.emitter.emit(JMP(Indirect(label))) + else: + raise NotImplementedError elif opcode == 'if': cls = { False: { diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index cf5276a..f7e4c34 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -1119,3 +1119,32 @@ Routines are read-only. | copy vec, foo | } ? TypeMismatchError + +Indirect call. + + | vector foo outputs x trashes z, n + | + | routine bar outputs x trashes z, n { + | ld x, 200 + | } + | + | routine main inputs bar outputs x, foo trashes a, z, n { + | copy bar, foo + | call foo + | } + = ok + +Calling the vector has indeed trashed stuff etc, + + | vector foo trashes x, z, n + | + | routine bar trashes x, z, n { + | ld x, 200 + | } + | + | routine main inputs bar outputs x, foo trashes z, n { + | ld x, 0 + | copy bar, foo + | call foo + | } + ? UninitializedOutputError: x diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index 3e812b6..156f110 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -261,3 +261,17 @@ Copy instruction inside interrupts off block. | } | } = 00c078ad0fc08d11c0ad10c08d12c05860e860 + +Indirect call. + + | vector foo outputs x trashes z, n + | + | routine bar outputs x trashes z, n { + | ld x, 200 + | } + | + | routine main inputs bar outputs x, foo trashes a, z, n { + | copy bar, foo + | call foo + | } + = 00c0 diff --git a/tests/SixtyPical Execution.md b/tests/SixtyPical Execution.md index 0f30395..af3cf1a 100644 --- a/tests/SixtyPical Execution.md +++ b/tests/SixtyPical Execution.md @@ -409,7 +409,7 @@ Indirect call. | ld x, 200 | } | - | routine main { + | routine main inputs bar outputs x, foo trashes a, z, n { | copy bar, foo | call foo | }