1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2024-11-26 14:49:15 +00:00

Lessen dependence on the internals of ParsingContext.

This commit is contained in:
Chris Pressey 2018-03-29 17:31:14 +01:00
parent b63b880b8c
commit 237a8b5b39

View File

@ -33,6 +33,13 @@ class ParsingContext(object):
def __str__(self): def __str__(self):
return "Symbols: {}\nStatics: {}\nTypedefs: {}\nConsts: {}".format(self.symbols, self.statics, self.typedefs, self.consts) return "Symbols: {}\nStatics: {}\nTypedefs: {}\nConsts: {}".format(self.symbols, self.statics, self.typedefs, self.consts)
def lookup(self, name):
if name in self.statics:
return self.statics[name].model
if name in self.symbols:
return self.symbols[name].model
return None
class Parser(object): class Parser(object):
def __init__(self, context, text, filename): def __init__(self, context, text, filename):
@ -43,15 +50,8 @@ class Parser(object):
def syntax_error(self, msg): def syntax_error(self, msg):
self.scanner.syntax_error(msg) self.scanner.syntax_error(msg)
def soft_lookup(self, name):
if name in self.context.statics:
return self.context.statics[name].model
if name in self.context.symbols:
return self.context.symbols[name].model
return None
def lookup(self, name): def lookup(self, name):
model = self.soft_lookup(name) model = self.context.lookup(name)
if model is None: if model is None:
self.syntax_error('Undefined symbol "{}"'.format(name)) self.syntax_error('Undefined symbol "{}"'.format(name))
return model return model
@ -71,7 +71,7 @@ class Parser(object):
while self.scanner.on(*typenames): while self.scanner.on(*typenames):
defn = self.defn() defn = self.defn()
name = defn.name name = defn.name
if name in self.context.symbols: if self.context.lookup(name):
self.syntax_error('Symbol "%s" already declared' % name) self.syntax_error('Symbol "%s" already declared' % name)
self.context.symbols[name] = SymEntry(defn, defn.location) self.context.symbols[name] = SymEntry(defn, defn.location)
defns.append(defn) defns.append(defn)
@ -83,7 +83,7 @@ class Parser(object):
else: else:
routine = self.legacy_routine() routine = self.legacy_routine()
name = routine.name name = routine.name
if name in self.context.symbols: if self.context.lookup(name):
self.syntax_error('Symbol "%s" already declared' % name) self.syntax_error('Symbol "%s" already declared' % name)
self.context.symbols[name] = SymEntry(routine, routine.location) self.context.symbols[name] = SymEntry(routine, routine.location)
routines.append(routine) routines.append(routine)
@ -99,18 +99,16 @@ class Parser(object):
for instr in self.backpatch_instrs: for instr in self.backpatch_instrs:
if instr.opcode in ('call', 'goto'): if instr.opcode in ('call', 'goto'):
name = instr.location name = instr.location
if name not in self.context.symbols: model = self.lookup(name)
self.syntax_error('Undefined routine "%s"' % name) if not isinstance(model.type, (RoutineType, VectorType)):
if not isinstance(self.context.symbols[name].model.type, (RoutineType, VectorType)):
self.syntax_error('Illegal call of non-executable "%s"' % name) self.syntax_error('Illegal call of non-executable "%s"' % name)
instr.location = self.context.symbols[name].model instr.location = model
if instr.opcode in ('copy',) and isinstance(instr.src, basestring): if instr.opcode in ('copy',) and isinstance(instr.src, basestring):
name = instr.src name = instr.src
if name not in self.context.symbols: model = self.lookup(name)
self.syntax_error('Undefined routine "%s"' % name) if not isinstance(model.type, (RoutineType, VectorType)):
if not isinstance(self.context.symbols[name].model.type, (RoutineType, VectorType)):
self.syntax_error('Illegal copy of non-executable "%s"' % name) self.syntax_error('Illegal copy of non-executable "%s"' % name)
instr.src = self.context.symbols[name].model instr.src = model
return Program(self.scanner.line_number, defns=defns, routines=routines) return Program(self.scanner.line_number, defns=defns, routines=routines)
@ -304,7 +302,7 @@ class Parser(object):
c = {} c = {}
for defn in statics: for defn in statics:
name = defn.name name = defn.name
if name in self.context.symbols or name in self.context.statics: if self.context.lookup(name):
self.syntax_error('Symbol "%s" already declared' % name) self.syntax_error('Symbol "%s" already declared' % name)
c[name] = SymEntry(defn, defn.location) c[name] = SymEntry(defn, defn.location)
return c return c
@ -336,7 +334,7 @@ class Parser(object):
elif forward: elif forward:
name = self.scanner.token name = self.scanner.token
self.scanner.scan() self.scanner.scan()
loc = self.soft_lookup(name) loc = self.context.lookup(name)
if loc is not None: if loc is not None:
return loc return loc
else: else: