Write stored values, and read values, through pointers.
Chris Pressey
4 years ago
7 | 7 | * Can `copy` literals into user-defined destinations. |
8 | 8 | * `buffer` and `pointer` types. |
9 | 9 | * `copy ^` syntax to load the addr of a buffer into a pointer. |
10 | * `copy []+y` syntax to write a value into memory through a pointer. | |
11 | * TODO: read through pointer. | |
12 | * TODO: insist the buffer being read or written to through pointer, appears in approporiate set. | |
10 | * `copy []+y` syntax to read and write values to and from memory through a pointer. | |
13 | 11 | |
14 | 12 | 0.7 |
15 | 13 | --- |
40 | 40 | TODO |
41 | 41 | ---- |
42 | 42 | |
43 | Insist the buffer being read or written to through pointer, appears in approporiate set. | |
44 | ||
45 | Add to pointer. | |
46 | ||
43 | 47 | ### `word table` and `vector table` types |
44 | 48 | |
45 | 49 | ### `low` and `high` address operators |
0 | 0 | buffer[2048] buf |
1 | 1 | pointer ptr @ 254 |
2 | byte foo | |
2 | 3 | |
3 | 4 | routine main |
4 | 5 | inputs buf |
5 | outputs buf, y | |
6 | outputs buf, y, foo | |
6 | 7 | trashes a, z, n, ptr |
7 | 8 | { |
8 | 9 | ld y, 0 |
9 | 10 | copy ^buf, ptr |
10 | 11 | copy 123, [ptr] + y |
12 | copy [ptr] + y, foo | |
13 | copy foo, [ptr] + y | |
11 | 14 | } |
294 | 294 | elif opcode == 'copy': |
295 | 295 | # 1. check that their types are compatible |
296 | 296 | |
297 | if isinstance(dest, IndirectRef): | |
297 | if isinstance(src, AddressRef) and isinstance(dest, LocationRef): | |
298 | if isinstance(src.ref.type, BufferType) and isinstance(dest.type, PointerType): | |
299 | pass | |
300 | else: | |
301 | raise TypeMismatchError((src, dest)) | |
302 | elif isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndirectRef): | |
298 | 303 | if src.type == TYPE_BYTE and isinstance(dest.ref.type, PointerType): |
299 | 304 | pass |
300 | 305 | else: |
301 | 306 | raise TypeMismatchError((src, dest)) |
302 | elif isinstance(src, AddressRef): | |
303 | if isinstance(src.ref.type, BufferType) and isinstance(dest.type, PointerType): | |
304 | pass | |
305 | else: | |
306 | raise TypeMismatchError((src, dest)) | |
307 | ||
307 | elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef): | |
308 | if isinstance(src.ref.type, PointerType) and dest.type == TYPE_BYTE: | |
309 | pass | |
310 | else: | |
311 | raise TypeMismatchError((src, dest)) | |
308 | 312 | elif isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, LocationRef): |
309 | 313 | if src.type == dest.type: |
310 | 314 | pass |
325 | 329 | |
326 | 330 | # 2. check that the context is meaningful |
327 | 331 | |
328 | if isinstance(dest, IndirectRef): | |
332 | if isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndirectRef): | |
329 | 333 | context.assert_meaningful(src, REG_Y) |
330 | 334 | # TODO this will need to be more sophisticated. it's the thing ref points to that is written, not ref itself. |
331 | 335 | context.set_written(dest.ref) |
336 | elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef): | |
337 | context.assert_meaningful(src.ref, REG_Y) | |
338 | # TODO this will need to be more sophisticated. the thing ref points to is touched, as well. | |
339 | context.set_touched(src.ref) | |
340 | context.set_written(dest) | |
332 | 341 | else: |
333 | 342 | context.assert_meaningful(src) |
334 | 343 | context.set_written(dest) |
273 | 273 | self.compile_block(instr.block) |
274 | 274 | self.emitter.emit(CLI()) |
275 | 275 | elif opcode == 'copy': |
276 | if isinstance(dest, IndirectRef): | |
276 | if isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndirectRef): | |
277 | 277 | if src.type == TYPE_BYTE and isinstance(dest.ref.type, PointerType): |
278 | 278 | if isinstance(src, ConstantRef): |
279 | 279 | dest_label = self.labels[dest.ref.name] |
280 | 280 | self.emitter.emit(LDA(Immediate(Byte(src.value)))) |
281 | 281 | self.emitter.emit(STA(IndirectY(dest_label))) |
282 | elif isinstance(src, LocationRef): | |
283 | src_label = self.labels[src.name] | |
284 | dest_label = self.labels[dest.ref.name] | |
285 | self.emitter.emit(LDA(Absolute(src_label))) | |
286 | self.emitter.emit(STA(IndirectY(dest_label))) | |
282 | 287 | else: |
283 | 288 | raise NotImplementedError((src, dest)) |
289 | else: | |
290 | raise NotImplementedError((src, dest)) | |
291 | elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef): | |
292 | if dest.type == TYPE_BYTE and isinstance(src.ref.type, PointerType): | |
293 | src_label = self.labels[src.ref.name] | |
294 | dest_label = self.labels[dest.name] | |
295 | self.emitter.emit(LDA(IndirectY(src_label))) | |
296 | self.emitter.emit(STA(Absolute(dest_label))) | |
284 | 297 | else: |
285 | 298 | raise NotImplementedError((src, dest)) |
286 | 299 | elif isinstance(src, AddressRef) and isinstance(dest, LocationRef) and \ |
1176 | 1176 | Buffers and pointers. |
1177 | 1177 | |
1178 | 1178 | Note that `^buf` is not considered "reading" buf, so does not require it in `inputs`. |
1179 | TODO: It *should* require it in `outputs`. | |
1179 | TODO: If reading from it through a pointer, it *should* require it in `inputs`. | |
1180 | TODO: If writing to it through a pointer, it *should* require it in `outputs`. | |
1181 | ||
1182 | Write literal through a pointer. | |
1180 | 1183 | |
1181 | 1184 | | buffer[2048] buf |
1182 | 1185 | | pointer ptr |
1183 | 1186 | | |
1184 | 1187 | | routine main |
1185 | | outputs y | |
1188 | | outputs y //, buf | |
1186 | 1189 | | trashes a, z, n, ptr |
1187 | 1190 | | { |
1188 | 1191 | | ld y, 0 |
1197 | 1200 | | pointer ptr |
1198 | 1201 | | |
1199 | 1202 | | routine main |
1203 | | // outputs buf | |
1200 | 1204 | | trashes a, z, n, ptr |
1201 | 1205 | | { |
1202 | 1206 | | copy ^buf, ptr |
1203 | 1207 | | copy 123, [ptr] + y |
1204 | 1208 | | } |
1205 | 1209 | ? UnmeaningfulReadError |
1210 | ||
1211 | Write stored value through a pointer. | |
1212 | ||
1213 | | buffer[2048] buf | |
1214 | | pointer ptr | |
1215 | | byte foo | |
1216 | | | |
1217 | | routine main | |
1218 | | inputs foo | |
1219 | | outputs y //, buf | |
1220 | | trashes a, z, n, ptr | |
1221 | | { | |
1222 | | ld y, 0 | |
1223 | | copy ^buf, ptr | |
1224 | | copy foo, [ptr] + y | |
1225 | | } | |
1226 | = ok | |
1227 | ||
1228 | Read through a pointer. | |
1229 | ||
1230 | | buffer[2048] buf | |
1231 | | pointer ptr | |
1232 | | byte foo | |
1233 | | | |
1234 | | routine main | |
1235 | | // inputs buf | |
1236 | | outputs foo | |
1237 | | trashes a, y, z, n, ptr | |
1238 | | { | |
1239 | | ld y, 0 | |
1240 | | copy ^buf, ptr | |
1241 | | copy [ptr] + y, foo | |
1242 | | } | |
1243 | = ok | |
1206 | 1244 | |
1207 | 1245 | ### routines ### |
1208 | 1246 |
356 | 356 | | } |
357 | 357 | = 00c0a000a90b85fea9c085ff60 |
358 | 358 | |
359 | Writing through a pointer. | |
359 | Writing literal through a pointer. | |
360 | 360 | |
361 | 361 | | buffer[2048] buf |
362 | 362 | | pointer ptr @ 254 |
370 | 370 | | copy 123, [ptr] + y |
371 | 371 | | } |
372 | 372 | = 00c0a000a90f85fea9c085ffa97b91fe60 |
373 | ||
374 | Write stored value through a pointer. | |
375 | ||
376 | | buffer[2048] buf | |
377 | | pointer ptr @ 254 | |
378 | | byte foo | |
379 | | | |
380 | | routine main | |
381 | | inputs foo | |
382 | | outputs y //, buf | |
383 | | trashes a, z, n, ptr | |
384 | | { | |
385 | | ld y, 0 | |
386 | | copy ^buf, ptr | |
387 | | copy foo, [ptr] + y | |
388 | | } | |
389 | = 00c0a000a91085fea9c085ffad12c091fe60 | |
390 | ||
391 | Reading through a pointer. | |
392 | ||
393 | | buffer[2048] buf | |
394 | | pointer ptr @ 254 | |
395 | | byte foo | |
396 | | | |
397 | | routine main | |
398 | | // inputs buf | |
399 | | outputs y, foo | |
400 | | trashes a, z, n, ptr | |
401 | | { | |
402 | | ld y, 0 | |
403 | | copy ^buf, ptr | |
404 | | copy [ptr] + y, foo | |
405 | | } | |
406 | = 00c0a000a91085fea9c085ffb1fe8d12c060 |