mirror of
https://github.com/michaelcmartin/Ophis.git
synced 2024-05-28 09:41:29 +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:
|
if len(self.stack) == 1:
|
||||||
Err.log("Unmatched .scend")
|
Err.log("Unmatched .scend")
|
||||||
self.stack.pop(0)
|
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.append(instruction_select)
|
||||||
passes.extend([Ophis.Passes.NormalizeModes(),
|
passes.extend([Ophis.Passes.NormalizeModes(),
|
||||||
Ophis.Passes.UpdateLabels(),
|
Ophis.Passes.UpdateLabels(),
|
||||||
|
Ophis.Passes.LabelMapper(),
|
||||||
a])
|
a])
|
||||||
|
|
||||||
for p in passes:
|
for p in passes:
|
||||||
|
|
|
@ -733,6 +733,39 @@ class NormalizeModes(Pass):
|
||||||
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):
|
class Assembler(Pass):
|
||||||
"""Converts the IR into a list of bytes, suitable for writing to
|
"""Converts the IR into a list of bytes, suitable for writing to
|
||||||
a file."""
|
a file."""
|
||||||
|
@ -755,16 +788,8 @@ class Assembler(Pass):
|
||||||
else:
|
else:
|
||||||
self.listing = Listing.NullLister()
|
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):
|
def postPass(self):
|
||||||
self.listing.dump()
|
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:
|
if Cmd.print_summary and Err.count == 0:
|
||||||
print>>sys.stderr, "Assembly complete: %s bytes output " \
|
print>>sys.stderr, "Assembly complete: %s bytes output " \
|
||||||
"(%s code, %s data, %s filler)" \
|
"(%s code, %s data, %s filler)" \
|
||||||
|
|
Loading…
Reference in New Issue
Block a user