aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/world/program.lux
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--stdlib/source/lux/world/program.lux128
1 files changed, 128 insertions, 0 deletions
diff --git a/stdlib/source/lux/world/program.lux b/stdlib/source/lux/world/program.lux
new file mode 100644
index 000000000..486e5b7b6
--- /dev/null
+++ b/stdlib/source/lux/world/program.lux
@@ -0,0 +1,128 @@
+(.module:
+ [lux #*
+ ["@" target]
+ [host (#+ import:)]
+ [abstract
+ [monad (#+ do)]]
+ [control
+ ["." function]
+ ["." io (#+ IO)]
+ [concurrency
+ ["." atom]
+ ["." promise (#+ Promise)]]
+ [parser
+ [environment (#+ Environment)]]]
+ [data
+ ["." maybe]
+ ["." text
+ ["%" format (#+ format)]]
+ [collection
+ ["." dictionary (#+ Dictionary)]]]]
+ [//
+ [file (#+ Path)]
+ [shell (#+ Exit)]])
+
+(signature: #export (Program !)
+ (: (-> Any (! Environment))
+ environment)
+ (: (-> Any (! Path))
+ directory)
+ (: (-> Exit (! Nothing))
+ exit))
+
+(def: #export (async program)
+ (-> (Program IO) (Program Promise))
+ (structure
+ (def: environment
+ (|>> (\ program environment) promise.future))
+ (def: directory
+ (|>> (\ program directory) promise.future))
+ (def: exit
+ (|>> (\ program exit) promise.future))))
+
+(def: #export (mock environment directory)
+ (-> Environment Path (Program IO))
+ (let [@dead? (atom.atom false)]
+ (structure
+ (def: environment
+ (function.constant (io.io environment)))
+ (def: directory
+ (function.constant (io.io directory)))
+ (def: (exit code)
+ (io.io (error! (%.int code)))))))
+
+## Do not trust the values of environment variables
+## https://wiki.sei.cmu.edu/confluence/display/java/ENV02-J.+Do+not+trust+the+values+of+environment+variables
+
+(with-expansions [<jvm> (as-is (import: java/lang/String)
+
+ (import: (java/util/Map$Entry k v)
+ ["#::."
+ (getKey [] k)
+ (getValue [] v)])
+
+ (import: (java/util/Iterator a)
+ ["#::."
+ (hasNext [] boolean)
+ (next [] a)])
+
+ (import: (java/util/Set a)
+ ["#::."
+ (iterator [] (java/util/Iterator a))])
+
+ (import: (java/util/Map k v)
+ ["#::."
+ (entrySet [] (java/util/Set (java/util/Map$Entry k v)))])
+
+ (import: java/lang/System
+ ["#::."
+ (#static getenv [] (java/util/Map java/lang/String java/lang/String))
+ (#static exit [int] #io void)])
+
+ (def: (jvm\\consume f iterator)
+ (All [a b] (-> (-> a b) (java/util/Iterator a) (List b)))
+ (if (java/util/Iterator::hasNext iterator)
+ (#.Cons (f (java/util/Iterator::next iterator))
+ (jvm\\consume f iterator))
+ #.Nil))
+
+ (def: (jvm\\to-kv entry)
+ (All [k v] (-> (java/util/Map$Entry k v) [k v]))
+ [(java/util/Map$Entry::getKey entry)
+ (java/util/Map$Entry::getValue entry)])
+
+ (def: jvm\\environment
+ (IO Environment)
+ (with-expansions [<jvm> (as-is (io.io (|> (java/lang/System::getenv)
+ java/util/Map::entrySet
+ java/util/Set::iterator
+ (..jvm\\consume ..jvm\\to-kv)
+ (dictionary.from-list text.hash))))]
+ (for {@.old <jvm>
+ @.jvm <jvm>})))
+ )]
+ (for {@.old (as-is <jvm>)
+ @.jvm (as-is <jvm>)}))
+
+(structure: #export default
+ (Program IO)
+
+ (def: (environment _)
+ (with-expansions [<jvm> ..jvm\\environment]
+ (for {@.old <jvm>
+ @.jvm <jvm>})))
+
+ (def: (directory _)
+ (with-expansions [<jvm> (\ io.monad map
+ (|>> (dictionary.get "user.dir")
+ (maybe.default ""))
+ ..jvm\\environment)]
+ (for {@.old <jvm>
+ @.jvm <jvm>})))
+
+ (def: (exit code)
+ (with-expansions [<jvm> (do io.monad
+ [_ (java/lang/System::exit code)]
+ (wrap (undefined)))]
+ (for {@.old <jvm>
+ @.jvm <jvm>}))))