(.module: lux (lux (control [monad #+ do] ["p" parser]) (concurrency [promise #+ Promise] [task #+ Task]) (data ["e" error] text/format) [io #- run] (time [instant]) [cli #+ program: CLI] (world [file #+ File])) (luxc [repl] (lang [".L" translation]))) (type: Build {#build-sources (List File) #build-target File #build-program Text}) (type: REPL {#repl-sources (List File) #repl-target File}) (def: (param [short long]) (-> [Text Text] (CLI Text)) (cli.somewhere (p.after (p.either (cli.this short) (cli.this long)) cli.any))) (def: build (CLI Build) ($_ p.seq (p.some (param ["-s" "--source"])) (param ["-t" "--target"]) (param ["-p" "--program"]))) (def: repl (CLI REPL) ($_ p.seq (p.some (param ["-s" "--source"])) (param ["-t" "--target"]))) (type: Service (#Build Build) (#REPL REPL)) (def: service (CLI Service) (p.alt (p.after (cli.this "build") build) (p.after (cli.this "repl") repl))) (def: (or-crash! failure-describer action) (All [a] (-> Text (Task a) (Promise a))) (do promise.Monad [?output action] (case ?output (#e.Error error) (exec (log! (format "\n" failure-describer "\n" error "\n")) ("lux io exit" 1)) (#e.Success output) (wrap output)))) (program: [{service ..service}] (exec (case service (#Build [sources target program]) (<| (or-crash! "Compilation failed:") (promise.future (do io.Monad [#let [start (io.run instant.now)] result (translationL.translate-program sources target program) #let [end (io.run instant.now) _ (log! (format "\n" "Elapsed time: " (%duration (instant.span start end))))]] (wrap result)))) (#REPL [sources target]) (<| (or-crash! "REPL failed:") (repl.run sources target))) (io [])))