diff --git a/src/Ophis/Listing.py b/src/Ophis/Listing.py index cf4101c..745ba94 100644 --- a/src/Ophis/Listing.py +++ b/src/Ophis/Listing.py @@ -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 diff --git a/src/Ophis/Main.py b/src/Ophis/Main.py index b84869b..32b3135 100644 --- a/src/Ophis/Main.py +++ b/src/Ophis/Main.py @@ -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: diff --git a/src/Ophis/Passes.py b/src/Ophis/Passes.py index a3ef4bf..9bde0a5 100644 --- a/src/Ophis/Passes.py +++ b/src/Ophis/Passes.py @@ -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 = []