def xcompound_to_ast_expr(xc: X.XprCompound, astree: AbstractSyntaxTree) -> AST.ASTExpr: """Convert a compound expression to an AST Expr node.""" op = xc.operator operands = xc.operands if len(operands) == 1: op1 = xxpr_to_ast_expr(operands[0], astree) return astree.mk_unary_op(op, op1) elif len(operands) == 2: if xc.is_stack_address: stackoffset = xc.stack_address_offset() rhslval = astree.mk_stack_variable_lval(stackoffset) return astree.mk_address_of(rhslval) else: op1 = xxpr_to_ast_expr(operands[0], astree) op2 = xxpr_to_ast_expr(operands[1], astree) if op1.ctype is not None and op in ["plus", "minus"]: return xtyped_expr_to_ast_expr(op, op1, op2, astree) else: return astree.mk_binary_op(op, op1, op2) else: raise UF.CHBError("AST conversion of compound expression " + str(xc) + " not yet supported")
def ast(self, astree: AbstractSyntaxTree, iaddr: str, bytestring: str, xdata: InstrXData) -> List[ASTInstruction]: lhs = xdata.vars[0] rhs1 = str(xdata.xprs[0]) rhs2 = xdata.xprs[1] rhs3 = xdata.xprs[3] if lhs == "SP" and rhs1 == "SP" and rhs2.is_constant: return [] lhsast = XU.xvariable_to_ast_lval(lhs, astree) if rhs1 == "SP" and rhs3.is_stack_address: rhs3 = cast("XprCompound", rhs3) stackoffset = rhs3.stack_address_offset() rhslval = astree.mk_stack_variable_lval(stackoffset) rhsast: ASTExpr = astree.mk_address_of(rhslval) elif rhs1 == "PC" or str(rhs2) == "PC": if rhs3.is_int_constant: rhsval = cast("XprConstant", rhs3).intvalue rhsast = astree.mk_integer_constant(rhsval) else: rhsast = XU.xxpr_to_ast_expr(rhs3, astree) else: rhsast = XU.xxpr_to_ast_expr(rhs3, astree) result = astree.mk_assign(lhsast, rhsast) astree.add_instruction_span(result.id, iaddr, bytestring) return [result]
def xtyped_expr_to_ast_expr(op: str, op1: AST.ASTExpr, op2: AST.ASTExpr, astree: AbstractSyntaxTree) -> AST.ASTExpr: """Determine if expression needs different representation based on type.""" if op1.ctype is None: raise UF.CHBError("Expression is not typed: " + str(op1)) if op1.ctype.is_pointer and op2.is_integer_constant: op2 = cast(AST.ASTIntegerConstant, op2) tgttype = cast("BCTypPtr", op1.ctype).tgttyp if tgttype.is_struct: compinfo = cast("BCTypComp", tgttype).compinfo fieldoffset = field_at_offset(compinfo, op2.cvalue, astree) lval = astree.mk_memref_lval(op1, fieldoffset) return astree.mk_address_of(lval) return astree.mk_binary_op(op, op1, op2)