import deriving 0.1.1a
[deriving.git] / syntax / utils.ml
blob6c963bb21d0ee474652571287df9ee901bc0f176
1 (* Copyright Jeremy Yallop 2007.
2 This file is free software, distributed under the MIT license.
3 See the file COPYING for details.
4 *)
6 type ('a,'b) either = Left of 'a | Right of 'b
8 let either_partition (f : 'a -> ('b, 'c) either) (l : 'a list)
9 : 'b list * 'c list =
10 let rec aux (lefts, rights) = function
11 | [] -> (List.rev lefts, List.rev rights)
12 | x::xs ->
13 match f x with
14 | Left l -> aux (l :: lefts, rights) xs
15 | Right r -> aux (lefts, r :: rights) xs
16 in aux ([], []) l
19 module List =
20 struct
21 include List
23 let fold_left1 : ('a -> 'a -> 'a) -> 'a list -> 'a
24 = fun f l -> match l with
25 | x::xs -> List.fold_left f x xs
26 | [] -> invalid_arg "fold_left1"
28 let rec fold_right1 : ('a -> 'a -> 'a) -> 'a list -> 'a
29 = fun f l -> match l with
30 | [x] -> x
31 | x::xs -> f x (fold_right1 f xs)
32 | [] -> invalid_arg "fold_right1"
34 let rec range from upto =
35 let rec aux f t result =
36 if f = t then result
37 else aux (f+1) t (f::result)
38 in if upto < from then raise (Invalid_argument "range")
39 else List.rev (aux from upto [])
41 let rec last : 'a list -> 'a = function
42 | [] -> invalid_arg "last"
43 | [x] -> x
44 | _::xs -> last xs
46 let concat_map f l =
47 let rec aux = function
48 | _, [] -> []
49 | f, x :: xs -> f x @ aux (f, xs)
50 in aux (f,l)
52 let concat_map2 (f : 'a -> 'b -> 'c list) (l1 : 'a list) (l2 : 'b list) : 'c list =
53 let rec aux = function
54 | [], [] -> []
55 | x::xs, y :: ys -> f x y @ aux (xs, ys)
56 | _ -> invalid_arg "concat_map2"
57 in aux (l1, l2)
59 let mapn ?(init=0) f =
60 let rec aux n = function
61 | [] -> []
62 | x::xs -> f x n :: aux (n+1) xs in
63 aux init
64 end
66 module F =
67 struct
68 let id x = x
69 let curry f x y = f (x,y)
70 let uncurry f (x,y) = f x y
71 end
73 module Option =
74 struct
75 let map f = function
76 | None -> None
77 | Some x -> Some (f x)
78 end
80 module DumpAst =
81 struct
82 open Camlp4.PreCast.Ast
84 let rec ident = function
85 | IdAcc (_, i1, i2) -> "IdAcc ("^ident i1^","^ident i2^")"
86 | IdApp (_, i1, i2) -> "IdApp ("^ident i1^","^ident i2^")"
87 | IdLid (_, s) -> "IdLid("^s^")"
88 | IdUid (_, s) -> "IdUid("^s^")"
89 | IdAnt (_, s) -> "IdAnt("^s^")"
91 let rec ctyp = function
92 | TyLab (_, s, c) -> "TyLab ("^s ^ "," ^ ctyp c ^")"
93 | TyDcl (_, s, cs, c2, ccs) -> "TyDcl ("^s ^", [" ^ String.concat ";" (List.map ctyp cs) ^"], "^ctyp c2 ^ ", ["^
94 String.concat "," (List.map (fun (c1,c2) -> "(" ^ ctyp c1 ^ ", " ^ ctyp c2 ^ ")") ccs)
95 ^ "])"
96 | TyObj (_, c, _) -> "TyObj ("^ ctyp c ^ ", ?)"
97 | TyOlb (_, s, c) -> "TyOlb ("^s ^ "," ^ ctyp c ^")"
98 | TyOf (_, c1, c2) -> "TyOf ("^ ctyp c1 ^ ", " ^ ctyp c2 ^ ")"
99 | TyOr (_, c1, c2) -> "TyOr ("^ ctyp c1 ^ ", " ^ ctyp c2 ^ ")"
100 | TyRec (_, c) -> "TyRec("^ctyp c^")"
101 | TySum (_, c) -> "TySum("^ctyp c^")"
102 | TyPrv (_, c) -> "TyPrv("^ctyp c^")"
103 | TyMut (_, c) -> "TyMut("^ctyp c^")"
104 | TyTup (_, c) -> "TyTup("^ctyp c^")"
105 | TyVrnEq (_, c) -> "TyVrnEq("^ctyp c^")"
106 | TyVrnSup (_, c) -> "TyVrnSup("^ctyp c^")"
107 | TyVrnInf (_, c) -> "TyVrnInf("^ctyp c^")"
108 | TyCls (_, i) -> "TyCls("^ident i^")"
109 | TyId (_, i) -> "TyId("^ident i^")"
110 | TyNil (_) -> "TyNil"
111 | TyAli (_, c1, c2) -> "TyAli ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
112 | TyAny (_) -> "TyAny"
113 | TyApp (_, c1, c2) -> "TyApp ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
114 | TyArr (_, c1, c2) -> "TyArr ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
115 | TyMan (_, c1, c2) -> "TyMan ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
116 | TyPol (_, c1, c2) -> "TyPol ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
117 | TyQuo (_, s) -> "TyQuo("^s^")"
118 | TyQuP (_, s) -> "TyQuP("^s^")"
119 | TyQuM (_, s) -> "TyQuM("^s^")"
120 | TyVrn (_, s) -> "TyVrn("^s^")"
121 | TyCol (_, c1, c2) -> "TyCol ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
122 | TySem (_, c1, c2) -> "TySem ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
123 | TyCom (_, c1, c2) -> "TyCom ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
124 | TyAnd (_, c1, c2) -> "TyAnd ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
125 | TySta (_, c1, c2) -> "TySta ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
126 | TyVrnInfSup (_, c1, c2) -> "TyVrnInfSup ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
127 | TyAmp (_, c1, c2) -> "TyAmp ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
128 | TyOfAmp (_, c1, c2) -> "TyOfAmp ("^ ctyp c1 ^ ", " ^ ctyp c2 ^")"
129 | TyAnt (_, s) -> "TyAnt("^s^")"
132 module StringMap =
133 struct
134 include Map.Make(String)
135 exception NotFound of string
136 let find s m =
137 try find s m
138 with Not_found -> raise (NotFound s)
139 let fromList : (key * 'a) list -> 'a t = fun elems ->
140 List.fold_right (F.uncurry add) elems empty
141 let union_disjoint2 l r =
142 fold
143 (fun k v r ->
144 if mem k r then invalid_arg "union_disjoint"
145 else add k v r) l r
146 let union_disjoint maps = List.fold_right union_disjoint2 maps empty
149 module Set =
150 struct
151 module type OrderedType = Set.OrderedType
152 module type S = sig
153 include Set.S
154 val fromList : elt list -> t
156 module Make (Ord : OrderedType) =
157 struct
158 include Set.Make(Ord)
159 let fromList elems = List.fold_right add elems empty
163 let random_id length =
164 let idchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'" in
165 let nidchars = String.length idchars in
166 let s = String.create length in
167 for i = 0 to length - 1 do
168 s.[i] <- idchars.[Random.int nidchars]
169 done;
172 (* The function used in OCaml to convert variant labels to their
173 integer representations. The formula is given in Jacques
174 Garrigue's 1998 ML workshop paper.
176 let tag_hash s =
177 let wrap = 0x40000000 in
178 let acc = ref 0 in
179 let mul = ref 1 in
180 let len = String.length s in
181 for i = 0 to len - 1 do
182 let c = String.unsafe_get s (len - i - 1) in
183 let n = Char.code c in
184 acc := (!acc + n * !mul) mod wrap;
185 mul := (!mul * 223) mod wrap;
186 done;
187 !acc
189 let _ =
190 (* Sanity check to make sure the function doesn't change underneath
191 us *)
192 assert (tag_hash "premiums" = tag_hash "squigglier");
193 assert (tag_hash "deriving" = 398308260)