git @ Cat's Eye Technologies SixtyPical / 98524e9
Vector and routine types are constructors with constraints now. Chris Pressey 9 years ago
5 changed file(s) with 60 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
3232
3333 For 0.6:
3434
35 * declared `inputs` `outputs` `trashes` on the `vector` type.
35 * declared `inputs` `outputs` `trashes` on the `vector` type...
36 * we need to get these 3 things onto the type, and also onto routine types
3637 * `goto` (tail call) a routine or a vector.
3738 * A more involved demo for the C64 — one that sets up an interrupt.
3839
11
22 from sixtypical.ast import Program, Routine, Block, Instr
33 from sixtypical.model import (
4 TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_ROUTINE, TYPE_VECTOR,
4 TYPE_BYTE, TYPE_BYTE_TABLE,
5 RoutineType, VectorType,
56 ConstantRef, LocationRef,
67 REG_A, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
78 )
223224 elif opcode == 'copy':
224225 if src.type == dest.type:
225226 pass
226 elif src.type == TYPE_ROUTINE and dest.type == TYPE_VECTOR:
227 elif isinstance(src.type, RoutineType) and isinstance(dest.type, VectorType):
227228 pass
228229 else:
229230 raise TypeMismatchError((src, dest))
22 from sixtypical.ast import Program, Routine, Block, Instr
33 from sixtypical.model import (
44 ConstantRef, LocationRef,
5 TYPE_BIT, TYPE_ROUTINE, TYPE_VECTOR,
5 TYPE_BIT,
6 RoutineType, VectorType,
67 REG_A, REG_X, REG_Y, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
78 )
89 from sixtypical.emitter import Byte, Label, Offset
241242 self.compile_block(instr.block)
242243 self.emitter.emit(CLI())
243244 elif opcode == 'copy':
244 if src.type in (TYPE_ROUTINE, TYPE_VECTOR) and dest.type == TYPE_VECTOR:
245 if isinstance(src.type, (RoutineType, VectorType)) and \
246 isinstance(dest.type, VectorType):
245247 src_label = self.labels[src.name]
246248 dest_label = self.labels[dest.name]
247249 self.emitter.emit(LDA(Absolute(src_label)))
1616 TYPE_BIT = Type('bit')
1717 TYPE_BYTE = Type('byte')
1818 TYPE_BYTE_TABLE = Type('byte table')
19 TYPE_ROUTINE = Type('routine')
20 TYPE_VECTOR = Type('vector') # the mem loc contains an address of a routine
19
20
21 class InteractionConstrainedType(Type):
22 """Used for routines and vectors."""
23 def __init__(self, name, inputs=None, outputs=None, trashes=None):
24 self.name = name
25 self.inputs = inputs or []
26 self.outputs = outputs or []
27 self.trashes = trashes or []
28
29 def __repr__(self):
30 return 'RoutineType(%r, inputs=%r, outputs=%r, trashes=%r)' % (
31 self.name, self.inputs, self.outputs, self.trashes
32 )
33
34 def __eq__(self, other):
35 return isinstance(other, RoutineType) and (
36 other.name == self.name and
37 other.inputs == self.inputs and
38 other.outputs == self.outputs and
39 other.trashes == self.trashes
40 )
41
42 def __hash__(self):
43 return hash(self.name) ^ hash(self.inputs) ^ hash(self.outputs) ^ hash(self.trashes)
44
45
46 class RoutineType(InteractionConstrainedType):
47 """This memory location contains the code for a routine."""
48 def __init__(self, **kwargs):
49 super(RoutineType, self).__init__('routine', **kwargs)
50
51
52 class VectorType(InteractionConstrainedType):
53 """This memory location contains the address of a routine."""
54 def __init__(self, **kwargs):
55 super(VectorType, self).__init__('vector', **kwargs)
2156
2257
2358 class Ref(object):
33
44 from sixtypical.ast import Program, Defn, Routine, Block, Instr
55 from sixtypical.model import (
6 TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_ROUTINE, TYPE_VECTOR,
6 TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE,
7 RoutineType, VectorType,
78 LocationRef, ConstantRef
89 )
910
114115 name = routine.name
115116 if name in self.symbols:
116117 raise SyntaxError(name)
117 self.symbols[name] = SymEntry(routine, LocationRef(TYPE_ROUTINE, name))
118 ref = LocationRef(
119 RoutineType(inputs=routine.inputs,
120 outputs=routine.outputs,
121 trashes=routine.trashes
122 ), name
123 )
124 self.symbols[name] = SymEntry(routine, ref)
118125 routines.append(routine)
119126 self.scanner.check_type('EOF')
120127 return Program(defns=defns, routines=routines)
127134 type = TYPE_BYTE_TABLE
128135 else:
129136 self.scanner.expect('vector')
130 type = TYPE_VECTOR
137 type = 'vector'
131138 self.scanner.check_type('identifier')
132139 name = self.scanner.token
133140 self.scanner.scan()
134141
135142 (inputs, outputs, trashes) = self.constraints()
136 if type != TYPE_VECTOR and (inputs or outputs or trashes):
143 if type == 'vector':
144 type = VectorType(inputs=inputs, outputs=outputs, trashes=trashes)
145 elif inputs or outputs or trashes:
137146 raise SyntaxError("Cannot apply constraints to non-vector type")
138147
139148 addr = None
259268 self.scanner.scan()
260269 if name not in self.symbols:
261270 raise SyntaxError('Undefined routine "%s"' % name)
262 if self.symbols[name].model.type != TYPE_ROUTINE:
271 if not isinstance(self.symbols[name].model.type, RoutineType):
263272 raise SyntaxError('Illegal call of non-routine "%s"' % name)
264273 return Instr(opcode=opcode, name=name, dest=None, src=None)
265274 elif self.scanner.token in ("copy",):