1
0
mirror of https://github.com/catseye/SixtyPical.git synced 2025-02-16 15:30:26 +00:00

Distinct symbol resolution phase (as a method on parser.)

This commit is contained in:
Chris Pressey 2018-09-07 14:27:49 +01:00
parent cc98e023c4
commit 29a5bba85c
2 changed files with 36 additions and 37 deletions

View File

@ -18,20 +18,6 @@ class Type(object):
def __hash__(self):
return hash(self.name)
def backpatch_constraint_labels(self, resolver):
def resolve(w):
if not isinstance(w, str):
return w
return resolver(w)
if isinstance(self, TableType):
self.of_type.backpatch_constraint_labels(resolver)
elif isinstance(self, VectorType):
self.of_type.backpatch_constraint_labels(resolver)
elif isinstance(self, RoutineType):
self.inputs = set([resolve(w) for w in self.inputs])
self.outputs = set([resolve(w) for w in self.outputs])
self.trashes = set([resolve(w) for w in self.trashes])
TYPE_BIT = Type('bit', max_range=(0, 1))
TYPE_BYTE = Type('byte', max_range=(0, 255))

View File

@ -74,6 +74,41 @@ class Parser(object):
def clear_statics(self):
self.context.statics = {}
def resolve_symbols(self, program):
def backpatch_constraint_labels(type_, resolver):
def resolve(w):
if not isinstance(w, str):
return w
return resolver(w)
if isinstance(type_, TableType):
backpatch_constraint_labels(type_.of_type, resolver)
elif isinstance(type_, VectorType):
backpatch_constraint_labels(type_.of_type, resolver)
elif isinstance(type_, RoutineType):
type_.inputs = set([resolve(w) for w in type_.inputs])
type_.outputs = set([resolve(w) for w in type_.outputs])
type_.trashes = set([resolve(w) for w in type_.trashes])
for defn in program.defns:
backpatch_constraint_labels(defn.location.type, lambda w: self.lookup(w))
for routine in program.routines:
backpatch_constraint_labels(routine.location.type, lambda w: self.lookup(w))
def resolve_fwd_reference(obj, field):
field_value = getattr(obj, field, None)
if isinstance(field_value, ForwardReference):
setattr(obj, field, self.lookup(field_value.name))
elif isinstance(field_value, IndexedRef):
if isinstance(field_value.ref, ForwardReference):
field_value.ref = self.lookup(field_value.ref.name)
for node in program.all_children():
if isinstance(node, SingleOp):
resolve_fwd_reference(node, 'location')
resolve_fwd_reference(node, 'src')
resolve_fwd_reference(node, 'dest')
# --- grammar productions
def program(self):
@ -102,30 +137,8 @@ class Parser(object):
routines.append(routine)
self.scanner.check_type('EOF')
# now backpatch the executable types.
#for type_name, type_ in self.context.typedefs.items():
# type_.backpatch_constraint_labels(lambda w: self.lookup(w))
for defn in defns:
defn.location.type.backpatch_constraint_labels(lambda w: self.lookup(w))
for routine in routines:
routine.location.type.backpatch_constraint_labels(lambda w: self.lookup(w))
program = Program(self.scanner.line_number, defns=defns, routines=routines)
def resolve_fwd_reference(obj, field):
field_value = getattr(obj, field, None)
if isinstance(field_value, ForwardReference):
setattr(obj, field, self.lookup(field_value.name))
elif isinstance(field_value, IndexedRef):
if isinstance(field_value.ref, ForwardReference):
field_value.ref = self.lookup(field_value.ref.name)
for node in program.all_children():
if isinstance(node, SingleOp):
resolve_fwd_reference(node, 'location')
resolve_fwd_reference(node, 'src')
resolve_fwd_reference(node, 'dest')
self.resolve_symbols(program)
return program
def typedef(self):