diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index 4214133..5d9012c 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -364,12 +364,18 @@ class Analyzer(object): elif isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndexedRef): if src.type == TYPE_WORD and TableType.is_a_table_type(dest.ref.type, TYPE_WORD): pass + elif isinstance(src.type, VectorType) and isinstance(dest.ref.type, TableType) and dest.ref.type.of_type == src.type: + # TODO ideally we'd check if the vectors in the table are compatible, rather than equal, to the src + pass else: - raise TypeMismatchError((src, dest)) + raise TypeMismatchError("""\n\n%r\n\n%r\n\n%r\n\n%r\n\n%r\n\n%r""" % (src, src.type, dest, dest.ref.type, dest.ref.type.of_type, (src.type == dest.ref.type.of_type))) elif isinstance(src, IndexedRef) and isinstance(dest, LocationRef): if TableType.is_a_table_type(src.ref.type, TYPE_WORD) and dest.type == TYPE_WORD: pass + elif isinstance(dest.type, VectorType) and isinstance(src.ref.type, TableType) and src.ref.type.of_type == dest.type: + # TODO ideally we'd check if the vectors in the table are compatible, rather than equal, to the src + pass else: raise TypeMismatchError((src, dest)) diff --git a/src/sixtypical/model.py b/src/sixtypical/model.py index 5c9eb9d..1868045 100644 --- a/src/sixtypical/model.py +++ b/src/sixtypical/model.py @@ -32,8 +32,8 @@ class ExecutableType(Type): self.trashes = trashes or set() def __repr__(self): - return 'RoutineType(%r, inputs=%r, outputs=%r, trashes=%r)' % ( - self.name, self.inputs, self.outputs, self.trashes + return '%s(%r, inputs=%r, outputs=%r, trashes=%r)' % ( + self.__class__.__name__, self.name, self.inputs, self.outputs, self.trashes ) def __eq__(self, other): @@ -66,6 +66,11 @@ class TableType(Type): self.size = size self.name = '{} table[{}]'.format(self.of_type.name, self.size) + def __repr__(self): + return '%s(%r, %r)' % ( + self.__class__.__name__, self.of_type, self.size + ) + @classmethod def is_a_table_type(cls_, x, of_type): return isinstance(x, TableType) and x.of_type == of_type @@ -123,6 +128,11 @@ class LocationRef(Ref): t.inputs = set([resolver(w) for w in t.inputs]) t.outputs = set([resolver(w) for w in t.outputs]) t.trashes = set([resolver(w) for w in t.trashes]) + if isinstance(self.type, TableType) and isinstance(self.type.of_type, ExecutableType): + t = self.type.of_type + t.inputs = set([resolver(w) for w in t.inputs]) + t.outputs = set([resolver(w) for w in t.outputs]) + t.trashes = set([resolver(w) for w in t.trashes]) @classmethod def format_set(cls, location_refs): diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index b9ccfd4..5cc6ee0 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -1900,3 +1900,33 @@ vector says it does. | ld a, x | } = ok + +### vector table ### + +Copying to and from a vector table. + + | vector + | outputs x + | trashes a, z, n + | one + | vector + | outputs x + | trashes a, z, n + | table[256] many + | + | routine bar outputs x trashes a, z, n { + | ld x, 200 + | } + | + | routine main + | inputs one, many + | outputs one, many + | trashes a, x, n, z + | { + | ld x, 0 + | copy bar, one + | copy one, many + x + | //copy many + x, one + | //call one + | } + = ok