(;module: lux (lux (control monad) (concurrency ["A" atom] ["P" promise]) (data ["e" error] [text "T/" Hash] text/format (coll ["D" dict] [array])) [meta #+ Monad] [host] [io]) (luxc ["&" base] ["&;" io] ["&;" module] ["&;" parser] ["&;" host] (compiler ["&&;" runtime] ["&&;" statement] ["&&;" common]) )) (def: (compile ast) (-> Code (Meta 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: " (%code ast))))) (def: (exhaust action) (All [a] (-> (Meta a) (Meta Unit))) (do Monad [result action] (exhaust action))) (def: (ensure-new-module! file-hash module-name) (-> Nat Text (Meta Unit)) (do Monad [module-exists? (meta;module-exists? module-name) _ (: (Meta 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] (Meta a) (Meta 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 (Meta 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 (meta;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))))) (host;import org.objectweb.asm.MethodVisitor) (def: init-cursor Cursor ["" +0 +0]) (def: #export init-type-context Type-Context {#;ex-counter +0 #;var-counter +0 #;var-bindings (list)}) (def: #export init-info Info {#;target "JVM" #;version &;version #;mode #;Build}) (def: #export (init-compiler host) (-> &&common;Host Compiler) {#;info init-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 (&host;init-host []))] compiler (or-crash! (&&runtime;compile-runtime compiler)) compiler (or-crash! (compile-module sources prelude compiler)) compiler (or-crash! (compile-module sources program compiler)) #let [_ (log! "Compilation complete!")]] (wrap [])))