let rec convert_expr ~env exp =
let ebody =
match exp.expr_t with
| CTTexpComma(e1,e2) ->
PexpComma(convert_expr ~env e1, convert_expr ~env e2)
| CTTexpAssign (e1,e2) ->
PexpAssign(convert_expr ~env e1, convert_expr ~env e2)
| CTTexpBinAssign((CTTbinPostPlusVV | CTTbinPostPlusPV), e1, _, e2) -> begin
match e2.expr_t with
CTTexpConstant(CTTconstInteger p) when eq_big_int p unit_big_int ->
PexpPostInc (convert_expr ~env e1)
| _ -> failwith "argument of post-plus must be 1"
end
| CTTexpBinAssign((CTTbinPostMinusVV | CTTbinPostMinusPV), e1, _, e2) -> begin
match e2.expr_t with
CTTexpConstant(CTTconstInteger p) when eq_big_int p unit_big_int ->
PexpPostDec (convert_expr ~env e1)
| _ -> failwith "argument of post-minus must be 1"
end
| CTTexpBinAssign (bop, e1, _, e2) ->
PexpBinAssign (convert_binop bop, convert_expr ~env e1, convert_expr ~env e2)
| CTTexpConditional(e1, e2, e3) ->
PexpConditional (convert_expr ~env e1, convert_expr ~env e2, convert_expr ~env e3)
| CTTexpBinExpr((CTTbinPostPlusVV | CTTbinPostPlusPV | CTTbinPostMinusVV | CTTbinPostMinusPV),_,_)
-> failwith "post+/- cannot appear in usual binary operation expression"
| CTTexpBinExpr(binop, e1, e2) ->
PexpBinExpr(convert_binop binop, convert_expr ~env e1, convert_expr ~env e2)
| CTTexpCoerce(ty, e1) ->
let sq, dc = convert_declarator_anonymous ~env ty in
PexpCast(Ptypename(sq,dc), convert_expr ~env e1)
| CTTexpUnaryExpr(uop, e1) ->
PexpUnaryExpr(uop, convert_expr ~env e1)
| CTTexpAddress(e1) ->
PexpAddress(convert_expr ~env e1)
| CTTexpPtrDeref(e1) ->
PexpPtrDeref(convert_expr ~env e1)
| CTTexpInvoke(e1,eargs) ->
PexpInvoke(convert_expr ~env e1, List.map (convert_expr ~env) eargs)
| CTTexpField (e1,id) ->
PexpField(convert_expr ~env e1, id)
| CTTexpConstant(const) ->
PexpConstant(convert_constant const)
| CTTexpVar(id) ->
PexpVar(id)
in
make_expr ebody ~orig:exp