import collections
-import contextlib
-import functools
-
-import mdis.dispatcher
-import mdis.visitor
-import mdis.walker
import openpower.oppc.pc_ast as pc_ast
+import openpower.oppc.pc_util as pc_util
-class Hook(mdis.dispatcher.Hook):
- def __call__(self, call):
- hook = super().__call__(call)
-
- class ConcreteHook(hook.__class__):
- @functools.wraps(hook.__call__)
- @contextlib.contextmanager
- def __call__(self, dispatcher, node, *args, **kwargs):
- return hook(dispatcher, node, *args, **kwargs)
-
- return ConcreteHook(*tuple(self))
-
-
-class Code(list):
- def __init__(self):
- self.__level = 0
- return super().__init__()
-
- def __enter__(self):
- self.__level += 1
- return self
-
- def __exit__(self, exc_type, exc_value, exc_traceback):
- self.__level -= 1
-
- def __str__(self):
- if len(self) == 0:
- raise ValueError("empty code")
-
- lines = []
- for (level, stmt) in self:
- line = ((" " * level * 4) + stmt)
- lines.append(line)
-
- return "\n".join(lines)
-
- def emit(self, stmt, level=0):
- item = ((level + self.__level), stmt)
- self.append(item)
-
-
-class PseudocodeVisitor(mdis.visitor.ContextVisitor):
+class PseudocodeVisitor(pc_util.Visitor):
def __init__(self, root):
+ self.__code = collections.defaultdict(lambda: pc_util.Code())
self.__root = root
- self.__code = collections.defaultdict(lambda: Code())
- return super().__init__()
+ return super().__init__(root=root)
def __iter__(self):
- yield from self.__code.items()
+ yield from self.__code[self.__root]
def __getitem__(self, node):
return self.__code[node]
- @Hook(pc_ast.Scope)
+ @pc_util.Hook(pc_ast.Scope)
def Scope(self, node):
yield node
if node is not self.__root:
for (level, stmt) in self[subnode]:
self[node].emit(stmt=stmt, level=level)
- @Hook(pc_ast.Call)
+ @pc_util.Hook(pc_ast.Call)
def Call(self, node):
yield node
args = []
stmt = f"{node.name}({args})"
self[node].emit(stmt=stmt)
- @Hook(pc_ast.AssignExpr, pc_ast.AssignIEAExpr)
+ @pc_util.Hook(pc_ast.AssignExpr, pc_ast.AssignIEAExpr)
def AssignExpr(self, node):
mapping = {
pc_ast.AssignExpr: "<-",
])
self[node].emit(stmt=stmt)
- @Hook(pc_ast.BinaryExpr)
+ @pc_util.Hook(pc_ast.BinaryExpr)
def BinaryExpr(self, node):
yield node
stmt = " ".join([
])
self[node].emit(stmt=f"({stmt})")
- @Hook(pc_ast.IfExpr)
+ @pc_util.Hook(pc_ast.IfExpr)
def IfExpr(self, node):
yield node
stmt = " ".join([
for (level, stmt) in self[node.orelse]:
self[node].emit(stmt=stmt, level=level)
- @Hook(pc_ast.ForExpr)
+ @pc_util.Hook(pc_ast.ForExpr)
def ForExpr(self, node):
yield node
stmt = " ".join([
for (level, stmt) in self[node.body]:
self[node].emit(stmt=stmt, level=level)
- @Hook(pc_ast.WhileExpr)
+ @pc_util.Hook(pc_ast.WhileExpr)
def WhileExpr(self, node):
yield node
stmt = " ".join([
for (level, stmt) in self[node.orelse]:
self[node].emit(stmt=stmt, level=level)
- @Hook(pc_ast.RepeatExpr)
+ @pc_util.Hook(pc_ast.RepeatExpr)
def RepeatExpr(self, node):
yield node
stmt = " ".join([
])
self[node].emit(stmt=f"({stmt})")
- @Hook(pc_ast.SwitchExpr)
+ @pc_util.Hook(pc_ast.SwitchExpr)
def SwitchExpr(self, node):
yield node
self[node].emit(f"switch({str(self[node.subject])})")
for (level, stmt) in self[node.cases]:
self[node].emit(stmt=stmt, level=level)
- @Hook(pc_ast.Cases)
+ @pc_util.Hook(pc_ast.Cases)
def Cases(self, node):
yield node
for subnode in node:
for (level, stmt) in self[subnode]:
self[node].emit(stmt=stmt, level=level)
- @Hook(pc_ast.Case)
+ @pc_util.Hook(pc_ast.Case)
def Case(self, node):
yield node
for (level, stmt) in self[node.labels]:
for (level, stmt) in self[node.body]:
self[node].emit(stmt=stmt, level=level)
- @Hook(pc_ast.Labels)
+ @pc_util.Hook(pc_ast.Labels)
def Labels(self, node):
yield node
if ((len(node) == 1) and isinstance(node[-1], pc_ast.DefaultLabel)):
stmt = f"case ({labels}):"
self[node].emit(stmt=stmt)
- @Hook(pc_ast.Label)
+ @pc_util.Hook(pc_ast.Label)
def Label(self, node):
yield node
self[node].emit(stmt=str(node))
- @Hook(pc_ast.DefaultLabel)
+ @pc_util.Hook(pc_ast.DefaultLabel)
def DefaultLabel(self, node):
yield node
self[node].emit(stmt="default:")
- @Hook(pc_ast.UnaryExpr)
+ @pc_util.Hook(pc_ast.UnaryExpr)
def UnaryExpr(self, node):
yield node
stmt = "".join([
])
self[node].emit(stmt=stmt)
- @Hook(pc_ast.BinLiteral, pc_ast.DecLiteral, pc_ast.HexLiteral)
+ @pc_util.Hook(pc_ast.BinLiteral, pc_ast.DecLiteral, pc_ast.HexLiteral)
def Integer(self, node):
yield node
self[node].emit(stmt=str(node))
- @Hook(pc_ast.StringLiteral)
+ @pc_util.Hook(pc_ast.StringLiteral)
def StringLiteral(self, node):
yield node
self[node].emit(stmt=f"'{str(node)}'")
- @Hook(pc_ast.Symbol)
+ @pc_util.Hook(pc_ast.Symbol)
def Symbol(self, node):
yield node
self[node].emit(stmt=str(node))
- @Hook(pc_ast.Attribute)
+ @pc_util.Hook(pc_ast.Attribute)
def Attribute(self, node):
yield node
stmt = ".".join([
])
self[node].emit(stmt=stmt)
- @Hook(pc_ast.Not, pc_ast.Add, pc_ast.Sub,
+ @pc_util.Hook(pc_ast.Not, pc_ast.Add, pc_ast.Sub,
pc_ast.Mul, pc_ast.MulS, pc_ast.MulU,
pc_ast.Div, pc_ast.DivT, pc_ast.Mod,
pc_ast.Sqrt,
stmt = mapping[node.__class__]
self[node].emit(stmt=stmt)
- @Hook(pc_ast.LParenthesis, pc_ast.RParenthesis,
+ @pc_util.Hook(pc_ast.LParenthesis, pc_ast.RParenthesis,
pc_ast.LBracket, pc_ast.RBracket)
def BracketOrParenthesis(self, node):
yield node
stmt = mapping[node.__class__]
self[node].emit(stmt=stmt)
- @Hook(pc_ast.Subscript)
+ @pc_util.Hook(pc_ast.Subscript)
def Subscript(self, node):
yield node
stmt = "".join([
])
self[node].emit(stmt=stmt)
- @Hook(pc_ast.RangeSubscript)
+ @pc_util.Hook(pc_ast.RangeSubscript)
def RangeSubscript(self, node):
yield node
stmt = "".join([
])
self[node].emit(stmt=stmt)
- @Hook(pc_ast.Colon)
+ @pc_util.Hook(pc_ast.Colon)
def Colon(self, node):
yield node
self[node].emit(stmt=":")
- @Hook(pc_ast.Linebreak, pc_ast.Endmarker)
+ @pc_util.Hook(pc_ast.Linebreak, pc_ast.Endmarker)
def Ignore(self, node):
yield node
- @Hook(pc_ast.Keyword)
+ @pc_util.Hook(pc_ast.Keyword)
def Keyword(self, node):
yield node
self[node].emit(stmt=node.__doc__)
- @Hook(pc_ast.Sequence)
+ @pc_util.Hook(pc_ast.Sequence)
def Sequence(self, node):
yield node
stmt = ",".join(map(lambda subnode: str(self[subnode]), node))
self[node].emit(stmt=f"({stmt})")
- @Hook(pc_ast.Literal)
+ @pc_util.Hook(pc_ast.Literal)
def Literal(self, node):
yield node
self[node].emit(stmt=str(node))
- @Hook(pc_ast.GPR, pc_ast.FPR, pc_ast.GPRZero)
+ @pc_util.Hook(pc_ast.GPR, pc_ast.FPR, pc_ast.GPRZero)
def Reg(self, node):
yield node
if isinstance(node, pc_ast.GPRZero):
else:
self[node].emit(stmt=f"({str(node)})")
- @Hook(pc_ast.Node)
+ @pc_util.Hook(pc_ast.Node)
def Node(self, node):
raise NotImplementedError(type(node))
-def traverse(root, visitor, walker):
- with visitor(root):
- for node in walker(root):
- traverse(root=node, visitor=visitor, walker=walker)
-
-
def pseudocode(root):
- walker = mdis.walker.Walker()
- visitor = PseudocodeVisitor(root=root)
- traverse(root=root, visitor=visitor, walker=walker)
- for (level, stmt) in visitor[root]:
- yield (level, stmt)
+ yield from PseudocodeVisitor(root=root)