Source file signature_with_global_bindings.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
[@@@ocaml.warning "+a-9-40-41-42"]
type t = {
sign : Subst.Lazy.persistent_signature;
bound_globals : Global_module.With_precision.t array;
}
let read_from_cmi (cmi : Cmi_format.cmi_infos_lazy) =
let cmi_sign, staticity = cmi.cmi_sign in
let sign =
Subst.Lazy.signature Make_local (Subst.for_loading_cmi ()) cmi_sign in
let bound_globals = cmi.cmi_globals in
{ sign = (sign, staticity); bound_globals }
let array_fold_left_filter_map f init array =
let ans, new_array = Array.fold_left_map f init array in
let new_array =
Array.of_seq (Seq.filter_map (fun a -> a) (Array.to_seq new_array))
in
ans, new_array
let name_in_subst (name : Global_module.Name.t) subst =
match name with
| { head; args = [] } ->
let head_as_param_name = head |> Global_module.Parameter_name.of_string in
Global_module.Parameter_name.Map.mem head_as_param_name subst
| _ -> false
let subst t (args : (Global_module.Parameter_name.t * Global_module.t) list) =
let { sign = (sign, staticity); bound_globals } = t in
match args with
| [] -> t
| _ ->
let arg_subst = Global_module.Parameter_name.Map.of_list args in
let add_and_update_binding subst (bound_global, prec) =
let name = Global_module.to_name bound_global in
if name_in_subst name arg_subst then
Misc.fatal_error "Unexpected parameterised parameter"
else
begin
let value, changed = Global_module.subst bound_global arg_subst in
let name_id = Ident.create_global name in
let value_as_name = Global_module.to_name value in
let value_id = Ident.create_global value_as_name in
let subst =
match changed with
| `Changed ->
Subst.add_module name_id (Pident value_id) subst
| `Did_not_change ->
subst
in
let new_bound_global =
if Global_module.is_complete value then
None
else
Some (value, prec)
in
subst, new_bound_global
end
in
let subst = Subst.identity in
let subst, bound_globals =
array_fold_left_filter_map add_and_update_binding subst bound_globals
in
let add_arg subst (name, value) =
let name_id =
Ident.create_global (name |> Global_module.Name.of_parameter_name)
in
let value_as_name = Global_module.to_name value in
let value_id = Ident.create_global value_as_name in
Subst.add_module name_id (Pident value_id) subst
in
let subst = List.fold_left add_arg subst args in
let sign = Subst.Lazy.signature Keep subst sign in
{ sign = (sign, staticity); bound_globals }