Refactor the label mapper to be more like the lister.

This commit is contained in:
Michael Martin 2014-05-13 21:13:27 -07:00
parent bac908bff5
commit 5b64c9701e
3 changed files with 68 additions and 50 deletions

View File

@ -78,3 +78,63 @@ class NullLister(object):
def dump(self):
pass
class LabelMapper(object):
"""Encapsulates the label map. Accepts label names, string
representations of program points, and the location."""
def __init__(self, fname):
self.labeldata = []
self.filename = fname
def mapLabel(self, label, ppt, location):
if label.startswith("_"):
try:
macroarg = int(label[1:], 10)
# If that didn't throw, this is a macro argument
# and we don't want to track it.
return
except ValueError:
pass
if label.startswith("_*"):
# This is the caller side of the macro arguments,
# and we don't want to track that either.
return
if label.startswith("*"):
# Unprocess anonymous labels
label = "*"
shortlocs = []
# Filenames tend to become absolute paths for better
# error processing, but that's a disaster in these
# charts. We split out the leafs here and then re-join
# the macro application arrows.
for loc in ppt.split('->'):
shortloc = loc.split('/')[-1]
shortloc = shortloc.split('\\')[-1]
shortlocs.append(shortloc)
self.labeldata.append((location, label, '->'.join(shortlocs)))
def dump(self):
if self.filename == "-":
out = sys.stdout
else:
out = file(self.filename, "w")
maxlabellen = 0
self.labeldata.sort()
for (loc, label, srcloc) in self.labeldata:
if len(label) > maxlabellen:
maxlabellen = len(label)
formatstr = "$%%04X | %%-%ds | %%s\n" % (maxlabellen)
for l in self.labeldata:
out.write(formatstr % l)
if self.filename != "-":
out.close()
class NullLabelMapper(object):
"A dummy LabelMapper that actually does nothing."
def mapLabel(self, label, ppt, location):
pass
def dump(self):
pass

View File

@ -63,7 +63,6 @@ def run_all():
passes.append(instruction_select)
passes.extend([Ophis.Passes.NormalizeModes(),
Ophis.Passes.UpdateLabels(),
Ophis.Passes.LabelMapper(),
a])
for p in passes:

View File

@ -733,54 +733,6 @@ class NormalizeModes(Pass):
pass
class LabelMapper(PCTracker):
"""Collect the value and source definition location for each label
in the source."""
name = "Label Mapping Pass"
def prePass(self):
self.labeldata = []
def visitLabel(self, node, env):
(label, val) = node.data
if label.startswith("_"):
try:
macroarg = int(label[1:], 10)
# If that didn't throw, this is a macro argument
# and we don't want to track it.
return
except ValueError:
pass
if label.startswith("_*"):
return
if label.startswith("*"):
label = "*"
location = val.value(env)
shortlocs = []
for loc in str(node.ppt).split('->'):
shortloc = loc.split('/')[-1]
shortloc = shortloc.split('\\')[-1]
shortlocs.append(shortloc)
self.labeldata.append((location, label, '->'.join(shortlocs)))
def visitUnknown(self, node, env):
pass
def postPass(self):
# TODO: Maybe fold all this into the listing file
if Cmd.mapfile is not None:
maxlabellen = 0
self.labeldata.sort()
for (loc, label, srcloc) in self.labeldata:
if len(label) > maxlabellen:
maxlabellen = len(label)
formatstr = "$%%04X | %%-%ds | %%s\n" % (maxlabellen)
f = open(Cmd.mapfile, 'w')
for l in self.labeldata:
f.write(formatstr % l)
f.close()
class Assembler(Pass):
"""Converts the IR into a list of bytes, suitable for writing to
a file."""
@ -802,9 +754,14 @@ class Assembler(Pass):
self.listing = Listing.Listing(Cmd.listfile)
else:
self.listing = Listing.NullLister()
if Cmd.mapfile is not None:
self.mapper = Listing.LabelMapper(Cmd.mapfile)
else:
self.mapper = Listing.NullLabelMapper()
def postPass(self):
self.listing.dump()
self.mapper.dump()
if Cmd.print_summary and Err.count == 0:
print>>sys.stderr, "Assembly complete: %s bytes output " \
"(%s code, %s data, %s filler)" \
@ -1043,7 +1000,9 @@ class Assembler(Pass):
self.assemble(node, Ops.modes.index("Zero Page, Relative"), env)
def visitLabel(self, node, env):
pass
(label, val) = node.data
location = val.value(env)
self.mapper.mapLabel(label, str(node.ppt), location)
def visitByte(self, node, env):
created = []