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
|
open Unix
open Lexing
(* Small things *)
let ord_couple (a, b) = if a < b then a, b else b, a
(* uniq_sorted : 'a list -> 'a list *)
let rec uniq_sorted = function
| [] -> []
| [a] -> [a]
| a::b::q when a = b -> uniq_sorted (b::q)
| a::r -> a::(uniq_sorted r)
(* list_fold_op : ('a -> 'a -> 'a) -> 'a list -> 'a *)
let rec list_fold_op op = function
| [] -> invalid_arg "list_fold_op on empty list"
| [a] -> a
| x::q -> op x (list_fold_op op q)
(* Either type *)
type ('a, 'b) either =
| Left of 'a
| Right of 'b
(* Locations *)
type position = Lexing.position
let position_unknown = Lexing.dummy_pos
type extent = position * position
let extent_unknown = (position_unknown, position_unknown)
let string_of_position p =
Printf.sprintf "%s:%i:%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol)
let string_of_extent (p,q) =
if p.pos_fname = q.pos_fname then
if p.pos_lnum = q.pos_lnum then
if p.pos_cnum = q.pos_cnum then
Printf.sprintf "%s:%i.%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol)
else
Printf.sprintf "%s:%i.%i-%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) (q.pos_cnum - q.pos_bol)
else
Printf.sprintf "%s:%i.%i-%i.%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) q.pos_lnum (q.pos_cnum - q.pos_bol)
else
Printf.sprintf "%s:%i.%i-%s:%i.%i" p.pos_fname p.pos_lnum (p.pos_cnum - p.pos_bol) q.pos_fname q.pos_lnum (q.pos_cnum - q.pos_bol)
(* Exceptions *)
exception NoLocError of string
let error x = raise (NoLocError x)
exception LocError of extent list * string
let loc_error l f x =
try f x with
| NoLocError e -> raise (LocError([l], e))
| LocError(q, e) -> raise (LocError(l::q, e))
let not_implemented e = error ("Not implemented: " ^ e)
(* Varmaps *)
module VarMap = Mapext.Make(String)
let disjoint_union k a b = match a, b with
| Some x, None -> Some x
| None, Some y -> Some y
| _ -> error ("Duplicate name in disjoint union: " ^ k)
module SSet = Set.Make(String)
(* Fixpoint *)
let rec fix equal f s =
let fs = f s in
if equal fs s
then fs
else fix equal f fs
let (@@) f x = f x
let print_list f sep fmt l =
let rec aux = function
| [] -> ()
| [a] -> f fmt a
| a::b -> f fmt a; Format.fprintf fmt "%s@," sep; aux b
in
aux l
let uid =
let c = ref 0 in
fun () -> c := !c + 1; string_of_int !c
(* String *)
let is_suffix s sf =
let n = String.length s in
let k = String.length sf in
n >= k && sf = String.sub s (n-k) k
(* Time heavy functions *)
let times_k : (string, float) Hashtbl.t = Hashtbl.create 10
let time id f =
let t0 = Unix.times () in
let result = f () in
let t1 = Unix.times () in
let t = t1.tms_utime -. t0.tms_utime in
let r = try Hashtbl.find times_k id with _ -> 0. in
Hashtbl.replace times_k id (r +. t);
result
let show_times () =
Format.printf "Times:@.";
Hashtbl.iter
(fun id t -> Format.printf "%s: %f@." id t)
times_k
|