Source file tail_analysis.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
open Std
open Browse_raw
open Typedtree
let tail_operator = function
| { exp_desc =
Texp_ident
{ desc =
{ Types.val_kind =
Types.Val_prim
{ Primitive.prim_name = "%sequand" | "%sequor"; _ };
_
};
_
};
_
} -> true
| _ -> false
let expr_tail_positions = function
| Texp_apply (callee, args, _, _, _) when tail_operator callee ->
begin match List.last args with
| None | Some (_, Omitted _) -> []
| Some (_, Arg (expr, _)) -> [ Expression expr ]
end
| Texp_instvar _
| Texp_setinstvar _
| Texp_override _
| Texp_assert _
| Texp_lazy _
| Texp_object _
| Texp_pack _
| Texp_function _
| Texp_apply _
| Texp_tuple _
| Texp_unboxed_tuple _
| Texp_ident _
| Texp_constant _
| Texp_construct _
| Texp_variant _
| Texp_record _
| Texp_record_unboxed_product _
| Texp_field _
| Texp_unboxed_field _
| Texp_setfield _
| Texp_array _
| Texp_while _
| Texp_for _
| Texp_send _
| Texp_new _
| Texp_unreachable
| Texp_extension_constructor _
| Texp_letop _
| Texp_typed_hole
| Texp_list_comprehension _
| Texp_array_comprehension _
| Texp_probe _
| Texp_probe_is_enabled _
| Texp_src_pos
| Texp_overwrite _
| Texp_mutvar _
| Texp_setmutvar _
| Texp_idx _
| Texp_atomic_loc _
| Texp_hole _
| Texp_quotation _
| Texp_antiquotation _
| Texp_unboxed_unit
| Texp_unboxed_bool _ -> []
| Texp_match (_, _, cs, _) -> List.map cs ~f:(fun c -> Case c)
| Texp_try (_, cs) -> List.map cs ~f:(fun c -> Case c)
| Texp_letmodule (_, _, _, _, e)
| Texp_letexception (_, e)
| Texp_let (_, _, e)
| Texp_letmutable (_, e)
| Texp_sequence (_, _, e)
| Texp_ifthenelse (_, e, None)
| Texp_open (_, e) -> [ Expression e ]
| Texp_ifthenelse (_, e1, Some e2) -> [ Expression e1; Expression e2 ]
| Texp_exclave e -> [ Expression e ]
| Texp_apply_layout (e, _) -> [ Expression e ]
let tail_positions = function
| Expression expr -> expr_tail_positions expr.exp_desc
| Case case -> [ Expression case.c_rhs ]
| _ -> []
let expr_entry_points = function
| Texp_function { body = Tfunction_body expr; _ } -> [ Expression expr ]
| Texp_function { body = Tfunction_cases { fc_cases; _ }; _ } ->
List.map fc_cases ~f:(fun c -> Case c)
| _ -> []
let entry_points = function
| Expression expr -> expr_entry_points expr.exp_desc
| _ -> []
let is_call = function
| Expression { exp_desc = Texp_apply _; _ } -> true
| _ -> false