aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Julian2021-12-25 22:05:54 -0400
committerEduardo Julian2021-12-25 22:05:54 -0400
commit00d92539208da86557e592a8c8df03d3b08e6b40 (patch)
treea71cc9e5f41c230f07956301263a710689e9dc85
parent63b45e09c5f5ceb59a48ed05cdc2d2c6cb038a7b (diff)
Dusting off the pure-Lux JVM compiler machinery. [Part 2]
-rw-r--r--documentation/bookmark/game/generation/name.md4
-rw-r--r--documentation/bookmark/game/mechanic/unlockable.md4
-rw-r--r--documentation/bookmark/game/worldbuilding/town.md4
-rw-r--r--documentation/bookmark/paradigm/logic_programming.md1
-rw-r--r--documentation/bookmark/tool/debugger.md20
-rw-r--r--lux-bootstrapper/src/lux/analyser/lux.clj3
-rw-r--r--lux-jvm/source/luxc/lang/translation/jvm.lux7
-rw-r--r--stdlib/project.clj2
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux10
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/host.lux163
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/program.lux25
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/runtime.lux144
-rw-r--r--stdlib/source/test/lux.lux4
-rw-r--r--stdlib/source/test/lux/data/collection/array.lux71
-rw-r--r--stdlib/source/test/lux/tool.lux21
-rw-r--r--stdlib/source/test/lux/tool/compiler/arity.lux29
16 files changed, 314 insertions, 198 deletions
diff --git a/documentation/bookmark/game/generation/name.md b/documentation/bookmark/game/generation/name.md
new file mode 100644
index 000000000..b4f042f48
--- /dev/null
+++ b/documentation/bookmark/game/generation/name.md
@@ -0,0 +1,4 @@
+# Reference
+
+0. [Sraƫka-Lillian - Procedural Phonology: Generating Name Generators](https://www.youtube.com/watch?v=XQKNwaCwD-I)
+
diff --git a/documentation/bookmark/game/mechanic/unlockable.md b/documentation/bookmark/game/mechanic/unlockable.md
new file mode 100644
index 000000000..48aa69735
--- /dev/null
+++ b/documentation/bookmark/game/mechanic/unlockable.md
@@ -0,0 +1,4 @@
+# Reference
+
+0. [How Do You Make Fun Unlockables? ~ Design Doc](https://www.youtube.com/watch?v=R8EyVhHRjqc)
+
diff --git a/documentation/bookmark/game/worldbuilding/town.md b/documentation/bookmark/game/worldbuilding/town.md
new file mode 100644
index 000000000..bbbdf4687
--- /dev/null
+++ b/documentation/bookmark/game/worldbuilding/town.md
@@ -0,0 +1,4 @@
+# Reference
+
+0. [What Makes a Good RPG Town? ~ Design Doc](https://www.youtube.com/watch?v=uXleufh2mY0)
+
diff --git a/documentation/bookmark/paradigm/logic_programming.md b/documentation/bookmark/paradigm/logic_programming.md
index cf7b7d13c..9cb7df2e6 100644
--- a/documentation/bookmark/paradigm/logic_programming.md
+++ b/documentation/bookmark/paradigm/logic_programming.md
@@ -12,6 +12,7 @@
# Reference
+0. [PrologHub](https://prologhub.com/)
0. https://book.simply-logical.space/
0. [Higher-Order Logic Programming](https://www.lix.polytechnique.fr/~dale/papers/Handbook_Logic_AI_LP.pdf)
0. [HiLog: A foundation for higher-order logic programming](http://www.sciencedirect.com/science/article/pii/074310669390039J)
diff --git a/documentation/bookmark/tool/debugger.md b/documentation/bookmark/tool/debugger.md
index fb4283d67..f39d1a80d 100644
--- a/documentation/bookmark/tool/debugger.md
+++ b/documentation/bookmark/tool/debugger.md
@@ -1,12 +1,14 @@
# Reference
-1. [Ruby Jard: Just Another Ruby Debugger](https://rubyjard.org/)
-1. [drgn: Scriptable debugger library](https://github.com/osandov/drgn)
-1. [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/)
-1. https://github.com/srg-imperial/SaBRe
-1. https://developer.mozilla.org/en-US/docs/Mozilla/Projects/WebReplay
-1. https://umaar.github.io/performance-debugging-devtools-2018/#/
-1. http://plasma-umass.org/BLeak/
-1. https://clinicjs.org/
-1. http://pev.sourceforge.net/
+0. [tokio-console](https://github.com/tokio-rs/console)
+ 0. [Announcing Tokio Console 0.1](https://tokio.rs/blog/2021-12-announcing-tokio-console)
+0. [Ruby Jard: Just Another Ruby Debugger](https://rubyjard.org/)
+0. [drgn: Scriptable debugger library](https://github.com/osandov/drgn)
+0. [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/)
+0. https://github.com/srg-imperial/SaBRe
+0. https://developer.mozilla.org/en-US/docs/Mozilla/Projects/WebReplay
+0. https://umaar.github.io/performance-debugging-devtools-2018/#/
+0. http://plasma-umass.org/BLeak/
+0. https://clinicjs.org/
+0. http://pev.sourceforge.net/
diff --git a/lux-bootstrapper/src/lux/analyser/lux.clj b/lux-bootstrapper/src/lux/analyser/lux.clj
index 842ad22ef..6f7b747c1 100644
--- a/lux-bootstrapper/src/lux/analyser/lux.clj
+++ b/lux-bootstrapper/src/lux/analyser/lux.clj
@@ -419,8 +419,7 @@
(do-analyse-apply analyse exo-type =fn ?args)))
_
- (do-analyse-apply analyse exo-type =fn ?args))
- )
+ (do-analyse-apply analyse exo-type =fn ?args)))
(defn analyse-case [analyse exo-type ?value ?branches]
(|do [_ (&/assert! (> (&/|length ?branches) 0)
diff --git a/lux-jvm/source/luxc/lang/translation/jvm.lux b/lux-jvm/source/luxc/lang/translation/jvm.lux
index 0d4f493bb..0dcb684e9 100644
--- a/lux-jvm/source/luxc/lang/translation/jvm.lux
+++ b/lux-jvm/source/luxc/lang/translation/jvm.lux
@@ -1,6 +1,6 @@
(.using
[library
- [lux {"-" Module Definition}
+ [lux {"-" Definition}
["[0]" ffi {"+" import: do_to object}]
[abstract
[monad {"+" do}]]
@@ -32,10 +32,7 @@
["[0]" version]
["[0]" generation]]]
[meta
- [io {"+" lux_context}]
- [archive
- [descriptor {"+" Module}]
- ["[0]" artifact]]]]]]]
+ [io {"+" lux_context}]]]]]]
[///
[host
["[0]" jvm {"+" Inst Definition Host State}
diff --git a/stdlib/project.clj b/stdlib/project.clj
index 82bdf265e..c7f49706f 100644
--- a/stdlib/project.clj
+++ b/stdlib/project.clj
@@ -1,4 +1,4 @@
-(def version "0.6.5-SNAPSHOT")
+(def version "0.6.5")
(def repo "https://github.com/LuxLang/lux")
(def sonatype-releases "https://oss.sonatype.org/service/local/staging/deploy/maven2/")
(def sonatype-snapshots "https://oss.sonatype.org/content/repositories/snapshots/")
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux
index 449060cf0..5b49ae38a 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/jvm.lux
@@ -1,7 +1,7 @@
(.using
[library
[lux {"-" Type Definition Primitive}
- ["[0]" ffi]
+ ["[0]" ffi {"+" import:}]
[abstract
["[0]" monad {"+" do}]]
[control
@@ -56,7 +56,7 @@
["[0]A" type]]
[generation
[jvm
- [runtime {"+" Anchor Definition}]]]
+ [runtime {"+" Anchor Definition Extender}]]]
["[0]" extension
["[0]" bundle]
[analysis
@@ -307,8 +307,10 @@
(generation.log! (format "Class " name)))]
(in directive.no_requirements)))]))
-(def: .public bundle
- (Bundle Anchor (Bytecode Any) Definition)
+(import: java/lang/ClassLoader)
+
+(def: .public (bundle class_loader extender)
+ (-> java/lang/ClassLoader Extender (Bundle Anchor (Bytecode Any) Definition))
(<| (bundle.prefix "jvm")
(|> bundle.empty
... TODO: Finish handling methods and un-comment.
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/host.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/host.lux
index a6fa7de6d..b15832011 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/host.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/host.lux
@@ -1,55 +1,64 @@
(.using
- [library
- [lux {"-" Definition}
- ["[0]" ffi {"+" import: do_to object}]
- [abstract
- [monad {"+" do}]]
- [control
- pipe
- ["[0]" try {"+" Try}]
- ["[0]" exception {"+" exception:}]
- ["[0]" io {"+" IO io}]
- [concurrency
- ["[0]" atom {"+" Atom atom}]]]
- [data
- [binary {"+" Binary}]
- ["[0]" product]
- ["[0]" text ("[1]#[0]" hash)
- ["%" format {"+" format}]]
- [collection
- ["[0]" array]
- ["[0]" dictionary {"+" Dictionary}]
- ["[0]" sequence]]
- ["[0]" format "_"
- ["[1]" binary]]]
- [target
- [jvm
- ["[0]" loader {"+" Library}]
- ["_" bytecode {"+" Bytecode}]
- ["[0]" modifier {"+" Modifier} ("[1]#[0]" monoid)]
- ["[0]" field {"+" Field}]
- ["[0]" method {"+" Method}]
- ["[0]" version]
- ["[0]" class {"+" Class}]
- ["[0]" encoding "_"
- ["[1]/[0]" name]]
- ["[0]" type
- ["[0]" descriptor]]]]
- [tool
- [compiler
- ["[0]" name]]]]]
- ["[0]" // "_"
- ["[1][0]" runtime {"+" Definition}]]
- )
+ [library
+ [lux {"-" Definition}
+ ["[0]" ffi {"+" import: do_to object}]
+ [abstract
+ [monad {"+" do}]]
+ [control
+ pipe
+ ["[0]" maybe]
+ ["[0]" try {"+" Try}]
+ ["[0]" exception {"+" exception:}]
+ ["[0]" io {"+" IO io}]
+ [concurrency
+ ["[0]" atom {"+" Atom atom}]]]
+ [data
+ [binary {"+" Binary}]
+ ["[0]" product]
+ ["[0]" text ("[1]#[0]" hash)
+ ["%" format {"+" format}]]
+ [collection
+ ["[0]" array]
+ ["[0]" dictionary {"+" Dictionary}]
+ ["[0]" sequence]]
+ ["[0]" format "_"
+ ["[1]" binary]]]
+ [target
+ [jvm
+ ["_" bytecode {"+" Bytecode}]
+ ["[0]" loader {"+" Library}]
+ ["[0]" modifier {"+" Modifier} ("[1]#[0]" monoid)]
+ ["[0]" field {"+" Field}]
+ ["[0]" method {"+" Method}]
+ ["[0]" version]
+ ["[0]" class {"+" Class}]
+ ["[0]" encoding "_"
+ ["[1]/[0]" name]]
+ ["[0]" type
+ ["[0]" descriptor]]]]
+ [tool
+ [compiler
+ [language
+ [lux
+ [version {"+" version}]
+ [generation {"+" Context}]]]
+ [meta
+ [io {"+" lux_context}]]]]]]
+ ["[0]" // "_"
+ ["[1][0]" runtime {"+" Definition}]]
+ )
(import: java/lang/reflect/Field
- (get ["?" java/lang/Object] "try" "?" java/lang/Object))
+ ["[1]::[0]"
+ (get ["?" java/lang/Object] "try" "?" java/lang/Object)])
(import: (java/lang/Class a)
- (getField [java/lang/String] "try" java/lang/reflect/Field))
+ ["[1]::[0]"
+ (getField [java/lang/String] "try" java/lang/reflect/Field)])
(import: java/lang/Object
- (getClass [] (java/lang/Class java/lang/Object)))
+ ["[1]::[0]"
+ (getClass [] (java/lang/Class java/lang/Object))])
(import: java/lang/ClassLoader)
@@ -57,7 +66,7 @@
(def: value::type (type.class "java.lang.Object" (list)))
(def: value::modifier ($_ modifier#composite field.public field.final field.static))
-(def: init::type (type.method [(list) type.void (list)]))
+(def: init::type (type.method [(list) (list) type.void (list)]))
(def: init::modifier ($_ modifier#composite method.public method.static method.strict))
(exception: .public (cannot_load [class Text
@@ -100,6 +109,13 @@
(def: class_path_separator
".")
+(def: .public (class_name [module_id artifact_id])
+ (-> Context Text)
+ (format lux_context
+ ..class_path_separator (%.nat version)
+ ..class_path_separator (%.nat module_id)
+ ..class_path_separator (%.nat artifact_id)))
+
(def: (evaluate! library loader eval_class valueG)
(-> Library java/lang/ClassLoader Text (Bytecode Any) (Try [Any Definition]))
(let [bytecode_name (text.replaced class_path_separator .module_separator eval_class)
@@ -125,8 +141,8 @@
(in [value
[eval_class bytecode]])))))
-(def: (execute! library loader temp_label [class_name class_bytecode])
- (-> Library java/lang/ClassLoader Text Definition (Try Any))
+(def: (execute! library loader [class_name class_bytecode])
+ (-> Library java/lang/ClassLoader Definition (Try Any))
(io.run! (do (try.with io.monad)
[existing_class? (|> (atom.read! library)
(# io.monad each (function (_ library)
@@ -138,28 +154,43 @@
(loader.store class_name class_bytecode library))]
(loader.load class_name loader))))
-(def: (define! library loader [module name] valueG)
- (-> Library java/lang/ClassLoader Symbol (Bytecode Any) (Try [Text Any Definition]))
- (let [class_name (format (text.replaced .module_separator class_path_separator module)
- class_path_separator (name.normal name)
- "___" (%.nat (text#hash name)))]
+(def: (define! library loader context custom valueG)
+ (-> Library java/lang/ClassLoader Context (Maybe Text) (Bytecode Any) (Try [Text Any Definition]))
+ (let [class_name (maybe.else (..class_name context)
+ custom)]
(do try.monad
[[value definition] (evaluate! library loader class_name valueG)]
(in [class_name value definition]))))
(def: .public host
- (IO //runtime.Host)
+ (IO [java/lang/ClassLoader //runtime.Host])
(io (let [library (loader.new_library [])
loader (loader.memory library)]
- (: //runtime.Host
- (implementation
- (def: (evaluate! temp_label valueG)
- (let [eval_class (|> temp_label name.normal (text.replaced " " "$"))]
- (# try.monad each product.left
- (..evaluate! library loader eval_class valueG))))
-
- (def: execute!
- (..execute! library loader))
-
- (def: define!
- (..define! library loader)))))))
+ [loader
+ (: //runtime.Host
+ (implementation
+ (def: (evaluate context valueG)
+ (# try.monad each product.left
+ (..evaluate! library loader (class_name context) valueG)))
+
+ (def: execute
+ (..execute! library loader))
+
+ (def: define
+ (..define! library loader))
+
+ (def: (ingest context bytecode)
+ [(..class_name context) bytecode])
+
+ (def: (re_learn context custom [_ bytecode])
+ (io.run! (loader.store (maybe.else (..class_name context) custom) bytecode library)))
+
+ (def: (re_load context custom [directive_name bytecode])
+ (io.run!
+ (do (try.with io.monad)
+ [.let [class_name (maybe.else (..class_name context)
+ custom)]
+ _ (loader.store class_name bytecode library)
+ class (loader.load class_name loader)]
+ (# io.monad in (..class_value class_name class)))))
+ ))])))
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/program.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/program.lux
index cea2a90f6..d788e3526 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/program.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/program.lux
@@ -20,14 +20,17 @@
[encoding
["[0]" name]]
["[0]" type
- ["[0]" reflection]]]]]]
+ ["[0]" reflection]]]]
+ [tool
+ [compiler
+ [language
+ [lux
+ [generation {"+" Context}]
+ [program {"+" Program}]]]]]]]
["[0]" //
["[1][0]" runtime {"+" Definition}]
["[1][0]" function/abstract]])
-(def: .public class
- "LuxProgram")
-
(def: ^Object
(type.class "java.lang.Object" (list)))
@@ -37,7 +40,8 @@
(def: ^Args
(type.array ^String))
-(def: main::type (type.method [(list ..^Args) type.void (list)]))
+(def: main::type
+ (type.method [(list) (list ..^Args) type.void (list)]))
(def: main::modifier
(Modifier Method)
@@ -128,8 +132,8 @@
_.aconst_null
//runtime.apply))
-(def: .public (program program)
- (-> (Bytecode Any) Definition)
+(def: .public (program artifact_name context program)
+ (-> (-> Context Text) (Program (Bytecode Any) Definition))
(let [super_class (|> ..^Object type.reflection reflection.reflection name.internal)
main (method.method ..main::modifier "main" ..main::type
(list)
@@ -138,13 +142,14 @@
..input_list
..feed_inputs
..run_io
- _.return)})]
- [..class
+ _.return)})
+ class (artifact_name context)]
+ [class
(<| (format.result class.writer)
try.trusted
(class.class version.v6_0
..program::modifier
- (name.internal ..class)
+ (name.internal class)
super_class
(list)
(list)
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/runtime.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/runtime.lux
index 99dbb01aa..c753851bc 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/runtime.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/jvm/runtime.lux
@@ -1,63 +1,65 @@
(.using
- [library
- [lux {"-" Type Definition Label case false true try}
- [abstract
- ["[0]" monad {"+" do}]
- ["[0]" enum]]
- [control
- ["[0]" try]]
- [data
- [binary {"+" Binary}]
- [collection
- ["[0]" list ("[1]#[0]" functor)]
- ["[0]" sequence]]
- ["[0]" format "_"
- ["[1]" binary]]
- [text
- ["%" format {"+" format}]]]
- [math
- [number
- ["n" nat]
- ["[0]" i32]
- ["[0]" i64]]]
- [target
- ["[0]" jvm "_"
- ["_" bytecode {"+" Label Bytecode}]
- ["[0]" modifier {"+" Modifier} ("[1]#[0]" monoid)]
- ["[0]" field {"+" Field}]
- ["[0]" method {"+" Method}]
- ["[1]/[0]" version]
- ["[0]" class {"+" Class}]
- ["[0]" constant
- [pool {"+" Resource}]]
- [encoding
- ["[0]" name]]
- ["[0]" type {"+" Type}
- ["[0]" category {"+" Return' Value'}]
- ["[0]" reflection]]]]]]
- ["[0]" // "_"
- ["[1][0]" type]
- ["[1][0]" value]
- ["[1][0]" function "_"
- ["[1]" abstract]
- [field
- [constant
- ["[1]/[0]" arity]]
- [variable
- ["[1]/[0]" count]]]]
- ["//[1]" /// "_"
- [//
- ["[0]" version]
- ["[0]" synthesis]
- ["[0]" generation]
- [///
- ["[1]" phase]
- [arity {"+" Arity}]
- [reference
- [variable {"+" Register}]]
- [meta
- [io {"+" lux_context}]
- [archive {"+" Archive}]]]]]])
+ [library
+ [lux {"-" Type Definition Label case false true try}
+ [abstract
+ ["[0]" monad {"+" do}]
+ ["[0]" enum]]
+ [control
+ ["[0]" try]]
+ [data
+ [binary {"+" Binary}]
+ ["[0]" product]
+ [collection
+ ["[0]" list ("[1]#[0]" functor)]
+ ["[0]" sequence]]
+ ["[0]" format "_"
+ ["[1]" binary]]
+ [text
+ ["%" format {"+" format}]]]
+ [math
+ [number
+ ["n" nat]
+ ["[0]" i32]
+ ["[0]" i64]]]
+ [target
+ ["[0]" jvm "_"
+ ["_" bytecode {"+" Label Bytecode}]
+ ["[0]" modifier {"+" Modifier} ("[1]#[0]" monoid)]
+ ["[0]" field {"+" Field}]
+ ["[0]" method {"+" Method}]
+ ["[1]/[0]" version]
+ ["[0]" class {"+" Class}]
+ ["[0]" constant
+ [pool {"+" Resource}]]
+ [encoding
+ ["[0]" name]]
+ ["[0]" type {"+" Type}
+ ["[0]" category {"+" Return' Value'}]
+ ["[0]" reflection]]]]]]
+ ["[0]" // "_"
+ ["[1][0]" type]
+ ["[1][0]" value]
+ ["[1][0]" function "_"
+ ["[1]" abstract]
+ [field
+ [constant
+ ["[1]/[0]" arity]]
+ [variable
+ ["[1]/[0]" count]]]]
+ ["//[1]" /// "_"
+ [//
+ ["[0]" version]
+ ["[0]" synthesis]
+ ["[0]" generation]
+ [///
+ ["[1]" phase]
+ [arity {"+" Arity}]
+ [reference
+ [variable {"+" Register}]]
+ [meta
+ [io {"+" lux_context}]
+ [archive {"+" Output Archive}
+ ["[0]" artifact {"+" Registry}]]]]]]])
(type: .public Byte_Code
Binary)
@@ -76,6 +78,7 @@
[Phase generation.Phase]
[Handler generation.Handler]
[Bundle generation.Bundle]
+ [Extender generation.Extender]
)
(type: .public (Generator i)
@@ -511,7 +514,7 @@
(def: ^Object (type.class "java.lang.Object" (list)))
(def: generate_runtime
- (Operation Any)
+ (Operation [artifact.ID (Maybe Text) Binary])
(let [class (..reflection ..class)
modifier (: (Modifier Class)
($_ modifier#composite
@@ -538,8 +541,9 @@
..try::method))
(sequence.sequence)))]
(do ////.monad
- [_ (generation.execute! [class bytecode])]
- (generation.save! ..artifact_id {.#None} [class bytecode]))))
+ [_ (generation.execute! [class bytecode])
+ _ (generation.save! ..artifact_id {.#None} [class bytecode])]
+ (in [..artifact_id {.#None} bytecode]))))
(def: generate_function
(Operation Any)
@@ -599,10 +603,20 @@
(generation.save! //function.artifact_id {.#None} [class bytecode]))))
(def: .public generate
- (Operation Any)
+ (Operation [Registry Output])
(do ////.monad
- [_ ..generate_runtime]
- ..generate_function))
+ [runtime_payload ..generate_runtime
+ ... _ ..generate_function
+ ]
+ (in [(|> artifact.empty
+ (artifact.resource .true artifact.no_dependencies)
+ product.right
+ ... (artifact.resource .true artifact.no_dependencies)
+ ... product.right
+ )
+ (sequence.sequence runtime_payload
+ ... function_payload
+ )])))
(def: .public forge_label
(Operation Label)
diff --git a/stdlib/source/test/lux.lux b/stdlib/source/test/lux.lux
index c200a0316..86ed33be3 100644
--- a/stdlib/source/test/lux.lux
+++ b/stdlib/source/test/lux.lux
@@ -56,7 +56,7 @@
["[1][0]" target]
["[1][0]" test]
["[1][0]" time]
- ... ["[1][0]" tool] ... TODO: Update & expand tests for this
+ ["[1][0]" tool]
["[1][0]" type]
["[1][0]" world]
["[1][0]" ffi]
@@ -97,7 +97,7 @@
/target.test
/test.test
/time.test
- ... /tool.test
+ /tool.test
/type.test
/world.test
/ffi.test
diff --git a/stdlib/source/test/lux/data/collection/array.lux b/stdlib/source/test/lux/data/collection/array.lux
index d9e3f01c2..2eca1688b 100644
--- a/stdlib/source/test/lux/data/collection/array.lux
+++ b/stdlib/source/test/lux/data/collection/array.lux
@@ -1,27 +1,28 @@
(.using
- [library
- [lux "*"
- ["_" test {"+" Test}]
- [abstract
- [monad {"+" do}]
- [\\specification
- ["$[0]" equivalence]
- ["$[0]" monoid]
- ["$[0]" mix]
- ["$[0]" functor {"+" Injection}]]]
- [control
- ["[0]" maybe]]
- [data
- ["[0]" bit]
- [collection
- ["[0]" list]
- ["[0]" set]]]
- [math
- ["[0]" random {"+" Random}]
- [number
- ["n" nat]]]]]
- [\\library
- ["[0]" / {"+" Array}]])
+ [library
+ [lux "*"
+ ["_" test {"+" Test}]
+ [abstract
+ [monad {"+" do}]
+ [\\specification
+ ["$[0]" equivalence]
+ ["$[0]" monoid]
+ ["$[0]" mix]
+ ["$[0]" functor {"+" Injection}]]]
+ [control
+ ["[0]" maybe]]
+ [data
+ ["[0]" bit]
+ ["[0]" text ("[1]#[0]" equivalence)]
+ [collection
+ ["[0]" list]
+ ["[0]" set]]]
+ [math
+ ["[0]" random {"+" Random}]
+ [number
+ ["n" nat]]]]]
+ [\\library
+ ["[0]" / {"+" Array}]])
(def: injection
(Injection Array)
@@ -29,7 +30,7 @@
(def: bounded_size
(Random Nat)
- (# random.monad each (|>> (n.% 100) (n.+ 1))
+ (# random.monad each (|>> (n.% 20) ++)
random.nat))
(def: structures
@@ -54,8 +55,28 @@
base random.nat
shift random.nat
.let [expected (n.+ base shift)]
- the_array (random.array size random.nat)]
+ the_array (random.array size random.nat)
+ evens (random.array size (random.only n.even? random.nat))]
($_ _.and
+ (let [(^open "/#[0]") /.functor
+ choose (: (-> Nat (Maybe Text))
+ (function (_ value)
+ (if (n.even? value)
+ {.#Some (# n.decimal encoded value)}
+ {.#None})))]
+ (_.cover [/.one]
+ (case [(|> evens
+ (/#each (# n.decimal encoded))
+ (/.read! 0))
+ (/.one choose evens)]
+ [{.#Some expected} {.#Some actual}]
+ (text#= expected actual)
+
+ [{.#None} {.#None}]
+ true
+
+ _
+ false)))
(_.cover [/.example]
(# (maybe.equivalence n.equivalence) =
(/.example n.even? the_array)
diff --git a/stdlib/source/test/lux/tool.lux b/stdlib/source/test/lux/tool.lux
index 3a9f547cd..5a7509b99 100644
--- a/stdlib/source/test/lux/tool.lux
+++ b/stdlib/source/test/lux/tool.lux
@@ -4,17 +4,20 @@
["_" test {"+" Test}]]]
["[0]" / "_"
[compiler
- [language
- [lux
- ["[1][0]" syntax]
- [phase
- ["[1][0]" analysis]
- ["[1][0]" synthesis]]]]]])
+ ["[1][0]" arity]
+ ... [language
+ ... [lux
+ ... ["[1][0]" syntax]
+ ... [phase
+ ... ["[1][0]" analysis]
+ ... ["[1][0]" synthesis]]]]
+ ]])
(def: .public test
Test
($_ _.and
- /syntax.test
- /analysis.test
- /synthesis.test
+ /arity.test
+ ... /syntax.test
+ ... /analysis.test
+ ... /synthesis.test
))
diff --git a/stdlib/source/test/lux/tool/compiler/arity.lux b/stdlib/source/test/lux/tool/compiler/arity.lux
new file mode 100644
index 000000000..0e9f3f25d
--- /dev/null
+++ b/stdlib/source/test/lux/tool/compiler/arity.lux
@@ -0,0 +1,29 @@
+(.using
+ [library
+ [lux "*"
+ ["_" test {"+" Test}]
+ [abstract
+ [monad {"+" do}]]
+ [data
+ ["[0]" bit ("[1]#[0]" equivalence)]]
+ [math
+ ["[0]" random {"+" Random}]
+ [number
+ ["n" nat]]]]]
+ [\\library
+ ["[0]" /]])
+
+(def: .public test
+ Test
+ (<| (_.covering /._)
+ (_.for [/.Arity])
+ (do [! random.monad]
+ [arity (# ! each (n.% 3) random.nat)]
+ ($_ _.and
+ (_.cover [/.nullary?]
+ (bit#= (n.= 0 arity) (/.nullary? arity)))
+ (_.cover [/.unary?]
+ (bit#= (n.= 1 arity) (/.unary? arity)))
+ (_.cover [/.multiary?]
+ (bit#= (n.>= 2 arity) (/.multiary? arity)))
+ ))))