package dolmen
Source file tag.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 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(* This file is free software, part of Archsat. See file "LICENSE" for more details. *) (* Arbitrary tags for expressions. Uses a mixed map (see containers.data.CCMixmap) *) (* Mixmap Implementation (from containers) *) (* ************************************************************************ *) (* Implementation taken from containers. *) type 'b injection = { get : (unit -> unit) -> 'b option; set : 'b -> (unit -> unit); } let create_inj () = let r = ref None in let get f = r := None; f (); !r and set v = (fun () -> r := Some v) in {get;set} module type S = sig type key type t (** A map containing values of different types, indexed by {!key}. *) val empty : t (** Empty map *) val get : inj:'a injection -> key -> t -> 'a option (** Get the value corresponding to this key, if it exists and belongs to the same key *) val add : inj:'a injection -> key -> 'a -> t -> t (** Bind the key to the value, using [inj] *) end module type ORD = sig type t val compare : t -> t -> int end module Make(X : ORD) : S with type key = X.t = struct module M = Map.Make(X) type key = X.t type t = (unit -> unit) M.t let empty = M.empty let get ~inj x map = try inj.get (M.find x map) with Not_found -> None let add ~inj x y map = M.add x (inj.set y) map end (* Functor instantiation *) (* ************************************************************************ *) module M = Make(struct type t = int let compare (a: int) (b: int) = compare a b end) type map = M.t type 'a t = { id : int; inj : 'a list injection; } let equal k k' = k.id = k'.id let mk_key id = { id; inj = create_inj (); } let max_id = ref 0 let create () = incr max_id; mk_key !max_id let empty = M.empty let get m k = match M.get ~inj:k.inj k.id m with | None -> [] | Some l -> l let last m k = match get m k with | x :: _ -> Some x | [] -> None let replace m k l = M.add ~inj:k.inj k.id l m let add m k v = replace m k (v :: get m k)