package mirage
The MirageOS library operating system
Install
Dune Dependency
Authors
Maintainers
Sources
mirage-4.9.0.tbz
sha256=0c07d59eb52dc3d1506eb4121c4953104a12df79d08a0f0923c9b71e7474a026
sha512=666bf9ee20c9f9de058441f252f4f40ceec6a9ffd00e5cd3b7bfa9532fd65000aeb8a83f9e55586be98d0a86ea72f2dda94e924608135e3d63441359505de58a
doc/src/mirage.functoria/engine.ml.html
Source file engine.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 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
(* * Copyright (c) 2013-2020 Thomas Gazagnaire <thomas@gazagnaire.org> * Copyright (c) 2013-2020 Anil Madhavapeddy <anil@recoil.org> * Copyright (c) 2015-2020 Gabriel Radanne <drupyog@zoho.com> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) open Astring open Action.Syntax type t = Device.Graph.t let if_keys x = Impl.collect (module Key.Set) (function If cond -> Key.deps cond | App | Dev _ -> Key.Set.empty) x module Keys = struct type t = Key.Set.t let union a b = Key.Set.union a b let empty = Key.Set.empty end let keys x = Impl.collect (module Keys) (function | Dev c -> Key.Set.of_list (Device.keys c) | If cond -> Key.deps cond | App -> Keys.empty) x module Runtime_args = struct type t = Runtime_arg.Set.t let union a b = Runtime_arg.Set.union a b let empty = Runtime_arg.Set.empty end let runtime_args x = Impl.collect (module Runtime_args) (function | Dev c -> Runtime_arg.Set.of_list (Device.runtime_args c) | If _ -> Runtime_args.empty | App -> Runtime_args.empty) x module Packages = struct type t = Package.Set.t Key.value let union x y = Key.(pure Package.Set.union $ x $ y) let empty = Key.pure Package.Set.empty end let packages t = let open Impl in let aux = function | Dev c -> let pkgs = Device.packages c in let runtime_args = Device.runtime_args c in let extra_pkgs = List.fold_left (fun acc k -> let pkgs = Runtime_arg.packages k in Package.Set.(union acc (of_list pkgs))) Package.Set.empty runtime_args in let aux x = Package.Set.(union (of_list x) extra_pkgs) in Key.(pure aux $ pkgs) | If _ | App -> Packages.empty in let return x = Package.Set.to_list x in Key.(pure return $ Impl.collect (module Packages) aux t) module Installs = struct type t = Install.t Key.value let union x y = Key.(pure Install.union $ x $ y) let empty = Key.pure Install.empty end let install i x = Impl.collect (module Installs) (function Dev c -> Device.install c i | If _ | App -> Installs.empty) x let files info t = Impl.collect (module Fpath.Set) (function Dev c -> Device.files c info | If _ | App -> Fpath.Set.empty) t module Dune = struct type t = Dune.stanza list let union = ( @ ) let empty = [] end let dune info = Impl.collect (module Dune) @@ function | Dev c -> Device.dune c info | If _ | App -> Dune.empty (* [module_expresion tbl c args] returns the module expression of the functor [c] applies to [args]. *) let module_expression fmt (c, args) = Fmt.pf fmt "%s%a" (Device.module_name c) Fmt.( list ~sep:(any "") (any "(" ++ of_to_string Device.Graph.impl_name ++ any ")")) args let find_all_devices info g i = let ctx = Info.context info in let id = Impl.with_left_most_device ctx i { f = Device.id } in let f x l = let (Device.Graph.D { dev; _ }) = x in if Device.id dev = id then x :: l else l in Device.Graph.fold f g [] let iter_actions f t = let f v res = let* () = res in f v in Device.Graph.fold f t (Action.ok ()) let lines_of_str str = String.fold_left (fun n -> function '\n' -> n + 1 | _ -> n) 0 str type main = { dir : Fpath.t; path : Fpath.t; mutable lines : int } let main info = let path = Info.main info in let dir = Fpath.(Info.(parent (config_file info) / project_name info)) in let+ str = Action.read_file path in let lines = lines_of_str str in { dir; path; lines } let append_main main msg fmt = let purpose = Fmt.str "Append to main.ml (%s)" msg in Fmt.kstr (fun str -> main.lines <- main.lines + lines_of_str str + 1; Action.with_output ~path:main.path ~append:true ~purpose (fun ppf -> Fmt.pf ppf "%s@." str)) fmt let pp_pos ppf = function | None -> () | Some (file, line, _, _) -> Fmt.pf ppf "# %d %S@." line file let reset_pos { dir; path; lines } = (* lines are 1-based and the line directive is refering to "next line will be Y", so if we put a directive in the first line of a file, it needs to say "# 2 myfile.ml" since the next line will be the second one. This is the reason for the 2 below. *) let file = Fpath.(dir // path) |> Fpath.normalize |> Fpath.to_string in Some (file, lines + 2, 0, 0) let configure info t = let f (v : t) = let* main = main info in let (D { dev; args; _ }) = v in let* () = Device.configure dev info in if args = [] then Action.ok () else let* () = append_main main "reset" "%a" pp_pos (reset_pos main) in append_main main "configure" "module %s = %a\n" (Device.Graph.impl_name v) module_expression (dev, args) in iter_actions f t let meta_init fmt (connect_name, result_name) = Fmt.pf fmt " let _%s = Lazy.force %s in@ " result_name connect_name let emit_connect fmt (iname, names, runtime_args, connect_code) = (* We avoid potential collision between double application by prefixing with "_". This also avoid warnings. *) let rnames = List.map (fun x -> "_" ^ x) names in let knames = List.map (fun k -> "_" ^ Runtime_arg.var_name k) runtime_args in let bind ppf name = Fmt.pf ppf " _%s >>= fun %s ->\n" name name in let bind_key ppf k = Fmt.pf ppf " let _%s = %a in\n" (Runtime_arg.var_name k) Runtime_arg.call k in let { Device.pos; code } = connect_code (rnames @ knames) in Fmt.pf fmt "let %s = lazy (\n%a%a%a%a %s@\n);;" iname Fmt.(list ~sep:nop meta_init) (List.combine names rnames) Fmt.(list ~sep:nop bind) rnames Fmt.(list ~sep:nop bind_key) runtime_args pp_pos pos code let emit_run main init main_name = (* "exit 1" is ok in this code, since cmdliner will print help. *) let force ppf name = Fmt.pf ppf "Lazy.force %s >>= fun _ ->\n " name in append_main main "emit_run" "let () =\n let t = %aLazy.force %s in\n run t\n;;" Fmt.(list ~sep:nop force) init main_name let connect ?(init = []) info t = let* main = main info in let f (v : t) = let (D { dev; args; deps; _ }) = v in let var_name = Device.Graph.var_name v in let impl_name = Device.Graph.impl_name v in let arg_names = List.map Device.Graph.var_name (args @ deps) in let runtime_args = Device.runtime_args dev in let* () = append_main main "connect" "%a" emit_connect (var_name, arg_names, runtime_args, Device.connect dev info impl_name) in append_main main "reset" "%a" pp_pos (reset_pos main) in let* () = iter_actions f t in let main_name = Device.Graph.var_name t in let init_names = List.fold_left (fun acc i -> match find_all_devices info t i with | [] -> assert false | ds -> List.map Device.Graph.var_name ds @ acc) [] init |> List.rev in emit_run main init_names main_name
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>