[Libre-soc-bugs] [Bug 1094] insndb instruction database visitor-walker is needed
bugzilla-daemon at libre-soc.org
bugzilla-daemon at libre-soc.org
Wed Jun 7 10:50:21 BST 2023
https://bugs.libre-soc.org/show_bug.cgi?id=1094
--- Comment #51 from Dmitry Selyutin <ghostmansd at gmail.com> ---
I've come up with the idea based on AST example you posted, and updated the
code. I think it takes best from the ideas you posted and Jacob's managers.
https://git.libre-soc.org/?p=openpower-isa.git;a=commitdiff;h=5f07a672ec7eb1cf3206f87ddc00ea10f4430a24
The idea is: all this stuff inherits from some generic Node. Each Node-derived
can specify what subnodes it has (also of class Node).
The visiting algorithm is then described as:
class Visitor:
@_contextlib.contextmanager
def Node(self, node, depth):
yield node
for subnode in node.subnodes:
manager = subnode.__class__.__name__
manager = getattr(self, manager, self.Node)
with manager(node=subnode, depth=(depth + 1)):
pass
def __getattr__(self, attr):
return self.Node
def __call__(self, node, depth):
manager = node.__class__.__name__
manager = getattr(self, manager, self.Node)
return manager(node=node, depth=depth)
def visit(visitor, node):
with visitor(node=node, depth=0):
pass
Note the way it's called: __call__ yields either overriden context manager or
default Node context manager (and the latter just goes over subnodes).
Then anyone can specify how the specific types are handled. Here's the visitor
which filters the concrete record in database and prints its opcodes. Note that
I also have __setitem__ in this _concrete_ visitor (not on top-level) which is
used to access command line arguments (I could've used just **kwargs here, or
call setattr(concrete_visitor, cmd_arg), or whatever).
class InstructionVisitor(BaseVisitor):
@contextlib.contextmanager
def Database(self, node, depth):
yield node
for subnode in node.subnodes:
if subnode.name == self["insn"]:
with self(node=subnode, depth=(depth + 1)):
pass
class OpcodesVisitor(InstructionVisitor):
@contextlib.contextmanager
def Record(self, node, depth):
for opcode in node.opcodes:
print(opcode)
yield node
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the libre-soc-bugs
mailing list