)
from openpower.insndb.core import (
Database,
- Handler,
- Matcher,
+ Dataclass,
+ Dict,
+ Record,
+ Records,
+ Tuple,
+ Visitor,
visit,
+ visitormethod,
)
return self
-class ListHandler(Handler):
+class TreeVisitor(Visitor):
+ def __init__(self):
+ self.__depth = 0
+ self.__path = [""]
+ return super().__init__()
+
@contextlib.contextmanager
- def Record(self, node, depth):
+ 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, path, node):
print(node.name)
yield node
-class InstructionMatcher(Matcher):
- def Record(self, node, depth):
- return (node.name == self["insn"])
-
+# No use other than checking issubclass and adding an argument.
+class InstructionVisitor(Visitor):
+ pass
-class SVP64InstructionMatcher(InstructionMatcher):
+class SVP64InstructionVisitor(InstructionVisitor):
pass
-class OpcodesHandler(Handler):
- @contextlib.contextmanager
- def Record(self, node, depth):
+class OpcodesVisitor(InstructionVisitor):
+ @visitormethod(Record)
+ def Record(self, path, node):
for opcode in node.opcodes:
print(opcode)
yield node
-class OperandsHandler(Handler):
- @contextlib.contextmanager
- def Record(self, node, depth):
- for operand in node.dynamic_operands:
- print(operand.name, ",".join(map(str, operand.span)))
- for operand in node.static_operands:
- if operand.name not in ("PO", "XO"):
- desc = f"{operand.name}={operand.value}"
- print(desc, ",".join(map(str, operand.span)))
+class OperandsVisitor(InstructionVisitor):
+ @visitormethod(Record)
+ def Record(self, path, node):
+ if isinstance(node, Record):
+ for operand in node.dynamic_operands:
+ print(operand.name, ",".join(map(str, operand.span)))
+ for operand in node.static_operands:
+ if operand.name not in ("PO", "XO"):
+ desc = f"{operand.name}={operand.value}"
+ print(desc, ",".join(map(str, operand.span)))
yield node
-class PCodeHandler(Handler):
- @contextlib.contextmanager
- def Record(self, node, depth):
- for line in node.pcode:
- print(line)
+class PCodeVisitor(InstructionVisitor):
+ @visitormethod(Record)
+ def Record(self, path, node):
+ if isinstance(node, Record):
+ for line in node.pcode:
+ print(line)
yield node
-class ExtrasHandler(Handler):
- @contextlib.contextmanager
- def Extra(self, node, depth):
- print(node.name)
- print(" sel", node.sel)
- print(" reg", node.reg)
- print(" seltype", node.seltype)
- print(" idx", node.idx)
+class ExtrasVisitor(SVP64InstructionVisitor):
+ @visitormethod(Record)
+ def Record(self, path, node):
+ for (name, extra) in node.extras.items():
+ print(name)
+ print(" sel", extra["sel"])
+ print(" reg", extra["reg"])
+ print(" seltype", extra["seltype"])
+ print(" idx", extra["idx"])
yield node
def main():
commands = {
+ "tree": (
+ TreeVisitor,
+ "list all records",
+ ),
"list": (
- ListHandler,
- Matcher,
+ ListVisitor,
"list available instructions",
),
"opcodes": (
- OpcodesHandler,
- InstructionMatcher,
+ OpcodesVisitor,
"print instruction opcodes",
),
"operands": (
- OperandsHandler,
- InstructionMatcher,
+ OperandsVisitor,
"print instruction operands",
),
"pcode": (
- PCodeHandler,
- InstructionMatcher,
+ PCodeVisitor,
"print instruction pseudocode",
),
"extras": (
- ExtrasHandler,
- InstructionMatcher,
+ ExtrasVisitor,
"print instruction extras (SVP64)",
),
}
default=False)
main_subparser = main_parser.add_subparsers(dest="command", required=True)
- for (command, (handler, matcher, help)) in commands.items():
- parser = main_subparser.add_parser(command, help=help)
- if issubclass(matcher, InstructionMatcher):
- if issubclass(matcher, SVP64InstructionMatcher):
+ for (command, (visitor, helper)) in commands.items():
+ parser = main_subparser.add_parser(command, help=helper)
+ if issubclass(visitor, InstructionVisitor):
+ if command in ("extras",):
arg_cls = SVP64Instruction
else:
arg_cls = Instruction
log = args.pop("log")
if not log:
os.environ["SILENCELOG"] = "true"
- handler = commands[command][0](**args)
- matcher = commands[command][1](**args)
+ visitor = commands[command][0]()
db = Database(find_wiki_dir())
- visit(handler=handler, matcher=matcher, node=db)
+ (path, records) = next(db.walk(match=lambda pair: isinstance(pair, Records)))
+ if not isinstance(visitor, InstructionVisitor):
+ match = lambda _: True
+ else:
+ insn = args.pop("insn")
+ def match(record):
+ return (isinstance(record, Record) and (record.name == insn))
+
+ for (subpath, node) in records.walk(match=match):
+ visit(visitor=visitor, node=node, path=subpath)
if __name__ == "__main__":