mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-12-21 12:29:46 +00:00
Refactor the label mapper to be more like the lister.
This commit is contained in:
parent
bac908bff5
commit
5b64c9701e
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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 = []
|
||||
|
Loading…
Reference in New Issue
Block a user