mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-12-21 12:29:46 +00:00
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:
parent
c0bf2e98b7
commit
70f93b22eb
@ -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]))
|
||||
|
@ -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:
|
||||
|
@ -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)" \
|
||||
|
Loading…
Reference in New Issue
Block a user