(;module: lux (lux (control monad ["ex" exception #+ exception:]) [io #- run] (concurrency ["P" promise] ["T" task]) (data ["e" error] [text "text/" Eq] text/format) [meta] [host] (world [file #+ File] [blob #+ Blob])) (luxc ["&" base])) (host;import java.lang.String (new [(Array byte)])) (def: host-extension Text ".jvm") (def: lux-extension Text ".lux") (exception: #export File-Not-Found) (exception: #export Module-Not-Found) (def: (find-source path dirs) (-> Text (List File) (T;Task [Text File])) (case dirs #;Nil (T;throw File-Not-Found path) (#;Cons dir dirs') (do T;Monad [#let [file (format dir "/" path)] ? (file;exists? file)] (if ? (wrap [path file]) (find-source path dirs'))))) (def: (either left right) (All [a] (-> (T;Task a) (T;Task a) (T;Task a))) (do P;Monad [?output left] (case ?output (#e;Success output) (wrap (#e;Success output)) (#e;Error error) right))) (def: #export (read-module dirs name) (-> (List File) Text (T;Task [File Text])) (let [host-path (format name host-extension lux-extension) lux-path (format name lux-extension)] (do T;Monad [[path file] (: (T;Task [Text File]) ($_ either (find-source host-path dirs) (find-source lux-path dirs) (T;throw Module-Not-Found name))) blob (file;read file)] (wrap [path (String.new blob)])))) (def: #export (write-module name descriptor) (-> Text Text (T;Task Unit)) (T;fail "'write-module' is undefined.")) (def: (platform-target root-target) (-> File File) (format root-target "/" (for {"JVM" "jvm" "JS" "js"}))) (def: (platform-file root-file) (-> File File) (format root-file (for {"JVM" ".class" "JS" ".js"}))) (def: #export (prepare-target target-dir) (-> File (T;Task Unit)) (do T;Monad [_ (file;make-dir target-dir) _ (file;make-dir (platform-target target-dir))] (wrap []))) (def: #export (prepare-module target-dir module-name) (-> File Text (T;Task Unit)) (do T;Monad [_ (file;make-dir (format (platform-target target-dir) "/" module-name))] (wrap []))) (def: #export (write-file target-dir file-name content) (-> File Text Blob (T;Task Unit)) (file;write content (format (platform-target target-dir) "/" (platform-file file-name))))