open Ast
open Static
let is_not_zero ty = match ty with
| TBitArray { se_desc = SInt 0 } -> false
| _ -> true
let rec simplify_exp e = match e.e_desc with
(* replace x[i..j] with [] if j < i *)
| Ecall("slice",
[{ se_desc = SInt min };
{ se_desc = SInt max }; n], _) when max < min ->
{ e with e_desc = Econst (VBitArray (Array.make 0 false)) }
(* replace x[i..i] with x[i] *)
| Ecall("slice", [min; max; n], args) when min = max ->
let new_e = { e with e_desc = Ecall("select", [min; n], args) } in
simplify_exp new_e
(* replace x.[] or [].x with x *)
| Ecall("concat", _, [{ e_ty = TBitArray { se_desc = SInt 0 } }; e1])
| Ecall("concat", _, [e1; { e_ty = TBitArray { se_desc = SInt 0 } }]) ->
e1
| Ecall(f, params, args) ->
{ e with e_desc = Ecall(f, params, List.map simplify_exp args) }
| _ -> e
let simplify_eq (pat,e) =
(pat, simplify_exp e)
let rec block b = match b with
| BEqs(eqs, vds) ->
let eqs = List.map simplify_eq eqs in
(* remove variables with size 0 *)
let vds = List.filter (fun vd -> is_not_zero vd.v_ty) vds in
let eqs = List.filter (fun (_, e) -> is_not_zero e.e_ty) eqs in
BEqs(eqs, vds)
| BIf(se, trueb, elseb) -> BIf(se, block trueb, block elseb)
let node n =
{ n with n_body = block n.n_body }
let program p =
{ p with p_nodes = List.map node p.p_nodes }