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
open Std
open Browse_raw
open Typedtree
let tail_operator = function
| { exp_desc =
Texp_ident
( _,
_,
{ 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_ident _
| Texp_constant _
| Texp_construct _
| Texp_variant _
| Texp_record _
| Texp_field _
| Texp_setfield _
| Texp_array _
| Texp_while _
| Texp_for _
| Texp_send _
| Texp_new _
| Texp_unreachable
| Texp_extension_constructor _
| Texp_letop _
| Texp_atomic_loc _
| Texp_typed_hole -> []
| 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_sequence (_, e)
| Texp_ifthenelse (_, e, None)
| Texp_open (_, e) -> [ Expression e ]
| Texp_ifthenelse (_, e1, Some e2) -> [ Expression e1; Expression e2 ]
let tail_positions = function
| Expression expr -> expr_tail_positions expr.exp_desc
| Case case -> [ Expression case.c_rhs ]
| _ -> []
let expr_entry_points = function
| _ -> []
let entry_points = function
| Expression expr -> expr_entry_points expr.exp_desc
| _ -> []
let is_call = function
| Expression { exp_desc = Texp_apply _; _ } -> true
| _ -> false