It's getting a little chaotic. Needs better error messages!
Chris Pressey
9 years ago
33 | 33 | For 0.6: |
34 | 34 | |
35 | 35 | * `call` vector (generates an JSR to a trampoline that does indirect JMP.) |
36 | * `goto` (tail call) a routine or a vector. | |
36 | * `goto` (tail call) a a vector. | |
37 | * add routine name to error messages. | |
38 | * routines shouldn't need to be listed as inputs. | |
39 | ||
40 | For 0.7: | |
41 | ||
37 | 42 | * A more involved demo for the C64 — one that sets up an interrupt? |
38 | 43 | |
39 | For 0.7: | |
44 | For 0.8: | |
40 | 45 | |
41 | 46 | * `word` type. |
42 | 47 | * `trash` instruction. |
46 | 51 | At some point... |
47 | 52 | |
48 | 53 | * `interrupt` routines. |
49 | * add line number (or at least routine name) to error messages. | |
50 | 54 | * 6502-mnemonic aliases (`sec`, `clc`) |
51 | 55 | * other handy aliases (`eq` for `z`, etc.) |
52 | 56 | * have `copy` instruction able to copy a constant to a user-def mem loc, etc. |
152 | 152 | type = routine.location.type |
153 | 153 | context = Context(type.inputs, type.outputs, type.trashes) |
154 | 154 | self.analyze_block(routine.block, context, routines) |
155 | for ref in type.outputs: | |
156 | context.assert_meaningful(ref, exception_class=UninitializedOutputError) | |
157 | for ref in context.each_touched(): | |
158 | if ref not in type.outputs and ref not in type.trashes: | |
159 | raise IllegalWriteError(ref.name) | |
155 | if not self.has_encountered_goto: | |
156 | for ref in type.outputs: | |
157 | context.assert_meaningful(ref, exception_class=UninitializedOutputError) | |
158 | for ref in context.each_touched(): | |
159 | if ref not in type.outputs and ref not in type.trashes: | |
160 | raise IllegalWriteError(ref.name) | |
160 | 161 | self.current_routine = None |
161 | 162 | |
162 | 163 | def analyze_block(self, block, context, routines): |
1133 | 1133 | | } |
1134 | 1134 | = ok |
1135 | 1135 | |
1136 | Calling the vector has indeed trashed stuff etc, | |
1136 | Calling the vector does indeed trash the things the vector says it does. | |
1137 | 1137 | |
1138 | 1138 | | vector foo trashes x, z, n |
1139 | 1139 | | |
1219 | 1219 | | goto bar |
1220 | 1220 | | } |
1221 | 1221 | ? IncompatibleConstraintsError |
1222 | ||
1223 | Can `goto` a routine that outputs or trashes less than the current routine. | |
1224 | ||
1225 | | routine bar trashes x, z, n { | |
1226 | | ld x, 1 | |
1227 | | } | |
1228 | | | |
1229 | | routine main trashes a, x, z, n { | |
1230 | | ld a, 0 | |
1231 | | ld x, 0 | |
1232 | | goto bar | |
1233 | | } | |
1234 | = ok | |
1235 | ||
1236 | Indirect goto. | |
1237 | ||
1238 | | vector foo outputs x trashes a, z, n | |
1239 | | | |
1240 | | routine bar outputs x trashes a, z, n { | |
1241 | | ld x, 200 | |
1242 | | } | |
1243 | | | |
1244 | | routine main inputs bar outputs x trashes foo, a, z, n { | |
1245 | | copy bar, foo | |
1246 | | goto foo | |
1247 | | } | |
1248 | = ok | |
1249 | ||
1250 | Jumping through the vector does indeed output the things the vector says it does. | |
1251 | ||
1252 | | vector foo trashes a, x, z, n | |
1253 | | | |
1254 | | routine bar trashes a, x, z, n { | |
1255 | | ld x, 200 | |
1256 | | } | |
1257 | | | |
1258 | | routine sub inputs bar trashes foo, a, x, z, n { | |
1259 | | ld x, 0 | |
1260 | | copy bar, foo | |
1261 | | goto foo | |
1262 | | } | |
1263 | | | |
1264 | | routine main inputs bar outputs a trashes z, n { | |
1265 | | call sub | |
1266 | | ld a, x | |
1267 | | } | |
1268 | ? UninitializedOutputError: x | |
1269 | ||
1270 | Ack, I have become a bit confused... |