package alba
Alba compiler
Install
Dune Dependency
Authors
Maintainers
Sources
0.4.4.tar.gz
sha256=4817038301d3e45bac9edf7e6f2fc8bf0a6d78e76e02ad7ea33ef69bcc17df3b
md5=25234357587126685d64f16236167937
doc/src/alba.albalib/alba_console.ml.html
Source file alba_console.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 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314
open Fmlib open Common module Parser = Parser_lang module Repl_parser = Parser.Make (Parser.Command) module Pretty_make (Io:Io.SIG) = struct module Located = Character_parser.Located module Expression = Ast.Expression module Out = Fmlib.Io.Output (Io) module PP = Pretty_printer.Pretty (Out) include PP let put_left (width:int) (s:string): t = let len = String.length s in if len < width then chain [string s; fill (width - len) ' '] else string s let print (fd:Io.File.Out.fd) (width:int) (pp:t): unit Io.t = Out.run fd (PP.run 0 width width pp) end (* Pretty_make *) module Located = Character_parser.Located module Make (Io:Io.SIG) = struct module Pretty = Pretty_make (Io) type command_line = { command: string option; workspace: string; package_paths: string list; verbosity: int; force: bool; arguments: string list (* reversed *) } module CLP = Argument_parser.Make (struct type t = command_line end) let find_in_array (p:'a->bool) (arr: 'a array): int = Interval.find (fun i -> p arr.(i)) 0 (Array.length arr) let find_elem_in_array (a:'a) (arr:'a array): int = find_in_array (fun e -> e = a) arr let has_file (name:string) (arr:string array): bool = find_elem_in_array name arr < Array.length arr let rec find_workspace (path:string) : (string * string array) option Io.t = (* Find a directory with a file named "alba-workspace.yml" in the directory [path] and all its parent directories. Return the path to the directory, the directory entries and the position of the file "alba-workspace.yml" in the entries. *) let open Io in Directory.read path >>= function | None -> return None | Some arr -> let len = Array.length arr in let pos = find_elem_in_array "alba-workspace.yml" arr in if pos = len then (* not the root of the workspace *) match Path.split path with | None -> return None | Some (dir,_) -> find_workspace dir else return @@ Some (path,arr) let find_packages (ws_path:string) (entries:string array) : string list Io.t = (* Find the packages in the workspace [ws_path]. Return a list of paths *) let open Io in let rec find path entries lst = let len = Array.length entries in let rec find_in_entries i lst = if i = len then return lst else let path1 = Path.join path entries.(i) in Directory.read path1 >>= function | None -> find_in_entries (i+1) lst | Some entries1 -> find path1 entries1 lst >>= fun lst -> find_in_entries (i+1) lst in if has_file "alba-package.yml" entries then return @@ path :: lst else find_in_entries 0 lst in find ws_path entries [] let explore_workspace (cmd:command_line) : (string * string list) option Io.t = (* Find the root of the workspace and a list of package directories in the workspace. *) let open Io in Stdout.line "explore workspace ..." >>= fun _ -> Path.absolute cmd.workspace >>= fun path -> find_workspace (Path.normalize path) >>= function | None -> return None | Some (path, entries) -> find_packages path entries >>= fun pkgs -> return @@ Some (path,pkgs) let compile (cmd:command_line): unit Io.t = Io.(Stdout.line "compile ..." >>= fun _ -> explore_workspace cmd >>= function | None -> Stdout.line "no workspace found" | Some (ws_path, _) -> Stdout.line ("workspace <" ^ ws_path ^ ">")) let status (_:command_line): unit Io.t = Io.Stdout.line "status ..." let evaluate (_:command_line): unit Io.t = let module Repl = Repl.Make (Io) in Repl.run_eval () let compile_module _: unit Io.t = let module Compile = Module.Make (Io) in Compile.run () let repl _: unit Io.t = let module Repl = Repl.Make (Io) in Repl.run_cli () let commands: (string*(command_line->unit Io.t)*string) list = ["compile", compile, "Compile the modules provided on the command line and all its \ dependencies if compilation is required. If no modules are provided \ all modules of the package which require compilation are compiled." ; "status", status, "Display all modules which require compilation or recompilation." ; "repl", repl, "Start an interactive programming session." ; "evaluate", evaluate, "Read an expression from standard input and evaluate it." ; "module", compile_module, "Compile a module from standard input. The module might have commands \ like ':evaluate <expression>' or ':typecheck <expression>' in it." ] let command_options: (CLP.key*CLP.spec*CLP.doc) list = let open CLP in [("-verbosity", Int (fun i a -> {a with verbosity = i}), "Verbosity level (default 1)" ); ("-w", String (fun s a -> {a with workspace = s}), "Path into an Alba workspace (default: current working directory)"); ("-I", String (fun s a -> {a with package_paths = s :: a.package_paths}), "Add argument to search path for used packages"); ("-force", Unit (fun a -> {a with force = true}), "Force compilation, even if it is not necessary") ] let parse (args:string array): (command_line,CLP.error) result = let open CLP in parse args {command = None; workspace = ""; package_paths = []; verbosity = 1; force = false; arguments = []} command_options (fun s a -> match a.command with | None -> {a with command = Some s} | Some _ -> {a with arguments = s :: a.arguments}) let print_options: Pretty.t = let open Pretty in chain (List.map (fun (key,spec,doc) -> chain [cut; put_left 20 (key ^ CLP.argument_type spec); nest 20 @@ fill_paragraph doc]) command_options) let print_commands: Pretty.t = let open Pretty in chain (List.map (fun (cmd,_,doc) -> chain [cut; put_left 10 cmd; nest 10 @@ fill_paragraph doc]) commands) let print_usage: Pretty.t = let open Pretty in chain [string "Usage: alba command options arguments"; cut; cut; nest_list 4 [string "Commands:"; print_commands]; cut; cut; nest_list 4 [string "Options:"; print_options]; cut] let print_error (s:string): unit Io.t = let open Pretty in print Io.File.stderr 80 (string "Error: " <+> string s <+> cut <+> cut <+> print_usage) let run (): unit = let open Io in Process.execute (Process.command_line >>= fun args -> match parse args with | Ok cl -> begin match cl.command with | None -> print_error "no commands given" | Some cmd -> match List.find (fun (c,_,_) -> c = cmd) commands with | None -> print_error ("Unknown command '" ^ cmd ^ "'") | Some (_,f,_) -> f cl end | Error e -> print_error (CLP.string_of_error e) >>= fun _ -> Process.exit 1 ) end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>