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
138
139
140
141
142
143
144
145
146
147
let rev_split_by_char c s =
let rec loop i l =
try
let i' = String.index_from s i c in
let s' = String.sub s i (i' - i) in
loop (i' + 1)
(if s' = "" then
l
else
s' :: l)
with Not_found -> String.sub s i (String.length s - i) :: l
in
loop 0 []
let string_of_string_list l = Printf.sprintf "[%s]" (String.concat "," l)
let string_fold_lefti f e0 s =
let len = String.length s in
let rec loop acc = function
| i when i = len -> acc
| i -> loop (f acc i (String.unsafe_get s i)) (i + 1)
in
loop e0 0
module Option = struct
let default x = function
| Some y -> y
| None -> x
let some v = Some v
let min_value x y =
match x, y with
| None, None | Some _, None | None, Some _ ->
invalid_arg "Util.Option.min_value"
| Some x, Some y -> some @@ min x y
let eq_value x y =
match x, y with
| None, None | Some _, None | None, Some _ ->
invalid_arg "Util.Option.eq_value"
| Some x, Some y -> x = y
let string_of_option f = function
| None -> "None"
| Some x -> Printf.sprintf "Some(%s)" (f x)
end
let indentation_prefix =
let h = Hashtbl.create 16 in
fun level ->
match Hashtbl.find h level with
| s -> s
| exception Not_found ->
let s = String.make (2 * level) ' ' in
Hashtbl.add h level s;
s
let read_file file_name =
let ic = open_in file_name in
let len = in_channel_length ic in
let b = Bytes.create len in
let offset = ref 0 in
let remaining = ref len in
while !remaining > 0 do
let i = input ic b !offset !remaining in
offset := !offset + i;
remaining :=
if i > 0 then
!remaining - i
else
0
done;
close_in ic;
Bytes.sub_string b 0 !offset
let protect ~finally f =
try
let x = f () in
finally ();
x
with e ->
finally ();
raise e
module List = struct
let rec pop_last = function
| [] -> failwith "Invalid argument [] for pop_last"
| _ :: [] -> []
| hd :: tl -> hd :: pop_last tl
let rec apply_until f = function
| [] -> None
| hd :: tl ->
(match f hd with
| None -> apply_until f tl
| x -> x)
let rec filter_map f = function
| [] -> []
| hd :: tl ->
(match f hd with
| None -> filter_map f tl
| Some x -> x :: filter_map f tl)
let find_opt f l = try Some (List.find f l) with Not_found -> None
let rec find_map f = function
| [] -> None
| x :: tl ->
(match f x with
| Some _ as r -> r
| None -> find_map f tl)
end
module Int_map = Map.Make (struct
type t = int
let compare (x : int) (y : int) = Stdlib.compare x y
end)
module Str_map = Map.Make (String)