diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index 15abcaf..f1b99fe 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -335,9 +335,9 @@ class Analyzer(object): self.routines = {} self.debug = debug - def assert_type(self, type, *locations): + def assert_type(self, type_, *locations): for location in locations: - if location.type != type: + if location.type != type_: raise TypeMismatchError(self.current_routine, location.name) def assert_affected_within(self, name, affecting_type, limiting_type): @@ -464,7 +464,7 @@ class Analyzer(object): context.assert_meaningful(dest.ref, REG_Y) context.set_written(dest.ref) elif src.type != dest.type: - raise TypeMismatchError(instr, '{} and {}'.format(src, name)) + raise TypeMismatchError(instr, '{} and {}'.format(src, dest)) else: context.set_written(dest) # FIXME: context.copy_range(src, dest) ? @@ -772,6 +772,7 @@ class Analyzer(object): if len(instr.locations) != 1: raise NotImplementedError("Only 1 location in save is supported right now") location = instr.locations[0] + self.assert_type(TYPE_BYTE, location) baton = context.extract(location) self.analyze_block(instr.block, context) diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index aa0efc7..34ed70f 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -636,4 +636,9 @@ class Compiler(object): self.emitter.emit(PLA()) self.emitter.emit(TAY()) else: - raise NotImplementedError + src_label = self.get_label(location.name) + self.emitter.emit(LDA(Absolute(src_label))) + self.emitter.emit(PHA()) + self.compile_block(instr.block) + self.emitter.emit(PLA()) + self.emitter.emit(STA(Absolute(src_label))) diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index 20dd7fc..1f44673 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -2047,6 +2047,44 @@ first in a nested series of `save`s. | } = ok +Not just registers, but also user-defined locations can be saved. + + | byte foo + | + | routine main + | trashes a, z, n + | { + | save foo { + | st 5, foo + | } + | } + = ok + +But only if they are bytes. + + | word foo + | + | routine main + | trashes a, z, n + | { + | save foo { + | copy 555, foo + | } + | } + ? TypeMismatchError + + | byte table[16] tab + | + | routine main + | trashes a, y, z, n + | { + | save tab { + | ld y, 0 + | st 5, tab + y + | } + | } + ? TypeMismatchError + ### copy ### Can't `copy` from a memory location that isn't initialized. diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index f08d835..955e21e 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -603,6 +603,25 @@ Compiling `save`. = $0816 PLA = $0817 RTS +Compiling `save` on a user-defined location. + + | byte foo + | routine main + | trashes a, z, n + | { + | save foo { + | ld a, 0 + | st a, foo + | } + | } + = $080D LDA $081B + = $0810 PHA + = $0811 LDA #$00 + = $0813 STA $081B + = $0816 PLA + = $0817 STA $081B + = $081A RTS + Indexed access. | byte one