def reduceConstExpr(self, e: expr.ExprET) -> expr.ExprET: """Converts: 5 + 6, 6 > 7, -5, +6, !7, ~9, ... to a single literal.""" newExpr = e if isinstance(e, expr.BinaryE): arg1 = e.arg1 arg2 = e.arg2 if arg1.exprCode == expr.LIT_EXPR_EC and\ arg2.exprCode == expr.LIT_EXPR_EC: if e.opr.opCode == op.BO_ADD_OC: newExpr = expr.LitE(arg1.val + arg2.val, loc=arg1.loc) elif e.opr.opCode == op.BO_SUB_OC: newExpr = expr.LitE(arg1.val - arg2.val, loc=arg1.loc) elif e.opr.opCode == op.BO_MUL_OC: newExpr = expr.LitE(arg1.val * arg2.val, loc=arg1.loc) elif e.opr.opCode == op.BO_DIV_OC: newExpr = expr.LitE(arg1.val / arg2.val, loc=arg1.loc) elif e.opr.opCode == op.BO_MOD_OC: newExpr = expr.LitE(arg1.val % arg2.val, loc=arg1.loc) elif e.opr.opCode == op.BO_LT_OC: newExpr = expr.LitE(int(arg1.val < arg2.val), loc=arg1.loc) elif e.opr.opCode == op.BO_LE_OC: newExpr = expr.LitE(int(arg1.val <= arg2.val), loc=arg1.loc) elif e.opr.opCode == op.BO_EQ_OC: newExpr = expr.LitE(int(arg1.val == arg2.val), loc=arg1.loc) elif e.opr.opCode == op.BO_NE_OC: newExpr = expr.LitE(int(arg1.val != arg2.val), loc=arg1.loc) elif e.opr.opCode == op.BO_GE_OC: newExpr = expr.LitE(int(arg1.val >= arg2.val), loc=arg1.loc) elif e.opr.opCode == op.BO_GT_OC: newExpr = expr.LitE(int(arg1.val > arg2.val), loc=arg1.loc) elif isinstance(e, expr.UnaryE): arg = e.arg if arg.exprCode == expr.LIT_EXPR_EC: if e.opr.opCode == op.UO_PLUS_OC: newExpr = e.arg elif e.opr.opCode == op.UO_MINUS_OC: newExpr = expr.LitE(e.arg.val * -1, loc=e.arg.loc) elif e.opr.opCode == op.UO_LNOT_OC: newExpr = expr.LitE(int(not (bool(e.arg.val))), loc=e.arg.loc) elif e.opr.opCode == op.UO_BIT_NOT_OC: newExpr = expr.LitE(~e.arg.val, loc=e.arg.loc) return newExpr
all_vars: Dict[types.VarNameT, types.ReturnT] = { "v:main:x": types.Int, "v:main:y": types.Int, "v:main:b": types.Int, } # end all_vars dict all_func: Dict[types.FuncNameT, graph.FuncNode] = { "f:main": graph.FuncNode( name= "f:main", params= [], returns= types.Int, basic_blocks= { 1: graph.BB([ # 1 is always start/entry BB. (REQUIRED) instr.AssignI(expr.VarE("v:main:b"), expr.LitE(1)), instr.CondI(expr.VarE("v:main:b")), ]), 2: graph.BB([ instr.AssignI(expr.VarE("v:main:y"), expr.VarE("v:main:x")), ]), 3: graph.BB([ instr.AssignI(expr.VarE("v:main:y"), expr.LitE(20)), ]), -1: graph.BB([ # -1 is end/exit block (REQUIRED, if more than one BB present) instr.UseI(expr.VarE("v:main:y")), ]), }, bb_edges= [ graph.BbEdge(1, 2, graph.FalseEdge), graph.BbEdge(1, 3, graph.TrueEdge),
"v:main:a": types.Int, "v:main:b": types.Int, "v:main:c": types.Int, "v:main:u": types.Ptr(to=types.Int), } # end all_vars dict all_func: Dict[types.FuncNameT, graph.FuncNode] = { "f:main": graph.FuncNode( name="f:main", params=[], returns=types.Int, basic_blocks={ 1: graph.BB([ # 1 is always start/entry BB. (REQUIRED) instr.AssignI(expr.VarE("v:main:a"), expr.LitE(10)), instr.AssignI(expr.VarE("v:main:c"), expr.LitE(20)), instr.AssignI(expr.VarE("v:main:b"), expr.LitE(2)), instr.CondI(expr.VarE("v:main:b")), ]), 2: graph.BB([ instr.AssignI(expr.VarE("v:main:u"), expr.UnaryE(op.AddrOf, expr.VarE("v:main:c"))), ]), 3: graph.BB([ instr.AssignI(expr.VarE("v:main:u"), expr.UnaryE(op.AddrOf, expr.VarE("v:main:a"))), ]), -1:
hooplIr.append(hooplInsn) break # must be only one unconditional edge insnList: str = "" with io.StringIO() as sio: prefix = "" for bbInsnId in hooplBbInsnIds[:-1]: sio.write(prefix) sio.write(bbInsnId) if not prefix: prefix = ", " insnList = sio.getvalue() hooplBb = f"bb{currBbLabel} = Block \"BB{currBbLabel}\" [{insnList}] {hooplBbInsnIds[-1]}" hooplBbs.append(hooplBb) hooplIr.append("") # for separation between insns and bbs for hooplBb in hooplBbs: hooplIr.append(hooplBb) return "\n".join(hooplIr) if __name__ == "__main__": instrs = [ instr.AssignI(expr.VarE("v:main:x"), expr.LitE(10)), instr.CondI(expr.VarE("v:main:x"), "True", "False"), instr.LabelI("True"), instr.LabelI("False"), ] print(Func.genBasicBlocks(instrs))