3 | 3 |
|
4 | 4 |
from sixtypical.ast import Program, Defn, Routine, Block, Instr
|
5 | 5 |
from sixtypical.model import (
|
6 | |
TYPE_BIT, TYPE_BYTE, LocationRef, ConstantRef
|
|
6 |
TYPE_BIT, TYPE_BYTE, TYPE_BYTE_TABLE,
|
|
7 |
LocationRef, ConstantRef
|
7 | 8 |
)
|
8 | 9 |
|
9 | 10 |
|
|
31 | 32 |
self.token = None
|
32 | 33 |
self.type = 'EOF'
|
33 | 34 |
return
|
34 | |
if self.scan_pattern(r'\,|\@|\{|\}', 'operator'):
|
|
35 |
if self.scan_pattern(r'\,|\@|\+|\{|\}', 'operator'):
|
35 | 36 |
return
|
36 | 37 |
if self.scan_pattern(r'\d+', 'integer literal'):
|
37 | 38 |
return
|
|
98 | 99 |
defn = self.defn()
|
99 | 100 |
name = defn.name
|
100 | 101 |
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))
|
103 | 104 |
defns.append(defn)
|
104 | 105 |
while self.scanner.on('routine'):
|
105 | 106 |
routine = self.routine()
|
|
112 | 113 |
return Program(defns=defns, routines=routines)
|
113 | 114 |
|
114 | 115 |
def defn(self):
|
|
116 |
type = TYPE_BYTE
|
115 | 117 |
self.scanner.expect('byte')
|
|
118 |
if self.scanner.consume('table'):
|
|
119 |
type = TYPE_BYTE_TABLE
|
|
120 |
self.scanner.check_type('identifier')
|
116 | 121 |
name = self.scanner.token
|
117 | 122 |
self.scanner.scan()
|
118 | 123 |
addr = None
|
|
120 | 125 |
self.scanner.check_type('integer literal')
|
121 | 126 |
addr = int(self.scanner.token)
|
122 | 127 |
self.scanner.scan()
|
123 | |
return Defn(name=name, addr=addr)
|
|
128 |
return Defn(name=name, type=type, addr=addr)
|
124 | 129 |
|
125 | 130 |
def routine(self):
|
126 | 131 |
self.scanner.expect('routine')
|
|
207 | 212 |
dest = self.locexpr()
|
208 | 213 |
self.scanner.expect(',')
|
209 | 214 |
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)
|
211 | 219 |
elif self.scanner.token in ("st",):
|
212 | 220 |
opcode = self.scanner.token
|
213 | 221 |
self.scanner.scan()
|
214 | 222 |
src = self.locexpr()
|
215 | 223 |
self.scanner.expect(',')
|
216 | 224 |
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)
|
218 | 229 |
elif self.scanner.token in ("shl", "shr", "inc", "dec"):
|
219 | 230 |
opcode = self.scanner.token
|
220 | 231 |
self.scanner.scan()
|
|
228 | 239 |
# TODO: check that is has been defined
|
229 | 240 |
return Instr(opcode=opcode, name=name, dest=None, src=None)
|
230 | 241 |
else:
|
231 | |
raise ValueError('bad opcode')
|
|
242 |
raise ValueError('bad opcode "%s"' % self.scanner.token)
|