From ceaae962d535af58f26ca3700c250ec7f56c2d2e Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Mon, 26 Mar 2018 12:48:57 +0100 Subject: [PATCH] Make tests pass. Add two more tests towards completeness of spec. --- src/sixtypical/analyzer.py | 23 +++++++++++++++++++---- tests/SixtyPical Analysis.md | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index 4b4e55a..830df54 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -264,9 +264,15 @@ class Context(object): self.set_meaningful(*refs) def set_unwriteable(self, *refs): + """Intended to be used for implementing analyzing `for`.""" for ref in refs: self._writeable.remove(ref) + def set_writeable(self, *refs): + """Intended to be used for implementing analyzing `for`.""" + for ref in refs: + self._writeable.add(ref) + def set_encountered_goto(self): self._has_encountered_goto = True @@ -670,9 +676,18 @@ class Analyzer(object): )) bottom = final - subcontext = context.clone() - subcontext.set_range(instr.dest, bottom, top) - subcontext.set_unwriteable(instr.dest) - self.analyze_block(instr.block, subcontext) + # inside the block, the loop variable cannot be modified, and we know its range. + context.set_range(instr.dest, bottom, top) + context.set_unwriteable(instr.dest) + # it will always be executed at least once, so analyze it having + # been executed the first time. + self.analyze_block(instr.block, context) + + # now analyze it having been executed a second time, with the context + # of it having already been executed. + self.analyze_block(instr.block, context) + + # after it is executed, we know the range of the loop variable. context.set_range(instr.dest, instr.final, instr.final) + context.set_writeable(instr.dest) diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index 023f143..074eeae 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -1685,6 +1685,17 @@ In a "for" loop, we know the exact range the loop variable takes on. | } ? RangeExceededError +You need to initialize the loop variable before the loop. + + | byte table[16] tab + | + | define foo routine inputs tab trashes a, x, c, z, v, n { + | for x up to 15 { + | ld a, 0 + | } + | } + ? UnmeaningfulReadError + You cannot modify the loop variable in a "for" loop. | byte table[16] tab @@ -1731,6 +1742,17 @@ In a "for" loop (downward-counting variant), we know the exact range the loop va | } ? RangeExceededError +You need to initialize the loop variable before a "for" loop (downward variant). + + | byte table[16] tab + | + | define foo routine inputs tab trashes a, x, c, z, v, n { + | for x down to 15 { + | ld a, 0 + | } + | } + ? UnmeaningfulReadError + You cannot modify the loop variable in a "for" loop (downward variant). | byte table[16] tab