11open ! Stdune
22open Fiber.O
33
4- module type Data = Memo_intf. Data
4+ module type Input = Memo_intf. Input
5+ module type Output = Memo_intf. Output
56
67module Function_name = Interned. Make (struct
78 let initial_size = 1024
@@ -15,10 +16,22 @@ module Spec = struct
1516 type ('a, 'b) t =
1617 { name : Function_name .t
1718 ; allow_cutoff : bool
18- ; input : (module Data with type t = 'a )
19- ; output : (module Data with type t = 'b )
19+ ; input : (module Input with type t = 'a )
20+ ; output : (module Output with type t = 'b )
2021 ; witness : 'a witness
22+ ; f : 'a -> 'b Fiber .t
23+ ; doc : string
2124 }
25+
26+ type packed = T : (_ , _ ) t -> packed [@@ unboxed]
27+
28+ let by_name = Function_name.Table. create ~default_value: None
29+
30+ let register t =
31+ Function_name.Table. set by_name ~key: t.name ~data: (Some (T t))
32+
33+ let find name =
34+ Function_name.Table. get by_name name
2235end
2336
2437module Id = Id. Make ()
@@ -104,7 +117,7 @@ module Cached_value = struct
104117
105118 let dep_changed (type a ) (node : (_, a) Dep_node.t ) prev_output curr_output =
106119 if node.spec.allow_cutoff then
107- let (module Output : Data with type t = a ) = node.spec.output in
120+ let (module Output : Output with type t = a ) = node.spec.output in
108121 not (Output. equal prev_output curr_output)
109122 else
110123 true
@@ -154,7 +167,7 @@ module Cached_value = struct
154167end
155168
156169let ser_input (type a ) (node : (a, _) Dep_node.t ) =
157- let (module Input : Data with type t = a ) = node.spec.input in
170+ let (module Input : Input with type t = a ) = node.spec.input in
158171 Input. to_sexp node.input
159172
160173let dag_node (dep_node : _ Dep_node.t ) = Lazy. force dep_node.dag_node
@@ -209,13 +222,12 @@ let dump_stack v =
209222 )
210223 >> | (fun _ -> v)
211224
212- module Make (Input : Data ) : S with type input := Input. t = struct
225+ module Make (Input : Input ) : S with type input := Input. t = struct
213226 module Table = Hashtbl. Make (Input )
214227
215228 type 'a t =
216229 { spec : (Input .t , 'a ) Spec .t
217230 ; cache : (Input .t , 'a ) Dep_node .t Table .t
218- ; f : Input .t -> 'a Fiber .t
219231 }
220232
221233 type _ Spec.witness + = W : Input .t Spec .witness
@@ -242,17 +254,27 @@ module Make(Input : Data) : S with type input := Input.t = struct
242254 Some (List. map cv.deps ~f: (fun (Last_dep. T (n ,_u )) ->
243255 (Function_name. to_string n.spec.name, ser_input n)))
244256
245- let create name ?(allow_cutoff =true ) output f =
257+ let create name ?(allow_cutoff =true ) ~ doc output f =
246258 let name = Function_name. make name in
259+ let spec =
260+ { Spec.
261+ name
262+ ; input = (module Input ); output
263+ ; allow_cutoff
264+ ; witness = W
265+ ; f
266+ ; doc
267+ }
268+ in
269+ Spec. register spec;
247270 { cache = Table. create 1024
248- ; spec = { name; input = (module Input ); output; allow_cutoff; witness = W }
249- ; f
271+ ; spec
250272 }
251273
252274 let compute t inp ivar dep_node =
253275 (* define the function to update / double check intermediate result *)
254276 (* set context of computation then run it *)
255- push_stack_frame (T dep_node) (t.f inp) >> = fun res ->
277+ push_stack_frame (T dep_node) (t.spec. f inp) >> = fun res ->
256278 (* update the output cache with the correct value *)
257279 let deps =
258280 Dag. children (dag_node dep_node)
@@ -336,3 +358,35 @@ module Make(Input : Data) : S with type input := Input.t = struct
336358 dep_node.spec.name = of_.spec.name
337359 end
338360end
361+
362+ let call name input =
363+ match
364+ let open Option.O in
365+ Function_name. get name >> = Spec. find
366+ with
367+ | None -> Exn. fatalf " @{<error>Error@}: function %s doesn't exist!" name
368+ | Some (Spec. T spec ) ->
369+ let (module Input : Input with type t = _ ) = spec.input in
370+ let (module Output : Output with type t = _ ) = spec.output in
371+ let input = Dune_lang.Decoder. parse Input. decode Univ_map. empty input in
372+ spec.f input >> | fun output ->
373+ Output. to_sexp output
374+
375+ module Function_info = struct
376+ type t =
377+ { name : string
378+ ; doc : string
379+ }
380+
381+ let of_spec (Spec. T spec ) =
382+ { name = Function_name. to_string spec.name
383+ ; doc = spec.doc
384+ }
385+ end
386+
387+ let registered_functions () =
388+ Function_name. all ()
389+ |> List. filter_map ~f: (Function_name.Table. get Spec. by_name)
390+ |> List. map ~f: Function_info. of_spec
391+ |> List. sort ~compare: (fun a b ->
392+ String. compare a.Function_info. name b.Function_info. name)
0 commit comments