mirror of
https://github.com/ocaml-tracing/ocaml-trace.git
synced 2026-03-11 04:58:36 -04:00
change meta_map impl to use Type module
This commit is contained in:
parent
efafd34a9e
commit
cf02db980a
4 changed files with 151 additions and 73 deletions
|
|
@ -1,12 +1,25 @@
|
||||||
|
|
||||||
(library
|
(library
|
||||||
(name trace_core)
|
(name trace_core)
|
||||||
(public_name trace.core)
|
(public_name trace.core)
|
||||||
(synopsis "Lightweight stub for tracing")
|
(synopsis "Lightweight stub for tracing"))
|
||||||
)
|
|
||||||
|
|
||||||
(rule
|
(rule
|
||||||
(targets atomic_.ml)
|
(targets atomic_.ml)
|
||||||
(action
|
(action
|
||||||
(with-stdout-to %{targets}
|
(with-stdout-to
|
||||||
(run ./gen/gen.exe --ocaml %{ocaml_version} --atomic))))
|
%{targets}
|
||||||
|
(run ./gen/gen.exe --ocaml %{ocaml_version} --atomic))))
|
||||||
|
|
||||||
|
(rule
|
||||||
|
(targets type_.ml)
|
||||||
|
(action
|
||||||
|
(with-stdout-to
|
||||||
|
%{targets}
|
||||||
|
(run ./gen/gen.exe --ocaml %{ocaml_version} --type-ml))))
|
||||||
|
|
||||||
|
(rule
|
||||||
|
(targets type_.mli)
|
||||||
|
(action
|
||||||
|
(with-stdout-to
|
||||||
|
%{targets}
|
||||||
|
(run ./gen/gen.exe --ocaml %{ocaml_version} --type-mli))))
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,2 @@
|
||||||
|
|
||||||
(executable
|
(executable
|
||||||
(name gen))
|
(name gen))
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,108 @@ let atomic_post_412 = {|
|
||||||
include Atomic
|
include Atomic
|
||||||
|}
|
|}
|
||||||
|
|
||||||
|
let type_ml_pre_510 =
|
||||||
|
{|
|
||||||
|
(* Type equality witness *)
|
||||||
|
|
||||||
|
type (_, _) eq = Equal: ('a, 'a) eq
|
||||||
|
|
||||||
|
(* Type identifiers *)
|
||||||
|
|
||||||
|
module Id = struct
|
||||||
|
type _ id = ..
|
||||||
|
module type ID = sig
|
||||||
|
type t
|
||||||
|
type _ id += Id : t id
|
||||||
|
end
|
||||||
|
|
||||||
|
type 'a t = (module ID with type t = 'a)
|
||||||
|
|
||||||
|
let make (type a) () : a t =
|
||||||
|
(module struct type t = a type _ id += Id : t id end)
|
||||||
|
|
||||||
|
let[@inline] uid (type a) ((module A) : a t) =
|
||||||
|
Obj.Extension_constructor.id (Obj.Extension_constructor.of_val A.Id)
|
||||||
|
|
||||||
|
let provably_equal
|
||||||
|
(type a b) ((module A) : a t) ((module B) : b t) : (a, b) eq option
|
||||||
|
=
|
||||||
|
match A.Id with B.Id -> Some Equal | _ -> None
|
||||||
|
end
|
||||||
|
|}
|
||||||
|
|
||||||
|
let type_mli_pre_510 =
|
||||||
|
{|
|
||||||
|
type (_, _) eq = Equal: ('a, 'a) eq (** *)
|
||||||
|
(** The purpose of [eq] is to represent type equalities that may not otherwise
|
||||||
|
be known by the type checker (e.g. because they may depend on dynamic data).
|
||||||
|
|
||||||
|
A value of type [(a, b) eq] represents the fact that types [a] and [b] are
|
||||||
|
equal.
|
||||||
|
|
||||||
|
If one has a value [eq : (a, b) eq] that proves types [a] and [b] are equal,
|
||||||
|
one can use it to convert a value of type [a] to a value of type [b] by
|
||||||
|
pattern matching on [Equal]:
|
||||||
|
{[
|
||||||
|
let cast (type a) (type b) (Equal : (a, b) Type.eq) (a : a) : b = a
|
||||||
|
]}
|
||||||
|
|
||||||
|
At runtime, this function simply returns its second argument unchanged.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** {1:identifiers Type identifiers} *)
|
||||||
|
|
||||||
|
(** Type identifiers.
|
||||||
|
|
||||||
|
A type identifier is a value that denotes a type. Given two type
|
||||||
|
identifiers, they can be tested for {{!Id.provably_equal}equality} to
|
||||||
|
prove they denote the same type. Note that:
|
||||||
|
|
||||||
|
- Unequal identifiers do not imply unequal types: a given type can be
|
||||||
|
denoted by more than one identifier.
|
||||||
|
- Type identifiers can be marshalled, but they get a new, distinct,
|
||||||
|
identity on unmarshalling, so the equalities are lost.
|
||||||
|
|
||||||
|
See an {{!Id.example}example} of use. *)
|
||||||
|
module Id : sig
|
||||||
|
|
||||||
|
(** {1:ids Type identifiers} *)
|
||||||
|
|
||||||
|
type 'a t
|
||||||
|
(** The type for identifiers for type ['a]. *)
|
||||||
|
|
||||||
|
val make : unit -> 'a t
|
||||||
|
(** [make ()] is a new type identifier. *)
|
||||||
|
|
||||||
|
val uid : 'a t -> int
|
||||||
|
(** [uid id] is a runtime unique identifier for [id]. *)
|
||||||
|
|
||||||
|
val provably_equal : 'a t -> 'b t -> ('a, 'b) eq option
|
||||||
|
(** [provably_equal i0 i1] is [Some Equal] if identifier [i0] is equal
|
||||||
|
to [i1] and [None] otherwise. *)
|
||||||
|
end
|
||||||
|
|}
|
||||||
|
|
||||||
|
let type_ml_post_510 = {|
|
||||||
|
include Type
|
||||||
|
|}
|
||||||
|
|
||||||
|
let type_mli_post_510 = {|
|
||||||
|
include module type of Type
|
||||||
|
|}
|
||||||
|
|
||||||
let p_version s = Scanf.sscanf s "%d.%d" (fun x y -> x, y)
|
let p_version s = Scanf.sscanf s "%d.%d" (fun x y -> x, y)
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
let atomic = ref false in
|
let atomic = ref false in
|
||||||
|
let type_ml = ref false in
|
||||||
|
let type_mli = ref false in
|
||||||
let ocaml = ref Sys.ocaml_version in
|
let ocaml = ref Sys.ocaml_version in
|
||||||
Arg.parse
|
Arg.parse
|
||||||
[
|
[
|
||||||
"--atomic", Arg.Set atomic, " atomic";
|
"--atomic", Arg.Set atomic, " atomic";
|
||||||
|
"--type-ml", Arg.Set type_ml, " type.ml";
|
||||||
|
"--type-mli", Arg.Set type_mli, " type.mli";
|
||||||
"--ocaml", Arg.Set_string ocaml, " set ocaml version";
|
"--ocaml", Arg.Set_string ocaml, " set ocaml version";
|
||||||
]
|
]
|
||||||
ignore "";
|
ignore "";
|
||||||
|
|
@ -67,4 +161,20 @@ let () =
|
||||||
atomic_post_412
|
atomic_post_412
|
||||||
in
|
in
|
||||||
print_endline code
|
print_endline code
|
||||||
|
) else if !type_ml then (
|
||||||
|
let code =
|
||||||
|
if (major, minor) < (5, 10) then
|
||||||
|
type_ml_pre_510
|
||||||
|
else
|
||||||
|
type_ml_post_510
|
||||||
|
in
|
||||||
|
print_endline code
|
||||||
|
) else if !type_mli then (
|
||||||
|
let code =
|
||||||
|
if (major, minor) < (5, 10) then
|
||||||
|
type_mli_pre_510
|
||||||
|
else
|
||||||
|
type_mli_post_510
|
||||||
|
in
|
||||||
|
print_endline code
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,83 +1,39 @@
|
||||||
module type KEY_IMPL = sig
|
module Type = Type_
|
||||||
type t
|
|
||||||
|
|
||||||
exception Store of t
|
|
||||||
|
|
||||||
val id : int
|
|
||||||
end
|
|
||||||
|
|
||||||
module Key = struct
|
module Key = struct
|
||||||
type 'a t = (module KEY_IMPL with type t = 'a)
|
type 'a t = 'a Type.Id.t
|
||||||
|
|
||||||
let _n = ref 0
|
let create = Type.Id.make
|
||||||
|
let id = Type.Id.uid
|
||||||
|
|
||||||
let create (type k) () =
|
let equal a b =
|
||||||
incr _n;
|
match Type.Id.provably_equal a b with
|
||||||
let id = !_n in
|
| None -> false
|
||||||
let module K = struct
|
| Some Type.Equal -> true
|
||||||
type t = k
|
|
||||||
|
|
||||||
let id = id
|
|
||||||
|
|
||||||
exception Store of k
|
|
||||||
end in
|
|
||||||
(module K : KEY_IMPL with type t = k)
|
|
||||||
|
|
||||||
let id (type k) (module K : KEY_IMPL with type t = k) = K.id
|
|
||||||
|
|
||||||
let equal : type a b. a t -> b t -> bool =
|
|
||||||
fun (module K1) (module K2) -> K1.id = K2.id
|
|
||||||
end
|
end
|
||||||
|
|
||||||
type pair = Pair : 'a Key.t * 'a -> pair
|
type pair = Pair : 'a Key.t * 'a -> pair
|
||||||
type exn_pair = E_pair : 'a Key.t * exn -> exn_pair
|
|
||||||
|
|
||||||
let pair_of_e_pair (E_pair (k, e)) =
|
module M = Map.Make (Int)
|
||||||
let module K = (val k) in
|
|
||||||
match e with
|
|
||||||
| K.Store v -> Pair (k, v)
|
|
||||||
| _ -> assert false
|
|
||||||
|
|
||||||
module M = Map.Make (struct
|
type t = pair M.t
|
||||||
type t = int
|
|
||||||
|
|
||||||
let compare (i : int) j = Stdlib.compare i j
|
|
||||||
end)
|
|
||||||
|
|
||||||
type t = exn_pair M.t
|
|
||||||
|
|
||||||
let empty = M.empty
|
let empty = M.empty
|
||||||
let mem k t = M.mem (Key.id k) t
|
let mem k t = M.mem (Key.id k) t
|
||||||
|
|
||||||
let find_exn (type a) (k : a Key.t) t : a =
|
let find_exn (type a) (k : a Key.t) t : a =
|
||||||
let module K = (val k) in
|
let (Pair (k', v)) = M.find (Key.id k) t in
|
||||||
let (E_pair (_, e)) = M.find K.id t in
|
match Type.Id.provably_equal k k' with
|
||||||
match e with
|
| None -> assert false
|
||||||
| K.Store v -> v
|
| Some Type.Equal -> v
|
||||||
| _ -> assert false
|
|
||||||
|
|
||||||
let find k t = try Some (find_exn k t) with Not_found -> None
|
let find k t = try Some (find_exn k t) with Not_found -> None
|
||||||
|
let add k v t = M.add (Key.id k) (Pair (k, v)) t
|
||||||
let add_e_pair_ p t =
|
let remove k t = M.remove (Key.id k) t
|
||||||
let (E_pair ((module K), _)) = p in
|
let cardinal = M.cardinal
|
||||||
M.add K.id p t
|
|
||||||
|
|
||||||
let add_pair_ p t =
|
|
||||||
let (Pair (((module K) as k), v)) = p in
|
|
||||||
let p = E_pair (k, K.Store v) in
|
|
||||||
M.add K.id p t
|
|
||||||
|
|
||||||
let add (type a) (k : a Key.t) v t =
|
|
||||||
let module K = (val k) in
|
|
||||||
add_e_pair_ (E_pair (k, K.Store v)) t
|
|
||||||
|
|
||||||
let remove (type a) (k : a Key.t) t =
|
|
||||||
let module K = (val k) in
|
|
||||||
M.remove K.id t
|
|
||||||
|
|
||||||
let cardinal t = M.cardinal t
|
|
||||||
let length = cardinal
|
let length = cardinal
|
||||||
let iter f t = M.iter (fun _ p -> f (pair_of_e_pair p)) t
|
let iter f t = M.iter (fun _ p -> f p) t
|
||||||
let to_list t = M.fold (fun _ p l -> pair_of_e_pair p :: l) t []
|
let to_list t = M.fold (fun _ p l -> p :: l) t []
|
||||||
|
let add_pair_ (Pair (k, v)) t = add k v t
|
||||||
let add_list t l = List.fold_right add_pair_ l t
|
let add_list t l = List.fold_right add_pair_ l t
|
||||||
let of_list l = add_list empty l
|
let of_list l = add_list empty l
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue