from openpower.decoder.pseudo.pagereader import ISA as _ISA
-class Node:
- def visit(self, handler, matcher, depth):
- if matcher(node=self, depth=depth):
- with handler(node=self, depth=depth):
- pass
-
-
class Visitor:
- def __init__(self, **parameters):
- self.__parameters = _types.MappingProxyType(parameters)
- return super().__init__()
-
- def __contains__(self, key):
- return self.__parameters.__contains__(key)
-
- def __getitem__(self, key):
- return self.__parameters.__getitem__(key)
-
- def Node(self, node, depth):
- raise NotImplementedError()
-
- def __call__(self, node, depth):
+ def __call__(self, node):
method = node.__class__.__name__
method = getattr(self, method, self.Node)
- return method(node=node, depth=depth)
-
+ return method(node=node)
-class Matcher(Visitor):
- def Node(self, node, depth):
- return True
-
-
-class Handler(Visitor):
@_contextlib.contextmanager
- def Node(self, node, depth):
+ def Node(self, node):
+ for subnode in node.subnodes:
+ with self(subnode):
+ pass
yield node
-def visit(node, handler, matcher=Matcher()):
- node.visit(handler=handler, matcher=matcher, depth=0)
+class Node:
+ @property
+ def subnodes(self):
+ yield from ()
+
+
+def walk(root):
+ nodes = _collections.deque([root])
+ while nodes:
+ node = nodes.popleft()
+ nodes.extend(node.subnodes)
+ yield node
@_functools.total_ordering
mdwn: MarkdownRecord
svp64: SVP64Record = None
- def visit(self, handler, matcher, depth):
- if matcher(node=self, depth=depth):
- with handler(node=self, depth=depth):
- for (name, fields) in self.extras.items():
- extra = Extra(name=name, **fields)
- extra.visit(depth=(depth + 1),
- handler=handler, matcher=matcher)
+ @property
+ def subnodes(self):
+ for (name, fields) in self.extras.items():
+ yield Extra(name=name, **fields)
@property
def extras(self):
return super().__init__()
- def visit(self, handler, matcher, depth):
- if matcher(node=self, depth=depth):
- with handler(node=self, depth=depth):
- for record in self:
- record.visit(depth=(depth + 1),
- handler=handler, matcher=matcher)
-
@property
def subnodes(self):
- for record in self.__db:
- yield record
+ yield from self
def __repr__(self):
return repr(self.__db)
)
from openpower.insndb.core import (
Database,
- Handler,
- Matcher,
- visit,
+ Visitor,
)
return self
-class ListHandler(Handler):
+class RecordNameVisitor(Visitor):
+ def __init__(self, name):
+ self.__name = name
+ self.__records = set()
+ return super().__init__()
+
@contextlib.contextmanager
- def Record(self, node, depth):
- print(node.name)
+ def Record(self, node):
+ if node.name == self.__name:
+ self.__records.add(node)
yield node
-
-class InstructionMatcher(Matcher):
- def Record(self, node, depth):
- return (node.name == self["insn"])
+ def __iter__(self):
+ yield from self.__records
-class SVP64InstructionMatcher(InstructionMatcher):
- pass
+class ListVisitor(Visitor):
+ @contextlib.contextmanager
+ def Record(self, node):
+ print(node.name)
+ yield node
-class OpcodesHandler(Handler):
+class OpcodesVisitor(Visitor):
@contextlib.contextmanager
- def Record(self, node, depth):
+ def Record(self, node):
for opcode in node.opcodes:
print(opcode)
yield node
-class OperandsHandler(Handler):
+class OperandsVisitor(Visitor):
@contextlib.contextmanager
- def Record(self, node, depth):
+ def Record(self, node):
for operand in node.dynamic_operands:
print(operand.name, ",".join(map(str, operand.span)))
for operand in node.static_operands:
yield node
-class PCodeHandler(Handler):
+class PCodeVisitor(Visitor):
@contextlib.contextmanager
- def Record(self, node, depth):
+ def Record(self, node):
for line in node.pcode:
print(line)
yield node
-class ExtrasHandler(Handler):
+class ExtrasVisitor(Visitor):
@contextlib.contextmanager
- def Extra(self, node, depth):
+ def Extra(self, node):
print(node.name)
print(" sel", node.sel)
print(" reg", node.reg)
def main():
commands = {
"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 command not in ("list",):
+ 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)
+ if command in ("list",):
+ nodes = (db,)
+ else:
+ match = RecordNameVisitor(name=args["insn"])
+ with match(node=db):
+ nodes = frozenset(match)
+
+ for node in nodes:
+ with visitor(node=node):
+ pass
if __name__ == "__main__":