let rec reduce_expr exp =
let v = visit_expr reduce_expr in
let body =
match exp.expr_t with
CTTexpBinAssign(
(CTTbinPlusPV | CTTbinMinusPV | CTTbinPostPlusPV | CTTbinPostMinusPV) as binop,
e_ptr,None,
e_off) -> begin
match calculate_magnitude exp.expr_type ~orig:exp with
Some multiply ->
let e_ptr = reduce_expr e_ptr in
let e_off = reduce_expr e_off in
let e2 =
make_expr_t
(CTTexpBinExpr (CTTbinTimes, e_off, multiply))
(type_of e_off)
~orig:e_off
in
let e2 = fold_constants e2 in
CTTexpBinAssign(binop,e_ptr,None,e2)
| None -> (v exp).expr_t
end
| CTTexpBinExpr(
(CTTbinPlusPV | CTTbinMinusPV) as binop,
e_ptr, e_off) -> begin
match calculate_magnitude exp.expr_type ~orig:exp with
Some multiply ->
let e_ptr = reduce_expr e_ptr in
let e_off = reduce_expr e_off in
let e2 =
make_expr_t
(CTTexpBinExpr (CTTbinTimes, e_off, multiply))
(type_of e_off)
~orig:e_off
in
let e2 = fold_constants e2 in
CTTexpBinExpr(binop,e_ptr,e2)
| None ->
(v exp).expr_t
end
| CTTexpCoerce(t,e1) ->
let e1 = reduce_expr e1 in
let new_t = convert_type t in
if equal_type ~check_qual:qual_eq ~check_iqual:qual_eq new_t e1.expr_type then
e1.expr_t
else
CTTexpCoerce(convert_type t, e1)
| _ -> (v exp).expr_t
in
let t = convert_type exp.expr_type in
make_expr_t body t ~orig:exp