3 import openpower
.oppc
.pc_ast
as pc_ast
4 import openpower
.oppc
.pc_util
as pc_util
7 class PseudocodeVisitor(pc_util
.Visitor
):
8 def __init__(self
, root
):
9 self
.__code
= collections
.defaultdict(lambda: pc_util
.Code())
12 return super().__init
__(root
=root
)
15 yield from self
.__code
[self
.__root
]
17 def __getitem__(self
, node
):
18 return self
.__code
[node
]
20 @pc_util.Hook(pc_ast
.Scope
)
21 def Scope(self
, node
):
23 if node
is not self
.__root
:
26 for (level
, stmt
) in self
[subnode
]:
27 self
[node
].emit(stmt
=stmt
, level
=level
)
30 for (level
, stmt
) in self
[subnode
]:
31 self
[node
].emit(stmt
=stmt
, level
=level
)
33 @pc_util.Hook(pc_ast
.Call
)
37 for subnode
in node
.args
:
38 for (level
, stmt
) in self
[subnode
]:
41 args
= ", ".join(args
)
42 stmt
= f
"{node.name}({args})"
43 self
[node
].emit(stmt
=stmt
)
45 @pc_util.Hook(pc_ast
.AssignExpr
, pc_ast
.AssignIEAExpr
)
46 def AssignExpr(self
, node
):
48 pc_ast
.AssignExpr
: "<-",
49 pc_ast
.AssignIEAExpr
: "<-iea",
52 lvalue
= str(self
[node
.lvalue
])
53 if (isinstance(node
.lvalue
, (pc_ast
.GPR
, pc_ast
.FPR
)) or
54 (isinstance(node
.lvalue
, (pc_ast
.Subscript
, pc_ast
.RangeSubscript
)) and
55 isinstance(node
.lvalue
.subject
, (pc_ast
.GPR
, pc_ast
.FPR
)))):
56 lvalue
= lvalue
.replace("(", "").replace(")", "")
57 rvalue
= str(self
[node
.rvalue
])
59 if isinstance(node
.rvalue
, pc_ast
.IfExpr
):
62 mapping
[node
.__class
__],
63 str(self
[node
.rvalue
.test
]),
65 str(self
[node
.rvalue
.body
[0]]),
67 str(self
[node
.rvalue
.orelse
[0]]),
72 mapping
[node
.__class
__],
75 self
[node
].emit(stmt
=stmt
)
77 @pc_util.Hook(pc_ast
.BinaryExpr
)
78 def BinaryExpr(self
, node
):
83 str(self
[node
.right
]),
85 self
[node
].emit(stmt
=f
"({stmt})")
87 @pc_util.Hook(pc_ast
.IfExpr
)
88 def IfExpr(self
, node
):
95 self
[node
].emit(stmt
=stmt
)
96 for (level
, stmt
) in self
[node
.body
]:
97 self
[node
].emit(stmt
=stmt
, level
=level
)
99 self
[node
].emit("else")
100 for (level
, stmt
) in self
[node
.orelse
]:
101 self
[node
].emit(stmt
=stmt
, level
=level
)
103 @pc_util.Hook(pc_ast
.ForExpr
)
104 def ForExpr(self
, node
):
108 str(self
[node
.subject
]),
110 str(self
[node
.start
]),
114 self
[node
].emit(stmt
=stmt
)
115 for (level
, stmt
) in self
[node
.body
]:
116 self
[node
].emit(stmt
=stmt
, level
=level
)
118 @pc_util.Hook(pc_ast
.WhileExpr
)
119 def WhileExpr(self
, node
):
124 str(self
[node
.test
]),
126 self
[node
].emit(stmt
=stmt
)
127 for (level
, stmt
) in self
[node
.body
]:
128 self
[node
].emit(stmt
=stmt
, level
=level
)
130 self
[node
].emit("else")
131 for (level
, stmt
) in self
[node
.orelse
]:
132 self
[node
].emit(stmt
=stmt
, level
=level
)
134 @pc_util.Hook(pc_ast
.RepeatExpr
)
135 def RepeatExpr(self
, node
):
138 f
"[{str(self[node.subject])}]",
140 str(self
[node
.times
]),
142 self
[node
].emit(stmt
=f
"({stmt})")
144 @pc_util.Hook(pc_ast
.SwitchExpr
)
145 def SwitchExpr(self
, node
):
147 self
[node
].emit(f
"switch({str(self[node.subject])})")
149 for (level
, stmt
) in self
[node
.cases
]:
150 self
[node
].emit(stmt
=stmt
, level
=level
)
152 @pc_util.Hook(pc_ast
.Cases
)
153 def Cases(self
, node
):
156 for (level
, stmt
) in self
[subnode
]:
157 self
[node
].emit(stmt
=stmt
, level
=level
)
159 @pc_util.Hook(pc_ast
.Case
)
160 def Case(self
, node
):
162 for (level
, stmt
) in self
[node
.labels
]:
163 self
[node
].emit(stmt
=stmt
, level
=level
)
164 for (level
, stmt
) in self
[node
.body
]:
165 self
[node
].emit(stmt
=stmt
, level
=level
)
167 @pc_util.Hook(pc_ast
.Labels
)
168 def Labels(self
, node
):
170 if ((len(node
) == 1) and isinstance(node
[-1], pc_ast
.DefaultLabel
)):
173 labels
= ", ".join(map(lambda label
: str(self
[label
]), node
))
174 stmt
= f
"case ({labels}):"
175 self
[node
].emit(stmt
=stmt
)
177 @pc_util.Hook(pc_ast
.Label
)
178 def Label(self
, node
):
180 self
[node
].emit(stmt
=str(node
))
182 @pc_util.Hook(pc_ast
.DefaultLabel
)
183 def DefaultLabel(self
, node
):
185 self
[node
].emit(stmt
="default:")
187 @pc_util.Hook(pc_ast
.UnaryExpr
)
188 def UnaryExpr(self
, node
):
192 f
"({str(self[node.value])})",
194 self
[node
].emit(stmt
=stmt
)
196 @pc_util.Hook(pc_ast
.BinLiteral
, pc_ast
.DecLiteral
, pc_ast
.HexLiteral
)
197 def Integer(self
, node
):
199 self
[node
].emit(stmt
=str(node
))
201 @pc_util.Hook(pc_ast
.StringLiteral
)
202 def StringLiteral(self
, node
):
204 self
[node
].emit(stmt
=f
"'{str(node)}'")
206 @pc_util.Hook(pc_ast
.Symbol
)
207 def Symbol(self
, node
):
209 self
[node
].emit(stmt
=str(node
))
211 @pc_util.Hook(pc_ast
.Attribute
)
212 def Attribute(self
, node
):
215 str(self
[node
.subject
]),
216 str(self
[node
.name
]),
218 self
[node
].emit(stmt
=stmt
)
220 @pc_util.Hook(pc_ast
.Not
, pc_ast
.Add
, pc_ast
.Sub
,
221 pc_ast
.Mul
, pc_ast
.MulS
, pc_ast
.MulU
,
222 pc_ast
.Div
, pc_ast
.DivT
, pc_ast
.Mod
,
224 pc_ast
.Eq
, pc_ast
.NotEq
,
225 pc_ast
.Lt
, pc_ast
.Le
, pc_ast
.LtU
,
226 pc_ast
.Gt
, pc_ast
.Ge
, pc_ast
.GtU
,
227 pc_ast
.LShift
, pc_ast
.RShift
,
228 pc_ast
.AssignOp
, pc_ast
.AssignIEAOp
,
229 pc_ast
.BitAnd
, pc_ast
.BitOr
, pc_ast
.BitXor
,
254 pc_ast
.AssignOp
: "<-",
255 pc_ast
.AssignIEAOp
: "<-iea",
259 pc_ast
.BitConcat
: "||",
261 stmt
= mapping
[node
.__class
__]
262 self
[node
].emit(stmt
=stmt
)
264 @pc_util.Hook(pc_ast
.LParenthesis
, pc_ast
.RParenthesis
,
265 pc_ast
.LBracket
, pc_ast
.RBracket
)
266 def BracketOrParenthesis(self
, node
):
269 pc_ast
.LParenthesis
: "(",
270 pc_ast
.RParenthesis
: ")",
271 pc_ast
.LBracket
: "[",
272 pc_ast
.RBracket
: "]",
274 stmt
= mapping
[node
.__class
__]
275 self
[node
].emit(stmt
=stmt
)
277 @pc_util.Hook(pc_ast
.Subscript
)
278 def Subscript(self
, node
):
281 str(self
[node
.subject
]),
283 str(self
[node
.index
]),
286 self
[node
].emit(stmt
=stmt
)
288 @pc_util.Hook(pc_ast
.RangeSubscript
)
289 def RangeSubscript(self
, node
):
292 str(self
[node
.subject
]),
294 str(self
[node
.start
]),
299 self
[node
].emit(stmt
=stmt
)
301 @pc_util.Hook(pc_ast
.Colon
)
302 def Colon(self
, node
):
304 self
[node
].emit(stmt
=":")
306 @pc_util.Hook(pc_ast
.Linebreak
, pc_ast
.Endmarker
)
307 def Ignore(self
, node
):
310 @pc_util.Hook(pc_ast
.Keyword
)
311 def Keyword(self
, node
):
313 self
[node
].emit(stmt
=node
.__doc
__)
315 @pc_util.Hook(pc_ast
.Sequence
)
316 def Sequence(self
, node
):
318 stmt
= ",".join(map(lambda subnode
: str(self
[subnode
]), node
))
319 self
[node
].emit(stmt
=f
"({stmt})")
321 @pc_util.Hook(pc_ast
.Literal
)
322 def Literal(self
, node
):
324 self
[node
].emit(stmt
=str(node
))
326 @pc_util.Hook(pc_ast
.GPR
, pc_ast
.FPR
, pc_ast
.GPRZero
)
329 if isinstance(node
, pc_ast
.GPRZero
):
330 self
[node
].emit(stmt
=f
"({str(node)}|0)")
332 self
[node
].emit(stmt
=f
"({str(node)})")
334 @pc_util.Hook(pc_ast
.Node
)
335 def Node(self
, node
):
336 raise NotImplementedError(type(node
))
339 def pseudocode(root
):
340 yield from PseudocodeVisitor(root
=root
)