From 5a5953ca4caa8feb0e6e0587dd85d7c3550cc052 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Sun, 18 Oct 2015 18:12:47 +0100 Subject: [PATCH] A little awkward, but analyze byte table access correctly. --- src/sixtypical/analyzer.py | 19 ++++++ tests/SixtyPical Analysis.md | 110 +++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index b3806f5..9ab4053 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -2,6 +2,7 @@ from sixtypical.ast import Program, Routine, Block, Instr from sixtypical.model import ( + TYPE_BYTE, TYPE_BYTE_TABLE, ConstantRef, LocationRef, FLAG_Z, FLAG_N, FLAG_V, FLAG_C ) @@ -34,6 +35,10 @@ class UsageClashError(StaticAnalysisError): pass +class TypeMismatchError(StaticAnalysisError): + pass + + class Context(): def __init__(self, inputs, outputs, trashes): self._store = {} # Ref -> INITALIZED/UNINITIALIZED @@ -137,10 +142,24 @@ def analyze_instr(instr, context, routines): src = instr.src if opcode == 'ld': + if instr.index: + if src.type == TYPE_BYTE_TABLE and dest.type == TYPE_BYTE: + pass + else: + raise TypeMismatchError((src, dest)) + elif src.type != dest.type: + raise TypeMismatchError((src, dest)) context.assert_initialized(src) context.assert_writeable(dest, FLAG_Z, FLAG_N) context.set_initialized(dest, FLAG_Z, FLAG_N) elif opcode == 'st': + if instr.index: + if src.type == TYPE_BYTE and dest.type == TYPE_BYTE_TABLE: + pass + else: + raise TypeMismatchError((src, dest)) + elif src.type != dest.type: + raise TypeMismatchError((src, dest)) context.assert_initialized(src) context.assert_writeable(dest) context.set_initialized(dest) diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index 8d8a00c..e5f3935 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -195,6 +195,116 @@ Can't `st` to a memory location that doesn't appear in (outputs ∪ trashes). | } ? IllegalWriteError: lives +Storing to a table, you must use an index, and vice-versa. + + | byte one + | byte table many + | + | routine main + | outputs one + | trashes a, x, n, z + | { + | ld x, 0 + | ld a, 0 + | st a, one + | } + = ok + + | byte one + | byte table many + | + | routine main + | outputs many + | trashes a, x, n, z + | { + | ld x, 0 + | ld a, 0 + | st a, many + | } + ? TypeMismatchError + + | byte one + | byte table many + | + | routine main + | outputs one + | trashes a, x, n, z + | { + | ld x, 0 + | ld a, 0 + | st a, one + x + | } + ? TypeMismatchError + + | byte one + | byte table many + | + | routine main + | outputs many + | trashes a, x, n, z + | { + | ld x, 0 + | ld a, 0 + | st a, many + x + | } + = ok + +Reading from a table, you must use an index, and vice-versa. + + | byte one + | byte table many + | + | routine main + | outputs one + | trashes a, x, n, z + | { + | ld x, 0 + | st x, one + | ld a, one + | } + = ok + + | byte one + | byte table many + | + | routine main + | outputs one + | trashes a, x, n, z + | { + | ld x, 0 + | st x, one + | ld a, one + x + | } + ? TypeMismatchError + + | byte one + | byte table many + | + | routine main + | outputs many + | trashes a, x, n, z + | { + | ld x, 0 + | ld a, 0 + | st a, many + x + | ld a, many + | } + ? TypeMismatchError + + | byte one + | byte table many + | + | routine main + | outputs many + | trashes a, x, n, z + | { + | ld x, 0 + | ld a, 0 + | st a, many + x + | ld a, many + x + | } + = ok + ### add ### Can't `add` from or to a memory location that isn't initialized.