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
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
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)
end