git @ Cat's Eye Technologies SixtyPical / fc8c85e
word types, with syntax and analysis thereof Chris Pressey 7 years ago
6 changed file(s) with 163 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
157157 self.current_routine = None
158158 self.has_encountered_goto = False
159159 self.routines = {}
160
161 def assert_type(self, type, *locations):
162 for location in locations:
163 if location.type != type:
164 raise TypeMismatchError('%s in %s' %
165 (location.name, self.current_routine.name)
166 )
160167
161168 def analyze_program(self, program):
162169 assert isinstance(program, Program)
201208 if src.type == TYPE_BYTE_TABLE and dest.type == TYPE_BYTE:
202209 pass
203210 else:
204 raise TypeMismatchError((src, dest))
211 raise TypeMismatchError('%s and %s in %s' %
212 (src.name, dest.name, self.current_routine.name)
213 )
205214 elif src.type != dest.type:
206 raise TypeMismatchError((src, dest))
215 raise TypeMismatchError('%s and %s in %s' %
216 (src.name, dest.name, self.current_routine.name)
217 )
207218 context.assert_meaningful(src)
208219 context.set_written(dest, FLAG_Z, FLAG_N)
209220 elif opcode == 'st':
213224 else:
214225 raise TypeMismatchError((src, dest))
215226 elif src.type != dest.type:
216 raise TypeMismatchError((src, dest))
227 raise TypeMismatchError('%s and %s in %s' %
228 (src.name, dest.name, self.current_routine.name)
229 )
217230 context.assert_meaningful(src)
218231 context.set_written(dest)
219232 elif opcode in ('add', 'sub'):
233 self.assert_type(TYPE_BYTE, src, dest)
220234 context.assert_meaningful(src, dest, FLAG_C)
221235 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
222236 elif opcode in ('inc', 'dec'):
237 self.assert_type(TYPE_BYTE, dest)
223238 context.assert_meaningful(dest)
224239 context.set_written(dest, FLAG_Z, FLAG_N)
225240 elif opcode == 'cmp':
241 self.assert_type(TYPE_BYTE, src, dest)
226242 context.assert_meaningful(src, dest)
227243 context.set_written(FLAG_Z, FLAG_N, FLAG_C)
228244 elif opcode in ('and', 'or', 'xor'):
245 self.assert_type(TYPE_BYTE, src, dest)
229246 context.assert_meaningful(src, dest)
230247 context.set_written(dest, FLAG_Z, FLAG_N)
231248 elif opcode in ('shl', 'shr'):
249 self.assert_type(TYPE_BYTE, dest)
232250 context.assert_meaningful(dest, FLAG_C)
233251 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C)
234252 elif opcode == 'call':
1616 TYPE_BIT = Type('bit')
1717 TYPE_BYTE = Type('byte')
1818 TYPE_BYTE_TABLE = Type('byte table')
19 TYPE_WORD = Type('word')
20 TYPE_WORD_TABLE = Type('word table')
1921
2022
2123 class ExecutableType(Type):
11
22 from sixtypical.ast import Program, Defn, Routine, Block, Instr
33 from sixtypical.model import (
4 TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE,
4 TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_WORD, TYPE_WORD_TABLE,
55 RoutineType, VectorType, ExecutableType,
66 LocationRef, ConstantRef
77 )
3131 def program(self):
3232 defns = []
3333 routines = []
34 while self.scanner.on('byte') or self.scanner.on('vector'):
34 while self.scanner.on('byte', 'word', 'vector'):
3535 defn = self.defn()
3636 name = defn.name
3737 if name in self.symbols:
4949 return Program(defns=defns, routines=routines)
5050
5151 def defn(self):
52 type = TYPE_BYTE
52 type = None
5353 if self.scanner.consume('byte'):
5454 type = TYPE_BYTE
5555 if self.scanner.consume('table'):
5656 type = TYPE_BYTE_TABLE
57 elif self.scanner.consume('word'):
58 type = TYPE_WORD
59 if self.scanner.consume('table'):
60 type = TYPE_WORD_TABLE
5761 else:
5862 self.scanner.expect('vector')
59 type = 'vector'
63 type = 'vector' # will be resolved to a Type below
6064 self.scanner.check_type('identifier')
6165 name = self.scanner.token
6266 self.scanner.scan()
5454 raise SyntaxError("Expected '%s', but found '%s'" %
5555 (token, self.token))
5656
57 def on(self, token):
58 return self.token == token
57 def on(self, *tokens):
58 return self.token in tokens
5959
6060 def on_type(self, type):
6161 return self.type == type
146146 | ld a, 0
147147 | }
148148 ? ForbiddenWriteError: z in main
149
150 Can't `ld` a `word` type.
151
152 | word foo
153 |
154 | routine main
155 | inputs foo
156 | trashes a, n, z
157 | {
158 | ld a, foo
159 | }
160 ? TypeMismatchError: foo and a in main
149161
150162 ### st ###
151163
300312 | }
301313 = ok
302314
315 Can't `st` a `word` type.
316
317 | word foo
318 |
319 | routine main
320 | outputs foo
321 | trashes a, n, z
322 | {
323 | ld a, 0
324 | st a, foo
325 | }
326 ? TypeMismatchError: a and foo in main
327
303328 ### add ###
304329
305330 Can't `add` from or to a memory location that isn't initialized.
423448 | }
424449 = ok
425450
451 Can't `inc` a `word` type.
452
453 | word foo
454 |
455 | routine main
456 | inputs foo
457 | outputs foo
458 | trashes z, n
459 | {
460 | inc foo
461 | }
462 ? TypeMismatchError: foo in main
463
426464 ### dec ###
427465
428466 Location must be initialized and writeable.
451489 | dec x
452490 | }
453491 = ok
492
493 Can't `dec` a `word` type.
494
495 | word foo
496 |
497 | routine main
498 | inputs foo
499 | outputs foo
500 | trashes z, n
501 | {
502 | dec foo
503 | }
504 ? TypeMismatchError: foo in main
454505
455506 ### cmp ###
456507
10471098 | }
10481099 = ok
10491100
1101 Can `copy` from a `byte` to a `byte`.
1102
1103 | byte source : 0
1104 | byte dest
1105 |
1106 | routine main
1107 | inputs source
1108 | outputs dest
1109 | trashes a, z, n
1110 | {
1111 | copy source, dest
1112 | }
1113 = ok
1114
1115 Can `copy` from a `word` to a `word`.
1116
1117 | word source : 0
1118 | word dest
1119 |
1120 | routine main
1121 | inputs source
1122 | outputs dest
1123 | trashes a, z, n
1124 | {
1125 | copy source, dest
1126 | }
1127 = ok
1128
1129 Can't `copy` from a `byte` to a `word`.
1130
1131 | byte source : 0
1132 | word dest
1133 |
1134 | routine main
1135 | inputs source
1136 | outputs dest
1137 | trashes a, z, n
1138 | {
1139 | copy source, dest
1140 | }
1141 ? TypeMismatchError
1142
1143 Can't `copy` from a `word` to a `byte`.
1144
1145 | word source : 0
1146 | byte dest
1147 |
1148 | routine main
1149 | inputs source
1150 | outputs dest
1151 | trashes a, z, n
1152 | {
1153 | copy source, dest
1154 | }
1155 ? TypeMismatchError
1156
1157 ### routines ###
1158
10501159 Routines are constants. You need not, and in fact cannot, specify a constant
10511160 as an input to, an output of, or as a trashed value of a routine.
10521161
142142 | }
143143 = ok
144144
145 User-defined locations of other types.
146
147 | byte table screen @ 1024
148 | word r1
149 | word r2 @ 60000
150 | word r3 : 2000
151 |
152 | routine main {
153 | }
154 = ok
155
156 Initialized memory locations.
157
158 | byte lives : 3
159 |
160 | routine main {
161 | ld a, lives
162 | st a, lives
163 | }
164 = ok
165
145166 Cannot have both initial value and explicit address.
146167
147168 | byte screen : 3 @ 1024