git @ Cat's Eye Technologies SixtyPical / c3a0659
Write sufficient tests (I think) for analysis of `if`s. Chris Pressey 6 years ago
4 changed file(s) with 66 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
3030
3131 For 0.2:
3232
33 * analyze `if` correctly.
33 * write a few more tests and clean up spec a bit.
3434
3535 For 0.3:
3636
1818
1919
2020 class UninitializedOutputError(StaticAnalysisError):
21 pass
22
23
24 class InconsistentInitializationError(StaticAnalysisError):
2125 pass
2226
2327
172176 analyze_block(instr.block1, context1, routines)
173177 analyze_block(instr.block2, context2, routines)
174178 for ref in context1.each_initialized():
175 context2.assert_initialized(ref)
179 context2.assert_initialized(ref, exception_class=InconsistentInitializationError)
176180 for ref in context2.each_initialized():
177 context1.assert_initialized(ref)
181 context1.assert_initialized(ref, exception_class=InconsistentInitializationError)
178182 context.set_from(context1)
179183 else:
180184 raise NotImplementedError(opcode)
164164 block2 = None
165165 if self.scanner.consume('else'):
166166 block2 = self.block()
167 else:
168 block2 = Block(instrs=[])
167169 return Instr(opcode='if', dest=None, src=src, block1=block1, block2=block2)
168170 elif self.scanner.token in ("ld", "add", "sub", "cmp", "and", "or", "xor"):
169171 opcode = self.scanner.token
412412 | }
413413 | }
414414 = ok
415
416 If a location is initialized in one block, is must be initialized in the other as well.
417
418 | routine foo
419 | inputs a
420 | outputs x
421 | trashes a, z, n, c
422 | {
423 | cmp a, 42
424 | if z {
425 | ld x, 7
426 | } else {
427 | ld a, 23
428 | }
429 | }
430 ? InconsistentInitializationError: x
431
432 | routine foo
433 | inputs a
434 | outputs x
435 | trashes a, z, n, c
436 | {
437 | cmp a, 42
438 | if z {
439 | ld a, 6
440 | } else {
441 | ld x, 7
442 | }
443 | }
444 ? InconsistentInitializationError: x
445
446 An `if` with a single block is analyzed as if it had an empty `else` block.
447
448 | routine foo
449 | inputs a
450 | outputs x
451 | trashes a, z, n, c
452 | {
453 | cmp a, 42
454 | if z {
455 | ld x, 7
456 | }
457 | }
458 ? InconsistentInitializationError: x
459
460 | routine foo
461 | inputs a
462 | outputs x
463 | trashes a, z, n, c
464 | {
465 | ld x, 0
466 | cmp a, 42
467 | if z {
468 | ld x, 7
469 | }
470 | }
471 = ok