class Node:
- @property
- def subnodes(self):
- yield from ()
+ def visit(self, handler, matcher, depth):
+ if matcher(node=self, depth=depth):
+ with handler(node=self, depth=depth):
+ pass
class Visitor:
- @_contextlib.contextmanager
- def Node(self, node, depth):
- yield node
- for subnode in node.subnodes:
- manager = subnode.__class__.__name__
- manager = getattr(self, manager, self.Node)
- with manager(node=subnode, depth=(depth + 1)):
- pass
+ def __init__(self, **parameters):
+ self.__parameters = _types.MappingProxyType(parameters)
+ return super().__init__()
- def __getattr__(self, attr):
- return self.Node
+ 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):
- manager = node.__class__.__name__
- manager = getattr(self, manager, self.Node)
- return manager(node=node, depth=depth)
+ method = node.__class__.__name__
+ method = getattr(self, method, self.Node)
+ return method(node=node, depth=depth)
-def visit(visitor, node):
- with visitor(node=node, depth=0):
- pass
+class Matcher(Visitor):
+ def Node(self, node, depth):
+ return True
+
+
+class Handler(Visitor):
+ @_contextlib.contextmanager
+ def Node(self, node, depth):
+ yield node
+
+
+def visit(node, handler, matcher=Matcher()):
+ node.visit(handler=handler, matcher=matcher, depth=0)
@_functools.total_ordering
seltype: _SelType
idx: _SVExtra
- def visit(self, visitor):
- with visitor.extra(extra=self) as extra:
- pass
-
@_functools.total_ordering
@_dataclasses.dataclass(eq=True, frozen=True)
mdwn: MarkdownRecord
svp64: SVP64Record = None
- @property
- def subnodes(self):
- for (name, fields) in self.extras.items():
- yield Extra(name=name, **fields)
+ 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 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:
)
from openpower.insndb.core import (
Database,
- Visitor,
+ Handler,
+ Matcher,
visit,
)
return self
-class BaseVisitor(Visitor):
- def __init__(self, **arguments):
- self.__arguments = types.MappingProxyType(arguments)
- return super().__init__()
-
- def __getitem__(self, argument):
- return self.__arguments[argument]
-
-
-class ListVisitor(BaseVisitor):
+class ListHandler(Handler):
@contextlib.contextmanager
def Record(self, node, depth):
print(node.name)
yield node
-class InstructionVisitor(BaseVisitor):
- @contextlib.contextmanager
- def Database(self, node, depth):
- yield node
- for subnode in node.subnodes:
- if subnode.name == self["insn"]:
- with self(node=subnode, depth=(depth + 1)):
- pass
+class InstructionMatcher(Matcher):
+ def Record(self, node, depth):
+ return (node.name == self["insn"])
-class SVP64InstructionVisitor(InstructionVisitor):
+class SVP64InstructionMatcher(InstructionMatcher):
pass
-class OpcodesVisitor(InstructionVisitor):
+class OpcodesHandler(Handler):
@contextlib.contextmanager
def Record(self, node, depth):
for opcode in node.opcodes:
yield node
-class OperandsVisitor(InstructionVisitor):
+class OperandsHandler(Handler):
@contextlib.contextmanager
def Record(self, node, depth):
for operand in node.dynamic_operands:
yield node
-class PCodeVisitor(InstructionVisitor):
+class PCodeHandler(Handler):
@contextlib.contextmanager
def Record(self, node, depth):
for line in node.pcode:
yield node
-class ExtrasVisitor(SVP64InstructionVisitor):
+class ExtrasHandler(Handler):
@contextlib.contextmanager
def Extra(self, node, depth):
print(node.name)
def main():
commands = {
"list": (
- ListVisitor,
+ ListHandler,
+ Matcher,
"list available instructions",
),
"opcodes": (
- OpcodesVisitor,
+ OpcodesHandler,
+ InstructionMatcher,
"print instruction opcodes",
),
"operands": (
- OperandsVisitor,
+ OperandsHandler,
+ InstructionMatcher,
"print instruction operands",
),
"pcode": (
- PCodeVisitor,
+ PCodeHandler,
+ InstructionMatcher,
"print instruction pseudocode",
),
"extras": (
- ExtrasVisitor,
+ ExtrasHandler,
+ InstructionMatcher,
"print instruction extras (SVP64)",
),
}
default=False)
main_subparser = main_parser.add_subparsers(dest="command", required=True)
- for (command, (visitor, help)) in commands.items():
+ for (command, (handler, matcher, help)) in commands.items():
parser = main_subparser.add_parser(command, help=help)
- if issubclass(visitor, InstructionVisitor):
- if issubclass(visitor, SVP64InstructionVisitor):
+ if issubclass(matcher, InstructionMatcher):
+ if issubclass(matcher, SVP64InstructionMatcher):
arg_cls = SVP64Instruction
else:
arg_cls = Instruction
log = args.pop("log")
if not log:
os.environ["SILENCELOG"] = "true"
- visitor = commands[command][0](**args)
+ handler = commands[command][0](**args)
+ matcher = commands[command][1](**args)
db = Database(find_wiki_dir())
- visit(visitor=visitor, node=db)
+ visit(handler=handler, matcher=matcher, node=db)
if __name__ == "__main__":