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:
parent
b63b880b8c
commit
237a8b5b39
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user