package b0
Software construction and deployment kit
Install
dune-project
Dependency
Authors
Maintainers
Sources
b0-0.0.6.tbz
sha512=e9aa779e66c08fc763019f16d4706f465d16c05d6400b58fbd0313317ef33ddea51952e2b058db28e65f7ddb7012f328c8bf02d8f1da17bb543348541a2587f0
doc/src/b0.file/b0_def.ml.html
Source file b0_def.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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
(*--------------------------------------------------------------------------- Copyright (c) 2020 The b0 programmers. All rights reserved. SPDX-License-Identifier: ISC ---------------------------------------------------------------------------*) open B0_std (* Names *) type t = { scope : B0_scope.t; name : string; basename : string; doc : string; meta : B0_meta.t } type def = t let scope d = d.scope let file d = B0_scope.file d.scope let scope_dir d = B0_scope.dir d.scope let name d = d.name let basename d = d.basename let doc d = d.doc let meta d = d.meta (* Defining values *) module type VALUE = sig type t val def_kind : string val def : t -> def val pp_name_str : string Fmt.t end module type S = sig val mangle_basename : string -> string type t val define : ?doc:string -> ?meta:B0_meta.t -> string -> def val def_kind : string val def : t -> def val name : t -> string val basename : t -> string val doc : t -> string val equal : t -> t -> bool val compare : t -> t -> int val meta : t -> B0_meta.t val mem_meta : 'a B0_meta.key -> t -> bool val has_tag : bool B0_meta.key -> t -> bool val find_meta : 'a B0_meta.key -> t -> 'a option val find_or_default_meta : 'a B0_meta.key -> t -> 'a val get_meta : 'a B0_meta.key -> t -> ('a, string) result val add : t -> unit val fold : (t -> 'a -> 'a) -> 'a -> 'a val list : unit -> t list val find : string -> t option val get : string -> t val get_or_suggest : string -> (t, t list) result val get_or_hint : string -> (t, string) result val get_list_or_hint : all_if_empty:bool -> string list -> (t list, string) result val scope_path : t -> string list val in_root_scope : t -> bool val in_current_scope : t -> bool val scope_dir : t -> Fpath.t option val scope_dir' : t -> (Fpath.t, string) result val in_scope_dir : t -> Fpath.t -> Fpath.t option val in_scope_dir' : t -> Fpath.t -> (Fpath.t, string) result val pp_name_str : string Fmt.t val pp_name : t Fmt.t val pp_doc : t Fmt.t val pp_synopsis : t Fmt.t val pp : t Fmt.t module Set : Set.S with type elt = t module Map : Map.S with type key = t end module Make (V : VALUE) = struct let mangle_basename s = try for i = 0 to String.length s - 1 do if s.[i] = B0_scope.sep.[0] then raise Exit; done; s with | Exit -> String.map (function '.' -> '-' | c -> c) s type t = V.t let def_kind = V.def_kind let def = V.def let name v = name (V.def v) let basename v = basename (V.def v) let doc v = doc (V.def v) let scope v = scope (V.def v) let equal v0 v1 = String.equal (name v0) (name v1) let compare v0 v1 = String.compare (name v0) (name v1) let meta v = meta (V.def v) let mem_meta k v = B0_meta.mem k (meta v) let has_tag k v = B0_meta.has_tag k (meta v) let find_meta k v = B0_meta.find k (meta v) let find_or_default_meta k v = B0_meta.find_or_default k (meta v) let get_meta k v = match find_meta k v with | Some v -> Ok v | None -> Fmt.error "%s %a does not define metadata %a" (String.Ascii.capitalize V.def_kind) V.pp_name_str (name v) B0_meta.Key.pp_name k let pp_name_str = V.pp_name_str let pp_name = Fmt.using name pp_name_str let pp_doc = Fmt.using doc (Fmt.st []) let pp_synopsis ppf v = Fmt.pf ppf "%a %a" pp_name v pp_doc v let pp ppf v = let pp_non_empty ppf m = match B0_meta.is_empty m with | true -> () | false -> Fmt.pf ppf "@, %a" B0_meta.pp m in Fmt.pf ppf "@[<v>@[%a@]%a@]" pp_synopsis v pp_non_empty (meta v) let defs = ref String.Map.empty let add v = defs := String.Map.add (name v) v !defs let raise_error_undefined name = B0_scope.raise_error "%s %a undefined in scope." (String.Ascii.capitalize V.def_kind) V.pp_name_str name let define ?(doc = "undocumented") ?(meta = B0_meta.empty) name = (* XXX with Printexc.get_callstack and a bit of munging we could maybe get the exact definition point. *) let kind = V.def_kind in let qname, scope = B0_scope.current_make_unique_qualified_name ~defs:!defs ~kind name in { scope; name = qname; basename = name; doc; meta } let scoped_find name = String.Map.find_opt (B0_scope.qualify_name_in_current ~kind:V.def_kind name) !defs let find = scoped_find let get name = match scoped_find name with | Some v -> v | None -> raise_error_undefined name let get_or_suggest name = match scoped_find name with | Some v -> Ok v | None -> let add_sugg k v acc = if String.edit_distance k name <= 2 then v :: acc else acc in Error (List.rev (String.Map.fold add_sugg !defs [])) let get_or_hint candidate = match get_or_suggest candidate with | Ok _ as v -> v | Error suggs -> let kind ppf () = Fmt.pf ppf "%s" def_kind in let hint = Fmt.did_you_mean in let pp = Fmt.unknown' ~kind V.pp_name_str ~hint in Fmt.error "@[%a@]" pp (candidate, List.map name suggs) let fold f acc = match B0_scope.current_is_root () with | true -> let add _ v acc = f v acc in String.Map.fold add !defs acc | false -> let prefix = B0_scope.current_scope_prefix () in let add k v acc = if String.starts_with ~prefix k then f v acc else acc in String.Map.fold add !defs acc let list () = List.rev (fold List.cons []) let get_list_or_hint ~all_if_empty names = if all_if_empty && names = [] then Ok (List.sort compare (list ())) else let rec loop vs es = function | [] -> if es <> [] then Error (String.concat "\n" (List.rev es)) else Ok (List.rev vs) | n :: ns -> match get_or_hint n with | Ok v -> loop (v :: vs) es ns | Error e -> loop vs (e :: es) ns in loop [] [] names let scope_path v = B0_scope.path (scope v) let in_root_scope v = B0_scope.is_root (scope v) let in_current_scope v = B0_scope.is_current (scope v) let scope_dir v = scope_dir (def v) let scope_dir' v = match scope_dir v with | None -> Fmt.error "%s %a has no scope directory." def_kind pp_name v | Some dir -> Ok dir let in_scope_dir v path = match scope_dir v with | None -> None | Some dir -> Some Fpath.(dir // path) let in_scope_dir' v path = match in_scope_dir v path with | Some v -> Ok v | None -> Fmt.error "%s %a has no scope directory, cannot lookup %a in it." def_kind pp_name v Fpath.pp path module T = struct type nonrec t = t let compare = compare end module Set = Set.Make(T) module Map = Map.Make(T) end type value = V : (module S with type t = 'a) * 'a -> value
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>