From f73a2313bdda39a85ca889b91497781f667f6697 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Thu, 8 Mar 2018 17:17:49 +0000 Subject: [PATCH] Add some failing tests for analyzing "for". --- src/sixtypical/analyzer.py | 13 +++++++++- tests/SixtyPical Analysis.md | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/sixtypical/analyzer.py b/src/sixtypical/analyzer.py index 88088aa..e413727 100644 --- a/src/sixtypical/analyzer.py +++ b/src/sixtypical/analyzer.py @@ -1,6 +1,6 @@ # encoding: UTF-8 -from sixtypical.ast import Program, Routine, Block, Instr, SingleOp, If, Repeat, WithInterruptsOff +from sixtypical.ast import Program, Routine, Block, Instr, SingleOp, If, Repeat, For, WithInterruptsOff from sixtypical.model import ( TYPE_BYTE, TYPE_WORD, TableType, BufferType, PointerType, VectorType, RoutineType, @@ -329,6 +329,8 @@ class Analyzer(object): self.analyze_if(instr, context) elif isinstance(instr, Repeat): self.analyze_repeat(instr, context) + elif isinstance(instr, For): + self.analyze_for(instr, context) elif isinstance(instr, WithInterruptsOff): self.analyze_block(instr.block, context) else: @@ -611,3 +613,12 @@ class Analyzer(object): self.analyze_block(instr.block, context) if instr.src is not None: context.assert_meaningful(instr.src) + + def analyze_for(self, instr, context): + # TODO: find the range of the loop variable in context, make sure it fits + + # TODO: set the loop variable as 'not writeable' in the context + + self.analyze_block(instr.block, context) + + # TODO: at the end of the loop, we know the new range of the loop variable diff --git a/tests/SixtyPical Analysis.md b/tests/SixtyPical Analysis.md index 47a9124..c9d2431 100644 --- a/tests/SixtyPical Analysis.md +++ b/tests/SixtyPical Analysis.md @@ -1659,6 +1659,56 @@ The body of `repeat forever` can be empty. | } = ok +### for ### + +Basic "open-faced for" loop. We'll start with the "upto" variant. + +In a "for" loop, we know the exact range the loop variable takes on. + + | byte table[16] tab + | + | define foo routine inputs tab trashes a, x, c, z, v, n { + | ld x, 0 + | for x upto 15 { + | ld a, tab + x + | } + | } + = ok + + | byte table[15] tab + | + | define foo routine inputs tab trashes a, x, c, z, v, n { + | ld x, 0 + | for x upto 15 { + | ld a, tab + x + | } + | } + ? RangeExceededError + +You cannot modify the loop variable in a "for" loop. + + | byte table[16] tab + | + | define foo routine inputs tab trashes a, x, c, z, v, n { + | ld x, 0 + | for x upto 15 { + | ld x, 0 + | } + | } + ? ForbiddenWriteError + +If the range isn't known to be smaller than the final value, you can't go up to it. + + | byte table[32] tab + | + | define foo routine inputs tab trashes a, x, c, z, v, n { + | ld x, 16 + | for x upto 15 { + | ld a, tab + x + | } + | } + ? RangeExceededError + ### copy ### Can't `copy` from a memory location that isn't initialized.