(;module: lux (lux (control monad ["ex" exception #+ exception:]) [io #+ Process] (concurrency ["P" promise] ["T" task]) (data ["e" error] [text "text/" Eq] text/format) [macro] [host] (world [file #+ File] [blob #+ Blob]))) (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) (exception: #export Could-Not-Read-All-Data) (host;import #long java.io.File (new [String]) (exists [] #io #try boolean) (mkdir [] #io #try boolean) (delete [] #io #try boolean) (length [] #io #try long) (listFiles [] #io #try (Array java.io.File)) (getAbsolutePath [] #io #try String) (isFile [] #io #try boolean) (isDirectory [] #io #try boolean)) (host;import java.lang.AutoCloseable (close [] #io #try void)) (host;import java.io.InputStream (read [(Array byte)] #io #try int)) (host;import java.io.FileInputStream (new [java.io.File] #io #try)) (def: file-exists? (-> File (Process Bool)) (|>. java.io.File.new (java.io.File.exists []))) (def: (find-source path dirs) (-> Text (List File) (Process [Text File])) (case dirs #;Nil (io;fail (File-Not-Found path)) (#;Cons dir dirs') (do io;Monad [#let [file (format dir "/" path)] ? (file-exists? file)] (if ? (wrap [path file]) (find-source path dirs'))))) (def: (either left right) (All [a] (-> (Process a) (Process a) (Process a))) (do io;Monad [?output left] (case ?output (#e;Success output) (wrap (#e;Success output)) (#e;Error error) right))) (def: #export (read-file file) (-> File (Process Blob)) (do io;Monad [#let [file' (java.io.File.new file)] size (java.io.File.length [] file') #let [data (blob;create (int-to-nat size))] stream (FileInputStream.new [file']) bytes-read (InputStream.read [data] stream) _ (AutoCloseable.close [] stream)] (if (i.= size bytes-read) (wrap data) (io;fail (Could-Not-Read-All-Data file))))) (def: #export (read-module dirs name) (-> (List File) Text (Process [File Text])) (let [host-path (format name host-extension lux-extension) lux-path (format name lux-extension)] (do io;Monad [[path file] (: (Process [Text File]) ($_ either (find-source host-path dirs) (find-source lux-path dirs) (io;fail (Module-Not-Found name)))) blob (read-file 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: #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-name (format (platform-target target-dir) "/") (file;write content)))