0 | 0 |
"""Data/storage model for SixtyPical."""
|
1 | 1 |
|
2 | |
|
3 | |
class Type(object):
|
4 | |
def __init__(self, name, max_range=None):
|
5 | |
self.name = name
|
6 | |
self.max_range = max_range
|
7 | |
|
8 | |
def __repr__(self):
|
9 | |
return 'Type(%r)' % self.name
|
10 | |
|
11 | |
def __eq__(self, other):
|
12 | |
return other.__class__ == self.__class__ and other.name == self.name
|
|
2 |
from collections import namedtuple
|
13 | 3 |
|
14 | 4 |
|
15 | |
TYPE_BIT = Type('bit', max_range=(0, 1))
|
16 | |
TYPE_BYTE = Type('byte', max_range=(0, 255))
|
17 | |
TYPE_WORD = Type('word', max_range=(0, 65535))
|
|
5 |
class BitType(namedtuple('BitType', ['typename'])):
|
|
6 |
max_range = (0, 1)
|
|
7 |
def __new__(cls):
|
|
8 |
return super(BitType, cls).__new__(cls, 'bit')
|
|
9 |
TYPE_BIT = BitType()
|
18 | 10 |
|
19 | 11 |
|
20 | |
class RoutineType(Type):
|
|
12 |
class ByteType(namedtuple('ByteType', ['typename'])):
|
|
13 |
max_range = (0, 255)
|
|
14 |
def __new__(cls):
|
|
15 |
return super(ByteType, cls).__new__(cls, 'byte')
|
|
16 |
TYPE_BYTE = ByteType()
|
|
17 |
|
|
18 |
|
|
19 |
class WordType(namedtuple('WordType', ['typename'])):
|
|
20 |
max_range = (0, 65535)
|
|
21 |
def __new__(cls):
|
|
22 |
return super(WordType, cls).__new__(cls, 'word')
|
|
23 |
TYPE_WORD = WordType()
|
|
24 |
|
|
25 |
|
|
26 |
class RoutineType(namedtuple('RoutineType', ['typename', 'inputs', 'outputs', 'trashes'])):
|
21 | 27 |
"""This memory location contains the code for a routine."""
|
22 | |
def __init__(self, inputs, outputs, trashes):
|
23 | |
self.inputs = inputs
|
24 | |
self.outputs = outputs
|
25 | |
self.trashes = trashes
|
|
28 |
max_range = (0, 0)
|
26 | 29 |
|
27 | |
def __repr__(self):
|
28 | |
return '%s(inputs=%r, outputs=%r, trashes=%r)' % (
|
29 | |
self.__class__.__name__, self.inputs, self.outputs, self.trashes
|
30 | |
)
|
31 | |
|
32 | |
def __eq__(self, other):
|
33 | |
return isinstance(other, RoutineType) and (
|
34 | |
other.inputs == self.inputs and
|
35 | |
other.outputs == self.outputs and
|
36 | |
other.trashes == self.trashes
|
37 | |
)
|
|
30 |
def __new__(cls, *args):
|
|
31 |
return super(RoutineType, cls).__new__(cls, 'routine', *args)
|
38 | 32 |
|
39 | 33 |
@classmethod
|
40 | 34 |
def executable_types_compatible(cls_, src, dest):
|
|
54 | 48 |
return False
|
55 | 49 |
|
56 | 50 |
|
57 | |
class VectorType(Type):
|
|
51 |
class VectorType(namedtuple('VectorType', ['typename', 'of_type'])):
|
58 | 52 |
"""This memory location contains the address of some other type (currently, only RoutineType)."""
|
59 | |
max_range = (0, 0)
|
|
53 |
max_range = (0, 65535)
|
60 | 54 |
|
61 | |
def __init__(self, of_type):
|
62 | |
self.of_type = of_type
|
63 | |
|
64 | |
def __repr__(self):
|
65 | |
return '%s(%r)' % (
|
66 | |
self.__class__.__name__, self.of_type
|
67 | |
)
|
68 | |
|
69 | |
def __eq__(self, other):
|
70 | |
return isinstance(other, VectorType) and self.of_type == other.of_type
|
|
55 |
def __new__(cls, *args):
|
|
56 |
return super(VectorType, cls).__new__(cls, 'vector', *args)
|
71 | 57 |
|
72 | 58 |
|
73 | |
class TableType(Type):
|
74 | |
def __init__(self, of_type, size):
|
75 | |
self.of_type = of_type
|
76 | |
self.size = size
|
|
59 |
class TableType(namedtuple('TableType', ['typename', 'of_type', 'size'])):
|
77 | 60 |
|
78 | |
def __repr__(self):
|
79 | |
return '%s(%r, %r)' % (
|
80 | |
self.__class__.__name__, self.of_type, self.size
|
81 | |
)
|
82 | |
|
83 | |
def __eq__(self, other):
|
84 | |
return isinstance(other, TableType) and self.of_type == other.of_type and self.size == other.size
|
|
61 |
def __new__(cls, *args):
|
|
62 |
return super(TableType, cls).__new__(cls, 'table', *args)
|
85 | 63 |
|
86 | 64 |
@property
|
87 | 65 |
def max_range(self):
|
|
92 | 70 |
return isinstance(x, TableType) and x.of_type == of_type
|
93 | 71 |
|
94 | 72 |
|
95 | |
class PointerType(Type):
|
96 | |
max_range = (0, 0)
|
|
73 |
class PointerType(namedtuple('PointerType', ['typename'])):
|
|
74 |
max_range = (0, 65535)
|
97 | 75 |
|
98 | |
def __init__(self):
|
99 | |
self.name = 'pointer'
|
100 | |
|
101 | |
def __eq__(self, other):
|
102 | |
return other.__class__ == self.__class__
|
|
76 |
def __new__(cls):
|
|
77 |
return super(PointerType, cls).__new__(cls, 'pointer')
|
103 | 78 |
|
104 | 79 |
|
105 | |
class Ref(object):
|
106 | |
pass
|
|
80 |
# --------------------------------------------------------
|
107 | 81 |
|
108 | 82 |
|
109 | |
class LocationRef(Ref):
|
110 | |
def __init__(self, type, name):
|
111 | |
self.name = name
|
112 | |
|
113 | |
def __eq__(self, other):
|
114 | |
return self.__class__ is other.__class__ and self.name == other.name
|
115 | |
|
116 | |
def __hash__(self):
|
117 | |
return hash(self.name)
|
118 | |
|
119 | |
def __repr__(self):
|
120 | |
return '%s(%r)' % (self.__class__.__name__, self.name)
|
121 | |
|
122 | |
def __str__(self):
|
123 | |
return self.name
|
|
83 |
class LocationRef(namedtuple('LocationRef', ['reftype', 'name'])):
|
|
84 |
def __new__(cls, *args):
|
|
85 |
return super(LocationRef, cls).__new__(cls, 'location', *args)
|
124 | 86 |
|
125 | 87 |
@classmethod
|
126 | 88 |
def format_set(cls, location_refs):
|
127 | 89 |
return '{%s}' % ', '.join([str(loc) for loc in sorted(location_refs, key=lambda x: x.name)])
|
128 | 90 |
|
129 | 91 |
|
130 | |
class IndirectRef(Ref):
|
131 | |
def __init__(self, ref):
|
132 | |
self.ref = ref
|
133 | |
|
134 | |
def __eq__(self, other):
|
135 | |
return isinstance(other, self.__class__) and self.ref == other.ref
|
136 | |
|
137 | |
def __hash__(self):
|
138 | |
return hash(self.__class__.name) ^ hash(self.ref)
|
139 | |
|
140 | |
def __repr__(self):
|
141 | |
return '%s(%r)' % (self.__class__.__name__, self.ref)
|
|
92 |
class IndirectRef(namedtuple('IndirectRef', ['reftype', 'ref'])):
|
|
93 |
def __new__(cls, *args):
|
|
94 |
return super(IndirectRef, cls).__new__(cls, 'indirect', *args)
|
142 | 95 |
|
143 | 96 |
@property
|
144 | 97 |
def name(self):
|
145 | 98 |
return '[{}]+y'.format(self.ref.name)
|
146 | 99 |
|
147 | 100 |
|
148 | |
class IndexedRef(Ref):
|
149 | |
def __init__(self, ref, offset, index):
|
150 | |
self.ref = ref
|
151 | |
self.offset = offset
|
152 | |
self.index = index
|
153 | |
|
154 | |
def __eq__(self, other):
|
155 | |
return isinstance(other, self.__class__) and self.ref == other.ref and self.offset == other.offset and self.index == other.index
|
156 | |
|
157 | |
def __hash__(self):
|
158 | |
return hash(self.__class__.name) ^ hash(self.ref) ^ hash(self.offset) ^ hash(self.index)
|
159 | |
|
160 | |
def __repr__(self):
|
161 | |
return '%s(%r, %r, %r)' % (self.__class__.__name__, self.ref, self.offset, self.index)
|
|
101 |
class IndexedRef(namedtuple('IndexedRef', ['reftype', 'ref', 'offset', 'index'])):
|
|
102 |
def __new__(cls, *args):
|
|
103 |
return super(IndexedRef, cls).__new__(cls, 'indexed', *args)
|
162 | 104 |
|
163 | 105 |
@property
|
164 | 106 |
def name(self):
|
165 | 107 |
return '{}+{}+{}'.format(self.ref.name, self.offset, self.index.name)
|
166 | 108 |
|
167 | 109 |
|
168 | |
class ConstantRef(Ref):
|
169 | |
def __init__(self, type, value):
|
170 | |
self.type = type
|
171 | |
self.value = value
|
172 | |
|
173 | |
def __eq__(self, other):
|
174 | |
return isinstance(other, ConstantRef) and (
|
175 | |
other.type == self.type and other.value == self.value
|
176 | |
)
|
177 | |
|
178 | |
def __hash__(self):
|
179 | |
return hash(str(self.value) + str(self.type))
|
180 | |
|
181 | |
def __repr__(self):
|
182 | |
return '%s(%r, %r)' % (self.__class__.__name__, self.type, self.value)
|
|
110 |
class ConstantRef(namedtuple('ConstantRef', ['reftype', 'type', 'value'])):
|
|
111 |
def __new__(cls, *args):
|
|
112 |
return super(ConstantRef, cls).__new__(cls, 'constant', *args)
|
183 | 113 |
|
184 | 114 |
def high_byte(self):
|
185 | 115 |
return (self.value >> 8) & 255
|
|
206 | 136 |
return 'constant({})'.format(self.value)
|
207 | 137 |
|
208 | 138 |
|
209 | |
REG_A = LocationRef(TYPE_BYTE, 'a')
|
210 | |
REG_X = LocationRef(TYPE_BYTE, 'x')
|
211 | |
REG_Y = LocationRef(TYPE_BYTE, 'y')
|
|
139 |
REG_A = LocationRef('a')
|
|
140 |
REG_X = LocationRef('x')
|
|
141 |
REG_Y = LocationRef('y')
|
212 | 142 |
|
213 | |
FLAG_Z = LocationRef(TYPE_BIT, 'z')
|
214 | |
FLAG_C = LocationRef(TYPE_BIT, 'c')
|
215 | |
FLAG_N = LocationRef(TYPE_BIT, 'n')
|
216 | |
FLAG_V = LocationRef(TYPE_BIT, 'v')
|
|
143 |
FLAG_Z = LocationRef('z')
|
|
144 |
FLAG_C = LocationRef('c')
|
|
145 |
FLAG_N = LocationRef('n')
|
|
146 |
FLAG_V = LocationRef('v')
|