(;module: lux (lux (control monad) [io #- run] (concurrency ["P" promise]) (data ["E" error] [text "T/" Eq] text/format) [macro] host) (luxc ["&" base])) (jvm-import java.io.File (new [String String]) (exists [] #io #try boolean)) (jvm-import java.io.Reader (close [] #io #try void)) (jvm-import java.io.FileReader (new [File])) (jvm-import java.io.BufferedReader (new [Reader]) (readLine [] #io #try #? String)) (def: host-extension Text ".jvm") (def: (find-in-sources path source-dirs) (-> &;Path (List &;Path) (P;Promise (Maybe File))) (loop [source-dirs source-dirs] (case source-dirs #;Nil (:: P;Monad wrap #;None) (#;Cons dir source-dirs') (do P;Monad [#let [file (File.new [dir path])] ?? (P;future (File.exists [] file))] (case ?? (#;Right true) (wrap (#;Some file)) _ (recur source-dirs')))))) (def: (read-source-code lux-file) (-> File (P;Promise (E;Error Text))) (P;future (let [reader (|> lux-file FileReader.new BufferedReader.new)] (loop [total ""] (do Monad [?line (BufferedReader.readLine [] reader)] (case ?line (#E;Error error) (wrap (#E;Error error)) (#E;Success #;None) (wrap (#E;Success total)) (#E;Success (#;Some line)) (if (T/= "" total) (recur line) (recur (format total "\n" line))))))))) (def: #export (read-module source-dirs module-name) (-> (List &;Path) Text (P;Promise (E;Error [&;Path Text]))) (let [host-path (format module-name host-extension ".lux") lux-path (format module-name ".lux")] (with-expansions [ (do-template [] [(do P;Monad [?file (find-in-sources source-dirs)]) (case ?file (#;Some file) (do @ [?code (read-source-code file)] (case ?code (#E;Error error) (wrap (#E;Error error)) (#E;Success code) (wrap (#E;Success [ code])))) #;None)] [host-path] [lux-path])] (<| (wrap (#E;Error (format "Module cannot be found: " module-name))))))) (def: #export (write-module module-name module-descriptor) (-> Text Text (P;Promise Unit)) (undefined))