temporary hack-revert, the original is now in branch "paths"
[openpower-isa.git] / src / openpower / insndb / db.py
index 6cd5d1c0564fdf6b1a3eeb2ae3d17c983fd3a135..fa5eb267ea7ae14f442183b260c2580b16d56a80 100644 (file)
@@ -8,8 +8,11 @@ from openpower.decoder.power_enums import (
 )
 from openpower.insndb.core import (
     Database,
+    Dataclass,
+    Dict,
     Record,
     Records,
+    Tuple,
     Visitor,
     visit,
     visitormethod,
@@ -39,9 +42,28 @@ class SVP64Instruction(Instruction):
         return self
 
 
+class TreeVisitor(Visitor):
+    def __init__(self):
+        self.__depth = 0
+        self.__path = [""]
+        return super().__init__()
+
+    @contextlib.contextmanager
+    def __call__(self, path, node):
+        with super().__call__(path=path, node=node):
+            self.__path.append(path)
+            print("/".join(self.__path))
+            if not isinstance(node, (Dataclass, Tuple, Dict)):
+                print("    ", repr(node), sep="")
+            self.__depth += 1
+            yield node
+            self.__path.pop(-1)
+            self.__depth -= 1
+
+
 class ListVisitor(Visitor):
     @visitormethod(Record)
-    def Record(self, node):
+    def Record(self, path, node):
         print(node.name)
         yield node
 
@@ -56,7 +78,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
@@ -64,7 +86,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)))
@@ -77,7 +99,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)
@@ -86,7 +108,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"])
@@ -98,6 +120,10 @@ class ExtrasVisitor(SVP64InstructionVisitor):
 
 def main():
     commands = {
+        "tree": (
+            TreeVisitor,
+            "list all records",
+        ),
         "list": (
             ListVisitor,
             "list available instructions",
@@ -145,16 +171,16 @@ 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 pair: isinstance(pair, Records)))
     if not isinstance(visitor, InstructionVisitor):
-        match = None
+        match = lambda _: True
     else:
         insn = args.pop("insn")
         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__":