Source file caqti_query.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
type t =
| L of string
| Q of string
| P of int
| S of t list
[@@deriving eq]
let normal =
let rec collect acc = function
| [] -> List.rev acc
| ((L"" | S[]) :: qs) -> collect acc qs
| ((P _ | Q _ as q) :: qs) -> collect (q :: acc) qs
| (S (q' :: qs') :: qs) -> collect acc (q' :: S qs' :: qs)
| (L s :: qs) -> collectL acc [s] qs
and collectL acc accL = function
| ((L"" | S[]) :: qs) -> collectL acc accL qs
| (L s :: qs) -> collectL acc (s :: accL) qs
| (S (q' :: qs') :: qs) -> collectL acc accL (q' :: S qs' :: qs)
| [] | ((P _ | Q _) :: _) as qs ->
collect (L (String.concat "" (List.rev accL)) :: acc) qs
in
fun q ->
(match collect [] [q] with
| [] -> S[]
| [q] -> q
| qs -> S qs)
let hash = Hashtbl.hash
let rec pp ppf = function
| L s -> Format.pp_print_string ppf s
| Q s ->
Format.pp_print_string ppf "E'";
for i = 0 to String.length s - 1 do
(match s.[i] with
| '\\' -> Format.pp_print_string ppf {|\\|}
| '\'' -> Format.pp_print_string ppf {|\'|}
| '\t' -> Format.pp_print_string ppf {|\t|}
| '\n' -> Format.pp_print_string ppf {|\n|}
| '\r' -> Format.pp_print_string ppf {|\r|}
| '\x00'..'\x1f' as c -> Format.fprintf ppf {|\x%02x|} (Char.code c)
| _ -> Format.pp_print_char ppf s.[i])
done;
Format.pp_print_char ppf '\''
| P n -> Format.pp_print_char ppf '$'; Format.pp_print_int ppf (n + 1)
| S qs -> List.iter (pp ppf) qs
let show q =
let buf = Buffer.create 512 in
let ppf = Format.formatter_of_buffer buf in
pp ppf q; Format.pp_print_flush ppf ();
Buffer.contents buf
let concat =
let rec loop pfx acc = function
| [] -> acc
| q :: qs -> loop pfx (pfx :: q :: acc) qs
in
fun sep -> function
| [] -> S[]
| q :: qs -> S (q :: loop (L sep) [] (List.rev qs))