(.require [library [lux (.except Module) ["[0]" debug] [abstract ["[0]" monad (.only do)]] [control ["[0]" io (.only IO io)] ["[0]" maybe] ["[0]" try (.only Try)] [concurrency ["[0]" async (.only Async) (.use "[1]#[0]" monad)]]] [data [binary (.only Binary)] ["[0]" product] ["[0]" text (.only) ["%" \\format (.only format)]] [collection ["[0]" dictionary (.only Dictionary)]]] [meta [type (.only sharing)] ["@" target] ["[0]" compiler [default ["[0]" platform (.only Platform)]] [language ["$" lux (.only) ["[1]/[0]" program (.only Program)] ["[0]" syntax] ["[0]" translation] ["[0]" declaration] ["[0]" analysis (.only) [macro (.only Expander)]] ["[0]" phase (.only) [extension (.only Extender) ["[0]E" analysis] ["[0]E" synthesis]]]]] [meta [packager (.only Packager)] [context (.only Context)] ["[0]" cli (.only Service)] ["[0]" import] ["[0]" export] ["[0]" cache ["[1]" archive]] [archive (.only Archive) ["[0]" unit] [module [descriptor (.only Module)]]] [io ["ioW" archive]]]] ... ["[0]" interpreter] ] ["[0]" world ["[0]" file] ["[0]" console] ["[1]/[0]" environment] [time ["[0]" instant]]]]]) (def (or_crash! failure_description action) (All (_ a) (-> Text (Async (Try a)) (Async a))) (do [! async.monad] [?output action] (when ?output {try.#Failure error} (let [report (format text.new_line failure_description text.new_line error text.new_line)] (do ! [_ (with_expansions [ (in {try.#Success (debug.log! report)})] (for @.js (is (Async (Try Any)) (when console.default {.#None} {.#Some console} (console.write_line report console))) (is (Async (Try Any)) )))] (io.run! (of world/environment.default exit +1)))) {try.#Success output} (in output)))) (def (timed process) (All (_ a) (-> (Async (Try a)) (Async (Try a)))) (do async.monad [.let [start (io.run! instant.now)] output process .let [_ (debug.log! (|> (io.run! instant.now) (instant.span start) %.duration (format "Duration: ")))]] (in output))) (def (package! fs host_dependencies [packager package] archive context) (-> (file.System Async) (Dictionary file.Path Binary) [Packager file.Path] Archive (Maybe unit.ID) (Async (Try Any))) (when (packager host_dependencies archive context) {try.#Success content} (when content {.#Left content} (of fs write package content) {.#Right content} (do [! (try.with async.monad)] [_ (of fs make_directory package) _ (monad.each ! (function (_ [name content]) (of fs write (file.rooted fs package name) content)) content)] (in []))) {try.#Failure error} (of async.monad in {try.#Failure error}))) (def (load_host_dependencies fs host_dependencies) (-> (file.System Async) (List file.Path) (Async (Try (Dictionary file.Path Binary)))) (do [! (try.with async.monad)] [] (loop (again [pending host_dependencies output (is (Dictionary file.Path Binary) (dictionary.empty text.hash))]) (when pending {.#End} (in output) {.#Item head tail} (do ! [content (of fs read head)] (again tail (dictionary.has head content output))))))) (with_expansions [ (these anchor expression artifact)] (def .public (compiler lux_compiler file_context expander host_analysis platform translation_bundle host_declaration_bundle program global extender service packager,package) (All (_ ) (-> (-> Any platform.Custom) Context Expander analysis.Bundle (IO (Platform )) (translation.Bundle ) (declaration.Bundle ) (Program expression artifact) (-> Archive Symbol (translation.Operation expression)) Extender Service [Packager file.Path] (Async Any))) (do [! async.monad] [platform (async.future platform)] (when service {cli.#Compilation compilation} (<| (or_crash! "Compilation failed:") ..timed (do (try.with async.monad) [import (import.import (the platform.#file_system platform) (the cli.#libraries compilation)) .let [all_extensions [(analysisE.bundle host_analysis) synthesisE.bundle translation_bundle host_declaration_bundle]] [state archive phase_wrapper] (sharing [] (is (Platform ) platform) (is (Async (Try [(declaration.State ) Archive phase.Wrapper])) (as_expected (platform.initialize file_context (the cli.#module compilation) expander platform program extender import (the cli.#sources compilation) (the cli.#configuration compilation) all_extensions)))) [archive state] (sharing [] (is (Platform ) platform) (is (Async (Try [Archive (declaration.State )])) (as_expected (platform.compile program global lux_compiler phase_wrapper import file_context extender expander platform compilation [archive state] all_extensions)))) _ (cache.cache! (the platform.#file_system platform) (the cli.#configuration compilation) file_context archive) host_dependencies (..load_host_dependencies (the platform.#file_system platform) (the cli.#host_dependencies compilation)) _ (..package! (for @.old (file.async file.default) @.jvm (file.async file.default) ... TODO: Handle this in a safer manner. ... This would crash if the compiler was run on a browser. @.js (maybe.trusted file.default)) host_dependencies packager,package archive (try.maybe ($/program.context archive)))] (in (debug.log! "Compilation complete!")))) {cli.#Export export} (<| (or_crash! "Export failed:") (do (try.with async.monad) [_ (export.export (the platform.#file_system platform) export)] (in (debug.log! "Export complete!")))) {cli.#Interpretation interpretation} ... TODO: Fix the interpreter... (undefined) ... (<| (or_crash! "Interpretation failed:") ... (do [! async.monad] ... [console (|> console.default ... async.future ... (of ! each (|>> try.trusted console.async)))] ... (interpreter.run! (try.with async.monad) console platform interpretation translation_bundle))) ))))