From 5a73d2e0260d4b1abf69013c84f9276e50503a25 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Sat, 10 Jun 2023 22:00:56 +0300 Subject: [PATCH] insndb: make walk yield paths --- src/openpower/insndb/core.py | 45 +++++++++++++++++++----------------- src/openpower/insndb/db.py | 22 +++++++++--------- 2 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/openpower/insndb/core.py b/src/openpower/insndb/core.py index 70e9c16c..23e68e39 100644 --- a/src/openpower/insndb/core.py +++ b/src/openpower/insndb/core.py @@ -72,7 +72,7 @@ class walkmethod: class Node: @walkmethod def walk(clsself, match=None): - return () + yield from () class DataclassMeta(type): @@ -93,9 +93,12 @@ class Dataclass(Node, metaclass=DataclassMeta): def field_value(field): return getattr(clsself, field.name) - field = (field_type if isinstance(clsself, type) else field_value) + field_node = (field_type if isinstance(clsself, type) else field_value) - yield from filter(match, map(field, _dataclasses.fields(clsself))) + for field in _dataclasses.fields(clsself): + path = field.name + node = field_node(field) + yield (path, node) class Tuple(Node, tuple): @@ -109,11 +112,11 @@ class Tuple(Node, tuple): match = lambda subnode: True if isinstance(clsself, type): - yield clsself.__datatype + yield ("[]", clsself.__datatype) else: - for item in clsself: + for (index, item) in enumerate(clsself): if match(item): - yield item + yield (str(index), item) class VisitorMethod: @@ -127,8 +130,8 @@ class VisitorMethod: return self.__nodecls @_contextlib.contextmanager - def __call__(self, node): - return self.__method(self=self, node=node) + def __call__(self, path, node): + return self.__method(self=self, path=path, node=node) class VisitorMeta(type): @@ -156,11 +159,11 @@ class VisitorMeta(type): class Visitor(metaclass=VisitorMeta): @_contextlib.contextmanager - def __call__(self, node): + def __call__(self, path, node): (visitorcls, nodecls) = map(type, (self, node)) if nodecls in visitorcls: handler = visitorcls[nodecls] - with handler(node=node) as ctx: + with handler(path=path, node=node) as ctx: yield ctx else: yield node @@ -180,18 +183,18 @@ class visitormethod: def walk(root, match=None): - nodes = _collections.deque([root]) - while nodes: - node = nodes.popleft() - nodes.extend(node.walk(match=match)) - yield node + pairs = _collections.deque([root]) + while pairs: + (path, node) = pairs.popleft() + pairs.extend(node.walk(match=match)) + yield (path, node) -def visit(visitor, node): - with visitor(node=node): +def visit(visitor, node, path="/"): + with visitor(path=path, node=node): if isinstance(node, Node): - for subnode in node.walk(): - visit(visitor=visitor, node=subnode) + for (subpath, subnode) in node.walk(): + visit(visitor=visitor, path=subpath, node=subnode) @_functools.total_ordering @@ -3834,10 +3837,10 @@ class Database(Node): match = lambda subnode: True if isinstance(clsself, type): - yield Records + yield ("records", Records) else: if match(clsself.__db): - yield clsself.__db + yield ("records", clsself.__db) def __repr__(self): return repr(self.__db) diff --git a/src/openpower/insndb/db.py b/src/openpower/insndb/db.py index fb9ee05c..15b915b9 100644 --- a/src/openpower/insndb/db.py +++ b/src/openpower/insndb/db.py @@ -45,9 +45,9 @@ class TreeVisitor(Visitor): return super().__init__() @contextlib.contextmanager - def __call__(self, node): - with super().__call__(node) as node: - print((" " * (self.__depth * 4)), repr(node)) + def __call__(self, path, node): + with super().__call__(path=path, node=node): + print((" " * (self.__depth * 4)), path) self.__depth += 1 yield node self.__depth -= 1 @@ -55,7 +55,7 @@ class TreeVisitor(Visitor): class ListVisitor(Visitor): @visitormethod(Record) - def Record(self, node): + def Record(self, path, node): print(node.name) yield node @@ -70,7 +70,7 @@ class SVP64InstructionVisitor(InstructionVisitor): class OpcodesVisitor(InstructionVisitor): @visitormethod(Record) - def Record(self, node): + def Record(self, path, node): for opcode in node.opcodes: print(opcode) yield node @@ -78,7 +78,7 @@ class OpcodesVisitor(InstructionVisitor): class OperandsVisitor(InstructionVisitor): @visitormethod(Record) - def Record(self, node): + def Record(self, path, node): if isinstance(node, Record): for operand in node.dynamic_operands: print(operand.name, ",".join(map(str, operand.span))) @@ -91,7 +91,7 @@ class OperandsVisitor(InstructionVisitor): class PCodeVisitor(InstructionVisitor): @visitormethod(Record) - def Record(self, node): + def Record(self, path, node): if isinstance(node, Record): for line in node.pcode: print(line) @@ -100,7 +100,7 @@ class PCodeVisitor(InstructionVisitor): class ExtrasVisitor(SVP64InstructionVisitor): @visitormethod(Record) - def Record(self, node): + def Record(self, path, node): for (name, extra) in node.extras.items(): print(name) print(" sel", extra["sel"]) @@ -163,7 +163,7 @@ def main(): visitor = commands[command][0]() db = Database(find_wiki_dir()) - records = next(db.walk(match=lambda node: isinstance(node, Records))) + (path, records) = next(db.walk(match=lambda node: isinstance(node, Records))) if not isinstance(visitor, InstructionVisitor): match = None else: @@ -171,8 +171,8 @@ def main(): def match(record): return (isinstance(record, Record) and (record.name == insn)) - for node in records.walk(match=match): - visit(visitor=visitor, node=node) + for (subpath, node) in records.walk(match=match): + visit(visitor=visitor, node=node, path=subpath) if __name__ == "__main__": -- 2.30.2