)
from openpower.insndb.core import (
Database,
+ Dataclass,
+ Dict,
+ Record,
+ Records,
+ Tuple,
Visitor,
+ visit,
+ visitormethod,
)
return self
-class BaseVisitor(Visitor):
- def __init__(self, **arguments):
- self.__arguments = types.MappingProxyType(arguments)
- self.__current_db = None
- self.__current_record = None
- self.__current_extra = None
+class TreeVisitor(Visitor):
+ def __init__(self):
+ self.__depth = 0
+ self.__path = [""]
return super().__init__()
- @property
- def arguments(self):
- return self.__arguments
-
- @property
- def current_db(self):
- return self.__current_db
-
- @property
- def current_record(self):
- return self.__current_record
-
- @property
- def current_extra(self):
- return self.__current_extra
-
- @contextlib.contextmanager
- def db(self, db):
- self.__current_db = db
- yield db
- self.__current_db = None
-
@contextlib.contextmanager
- def record(self, record):
- self.__current_record = record
- yield record
- self.__current_record = None
-
- @contextlib.contextmanager
- def extra(self, extra):
- self.__current_extra = extra
- yield extra
- self.__current_extra = None
-
-
-class ListVisitor(BaseVisitor):
- @contextlib.contextmanager
- def record(self, record):
- print(record.name)
- yield record
-
-
-class InstructionVisitor(BaseVisitor):
+ 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
+
+
+# No use other than checking issubclass and adding an argument.
+class InstructionVisitor(Visitor):
pass
-
class SVP64InstructionVisitor(InstructionVisitor):
pass
class OpcodesVisitor(InstructionVisitor):
- @contextlib.contextmanager
- def record(self, record):
- for opcode in record.opcodes:
+ @visitormethod(Record)
+ def Record(self, path, node):
+ for opcode in node.opcodes:
print(opcode)
+ yield node
class OperandsVisitor(InstructionVisitor):
- @contextlib.contextmanager
- def record(self, record):
- with super().record(record=record):
- if self.current_record.name == self.arguments["insn"]:
- for operand in record.dynamic_operands:
- print(operand.name, ",".join(map(str, operand.span)))
- for operand in record.static_operands:
- if operand.name not in ("PO", "XO"):
- desc = f"{operand.name}={operand.value}"
- print(desc, ",".join(map(str, operand.span)))
-
- yield record
+ @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 PCodeVisitor(InstructionVisitor):
- @contextlib.contextmanager
- def record(self, record):
- with super().record(record=record):
- if self.current_record.name == self.arguments["insn"]:
- for line in record.pcode:
- print(line)
+ @visitormethod(Record)
+ def Record(self, path, node):
+ if isinstance(node, Record):
+ for line in node.pcode:
+ print(line)
+ yield node
class ExtrasVisitor(SVP64InstructionVisitor):
- @contextlib.contextmanager
- def extra(self, extra):
- with super().extra(extra=extra) as extra:
- if self.current_record.name == self.arguments["insn"]:
- print(extra.name)
- print(" sel", extra.sel)
- print(" reg", extra.reg)
- print(" seltype", extra.seltype)
- print(" idx", extra.idx)
- pass
-
- yield extra
+ @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": (
ListVisitor,
"list available instructions",
default=False)
main_subparser = main_parser.add_subparsers(dest="command", required=True)
- for (command, (visitor, help)) in commands.items():
- parser = main_subparser.add_parser(command, help=help)
+ for (command, (visitor, helper)) in commands.items():
+ parser = main_subparser.add_parser(command, help=helper)
if issubclass(visitor, InstructionVisitor):
- if issubclass(visitor, SVP64InstructionVisitor):
+ if command in ("extras",):
arg_cls = SVP64Instruction
else:
arg_cls = Instruction
log = args.pop("log")
if not log:
os.environ["SILENCELOG"] = "true"
- visitor = commands[command][0](**args)
+ visitor = commands[command][0]()
db = Database(find_wiki_dir())
- db.visit(visitor=visitor)
+ (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__":