mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-08-10 06:24:56 +00:00
Allow copying a routine directly into a vector table.
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
from sixtypical.ast import Program, Routine, Block, Instr
|
from sixtypical.ast import Program, Routine, Block, Instr
|
||||||
from sixtypical.model import (
|
from sixtypical.model import (
|
||||||
TYPE_BYTE, TYPE_WORD,
|
TYPE_BYTE, TYPE_WORD,
|
||||||
TableType, BufferType, PointerType, VectorType, ExecutableType,
|
TableType, BufferType, PointerType, VectorType, ExecutableType, RoutineType,
|
||||||
ConstantRef, LocationRef, IndirectRef, IndexedRef, AddressRef,
|
ConstantRef, LocationRef, IndirectRef, IndexedRef, AddressRef,
|
||||||
REG_A, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
|
REG_A, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
|
||||||
)
|
)
|
||||||
@@ -141,6 +141,9 @@ class Context(object):
|
|||||||
|
|
||||||
def set_touched(self, *refs):
|
def set_touched(self, *refs):
|
||||||
for ref in refs:
|
for ref in refs:
|
||||||
|
# FIXME review the whole "touched" thing. what does it even mean? how is it different from "written"?
|
||||||
|
if isinstance(ref.type, RoutineType):
|
||||||
|
continue
|
||||||
self._touched.add(ref)
|
self._touched.add(ref)
|
||||||
|
|
||||||
def set_meaningful(self, *refs):
|
def set_meaningful(self, *refs):
|
||||||
@@ -364,8 +367,8 @@ class Analyzer(object):
|
|||||||
elif isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndexedRef):
|
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):
|
if src.type == TYPE_WORD and TableType.is_a_table_type(dest.ref.type, TYPE_WORD):
|
||||||
pass
|
pass
|
||||||
elif isinstance(src.type, VectorType) and isinstance(dest.ref.type, TableType) and dest.ref.type.of_type == src.type:
|
elif (isinstance(src.type, ExecutableType) and isinstance(dest.ref.type, TableType) and
|
||||||
# TODO ideally we'd check if the vectors in the table are compatible, rather than equal, to the src
|
ExecutableType.executable_types_compatible(src.type, dest.ref.type.of_type)):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise TypeMismatchError((src, dest))
|
raise TypeMismatchError((src, dest))
|
||||||
@@ -373,8 +376,8 @@ class Analyzer(object):
|
|||||||
elif isinstance(src, IndexedRef) and isinstance(dest, LocationRef):
|
elif isinstance(src, IndexedRef) and isinstance(dest, LocationRef):
|
||||||
if TableType.is_a_table_type(src.ref.type, TYPE_WORD) and dest.type == TYPE_WORD:
|
if TableType.is_a_table_type(src.ref.type, TYPE_WORD) and dest.type == TYPE_WORD:
|
||||||
pass
|
pass
|
||||||
elif isinstance(dest.type, VectorType) and isinstance(src.ref.type, TableType) and src.ref.type.of_type == dest.type:
|
elif (isinstance(src.ref.type, TableType) and isinstance(dest.type, VectorType) and
|
||||||
# TODO ideally we'd check if the vectors in the table are compatible, rather than equal, to the src
|
ExecutableType.executable_types_compatible(src.ref.type.of_type, dest.type)):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise TypeMismatchError((src, dest))
|
raise TypeMismatchError((src, dest))
|
||||||
|
@@ -47,6 +47,19 @@ class ExecutableType(Type):
|
|||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return hash(self.name) ^ hash(self.inputs) ^ hash(self.outputs) ^ hash(self.trashes)
|
return hash(self.name) ^ hash(self.inputs) ^ hash(self.outputs) ^ hash(self.trashes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def executable_types_compatible(cls_, src, dest):
|
||||||
|
"""Returns True iff a value of type `src` can be assigned to a storage location of type `dest`."""
|
||||||
|
if isinstance(src, ExecutableType) and isinstance(dest, VectorType):
|
||||||
|
# TODO: I'm sure we can replace some of these with subset-containment, but that requires thought
|
||||||
|
return (
|
||||||
|
src.inputs == dest.inputs and
|
||||||
|
src.outputs == dest.outputs and
|
||||||
|
src.trashes == dest.trashes
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class RoutineType(ExecutableType):
|
class RoutineType(ExecutableType):
|
||||||
"""This memory location contains the code for a routine."""
|
"""This memory location contains the code for a routine."""
|
||||||
|
@@ -1892,9 +1892,9 @@ vector says it does.
|
|||||||
| }
|
| }
|
||||||
= ok
|
= ok
|
||||||
|
|
||||||
### vector table ###
|
### Vector tables ###
|
||||||
|
|
||||||
Copying to and from a vector table.
|
A vector can be copied into a vector table.
|
||||||
|
|
||||||
| vector one
|
| vector one
|
||||||
| outputs x
|
| outputs x
|
||||||
@@ -1915,7 +1915,70 @@ Copying to and from a vector table.
|
|||||||
| ld x, 0
|
| ld x, 0
|
||||||
| copy bar, one
|
| copy bar, one
|
||||||
| copy one, many + x
|
| copy one, many + x
|
||||||
|
| }
|
||||||
|
= ok
|
||||||
|
|
||||||
|
A vector can be copied out of a vector table.
|
||||||
|
|
||||||
|
| vector one
|
||||||
|
| outputs x
|
||||||
|
| trashes a, z, n
|
||||||
|
| vector table[256] many
|
||||||
|
| outputs x
|
||||||
|
| trashes a, z, n
|
||||||
|
|
|
||||||
|
| 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 many + x, one
|
| copy many + x, one
|
||||||
| call one
|
| call one
|
||||||
| }
|
| }
|
||||||
= ok
|
= ok
|
||||||
|
|
||||||
|
A routine can be copied into a vector table.
|
||||||
|
|
||||||
|
| vector table[256] many
|
||||||
|
| outputs x
|
||||||
|
| trashes a, z, n
|
||||||
|
|
|
||||||
|
| routine bar outputs x trashes a, z, n {
|
||||||
|
| ld x, 200
|
||||||
|
| }
|
||||||
|
|
|
||||||
|
| routine main
|
||||||
|
| inputs many
|
||||||
|
| outputs many
|
||||||
|
| trashes a, x, n, z
|
||||||
|
| {
|
||||||
|
| ld x, 0
|
||||||
|
| copy bar, many + x
|
||||||
|
| }
|
||||||
|
= ok
|
||||||
|
|
||||||
|
A vector in a vector table cannot be directly called.
|
||||||
|
|
||||||
|
| vector table[256] many
|
||||||
|
| outputs x
|
||||||
|
| trashes a, z, n
|
||||||
|
|
|
||||||
|
| routine bar outputs x trashes a, z, n {
|
||||||
|
| ld x, 200
|
||||||
|
| }
|
||||||
|
|
|
||||||
|
| routine main
|
||||||
|
| inputs many
|
||||||
|
| outputs many
|
||||||
|
| trashes a, x, n, z
|
||||||
|
| {
|
||||||
|
| ld x, 0
|
||||||
|
| copy bar, many + x
|
||||||
|
| call many + x
|
||||||
|
| }
|
||||||
|
? ValueError
|
||||||
|
Reference in New Issue
Block a user