class CodeVisitor(pc_util.Visitor):
def __init__(self, insn, root):
+ if not isinstance(root, pc_ast.Scope):
+ raise ValueError(root)
+
self.__root = root
self.__insn = insn
- self.__attrs = {}
self.__decls = set()
self.__header = object()
self.__footer = object()
super().__init__(root=root)
- self.__code[self.__header].emit(stmt="void")
- self.__code[self.__header].emit(stmt=f"oppc_{insn.name}(struct oppc_value const *insn) {{")
- with self.__code[self.__header]:
- for decl in self.__decls:
- self.__code[self.__header].emit(stmt=f"struct oppc_value {decl};")
+ for decl in self.__decls:
+ self.__code[self.__header].emit(stmt=f"struct oppc_value {decl};")
decls = sorted(filter(lambda decl: decl in insn.fields, self.__decls))
if decls:
self.__code[self.__header].emit()
symbol = pc_ast.Symbol(decl)
assign = pc_ast.AssignExpr(lvalue=symbol, rvalue=transient)
self.traverse(root=assign)
- with self[self.__header]:
- for (level, stmt) in self[assign]:
- self[self.__header].emit(stmt=stmt, level=level)
+ for (level, stmt) in self[assign]:
+ self[self.__header].emit(stmt=stmt, level=level)
for (lbit, rbit) in enumerate(insn.fields[decl]):
lsymbol = pc_ast.Symbol(decl)
rsymbol = Instruction()
rvalue = pc_ast.SubscriptExpr(index=rindex, subject=rsymbol)
assign = pc_ast.AssignExpr(lvalue=lvalue, rvalue=rvalue)
self.traverse(root=assign)
- with self[self.__header]:
- for (level, stmt) in self[assign]:
- self[self.__header].emit(stmt=stmt, level=level)
+ for (level, stmt) in self[assign]:
+ self[self.__header].emit(stmt=stmt, level=level)
self.__code[self.__header].emit()
if decls:
self.__code[self.__header].emit()
- self.__code[self.__footer].emit(stmt=f"}}")
def __iter__(self):
- yield from self.__code[self.__header]
- yield from self.__code[self.__root]
- yield from self.__code[self.__footer]
+ yield from self[self.__header]
+ for (level, stmt) in self[self.__root]:
+ yield ((level - 1), stmt)
+ yield from self[self.__footer]
def __getitem__(self, node):
return self.__code[node]
def fixup_ternary(self, node):
self[node].clear()
- test = self.call(name="oppc_bool", code=[
+ test = self.call(name="oppc_cast_bool", code=[
self[node.test],
])
self[node].emit(stmt="(")
comparison = (
pc_ast.Lt, pc_ast.Le,
- pc_ast.Eq, pc_ast.NotEq,
+ pc_ast.Eq, pc_ast.Ne,
pc_ast.Ge, pc_ast.Gt,
pc_ast.LtU, pc_ast.GtU,
)
yield node
if isinstance(node.value, pc_ast.IfExpr):
self.fixup_ternary(node=node.value)
+ transient = self.transient()
call = self.call(name=str(self[node.op]), code=[
+ self[transient],
self[node.value],
])
with self.pseudocode(node=node):
pc_ast.Not, pc_ast.Add, pc_ast.Sub,
pc_ast.Mul, pc_ast.Div, pc_ast.Mod,
pc_ast.Lt, pc_ast.Le,
- pc_ast.Eq, pc_ast.NotEq,
+ pc_ast.Eq, pc_ast.Ne,
pc_ast.Ge, pc_ast.Gt,
pc_ast.LtU, pc_ast.GtU,
pc_ast.LShift, pc_ast.RShift,
pc_ast.Lt: "oppc_lt",
pc_ast.Le: "oppc_le",
pc_ast.Eq: "oppc_eq",
+ pc_ast.Ne: "oppc_ne",
pc_ast.LtU: "oppc_ltu",
pc_ast.GtU: "oppc_gtu",
- pc_ast.NotEq: "oppc_noteq",
pc_ast.Ge: "oppc_ge",
pc_ast.Gt: "oppc_gt",
pc_ast.LShift: "oppc_lshift",
@pc_util.Hook(pc_ast.IfExpr)
def IfExpr(self, node):
yield node
- test = self.call(name="oppc_bool", code=[
+ test = self.call(name="oppc_cast_bool", code=[
self[node.test],
])
self[node].emit(stmt="if (")
@pc_util.Hook(pc_ast.SwitchExpr)
def SwitchExpr(self, node):
yield node
- subject = self.call(name="oppc_int64", code=[
+ subject = self.call(name="oppc_cast_int64", code=[
self[node.subject],
])
self[node].emit(stmt="switch (")
@pc_util.Hook(pc_ast.Call)
def Call(self, node):
yield node
- code = tuple(map(lambda arg: self[arg], node.args))
- call = self.call(name=str(node.name), code=code)
- for (level, stmt) in self[call]:
- self[node].emit(stmt=stmt, level=level)
+ if node.args:
+ transient = self.transient()
+ code = [self[transient]]
+ else:
+ code = []
+ code.extend(map(lambda arg: self[arg], node.args))
+ name = f"OPPC_CALL_{str(node.name)}"
+ with self.pseudocode(node=node):
+ call = self.call(name=name, code=code)
+ for (level, stmt) in self[call]:
+ self[node].emit(stmt=stmt, level=level)
@pc_util.Hook(pc_ast.Attribute.Name)
def AttributeName(self, node):
symbol = f"OPPC_ATTR_{attr.replace('.', '_')}"
self[node].emit(f"/* {attr} */")
self[node].emit(stmt=symbol)
- self.__attrs[node] = symbol
@pc_util.Hook(pc_ast.Symbol)
def Symbol(self, node):
decl = str(node)
if decl not in ("fallthrough",):
if decl in ("TRAP",):
- self[node].emit(stmt=f"{decl}();")
+ self[node].emit(stmt=f"OPPC_CALL_{decl}();")
else:
if node in self.__pseudocode:
self.__decls.add(decl)