import openpower.oppc.pc_lexer as pc_lexer
import openpower.oppc.pc_parser as pc_parser
-import openpower.oppc.pc_util as pc_util
+import openpower.oppc.pc_pseudocode as pc_pseudocode
def dedent(line):
origin = tuple(origin)
tree = parser.parse(code="\n".join(origin))
stream = io.StringIO()
- for (level, line) in pc_util.pseudocode(tree):
+ for (level, line) in pc_pseudocode.pseudocode(tree):
print(f"{' ' * 4 * level}{line}", file=stream)
stream.seek(0)
target = tuple(stream)
"""
tree = parser.parse(code=code)
print(tree)
-for (level, line) in pc_util.pseudocode(tree):
+for (level, line) in pc_pseudocode.pseudocode(tree):
print(f"{' ' * 4 * level}{line}")
--- /dev/null
+import collections
+import contextlib
+import functools
+
+import mdis.dispatcher
+import mdis.visitor
+import mdis.walker
+
+import openpower.oppc.pc_ast as pc_ast
+
+
+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):
+ def __init__(self, root):
+ self.__root = root
+ self.__code = collections.defaultdict(lambda: Code())
+
+ return super().__init__()
+
+ def __iter__(self):
+ yield from self.__code.items()
+
+ def __getitem__(self, node):
+ return self.__code[node]
+
+ @Hook(pc_ast.Scope)
+ def Scope(self, node):
+ yield node
+ if node is not self.__root:
+ with self[node]:
+ for subnode in node:
+ for (level, stmt) in self[subnode]:
+ self[node].emit(stmt=stmt, level=level)
+ else:
+ for subnode in node:
+ for (level, stmt) in self[subnode]:
+ self[node].emit(stmt=stmt, level=level)
+
+ @Hook(pc_ast.Call)
+ def Call(self, node):
+ yield node
+ args = []
+ for subnode in node.args:
+ for (level, stmt) in self[subnode]:
+ assert level == 0
+ args.append(stmt)
+ args = ", ".join(args)
+ stmt = f"{node.name}({args})"
+ self[node].emit(stmt=stmt)
+
+ @Hook(pc_ast.AssignExpr, pc_ast.AssignIEAExpr)
+ def AssignExpr(self, node):
+ mapping = {
+ pc_ast.AssignExpr: "<-",
+ pc_ast.AssignIEAExpr: "<-iea",
+ }
+ yield node
+ lvalue = str(self[node.lvalue])
+ if (isinstance(node.lvalue, (pc_ast.GPR, pc_ast.FPR)) or
+ (isinstance(node.lvalue, (pc_ast.Subscript, pc_ast.RangeSubscript)) and
+ isinstance(node.lvalue.subject, (pc_ast.GPR, pc_ast.FPR)))):
+ lvalue = lvalue.replace("(", "").replace(")", "")
+ rvalue = str(self[node.rvalue])
+
+ if isinstance(node.rvalue, pc_ast.IfExpr):
+ # All right, this deserves an explanation.
+ # We basically convert T <- C ? A : B into this code:
+ #
+ # if C then
+ # T <- A
+ # else
+ # T <- B
+ #
+ # To make things work, we must ensure that objects are unique.
+ # Otherwise we'll reuse the bogus code already produced before.
+ (body, orelse) = map(lambda node: node.clone(),
+ (node.rvalue.body[0], node.rvalue.orelse[0]))
+ body = pc_ast.Scope([node.__class__(lvalue=node.lvalue.clone(), rvalue=body)])
+ orelse = pc_ast.Scope([node.__class__(lvalue=node.lvalue.clone(), rvalue=orelse)])
+ tmpnode = node.rvalue.clone(body=body, orelse=orelse)
+ walker = mdis.walker.Walker()
+ traverse(root=tmpnode, visitor=self, walker=walker)
+ for (level, stmt) in self[tmpnode]:
+ self[node].emit(stmt=stmt, level=level)
+ else:
+ stmt = " ".join([
+ lvalue,
+ mapping[node.__class__],
+ rvalue,
+ ])
+ self[node].emit(stmt=stmt)
+
+ @Hook(pc_ast.BinaryExpr)
+ def BinaryExpr(self, node):
+ yield node
+ stmt = " ".join([
+ str(self[node.left]),
+ str(self[node.op]),
+ str(self[node.right]),
+ ])
+ self[node].emit(stmt=f"({stmt})")
+
+ @Hook(pc_ast.IfExpr)
+ def IfExpr(self, node):
+ yield node
+ stmt = " ".join([
+ "if",
+ str(self[node.test]),
+ "then",
+ ])
+ self[node].emit(stmt=stmt)
+ for (level, stmt) in self[node.body]:
+ self[node].emit(stmt=stmt, level=level)
+ if node.orelse:
+ self[node].emit("else")
+ for (level, stmt) in self[node.orelse]:
+ self[node].emit(stmt=stmt, level=level)
+
+ @Hook(pc_ast.ForExpr)
+ def ForExpr(self, node):
+ yield node
+ stmt = " ".join([
+ "for",
+ str(self[node.subject]),
+ "=",
+ str(self[node.start]),
+ "to",
+ str(self[node.end]),
+ ])
+ self[node].emit(stmt=stmt)
+ for (level, stmt) in self[node.body]:
+ self[node].emit(stmt=stmt, level=level)
+
+ @Hook(pc_ast.WhileExpr)
+ def WhileExpr(self, node):
+ yield node
+ stmt = " ".join([
+ "do",
+ "while",
+ str(self[node.test]),
+ ])
+ self[node].emit(stmt=stmt)
+ for (level, stmt) in self[node.body]:
+ self[node].emit(stmt=stmt, level=level)
+ if node.orelse:
+ self[node].emit("else")
+ for (level, stmt) in self[node.orelse]:
+ self[node].emit(stmt=stmt, level=level)
+
+ @Hook(pc_ast.RepeatExpr)
+ def RepeatExpr(self, node):
+ yield node
+ stmt = " ".join([
+ f"[{str(self[node.subject])}]",
+ "*",
+ str(self[node.times]),
+ ])
+ self[node].emit(stmt=f"({stmt})")
+
+ @Hook(pc_ast.SwitchExpr)
+ def SwitchExpr(self, node):
+ yield node
+ self[node].emit(f"switch({str(self[node.subject])})")
+ with self[node]:
+ for (level, stmt) in self[node.cases]:
+ self[node].emit(stmt=stmt, level=level)
+
+ @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)
+ def Case(self, node):
+ yield node
+ for (level, stmt) in self[node.labels]:
+ self[node].emit(stmt=stmt, level=level)
+ for (level, stmt) in self[node.body]:
+ self[node].emit(stmt=stmt, level=level)
+
+ @Hook(pc_ast.Labels)
+ def Labels(self, node):
+ yield node
+ if ((len(node) == 1) and isinstance(node[-1], pc_ast.DefaultLabel)):
+ stmt = "default:"
+ else:
+ labels = ", ".join(map(lambda label: str(self[label]), node))
+ stmt = f"case ({labels}):"
+ self[node].emit(stmt=stmt)
+
+ @Hook(pc_ast.Label)
+ def Label(self, node):
+ yield node
+ self[node].emit(stmt=str(node))
+
+ @Hook(pc_ast.DefaultLabel)
+ def DefaultLabel(self, node):
+ yield node
+ self[node].emit(stmt="default:")
+
+ @Hook(pc_ast.UnaryExpr)
+ def UnaryExpr(self, node):
+ yield node
+ stmt = "".join([
+ str(self[node.op]),
+ f"({str(self[node.value])})",
+ ])
+ self[node].emit(stmt=stmt)
+
+ @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)
+ def StringLiteral(self, node):
+ yield node
+ self[node].emit(stmt=f"'{str(node)}'")
+
+ @Hook(pc_ast.Symbol)
+ def Symbol(self, node):
+ yield node
+ self[node].emit(stmt=str(node))
+
+ @Hook(pc_ast.Attribute)
+ def Attribute(self, node):
+ yield node
+ stmt = ".".join([
+ str(self[node.subject]),
+ str(self[node.name]),
+ ])
+ self[node].emit(stmt=stmt)
+
+ @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,
+ pc_ast.Eq, pc_ast.NotEq,
+ pc_ast.Lt, pc_ast.Le, pc_ast.LtU,
+ pc_ast.Gt, pc_ast.Ge, pc_ast.GtU,
+ pc_ast.LShift, pc_ast.RShift,
+ pc_ast.AssignOp, pc_ast.AssignIEAOp,
+ pc_ast.BitAnd, pc_ast.BitOr, pc_ast.BitXor,
+ pc_ast.BitConcat)
+ def Op(self, node):
+ yield node
+ mapping = {
+ pc_ast.Not: "¬",
+ pc_ast.Add: "+",
+ pc_ast.Sub: "-",
+ pc_ast.Mul: "*",
+ pc_ast.MulS: "*si",
+ pc_ast.MulU: "*ui",
+ pc_ast.Div: "/",
+ pc_ast.DivT: "÷",
+ pc_ast.Mod: "%",
+ pc_ast.Sqrt: "√",
+ pc_ast.Eq: "=",
+ pc_ast.NotEq: "!=",
+ pc_ast.Lt: "<",
+ pc_ast.Le: "<=",
+ pc_ast.LtU: "<u",
+ pc_ast.Gt: ">",
+ pc_ast.Ge: ">=",
+ pc_ast.GtU: ">u",
+ pc_ast.LShift: "<<",
+ pc_ast.RShift: ">>",
+ pc_ast.AssignOp: "<-",
+ pc_ast.AssignIEAOp: "<-iea",
+ pc_ast.BitAnd: "&",
+ pc_ast.BitOr: "|",
+ pc_ast.BitXor: "^",
+ pc_ast.BitConcat: "||",
+ }
+ stmt = mapping[node.__class__]
+ self[node].emit(stmt=stmt)
+
+ @Hook(pc_ast.LParenthesis, pc_ast.RParenthesis,
+ pc_ast.LBracket, pc_ast.RBracket)
+ def BracketOrParenthesis(self, node):
+ yield node
+ mapping = {
+ pc_ast.LParenthesis: "(",
+ pc_ast.RParenthesis: ")",
+ pc_ast.LBracket: "[",
+ pc_ast.RBracket: "]",
+ }
+ stmt = mapping[node.__class__]
+ self[node].emit(stmt=stmt)
+
+ @Hook(pc_ast.Subscript)
+ def Subscript(self, node):
+ yield node
+ stmt = "".join([
+ str(self[node.subject]),
+ "[",
+ str(self[node.index]),
+ "]",
+ ])
+ self[node].emit(stmt=stmt)
+
+ @Hook(pc_ast.RangeSubscript)
+ def RangeSubscript(self, node):
+ yield node
+ stmt = "".join([
+ str(self[node.subject]),
+ "[",
+ str(self[node.start]),
+ ":",
+ str(self[node.end]),
+ "]",
+ ])
+ self[node].emit(stmt=stmt)
+
+ @Hook(pc_ast.Colon)
+ def Colon(self, node):
+ yield node
+ self[node].emit(stmt=":")
+
+ @Hook(pc_ast.Linebreak, pc_ast.Endmarker)
+ def Ignore(self, node):
+ yield node
+
+ @Hook(pc_ast.Keyword)
+ def Keyword(self, node):
+ yield node
+ self[node].emit(stmt=node.__doc__)
+
+ @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)
+ def Literal(self, node):
+ yield node
+ self[node].emit(stmt=str(node))
+
+ @Hook(pc_ast.GPR, pc_ast.FPR, pc_ast.GPRZero)
+ def Reg(self, node):
+ yield node
+ if isinstance(node, pc_ast.GPRZero):
+ self[node].emit(stmt=f"({str(node)}|0)")
+ else:
+ self[node].emit(stmt=f"({str(node)})")
+
+ @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)
+++ /dev/null
-import collections
-import contextlib
-import functools
-
-import mdis.dispatcher
-import mdis.visitor
-import mdis.walker
-
-import openpower.oppc.pc_ast as pc_ast
-
-
-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):
- def __init__(self, root):
- self.__root = root
- self.__code = collections.defaultdict(lambda: Code())
-
- return super().__init__()
-
- def __iter__(self):
- yield from self.__code.items()
-
- def __getitem__(self, node):
- return self.__code[node]
-
- @Hook(pc_ast.Scope)
- def Scope(self, node):
- yield node
- if node is not self.__root:
- with self[node]:
- for subnode in node:
- for (level, stmt) in self[subnode]:
- self[node].emit(stmt=stmt, level=level)
- else:
- for subnode in node:
- for (level, stmt) in self[subnode]:
- self[node].emit(stmt=stmt, level=level)
-
- @Hook(pc_ast.Call)
- def Call(self, node):
- yield node
- args = []
- for subnode in node.args:
- for (level, stmt) in self[subnode]:
- assert level == 0
- args.append(stmt)
- args = ", ".join(args)
- stmt = f"{node.name}({args})"
- self[node].emit(stmt=stmt)
-
- @Hook(pc_ast.AssignExpr, pc_ast.AssignIEAExpr)
- def AssignExpr(self, node):
- mapping = {
- pc_ast.AssignExpr: "<-",
- pc_ast.AssignIEAExpr: "<-iea",
- }
- yield node
- lvalue = str(self[node.lvalue])
- if (isinstance(node.lvalue, (pc_ast.GPR, pc_ast.FPR)) or
- (isinstance(node.lvalue, (pc_ast.Subscript, pc_ast.RangeSubscript)) and
- isinstance(node.lvalue.subject, (pc_ast.GPR, pc_ast.FPR)))):
- lvalue = lvalue.replace("(", "").replace(")", "")
- rvalue = str(self[node.rvalue])
-
- if isinstance(node.rvalue, pc_ast.IfExpr):
- # All right, this deserves an explanation.
- # We basically convert T <- C ? A : B into this code:
- #
- # if C then
- # T <- A
- # else
- # T <- B
- #
- # To make things work, we must ensure that objects are unique.
- # Otherwise we'll reuse the bogus code already produced before.
- (body, orelse) = map(lambda node: node.clone(),
- (node.rvalue.body[0], node.rvalue.orelse[0]))
- body = pc_ast.Scope([node.__class__(lvalue=node.lvalue.clone(), rvalue=body)])
- orelse = pc_ast.Scope([node.__class__(lvalue=node.lvalue.clone(), rvalue=orelse)])
- tmpnode = node.rvalue.clone(body=body, orelse=orelse)
- walker = mdis.walker.Walker()
- traverse(root=tmpnode, visitor=self, walker=walker)
- for (level, stmt) in self[tmpnode]:
- self[node].emit(stmt=stmt, level=level)
- else:
- stmt = " ".join([
- lvalue,
- mapping[node.__class__],
- rvalue,
- ])
- self[node].emit(stmt=stmt)
-
- @Hook(pc_ast.BinaryExpr)
- def BinaryExpr(self, node):
- yield node
- stmt = " ".join([
- str(self[node.left]),
- str(self[node.op]),
- str(self[node.right]),
- ])
- self[node].emit(stmt=f"({stmt})")
-
- @Hook(pc_ast.IfExpr)
- def IfExpr(self, node):
- yield node
- stmt = " ".join([
- "if",
- str(self[node.test]),
- "then",
- ])
- self[node].emit(stmt=stmt)
- for (level, stmt) in self[node.body]:
- self[node].emit(stmt=stmt, level=level)
- if node.orelse:
- self[node].emit("else")
- for (level, stmt) in self[node.orelse]:
- self[node].emit(stmt=stmt, level=level)
-
- @Hook(pc_ast.ForExpr)
- def ForExpr(self, node):
- yield node
- stmt = " ".join([
- "for",
- str(self[node.subject]),
- "=",
- str(self[node.start]),
- "to",
- str(self[node.end]),
- ])
- self[node].emit(stmt=stmt)
- for (level, stmt) in self[node.body]:
- self[node].emit(stmt=stmt, level=level)
-
- @Hook(pc_ast.WhileExpr)
- def WhileExpr(self, node):
- yield node
- stmt = " ".join([
- "do",
- "while",
- str(self[node.test]),
- ])
- self[node].emit(stmt=stmt)
- for (level, stmt) in self[node.body]:
- self[node].emit(stmt=stmt, level=level)
- if node.orelse:
- self[node].emit("else")
- for (level, stmt) in self[node.orelse]:
- self[node].emit(stmt=stmt, level=level)
-
- @Hook(pc_ast.RepeatExpr)
- def RepeatExpr(self, node):
- yield node
- stmt = " ".join([
- f"[{str(self[node.subject])}]",
- "*",
- str(self[node.times]),
- ])
- self[node].emit(stmt=f"({stmt})")
-
- @Hook(pc_ast.SwitchExpr)
- def SwitchExpr(self, node):
- yield node
- self[node].emit(f"switch({str(self[node.subject])})")
- with self[node]:
- for (level, stmt) in self[node.cases]:
- self[node].emit(stmt=stmt, level=level)
-
- @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)
- def Case(self, node):
- yield node
- for (level, stmt) in self[node.labels]:
- self[node].emit(stmt=stmt, level=level)
- for (level, stmt) in self[node.body]:
- self[node].emit(stmt=stmt, level=level)
-
- @Hook(pc_ast.Labels)
- def Labels(self, node):
- yield node
- if ((len(node) == 1) and isinstance(node[-1], pc_ast.DefaultLabel)):
- stmt = "default:"
- else:
- labels = ", ".join(map(lambda label: str(self[label]), node))
- stmt = f"case ({labels}):"
- self[node].emit(stmt=stmt)
-
- @Hook(pc_ast.Label)
- def Label(self, node):
- yield node
- self[node].emit(stmt=str(node))
-
- @Hook(pc_ast.DefaultLabel)
- def DefaultLabel(self, node):
- yield node
- self[node].emit(stmt="default:")
-
- @Hook(pc_ast.UnaryExpr)
- def UnaryExpr(self, node):
- yield node
- stmt = "".join([
- str(self[node.op]),
- f"({str(self[node.value])})",
- ])
- self[node].emit(stmt=stmt)
-
- @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)
- def StringLiteral(self, node):
- yield node
- self[node].emit(stmt=f"'{str(node)}'")
-
- @Hook(pc_ast.Symbol)
- def Symbol(self, node):
- yield node
- self[node].emit(stmt=str(node))
-
- @Hook(pc_ast.Attribute)
- def Attribute(self, node):
- yield node
- stmt = ".".join([
- str(self[node.subject]),
- str(self[node.name]),
- ])
- self[node].emit(stmt=stmt)
-
- @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,
- pc_ast.Eq, pc_ast.NotEq,
- pc_ast.Lt, pc_ast.Le, pc_ast.LtU,
- pc_ast.Gt, pc_ast.Ge, pc_ast.GtU,
- pc_ast.LShift, pc_ast.RShift,
- pc_ast.AssignOp, pc_ast.AssignIEAOp,
- pc_ast.BitAnd, pc_ast.BitOr, pc_ast.BitXor,
- pc_ast.BitConcat)
- def Op(self, node):
- yield node
- mapping = {
- pc_ast.Not: "¬",
- pc_ast.Add: "+",
- pc_ast.Sub: "-",
- pc_ast.Mul: "*",
- pc_ast.MulS: "*si",
- pc_ast.MulU: "*ui",
- pc_ast.Div: "/",
- pc_ast.DivT: "÷",
- pc_ast.Mod: "%",
- pc_ast.Sqrt: "√",
- pc_ast.Eq: "=",
- pc_ast.NotEq: "!=",
- pc_ast.Lt: "<",
- pc_ast.Le: "<=",
- pc_ast.LtU: "<u",
- pc_ast.Gt: ">",
- pc_ast.Ge: ">=",
- pc_ast.GtU: ">u",
- pc_ast.LShift: "<<",
- pc_ast.RShift: ">>",
- pc_ast.AssignOp: "<-",
- pc_ast.AssignIEAOp: "<-iea",
- pc_ast.BitAnd: "&",
- pc_ast.BitOr: "|",
- pc_ast.BitXor: "^",
- pc_ast.BitConcat: "||",
- }
- stmt = mapping[node.__class__]
- self[node].emit(stmt=stmt)
-
- @Hook(pc_ast.LParenthesis, pc_ast.RParenthesis,
- pc_ast.LBracket, pc_ast.RBracket)
- def BracketOrParenthesis(self, node):
- yield node
- mapping = {
- pc_ast.LParenthesis: "(",
- pc_ast.RParenthesis: ")",
- pc_ast.LBracket: "[",
- pc_ast.RBracket: "]",
- }
- stmt = mapping[node.__class__]
- self[node].emit(stmt=stmt)
-
- @Hook(pc_ast.Subscript)
- def Subscript(self, node):
- yield node
- stmt = "".join([
- str(self[node.subject]),
- "[",
- str(self[node.index]),
- "]",
- ])
- self[node].emit(stmt=stmt)
-
- @Hook(pc_ast.RangeSubscript)
- def RangeSubscript(self, node):
- yield node
- stmt = "".join([
- str(self[node.subject]),
- "[",
- str(self[node.start]),
- ":",
- str(self[node.end]),
- "]",
- ])
- self[node].emit(stmt=stmt)
-
- @Hook(pc_ast.Colon)
- def Colon(self, node):
- yield node
- self[node].emit(stmt=":")
-
- @Hook(pc_ast.Linebreak, pc_ast.Endmarker)
- def Ignore(self, node):
- yield node
-
- @Hook(pc_ast.Keyword)
- def Keyword(self, node):
- yield node
- self[node].emit(stmt=node.__doc__)
-
- @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)
- def Literal(self, node):
- yield node
- self[node].emit(stmt=str(node))
-
- @Hook(pc_ast.GPR, pc_ast.FPR, pc_ast.GPRZero)
- def Reg(self, node):
- yield node
- if isinstance(node, pc_ast.GPRZero):
- self[node].emit(stmt=f"({str(node)}|0)")
- else:
- self[node].emit(stmt=f"({str(node)})")
-
- @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)