(;module: lux (lux (control monad) (concurrency ["P" promise]) (data ["E" error] [text "T/" Hash] text/format) [macro #+ Monad]) (luxc ["&" base] ["&;" io] ["&;" module] ["&;" parser] (compiler ["&&;" runtime] ["&&;" statement]) )) (def: (compile ast) (-> Code (Lux Unit)) (case ast (^ [_ (#;Form (list [_ (#;Symbol ["" "_lux_def"])] [_ (#;Symbol ["" def-name])] def-value def-meta))]) (&&statement;compile-def def-name def-value def-meta) (^ [_ (#;Form (list [_ (#;Symbol ["" "_lux_program"])] [_ (#;Symbol ["" prog-args])] prog-body))]) (&&statement;compile-program prog-args prog-body) _ (&;fail (format "Unrecognized statement: " (%ast ast))))) (def: (exhaust action) (All [a] (-> (Lux a) (Lux Unit))) (do Monad [result action] (exhaust action))) (def: (ensure-new-module! file-hash module-name) (-> Nat Text (Lux Unit)) (do Monad [module-exists? (macro;module-exists? module-name) _ (: (Lux Unit) (if module-exists? (&;fail (format "Cannot re-define a module: " module-name)) (wrap []))) _ (&module;create file-hash module-name)] (wrap []))) (def: prelude Text "lux") (def: (with-active-compilation [module-name file-name source-code] action) (All [a] (-> [Text Text Text] (Lux a) (Lux a))) (do Monad [_ (ensure-new-module! (T/hash source-code) module-name) #let [init-cursor [file-name +0 +0]] output (&;with-source-code [init-cursor source-code] action) _ (&module;flag-compiled! module-name)] (wrap output))) (def: parse (Lux Code) (function [compiler] (case (&parser;parse (get@ #;source compiler)) (#E;Error error) (#E;Error error) (#E;Success [source' output]) (#E;Success [(set@ #;source source' compiler) output])))) (def: (compile-module source-dirs module-name compiler) (-> (List &;Path) Text Compiler (P;Promise (E;Error Compiler))) (do P;Monad [?input (&io;read-module source-dirs module-name)] (case ?input (#E;Success [file-name file-content]) (let [compilation (do Monad [_ (with-active-compilation [module-name file-name file-content] (exhaust (do @ [ast parse] (compile ast))))] (wrap []) ## (&module;generate-descriptor module-name) )] (case (macro;run' compiler compilation) (#E;Success [compiler module-descriptor]) (do @ [## _ (&io;write-module module-name module-descriptor) ] (wrap (#E;Success compiler))) (#E;Error error) (wrap (#E;Error error)))) (#E;Error error) (wrap (#E;Error error))))) (type: Host Unit) (def: init-host Host []) (def: init-cursor Cursor ["" +0 +0]) (def: init-type-context Type-Context {#;ex-counter +0 #;var-counter +0 #;var-bindings (list)}) (def: compiler-version Text "0.6.0") (def: init-compiler-info Compiler-Info {#;compiler-version compiler-version #;compiler-mode #;Build}) (def: (init-compiler host) (-> Host Compiler) {#;info init-compiler-info #;source [init-cursor ""] #;cursor init-cursor #;modules (list) #;scopes (list) #;type-context init-type-context #;expected #;None #;seed +0 #;scope-type-vars (list) #;host (:! Void host)}) (def: (or-crash! action) (All [a] (-> (P;Promise (E;Error a)) (P;Promise a))) (do P;Monad [?output action] (case ?output (#E;Error error) (error! error) (#E;Success output) (wrap output)))) (def: #export (compile-program program target sources) (-> &;Path &;Path (List &;Path) (P;Promise Unit)) (do P;Monad [#let [compiler (init-compiler init-host)] _ (or-crash! (&&runtime;compile-runtime [])) compiler (or-crash! (compile-module sources prelude compiler)) compiler (or-crash! (compile-module sources program compiler)) #let [_ (log! "Compilation complete!")]] (wrap [])))