let opt_useless program =
let rec check_expr e =
match e.expr_val with
| Var(f, l) ->
(
match f.var_def with
| None -> failwith "internal error"
| Some d ->
List.iter check_expr l;
match d.def_value with
| Function f ->
if not f.func_used then
(
f.func_used <- true;
check_block f.func_value
)
| _ -> ()
)
| Arr(e1, e2)
| Lt(e1, e2)
| Le(e1, e2)
| Eq(e1, e2)
| Neq(e1, e2)
| Or(e1, e2)
| And(e1, e2)
| Plus(e1, e2)
| Minus(e1, e2)
| Mult(e1, e2)
| Div(e1, e2)
| Mod(e1, e2) ->
check_expr e1;
check_expr e2
| Rec(e, _)
| Address_of e
| Bang e
| Not e
| Uminus e ->
check_expr e
| New _
| Int _
| Bool _ -> ()
and check_instr = function
| Proc(p, l) ->
let d =
match p.var_def with
| Some d -> d
| None -> failwith "internal error"
in
(
List.iter check_expr l;
match d.def_value with
| Function f ->
if not f.func_used then
(
f.func_used <- true;
check_block f.func_value
)
| _ -> failwith "internal error"
)
| If(e, s1, s2) ->
check_expr e;
check_instr s1.stt_value;
check_instr s2.stt_value
| While(e, s) ->
check_expr e;
check_instr s.stt_value
| Compound ss ->
List.iter (fun s -> check_instr s.stt_value) ss
| Assign(e1, e2) ->
check_expr e1;
check_expr e2
| Delete e
| Return e ->
check_expr e
| Noop -> ()
and check_block block =
List.iter (fun s -> check_instr s.stt_value) block.block_stts
in
check_block (snd program)