diff --git a/src/sixtypical/parser.py b/src/sixtypical/parser.py index 5007d53..618ea2a 100644 --- a/src/sixtypical/parser.py +++ b/src/sixtypical/parser.py @@ -29,6 +29,8 @@ class Parser(object): raise SyntaxError('Undefined symbol "%s"' % name) return self.symbols[name].model + # --- grammar productions + def program(self): defns = [] routines = [] @@ -47,6 +49,19 @@ class Parser(object): self.symbols[name] = SymEntry(routine, routine.location) routines.append(routine) self.scanner.check_type('EOF') + # now backpatch the executable types. + for defn in defns: + if isinstance(defn.location.type, VectorType): + t = defn.location.type + t.inputs = set([self.lookup(w) for w in t.inputs]) + t.outputs = set([self.lookup(w) for w in t.outputs]) + t.trashes = set([self.lookup(w) for w in t.trashes]) + for routine in routines: + if isinstance(routine.location.type, ExecutableType): + t = routine.location.type + t.inputs = set([self.lookup(w) for w in t.inputs]) + t.outputs = set([self.lookup(w) for w in t.outputs]) + t.trashes = set([self.lookup(w) for w in t.trashes]) return Program(defns=defns, routines=routines) def defn(self): @@ -108,11 +123,11 @@ class Parser(object): outputs = set() trashes = set() if self.scanner.consume('inputs'): - inputs = set(self.locexprs()) + inputs = set(self.labels()) if self.scanner.consume('outputs'): - outputs = set(self.locexprs()) + outputs = set(self.labels()) if self.scanner.consume('trashes'): - trashes = set(self.locexprs()) + trashes = set(self.labels()) return (inputs, outputs, trashes) def routine(self): @@ -137,6 +152,20 @@ class Parser(object): location=location ) + def labels(self): + accum = [] + accum.append(self.label()) + while self.scanner.consume(','): + accum.append(self.label()) + return accum + + def label(self): + """Like a locexpr, but does not allow literal values, and the labels do not + need to be defined yet. They will be resolved at the end of parsing.""" + loc = self.scanner.token + self.scanner.scan() + return loc + def locexprs(self): accum = [] accum.append(self.locexpr()) diff --git a/tests/SixtyPical Syntax.md b/tests/SixtyPical Syntax.md index b7b6c73..8fdebee 100644 --- a/tests/SixtyPical Syntax.md +++ b/tests/SixtyPical Syntax.md @@ -305,6 +305,25 @@ Only vectors can be decorated with constraints like that. | } ? SyntaxError +Constraints set may only contain labels. + + | vector cinv + | inputs a + | outputs 200 + | trashes a, x, z, n + | @ 788 + | + | routine foo { + | ld a, 0 + | } + | routine main { + | with interrupts off { + | copy foo, cinv + | } + | call cinv + | } + ? SyntaxError + A vector can name itself in its inputs, outputs, and trashes. | vector cinv