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.
This commit is contained in:
Michael Martin 2014-05-09 23:11:09 -07:00
parent c0bf2e98b7
commit 70f93b22eb
3 changed files with 34 additions and 13 deletions

View File

@ -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]))

View File

@ -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:

View File

@ -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)" \