17 | 17 |
class Parser(object):
|
18 | 18 |
def __init__(self, text):
|
19 | 19 |
self.scanner = Scanner(text)
|
20 | |
self.symbols = {} # token -> SymEntry
|
21 | |
self.typedefs = {} # token -> Type AST
|
|
20 |
self.symbols = {} # token -> SymEntry
|
|
21 |
self.current_statics = {} # token -> SymEntry
|
|
22 |
self.typedefs = {} # token -> Type AST
|
22 | 23 |
for token in ('a', 'x', 'y'):
|
23 | 24 |
self.symbols[token] = SymEntry(None, LocationRef(TYPE_BYTE, token))
|
24 | 25 |
for token in ('c', 'z', 'n', 'v'):
|
|
26 | 27 |
self.backpatch_instrs = []
|
27 | 28 |
|
28 | 29 |
def lookup(self, name):
|
|
30 |
if name in self.current_statics:
|
|
31 |
return self.current_statics[name].model
|
29 | 32 |
if name not in self.symbols:
|
30 | 33 |
raise SyntaxError('Undefined symbol "%s"' % name)
|
31 | 34 |
return self.symbols[name].model
|
|
208 | 211 |
type_ = self.defn_type()
|
209 | 212 |
if not isinstance(type_, RoutineType):
|
210 | 213 |
raise SyntaxError("Can only define a routine, not %r" % type_)
|
|
214 |
statics = []
|
211 | 215 |
if self.scanner.consume('@'):
|
212 | 216 |
self.scanner.check_type('integer literal')
|
213 | 217 |
block = None
|
214 | 218 |
addr = int(self.scanner.token)
|
215 | 219 |
self.scanner.scan()
|
216 | 220 |
else:
|
|
221 |
statics = self.statics()
|
|
222 |
|
|
223 |
self.current_statics = {}
|
|
224 |
for defn in statics:
|
|
225 |
name = defn.name
|
|
226 |
if name in self.symbols or name in self.current_statics:
|
|
227 |
raise SyntaxError('Symbol "%s" already declared' % name)
|
|
228 |
self.current_statics[name] = SymEntry(defn, defn.location)
|
217 | 229 |
block = self.block()
|
|
230 |
self.current_statics = {}
|
|
231 |
|
218 | 232 |
addr = None
|
219 | 233 |
location = LocationRef(type_, name)
|
220 | 234 |
return Routine(
|
221 | 235 |
name=name, block=block, addr=addr,
|
222 | |
location=location
|
|
236 |
location=location, statics=statics
|
223 | 237 |
)
|
224 | 238 |
|
225 | 239 |
def labels(self):
|
|
282 | 296 |
index = self.locexpr()
|
283 | 297 |
loc = IndexedRef(loc, index)
|
284 | 298 |
return loc
|
|
299 |
|
|
300 |
def statics(self):
|
|
301 |
defns = []
|
|
302 |
while self.scanner.consume('static'):
|
|
303 |
defn = self.defn()
|
|
304 |
if defn.initial is None:
|
|
305 |
raise SyntaxError("Static definition {} must have initial value".format(defn))
|
|
306 |
defns.append(defn)
|
|
307 |
return defns
|
285 | 308 |
|
286 | 309 |
def block(self):
|
287 | 310 |
instrs = []
|