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 (level
, stmt
) in self
[node
.args
]:
40 args
= ", ".join(args
)
41 stmt
= f
"{node.name}({args})"
42 self
[node
].emit(stmt
=stmt
)
44 @pc_util.Hook(pc_ast
.AssignExpr
, pc_ast
.AssignIEAExpr
)
45 def AssignExpr(self
, node
):
47 pc_ast
.AssignExpr
: "<-",
48 pc_ast
.AssignIEAExpr
: "<-iea",
51 lvalue
= str(self
[node
.lvalue
])
52 if (isinstance(node
.lvalue
, (pc_ast
.GPR
, pc_ast
.FPR
)) or
53 (isinstance(node
.lvalue
, (pc_ast
.SubscriptExpr
, pc_ast
.RangeSubscriptExpr
)) and
54 isinstance(node
.lvalue
.subject
, (pc_ast
.GPR
, pc_ast
.FPR
)))):
55 lvalue
= lvalue
.replace("(", "").replace(")", "")
56 rvalue
= str(self
[node
.rvalue
])
58 if isinstance(node
.rvalue
, pc_ast
.IfExpr
):
61 mapping
[node
.__class
__],
62 str(self
[node
.rvalue
.test
]),
64 str(self
[node
.rvalue
.body
[0]]),
66 str(self
[node
.rvalue
.orelse
[0]]),
71 mapping
[node
.__class
__],
74 self
[node
].emit(stmt
=stmt
)
76 @pc_util.Hook(pc_ast
.BinaryExpr
)
77 def BinaryExpr(self
, node
):
82 str(self
[node
.right
]),
84 self
[node
].emit(stmt
=f
"({stmt})")
86 @pc_util.Hook(pc_ast
.IfExpr
)
87 def IfExpr(self
, node
):
94 self
[node
].emit(stmt
=stmt
)
95 for (level
, stmt
) in self
[node
.body
]:
96 self
[node
].emit(stmt
=stmt
, level
=level
)
98 self
[node
].emit(stmt
="else")
99 for (level
, stmt
) in self
[node
.orelse
]:
100 self
[node
].emit(stmt
=stmt
, level
=level
)
102 @pc_util.Hook(pc_ast
.ForExpr
)
103 def ForExpr(self
, node
):
107 str(self
[node
.subject
]),
109 str(self
[node
.start
]),
113 self
[node
].emit(stmt
=stmt
)
114 for (level
, stmt
) in self
[node
.body
]:
115 self
[node
].emit(stmt
=stmt
, level
=level
)
117 @pc_util.Hook(pc_ast
.WhileExpr
)
118 def WhileExpr(self
, node
):
123 str(self
[node
.test
]),
125 self
[node
].emit(stmt
=stmt
)
126 for (level
, stmt
) in self
[node
.body
]:
127 self
[node
].emit(stmt
=stmt
, level
=level
)
129 self
[node
].emit(stmt
="else")
130 for (level
, stmt
) in self
[node
.orelse
]:
131 self
[node
].emit(stmt
=stmt
, level
=level
)
133 @pc_util.Hook(pc_ast
.RepeatExpr
)
134 def RepeatExpr(self
, node
):
137 f
"[{str(self[node.subject])}]",
139 str(self
[node
.times
]),
141 self
[node
].emit(stmt
=f
"({stmt})")
143 @pc_util.Hook(pc_ast
.SwitchExpr
)
144 def SwitchExpr(self
, node
):
146 self
[node
].emit(stmt
=f
"switch({str(self[node.subject])})")
148 for (level
, stmt
) in self
[node
.cases
]:
149 self
[node
].emit(stmt
=stmt
, level
=level
)
151 @pc_util.Hook(pc_ast
.Cases
)
152 def Cases(self
, node
):
155 for (level
, stmt
) in self
[subnode
]:
156 self
[node
].emit(stmt
=stmt
, level
=level
)
158 @pc_util.Hook(pc_ast
.Case
)
159 def Case(self
, node
):
161 for (level
, stmt
) in self
[node
.labels
]:
162 self
[node
].emit(stmt
=stmt
, level
=level
)
163 for (level
, stmt
) in self
[node
.body
]:
164 self
[node
].emit(stmt
=stmt
, level
=level
)
166 @pc_util.Hook(pc_ast
.Labels
)
167 def Labels(self
, node
):
169 if ((len(node
) == 1) and isinstance(node
[-1], pc_ast
.DefaultLabel
)):
172 labels
= ", ".join(map(lambda label
: str(self
[label
]), node
))
173 stmt
= f
"case ({labels}):"
174 self
[node
].emit(stmt
=stmt
)
176 @pc_util.Hook(pc_ast
.Label
)
177 def Label(self
, node
):
179 self
[node
].emit(stmt
=str(node
))
181 @pc_util.Hook(pc_ast
.DefaultLabel
)
182 def DefaultLabel(self
, node
):
184 self
[node
].emit(stmt
="default:")
186 @pc_util.Hook(pc_ast
.UnaryExpr
)
187 def UnaryExpr(self
, node
):
191 f
"({str(self[node.value])})",
193 self
[node
].emit(stmt
=stmt
)
195 @pc_util.Hook(pc_ast
.BinLiteral
, pc_ast
.DecLiteral
, pc_ast
.HexLiteral
)
196 def Integer(self
, node
):
198 self
[node
].emit(stmt
=str(node
))
200 @pc_util.Hook(pc_ast
.StringLiteral
)
201 def StringLiteral(self
, node
):
203 self
[node
].emit(stmt
=f
"'{str(node)}'")
205 @pc_util.Hook(pc_ast
.Symbol
)
206 def Symbol(self
, node
):
208 self
[node
].emit(stmt
=str(node
))
210 @pc_util.Hook(pc_ast
.Attribute
)
211 def Attribute(self
, node
):
214 str(self
[node
.subject
]),
215 str(self
[node
.name
]),
217 self
[node
].emit(stmt
=stmt
)
219 @pc_util.Hook(pc_ast
.Not
, pc_ast
.Add
, pc_ast
.Sub
,
220 pc_ast
.Mul
, pc_ast
.MulS
, pc_ast
.MulU
,
221 pc_ast
.Div
, pc_ast
.DivT
, pc_ast
.Mod
,
223 pc_ast
.Eq
, pc_ast
.NotEq
,
224 pc_ast
.Lt
, pc_ast
.Le
, pc_ast
.LtU
,
225 pc_ast
.Gt
, pc_ast
.Ge
, pc_ast
.GtU
,
226 pc_ast
.LShift
, pc_ast
.RShift
,
227 pc_ast
.AssignOp
, pc_ast
.AssignIEAOp
,
228 pc_ast
.BitAnd
, pc_ast
.BitOr
, pc_ast
.BitXor
,
253 pc_ast
.AssignOp
: "<-",
254 pc_ast
.AssignIEAOp
: "<-iea",
258 pc_ast
.BitConcat
: "||",
260 stmt
= mapping
[node
.__class
__]
261 self
[node
].emit(stmt
=stmt
)
263 @pc_util.Hook(pc_ast
.LParenthesis
, pc_ast
.RParenthesis
,
264 pc_ast
.LBracket
, pc_ast
.RBracket
)
265 def BracketOrParenthesis(self
, node
):
268 pc_ast
.LParenthesis
: "(",
269 pc_ast
.RParenthesis
: ")",
270 pc_ast
.LBracket
: "[",
271 pc_ast
.RBracket
: "]",
273 stmt
= mapping
[node
.__class
__]
274 self
[node
].emit(stmt
=stmt
)
276 @pc_util.Hook(pc_ast
.SubscriptExpr
)
277 def SubscriptExpr(self
, node
):
280 str(self
[node
.subject
]),
282 str(self
[node
.index
]),
285 self
[node
].emit(stmt
=stmt
)
287 @pc_util.Hook(pc_ast
.RangeSubscriptExpr
)
288 def RangeSubscriptExpr(self
, node
):
291 str(self
[node
.subject
]),
293 str(self
[node
.start
]),
298 self
[node
].emit(stmt
=stmt
)
300 @pc_util.Hook(pc_ast
.Colon
)
301 def Colon(self
, node
):
303 self
[node
].emit(stmt
=":")
305 @pc_util.Hook(pc_ast
.Linebreak
, pc_ast
.Endmarker
)
306 def Ignore(self
, node
):
309 @pc_util.Hook(pc_ast
.Keyword
)
310 def Keyword(self
, node
):
312 self
[node
].emit(stmt
=node
.__doc
__)
314 @pc_util.Hook(pc_ast
.Sequence
)
315 def Sequence(self
, node
):
317 stmt
= ",".join(map(lambda subnode
: str(self
[subnode
]), node
))
318 self
[node
].emit(stmt
=f
"({stmt})")
320 @pc_util.Hook(pc_ast
.Literal
)
321 def Literal(self
, node
):
323 self
[node
].emit(stmt
=str(node
))
325 @pc_util.Hook(pc_ast
.GPR
, pc_ast
.FPR
, pc_ast
.GPRZero
)
328 if isinstance(node
, pc_ast
.GPRZero
):
329 self
[node
].emit(stmt
=f
"({str(node)}|0)")
331 self
[node
].emit(stmt
=f
"({str(node)})")
333 @pc_util.Hook(pc_ast
.Node
)
334 def Node(self
, node
):
335 raise NotImplementedError(type(node
))
338 def pseudocode(root
):
339 yield from PseudocodeVisitor(root
=root
)