From d815e05e0ce713d8d59da35b42ccf61141f67750 Mon Sep 17 00:00:00 2001 From: Chris Pressey Date: Thu, 8 Mar 2018 16:54:12 +0000 Subject: [PATCH] Syntax for "open-faced for loop". --- src/sixtypical/ast.py | 5 +++++ src/sixtypical/parser.py | 23 +++++++++++++++++++---- tests/SixtyPical Syntax.md | 16 ++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/sixtypical/ast.py b/src/sixtypical/ast.py index 0ab9f33..2029173 100644 --- a/src/sixtypical/ast.py +++ b/src/sixtypical/ast.py @@ -83,5 +83,10 @@ class Repeat(Instr): child_attrs = ('block',) +class For(Instr): + value_attrs = ('dest', 'direction', 'final') + child_attrs = ('block',) + + class WithInterruptsOff(Instr): child_attrs = ('block',) diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index 4caf862..061ba03 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -1,6 +1,6 @@ # encoding: UTF-8 -from sixtypical.ast import Program, Defn, Routine, Block, SingleOp, If, Repeat, WithInterruptsOff +from sixtypical.ast import Program, Defn, Routine, Block, SingleOp, If, Repeat, For, WithInterruptsOff from sixtypical.model import ( TYPE_BIT, TYPE_BYTE, TYPE_WORD, RoutineType, VectorType, TableType, BufferType, PointerType, @@ -136,11 +136,15 @@ class Parser(object): return Defn(self.scanner.line_number, name=name, addr=addr, initial=initial, location=location) + def literal_int(self): + self.scanner.check_type('integer literal') + c = int(self.scanner.token) + self.scanner.scan() + return c + def defn_size(self): self.scanner.expect('[') - self.scanner.check_type('integer literal') - size = int(self.scanner.token) - self.scanner.scan() + size = self.literal_int() self.scanner.expect(']') return size @@ -372,6 +376,17 @@ class Parser(object): else: self.scanner.expect('forever') return Repeat(self.scanner.line_number, src=src, block=block, inverted=inverted) + elif self.scanner.consume('for'): + dest = self.locexpr() + if self.scanner.consume('downto'): + direction = -1 + elif self.scanner.consume('upto'): + direction = 1 + else: + self.syntax_error('expected "upto" or "downto", found "%s"' % self.scanner.token) + final = self.literal_int() + block = self.block() + return For(self.scanner.line_number, dest=dest, direction=direction, final=final, block=block) elif self.scanner.token in ("ld",): # the same as add, sub, cmp etc below, except supports an indlocexpr for the src opcode = self.scanner.token diff --git a/tests/SixtyPical Syntax.md b/tests/SixtyPical Syntax.md index a434345..29bd84b 100644 --- a/tests/SixtyPical Syntax.md +++ b/tests/SixtyPical Syntax.md @@ -131,6 +131,22 @@ Repeat with not | } = ok +Basic "open-faced for" loops, up and down. + + | byte table[256] tab + | + | routine foo trashes a, x, c, z, v { + | ld x, 0 + | for x upto 15 { + | ld a, tab + x + | } + | ld x, 15 + | for x downto 0 { + | ld a, tab + x + | } + | } + = ok + User-defined memory addresses of different types. | byte byt