git @ Cat's Eye Technologies SixtyPical / 4287bf8
Parse byte table declarations and indexing modifiers. Chris Pressey 6 years ago
3 changed file(s) with 35 addition(s) and 12 deletion(s). Raw diff Collapse all Expand all
00 SixtyPical
11 ==========
22
3 This document describes the SixtyPical programming language version 0.4,
3 This document describes the SixtyPical programming language version 0.5-PRE,
44 both its execution aspect and its static analysis aspect (even though
55 these are, technically speaking, separate concepts.)
66
324324 -------
325325
326326 Program ::= {Defn} {Routine}.
327 Defn ::= "byte" NewIdent.
327 Defn ::= "byte" ["table"] NewIdent ["@" WordConst].
328328 Routine ::= "routine" NewIdent
329329 ["inputs" LocExprs] ["outputs" LocExprs] ["trashes" LocExprs]
330330 (Block | "@" WordConst).
335335 LitByte ::= "0" ... "255".
336336 LitWord ::= "0" ... "65535".
337337 Block ::= "{" {Instr} "}".
338 Instr ::= "ld" LocExpr "," LocExpr
339 | "st" LocExpr "," LocExpr
338 Instr ::= "ld" LocExpr "," LocExpr ["+" LocExpr]
339 | "st" LocExpr "," LocExpr ["+" LocExpr]
340340 | "add" LocExpr "," LocExpr
341341 | "sub" LocExpr "," LocExpr
342342 | "cmp" LocExpr "," LocExpr
33
44 from sixtypical.ast import Program, Defn, Routine, Block, Instr
55 from sixtypical.model import (
6 TYPE_BIT, TYPE_BYTE, LocationRef, ConstantRef
6 TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE,
7 LocationRef, ConstantRef
78 )
89
910
3132 self.token = None
3233 self.type = 'EOF'
3334 return
34 if self.scan_pattern(r'\,|\@|\{|\}', 'operator'):
35 if self.scan_pattern(r'\,|\@|\+|\{|\}', 'operator'):
3536 return
3637 if self.scan_pattern(r'\d+', 'integer literal'):
3738 return
9899 defn = self.defn()
99100 name = defn.name
100101 if name in self.symbols:
101 raise SyntaxError(name)
102 self.symbols[name] = SymEntry(defn, LocationRef(TYPE_BYTE, name))
102 raise SyntaxError('Symbol "%s" already declared' % name)
103 self.symbols[name] = SymEntry(defn, LocationRef(defn.type, name))
103104 defns.append(defn)
104105 while self.scanner.on('routine'):
105106 routine = self.routine()
112113 return Program(defns=defns, routines=routines)
113114
114115 def defn(self):
116 type = TYPE_BYTE
115117 self.scanner.expect('byte')
118 if self.scanner.consume('table'):
119 type = TYPE_BYTE_TABLE
120 self.scanner.check_type('identifier')
116121 name = self.scanner.token
117122 self.scanner.scan()
118123 addr = None
120125 self.scanner.check_type('integer literal')
121126 addr = int(self.scanner.token)
122127 self.scanner.scan()
123 return Defn(name=name, addr=addr)
128 return Defn(name=name, type=type, addr=addr)
124129
125130 def routine(self):
126131 self.scanner.expect('routine')
207212 dest = self.locexpr()
208213 self.scanner.expect(',')
209214 src = self.locexpr()
210 return Instr(opcode=opcode, dest=dest, src=src)
215 index = None
216 if self.scanner.consume('+'):
217 index = self.locexpr()
218 return Instr(opcode=opcode, dest=dest, src=src, index=index)
211219 elif self.scanner.token in ("st",):
212220 opcode = self.scanner.token
213221 self.scanner.scan()
214222 src = self.locexpr()
215223 self.scanner.expect(',')
216224 dest = self.locexpr()
217 return Instr(opcode=opcode, dest=dest, src=src)
225 index = None
226 if self.scanner.consume('+'):
227 index = self.locexpr()
228 return Instr(opcode=opcode, dest=dest, src=src, index=index)
218229 elif self.scanner.token in ("shl", "shr", "inc", "dec"):
219230 opcode = self.scanner.token
220231 self.scanner.scan()
228239 # TODO: check that is has been defined
229240 return Instr(opcode=opcode, name=name, dest=None, src=None)
230241 else:
231 raise ValueError('bad opcode')
242 raise ValueError('bad opcode "%s"' % self.scanner.token)
165165 | ld y, 1
166166 | }
167167 ? SyntaxError
168
169 Declaring a byte table memory location.
170
171 | byte table tab
172 |
173 | routine main {
174 | ld x, 0
175 | ld y, 0
176 | ld a, tab + x
177 | st a, tab + y
178 | }
179 = ok