From 70f93b22ebf3db9c6874e2923c62e2e6981e8bf1 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Fri, 9 May 2014 23:11:09 -0700 Subject: [PATCH] Rework label map collection This uses a pass to interrogate the system for locations, then dumps those out instead. It handles includes, anonymous labels, and basic macros, but it does so in a somewhat ugly way. This data can be readily abbreviated and should also be re-sorted. --- src/Ophis/Environment.py | 5 ----- src/Ophis/Main.py | 1 + src/Ophis/Passes.py | 41 ++++++++++++++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/Ophis/Environment.py b/src/Ophis/Environment.py index 7563d96..7d7546d 100644 --- a/src/Ophis/Environment.py +++ b/src/Ophis/Environment.py @@ -88,8 +88,3 @@ class Environment(object): if len(self.stack) == 1: Err.log("Unmatched .scend") self.stack.pop(0) - - def dump_mapfile(self, f): - for d in self.dicts: - for k in d: - f.write("{0:<30} ${1:04X}\n".format(k, d[k])) diff --git a/src/Ophis/Main.py b/src/Ophis/Main.py index 32b3135..b84869b 100644 --- a/src/Ophis/Main.py +++ b/src/Ophis/Main.py @@ -63,6 +63,7 @@ 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 4ecce5b..bb29102 100644 --- a/src/Ophis/Passes.py +++ b/src/Ophis/Passes.py @@ -733,6 +733,39 @@ 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 + location = val.value(env) + self.labeldata.append((label, str(node.ppt), location)) + + 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 + maxsrcloclen = 0 + for (label, srcloc, loc) in self.labeldata: + if len(label) > maxlabellen: + maxlabellen = len(label) + if len(srcloc) > maxsrcloclen: + maxsrcloclen = len(srcloc) + formatstr = "%%-%ds %%-%ds $%%04X\n" % (maxlabellen, maxsrcloclen) + 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.""" @@ -755,16 +788,8 @@ class Assembler(Pass): else: self.listing = Listing.NullLister() - def go(self, node, env): - # record env, as we need it in postPass - self.env = env - super(Assembler, self).go(node, env) - def postPass(self): self.listing.dump() - if Cmd.mapfile is not None: - with open(Cmd.mapfile, 'w') as f: - self.env.dump_mapfile(f) if Cmd.print_summary and Err.count == 0: print>>sys.stderr, "Assembly complete: %s bytes output " \ "(%s code, %s data, %s filler)" \