diff --git a/HISTORY.md b/HISTORY.md index 05a91d9..0c66e7f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -10,6 +10,7 @@ History of SixtyPical * Initialized `word` memory locations. * Can `copy` a literal word to a word table. * Subtract word (constant or memory location) from word memory location. +* `trash` instruction explicitly indicates a value is no longer considered meaningful. * Fixed bug which was preventing `if` branches to diverge in what they initialized, if it was already initialized when going into the `if`. * Fixed a bug which was making it crash when trying to analyze `repeat forever` loops. diff --git a/README.md b/README.md index 2e117eb..863cdb3 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,6 @@ This should be tracked in the abstract interpretation. * `byte table` and `word table` of sizes other than 256 * initialized `byte table` memory locations * always analyze before executing or compiling, unless told not to -* `trash` instruction. * `interrupt` routines -- to indicate that "the supervisor" has stored values on the stack, so we can trash them. * error messages that include the line number of the source code * have `copy` instruction able to copy a byte to a user-def mem loc, etc. diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index f85355a..e193c46 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -431,5 +431,7 @@ class Analyzer(object): self.assert_affected_within('trashes', type_.trashes, current_type.trashes) self.has_encountered_goto = True + elif opcode == 'trash': + context.set_unmeaningful(instr.dest) else: raise NotImplementedError(opcode) diff --git a/src/sixtypical/compiler.py b/src/sixtypical/compiler.py index 3b8149b..99eb5cc 100644 --- a/src/sixtypical/compiler.py +++ b/src/sixtypical/compiler.py @@ -470,5 +470,7 @@ class Compiler(object): self.emitter.emit(STA(Absolute(Offset(dest_label, 1)))) else: raise NotImplementedError(src.type) + elif opcode == 'trash': + pass else: raise NotImplementedError(opcode) diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index 58f81db..81c4adf 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -305,5 +305,8 @@ class Parser(object): self.scanner.expect("off") block = self.block() return Instr(opcode='with-sei', dest=None, src=None, block=block) + elif self.scanner.consume("trash"): + dest = self.locexpr() + return Instr(opcode='trash', src=None, dest=dest) else: raise ValueError('bad opcode "%s"' % self.scanner.token) diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index 3fb6116..963f0ff 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -1089,6 +1089,43 @@ same constraints. | } ? UnmeaningfulReadError: a in main +### trash ### + +Trash does nothing except indicate that we do not care about the value anymore. + + | routine foo + | inputs a + | outputs x + | trashes a, z, n + | { + | st a, x + | ld a, 0 + | trash a + | } + = ok + + | routine foo + | inputs a + | outputs a, x + | trashes z, n + | { + | st a, x + | ld a, 0 + | trash a + | } + ? UnmeaningfulOutputError: a in foo + + | routine foo + | inputs a + | outputs x + | trashes a, z, n + | { + | st a, x + | trash a + | st a, x + | } + ? UnmeaningfulReadError: a in foo + ### if ### Both blocks of an `if` are analyzed. diff --git a/tests/SixtyPical Compilation.md b/tests/SixtyPical Compilation.md index da0b9ba..9382fb9 100644 --- a/tests/SixtyPical Compilation.md +++ b/tests/SixtyPical Compilation.md @@ -1073,3 +1073,20 @@ Note that this is *not* range-checked. (Yet.) = $083B LDA ($FE),Y = $083D STA $1041 = $0840 RTS + +### Trash + +Trash does nothing except indicate that we do not care about the value anymore. + + | routine main + | inputs a + | outputs x + | trashes a, z, n + | { + | ld x, a + | ld a, 0 + | trash a + | } + = $080D TAX + = $080E LDA #$00 + = $0810 RTS diff --git a/tests/SixtyPical Syntax.md b/tests/SixtyPical Syntax.md index 74a1551..57007ce 100644 --- a/tests/SixtyPical Syntax.md +++ b/tests/SixtyPical Syntax.md @@ -70,6 +70,14 @@ Extern routines | @ 65487 = ok +Trash. + + | routine main { + | trash a + | trash n + | } + = ok + If with not | routine foo {