package forester
A tool for tending mathematical forests
Install
Dune Dependency
Authors
Maintainers
Sources
5.0.tar.gz
md5=24f4aed96a8b8af33aba13fba66f1b37
sha512=d36b896aca11858bb4a00fc704c16cc27a1f197bdb3e479d6132fd70f70d67d7158096285cb0b6fb00db14417f0f822cc27fe65d82f0971e42378fd8271ce573
doc/src/forester.compiler/Driver.ml.html
Source file Driver.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 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286
(* * SPDX-FileCopyrightText: 2024 The Forester Project Contributors * * SPDX-License-Identifier: GPL-3.0-or-later *) open Forester_core open Forester_prelude open State.Syntax open struct module T = Types end let update (action : Action.t) (forest : State.t) = let open Action in let forest = State.update_history forest action in match action with | Quit e -> begin match e with | Fail -> exit 1 | Finished -> exit 0 end | Query q -> let@ () = Reporter.trace "when running query" in let r = Forest.run_datalog_query forest.graphs q in Query_results r, forest | Query_results _ -> Done, forest | Report_errors (_, next_action) -> next_action, forest | Load_all_configured_dirs -> let@ () = Reporter.trace "when loading files from disk" in let tree_dirs = Eio_util.paths_of_dirs ~env: forest.env forest.config.trees in List.iter (fun path -> assert (Eio.Path.is_directory path)) tree_dirs; let docs = Phases.load tree_dirs in Seq.iter (fun doc -> let lsp_uri = Lsp.Text_document.documentUri doc in let uri = URI_scheme.lsp_uri_to_uri ~base: forest.config.url lsp_uri in URI.Tbl.replace forest.resolver uri (Lsp.Uri.to_path lsp_uri); forest.={uri} <- Document doc ) docs; Logs.debug (fun m -> m "loaded %d trees" (Seq.length docs)); Parse_all, forest | Parse_all -> let@ () = Reporter.trace "when parsing trees" in let errors, succeeded = Phases.parse forest in List.iter (fun (code : Tree.code) -> let@ uri = Option.iter @~ Tree.(identity_to_uri code.identity) in forest.={uri} <- Parsed code; forest.?{uri} <- [] ) succeeded; if (List.length errors = 0) then assert ( Seq.for_all Tree.is_parsed (URI.Tbl.to_seq_values forest.index) ); List.iter (fun diag -> let@ uri = Option.iter @~ Option.map (URI_scheme.lsp_uri_to_uri ~base: forest.config.url) (Reporter.guess_uri diag) in forest.?{uri} <- [diag] ) errors; Action.report ~errors ~next_action: Build_import_graph, forest | Build_import_graph -> let@ () = Reporter.trace "when building import graph" in let errors, import_graph = Phases.build_import_graph forest in Logs.debug (fun m -> m "import graph has %d vertices" (Forest_graph.nb_vertex import_graph)); Action.report ~errors ~next_action: Expand_all, {forest with import_graph} | Expand_all -> let@ () = Reporter.tracef "when expanding trees" in Logs.debug (fun m -> m "expanding trees"); let errors = Phases.expand_all forest in Action.report ~errors ~next_action: Eval_all, forest | Expand uri -> let@ () = Reporter.tracef "when expanding %a" URI.pp uri in begin match Option.bind forest.={uri} Tree.to_code with | None -> Action.report ~errors: [Reporter.diagnostic (Resource_not_found uri)] ~next_action: Done, forest | Some code -> let result, errors = Phases.expand forest code in forest.={uri} <- Expanded result; Action.report ~errors ~next_action: (Eval uri), forest end | Eval_all -> let@ () = Reporter.tracef "when evaluating" in Logs.debug (fun m -> m "evaluating"); let result = Phases.eval forest in let jobs, errors = result |> List.of_seq |> List.map (fun (Eval.{articles; jobs}, diagnostics) -> begin let@ article = List.iter @~ articles in State.plant_resource (T.Article article) forest end; jobs, diagnostics ) |> List.split |> fun (j, e) -> List.concat j, List.concat e in Logs.debug (fun m -> m "got %d resources " (Seq.length (State.get_all_resources forest))); Action.report ~errors ~next_action: (Run_jobs jobs), forest | Eval uri -> let@ () = Reporter.tracef "when evaluating %a" URI.pp uri in let result, _err = Phases.eval_only uri forest in Done, result | Plant_assets -> let@ () = Reporter.tracef "when planting assets" in (* TODO: We really only need to plant the assets that are referred to (look for calls to Asset_router.uri_of_asset).*) let paths = Dir_scanner.scan_asset_directories (Eio_util.paths_of_dirs ~env: forest.env forest.config.assets) in Logs.debug (fun m -> m "planting %i assets" (Seq.length paths)); let module EP = Eio.Path in begin let@ path = Eio.Fiber.List.iter ~max_fibers: 20 @~ List.of_seq paths in let@ () = Reporter.easy_run in let content = EP.load path in let source_path = EP.native_exn path in let uri = Asset_router.install ~config: forest.config ~source_path ~content in Logs.debug (fun m -> m "Installed %s at %a" source_path URI.pp uri); State.plant_resource (T.Asset {uri; content}) forest end; Done, forest | Plant_foreign -> let@ () = Reporter.tracef "when planting foreign forest" in Logs.debug (fun m -> m "Planting foreign forests"); let result, err = Phases.implant_foreign forest in Report_errors (err, Done), result | Run_jobs jobs -> Phases.run_jobs forest jobs; Done, forest | Load_tree path -> let@ () = Reporter.tracef "when loading %a" Eio.Path.pp path in let doc = Imports.load_tree path in Logs.debug (fun m -> m "%s" (Lsp.Text_document.text doc)); let lsp_uri = Lsp.Text_document.documentUri doc in let uri = URI_scheme.lsp_uri_to_uri ~base: forest.config.url lsp_uri in forest.={uri} <- Document doc; Parse lsp_uri, forest | Parse uri -> let@ () = Reporter.tracef "when parsing %s" (Lsp.Uri.to_string uri) in Logs.debug (fun m -> m "Reparsing"); let uri = URI_scheme.lsp_uri_to_uri ~base: forest.config.url uri in begin match Option.bind forest.={uri} Tree.to_doc with | Some doc -> begin match Parse.parse_document ~config: forest.config doc with | Ok code -> forest.={uri} <- Parsed code; forest.?{uri} <- []; Imports.fixup code forest; Expand uri, forest | Error diagnostic -> forest.?{uri} <- [diagnostic]; (Report_errors ([diagnostic], Done)), forest end | None -> match Imports.resolve_uri_to_code forest uri with | None -> Reporter.fatal (Resource_not_found uri) | Some code -> Imports.fixup code forest; forest.={uri} <- Parsed code; Expand uri, forest end | Done -> Done, forest let run_until_done a s : State.t = let fatal d = Reporter.Tty.display d; exit 1 in let emit = Reporter.Tty.display in Reporter.run ~emit ~fatal @@ fun () -> let rec go action state = let new_action, new_state = update action state in match action with | Quit Fail -> exit 1 | Quit Finished -> exit 0 | Done -> new_state | _ -> go new_action new_state in go a s let implant_foreign = run_until_done Plant_foreign let plant_assets = run_until_done Plant_assets let any_fatal = List.fold_left Asai.Diagnostic.( fun acc x -> acc || x.severity = Error || x.severity = Bug ) false let batch_run ~env ~(config : Config.t) ~dev = let init = State.make ~env ~config ~dev () |> plant_assets |> implant_foreign in let rec go action state = let new_action, new_state = update action state in match action with | Quit Fail -> exit 1 | Quit Finished -> exit 0 | Done -> new_state | Report_errors (errors, _) -> assert (List.length errors > 0); Logs.debug (fun m -> m "got %d errors" (List.length errors)); List.iter Reporter.Tty.display errors; if any_fatal errors then go (Quit Fail) new_state else go new_action new_state | _ -> go new_action new_state in go Load_all_configured_dirs init let language_server ~env ~config = let init = State.make ~env ~config ~dev: true () in let rec go action state = let new_action, new_state = update action state in match action with | Quit Fail -> exit 1 | Quit Finished -> exit 0 | Done -> new_state | _ -> go new_action new_state in let _, state = update Plant_assets init in go Load_all_configured_dirs state let run_with_history a s = let history = ref [] in let rec go action state = history := action :: !history; match update action state with | new_action, new_state -> if action = Done then new_state else begin go new_action new_state end in let forest = go a s in forest, List.rev !history let collect_emitted_errors a s = let errors = ref [] in let rec go action state = match update action state with | new_action, new_state -> match action with | Done -> new_state | Report_errors (errs, _) -> begin errors := errs @ !errors; go new_action new_state end | _ -> go new_action new_state in let forest = go a s in forest, List.rev !errors let rec force : Action.t list -> State.t -> State.t = fun msgs state -> match msgs with | [] -> state | msg :: remaining -> let _discard, new_state = update msg state in force remaining new_state
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>