aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--documentation/bookmark/error_messages.md1
-rw-r--r--documentation/bookmark/scheduling.md4
-rw-r--r--documentation/bookmark/tool/text_editor.md1
-rw-r--r--lux-jvm/source/luxc/lang/directive/jvm.lux48
-rw-r--r--lux-jvm/source/luxc/lang/translation/jvm/extension/host.lux287
-rw-r--r--lux-jvm/source/luxc/lang/translation/jvm/function.lux6
-rw-r--r--lux-jvm/source/luxc/lang/translation/jvm/runtime.lux10
-rw-r--r--stdlib/commands.md4
-rw-r--r--stdlib/source/library/lux/data/collection/dictionary.lux46
-rw-r--r--stdlib/source/library/lux/program.lux47
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/generation.lux128
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux113
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux6
-rw-r--r--stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux15
-rw-r--r--stdlib/source/library/lux/tool/compiler/meta/archive.lux9
-rw-r--r--stdlib/source/library/lux/tool/compiler/meta/archive/artifact.lux107
-rw-r--r--stdlib/source/library/lux/tool/compiler/meta/archive/dependency.lux215
-rw-r--r--stdlib/source/library/lux/tool/compiler/meta/cache/dependency.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/meta/io/archive.lux2
-rw-r--r--stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux25
-rw-r--r--stdlib/source/test/lux/extension.lux5
21 files changed, 728 insertions, 353 deletions
diff --git a/documentation/bookmark/error_messages.md b/documentation/bookmark/error_messages.md
index 9ad8c04f2..f3b7a3120 100644
--- a/documentation/bookmark/error_messages.md
+++ b/documentation/bookmark/error_messages.md
@@ -1,4 +1,5 @@
# Reference
+1. [Error Messages in Haskell, and how to Improve them](https://anthony.noided.media/blog/haskell/programming/2020/05/14/haskell-errors.html)
1. [The Futhark Error Index](https://futhark-lang.org/blog/2021-09-24-the-futhark-error-index.html)
diff --git a/documentation/bookmark/scheduling.md b/documentation/bookmark/scheduling.md
new file mode 100644
index 000000000..1b09091b6
--- /dev/null
+++ b/documentation/bookmark/scheduling.md
@@ -0,0 +1,4 @@
+# Reference
+
+1. [The Many Uses of Schedulers](https://eruhinim.com/post/many-uses-of-schedulers/)
+
diff --git a/documentation/bookmark/tool/text_editor.md b/documentation/bookmark/tool/text_editor.md
index 2142fa0be..f835ab41f 100644
--- a/documentation/bookmark/tool/text_editor.md
+++ b/documentation/bookmark/tool/text_editor.md
@@ -169,6 +169,7 @@
## General
+1. https://texteditors.org/cgi-bin/wiki.pl?EditorIndex
1. [Slate: A completely customizable framework for building rich text editors.](https://github.com/ianstormtaylor/slate)
1. [Trix: A rich text editor for everyday writing.](https://trix-editor.org/)
1. [Left](https://100r.co/site/left.html)
diff --git a/lux-jvm/source/luxc/lang/directive/jvm.lux b/lux-jvm/source/luxc/lang/directive/jvm.lux
index 60032010d..3c384b475 100644
--- a/lux-jvm/source/luxc/lang/directive/jvm.lux
+++ b/lux-jvm/source/luxc/lang/directive/jvm.lux
@@ -20,7 +20,8 @@
[array {"+" Array}]
["[0]" list ("[1]#[0]" mix functor monoid)]
["[0]" dictionary {"+" Dictionary}]
- ["[0]" sequence {"+" Sequence} ("[1]#[0]" functor mix)]]]
+ ["[0]" sequence {"+" Sequence} ("[1]#[0]" functor mix)]
+ ["[0]" set {"+" Set}]]]
[math
[number
["[0]" nat]]]
@@ -28,7 +29,7 @@
["/" jvm
[encoding
["[0]" name {"+" External}]]
- ["[1][0]" type {"+" Type Constraint}
+ ["[1][0]" type {"+" Type Typed Constraint}
[category {"+" Void Value Return Primitive Object Class Var Parameter}]
["[0]" parser]
["[0]T" lux]
@@ -54,7 +55,9 @@
[directive
["[0]/" lux]]]]]]
[meta
- [archive {"+" Archive}]]]]]]
+ [archive {"+" Archive}
+ ["[0]" artifact]
+ ["[0]" dependency]]]]]]]
[///
[host
["[0]" jvm {"+" Inst}
@@ -692,7 +695,7 @@
(type: (Constructor a)
[Privacy Bit (List Annotation) (List (Type Var)) (List (Type Class))
- Text (List Argument) (List [(Type Value) a])
+ Text (List Argument) (List (Typed a))
a])
(type: (Override a)
@@ -722,6 +725,35 @@
{#Static (Static a)}
{#Abstract Abstract}))
+(def: (method_dependencies archive method)
+ (-> Archive (Method Synthesis)
+ (generation.Operation jvm.Anchor jvm.Inst jvm.Definition
+ (Set artifact.Dependency)))
+ (case method
+ {#Constructor [privacy strict_floating_point? annotations variables exceptions
+ self arguments constructor_arguments
+ body]}
+ (do [! phase.monad]
+ [all_super_ctor_dependencies (monad.each ! (|>> product.right (dependency.dependencies archive))
+ constructor_arguments)
+ body_dependencies (dependency.dependencies archive body)]
+ (in (dependency.all (list& body_dependencies all_super_ctor_dependencies))))
+
+
+ (^or {#Override [[parent_name parent_variables] name strict_floating_point? annotations variables
+ self arguments return exceptions
+ body]}
+ {#Virtual [name privacy final? strict_floating_point? annotations variables
+ self arguments return exceptions
+ body]}
+ {#Static [name privacy strict_floating_point? annotations variables
+ arguments return exceptions
+ body]})
+ (dependency.dependencies archive body)
+
+ {#Abstract _}
+ (# phase.monad in artifact.no_dependencies)))
+
(def: constructor
(Parser (Constructor Code))
(let [constructor_argument (: (Parser [(Type Value) Code])
@@ -1434,6 +1466,10 @@
methodsA (monad.each ! (method_analysis archive declaration supers) methodsC)
methodsS (monad.each ! (method_synthesis archive) methodsA)
methodsG (monad.each ! (method_generation archive super_class) methodsS)
+ all_dependencies (|> methodsS
+ (monad.each ! (method_dependencies archive))
+ (# ! each dependency.all)
+ directive.lifted_generation)
.let [directive [class_name
(def.class {jvm.#V1_6} {jvm.#Public} jvm.noneC class_name
(list#each ..constraint type_variables)
@@ -1443,7 +1479,7 @@
methodsG)))]]]
(directive.lifted_generation
(do !
- [artifact_id (generation.learn_custom class_name)
+ [artifact_id (generation.learn_custom class_name all_dependencies)
_ (generation.execute! directive)
_ (generation.save! artifact_id {.#Some class_name} directive)
_ (generation.log! (format "JVM Class " (%.text class_name)))]
@@ -1470,7 +1506,7 @@
def.fuse))]]]
(directive.lifted_generation
(do !
- [artifact_id (generation.learn_custom class_name)
+ [artifact_id (generation.learn_custom class_name artifact.no_dependencies)
_ (generation.execute! directive)
_ (generation.save! artifact_id {.#Some class_name} directive)
_ (generation.log! (format "JVM Interface " (%.text class_name)))]
diff --git a/lux-jvm/source/luxc/lang/translation/jvm/extension/host.lux b/lux-jvm/source/luxc/lang/translation/jvm/extension/host.lux
index bbc8920f6..ee4096fe1 100644
--- a/lux-jvm/source/luxc/lang/translation/jvm/extension/host.lux
+++ b/lux-jvm/source/luxc/lang/translation/jvm/extension/host.lux
@@ -1,71 +1,73 @@
(.using
- [library
- [lux {"-" Type Label Primitive int char type}
- [ffi {"+" import:}]
- [abstract
- ["[0]" monad {"+" do}]]
- [control
- ["[0]" maybe ("[1]#[0]" functor)]
- ["[0]" exception {"+" exception:}]
- ["[0]" function]
- ["<>" parser ("[1]#[0]" monad)
- ["<[0]>" text]
- ["<[0]>" synthesis {"+" Parser}]]]
- [data
- ["[0]" product]
- ["[0]" text ("[1]#[0]" equivalence)
- ["%" format {"+" format}]]
- [collection
- ["[0]" list ("[1]#[0]" monad mix)]
- ["[0]" dictionary {"+" Dictionary}]
- ["[0]" set]]]
- [macro
- ["[0]" template]]
- [math
- [number
- ["n" nat]]]
- [target
- [jvm
- ["[0]" type {"+" Type Typed Argument}
- ["[0]" category {"+" Void Value Return Primitive Object Class Array Var Parameter Method}]
- ["[0]" box]
- ["[0]" reflection]
- ["[0]" signature]
- ["[0]" descriptor]
- ["[0]" parser]]]]
- [tool
- [compiler
- ["[0]" phase ("[1]#[0]" monad)]
- [reference {"+" }
- ["[0]" variable {"+" Variable Register}]]
- [meta
- [archive {"+" Archive}]]
- [language
- [lux
- [analysis {"+" Environment}]
- ["[0]" synthesis {"+" Synthesis Path %synthesis}]
- ["[0]" generation]
- [phase
- [generation
- [extension {"+" Nullary Unary Binary
- nullary unary binary}]]
+ [library
+ [lux {"-" Type Label Primitive int char type}
+ [ffi {"+" import:}]
+ [abstract
+ ["[0]" monad {"+" do}]]
+ [control
+ ["[0]" maybe ("[1]#[0]" functor)]
+ ["[0]" exception {"+" exception:}]
+ ["[0]" function]
+ ["<>" parser ("[1]#[0]" monad)
+ ["<[0]>" text]
+ ["<[0]>" synthesis {"+" Parser}]]]
+ [data
+ ["[0]" product]
+ ["[0]" text ("[1]#[0]" equivalence)
+ ["%" format {"+" format}]]
+ [collection
+ ["[0]" list ("[1]#[0]" monoid mix monad)]
+ ["[0]" dictionary {"+" Dictionary}]
+ ["[0]" set {"+" Set}]]]
+ [macro
+ ["[0]" template]]
+ [math
+ [number
+ ["n" nat]]]
+ [target
+ [jvm
+ ["[0]" type {"+" Type Typed Argument}
+ ["[0]" category {"+" Void Value Return Primitive Object Class Array Var Parameter Method}]
+ ["[0]" box]
+ ["[0]" reflection]
+ ["[0]" signature]
+ ["[0]" descriptor]
+ ["[0]" parser]]]]
+ [tool
+ [compiler
+ ["[0]" phase ("[1]#[0]" monad)]
+ [reference {"+" }
+ ["[0]" variable {"+" Variable Register}]]
+ [meta
+ [archive {"+" Archive}
+ ["[0]" artifact]
+ ["[0]" dependency]]]
+ [language
+ [lux
+ [analysis {"+" Environment}]
+ ["[0]" synthesis {"+" Synthesis Path %synthesis}]
+ ["[0]" generation]
+ [phase
+ [generation
+ [extension {"+" Nullary Unary Binary
+ nullary unary binary}]]
+ [analysis
+ ["[0]A" reference]]
+ ["[0]" extension
+ ["[0]" bundle]
[analysis
- ["[0]A" reference]]
- ["[0]" extension
- ["[0]" bundle]
- [analysis
- ["/" jvm]]]]]]]]]]
- [luxc
- [lang
- [host
- ["$" jvm {"+" Label Inst Def Handler Bundle Operation Phase}
- ["_" inst]
- ["_[0]" def]]]]]
- ["[0]" // "_"
- [common {"+" custom}]
- ["/[1]" //
- ["[1][0]" reference]
- ["[1][0]" function]]])
+ ["/" jvm]]]]]]]]]]
+ [luxc
+ [lang
+ [host
+ ["$" jvm {"+" Label Inst Def Handler Bundle Operation Phase}
+ ["_" inst]
+ ["_[0]" def]]]]]
+ ["[0]" // "_"
+ [common {"+" custom}]
+ ["/[1]" //
+ ["[1][0]" reference]
+ ["[1][0]" function]]])
(template [<name> <category> <parser>]
[(def: .public <name>
@@ -1073,6 +1075,13 @@
... (# type.equivalence = type.double returnT)
(unwrap_primitive _.DRETURN type.double)))))))
+(def: (method_dependencies archive method)
+ (-> Archive (/.Overriden_Method Synthesis) (Operation (Set artifact.Dependency)))
+ (let [[_super _name _strict_fp? _annotations
+ _t_vars _this _arguments _return _exceptions
+ bodyS] method]
+ (dependency.dependencies archive bodyS)))
+
(def: class::anonymous
Handler
(..custom
@@ -1086,72 +1095,86 @@
inputsTS
overriden_methods])
(do [! phase.monad]
- [[context _] (generation.with_new_context archive (in []))
- .let [[module_id artifact_id] context
- anonymous_class_name (///.class_name context)
- class (type.class anonymous_class_name (list))
- total_environment (|> overriden_methods
- ... Get all the environments.
- (list#each product.left)
- ... Combine them.
- list#conjoint
- ... Remove duplicates.
- (set.of_list synthesis.hash)
- set.list)
- global_mapping (|> total_environment
- ... Give them names as "foreign" variables.
- list.enumeration
- (list#each (function (_ [id capture])
- [capture {variable.#Foreign id}]))
- (dictionary.of_list synthesis.hash))
- normalized_methods (list#each (function (_ [environment
- [ownerT name
- strict_fp? annotations vars
- self_name arguments returnT exceptionsT
- body]])
- (let [local_mapping (|> environment
- list.enumeration
- (list#each (function (_ [foreign_id capture])
- [(synthesis.variable/foreign foreign_id)
- (|> global_mapping
- (dictionary.value capture)
- maybe.trusted)]))
- (dictionary.of_list synthesis.hash))]
- [ownerT name
- strict_fp? annotations vars
- self_name arguments returnT exceptionsT
- (normalize_method_body local_mapping body)]))
- overriden_methods)]
- inputsTI (monad.each ! (generate_input generate archive) inputsTS)
- method_definitions (|> normalized_methods
- (monad.each ! (function (_ [ownerT name
- strict_fp? annotations varsT
- self_name arguments returnT exceptionsT
- bodyS])
- (do !
- [bodyG (generation.with_context artifact_id
- (generate archive bodyS))
- .let [argumentsT (list#each product.right arguments)]]
- (in (_def.method {$.#Public}
- (if strict_fp?
- ($_ $.++M $.finalM $.strictM)
- $.finalM)
- name
- (type.method [varsT argumentsT returnT exceptionsT])
- (|>> (prepare_arguments 1 argumentsT)
- bodyG
- (returnI returnT)))))))
- (# ! each _def.fuse))
- .let [directive [anonymous_class_name
- (_def.class {$.#V1_6} {$.#Public} $.finalC
- anonymous_class_name (list)
- super_class super_interfaces
- (|>> (///function.with_environment total_environment)
- (..with_anonymous_init class total_environment super_class inputsTI)
- method_definitions))]]
- _ (generation.execute! directive)
- _ (generation.save! artifact_id {.#None} directive)]
- (..anonymous_instance generate archive class total_environment)))]))
+ [all_input_dependencies (monad.each ! (|>> product.right (dependency.dependencies archive)) inputsTS)
+ all_closure_dependencies (|> overriden_methods
+ (list#each product.left)
+ list.together
+ (monad.each ! (dependency.dependencies archive)))
+ all_method_dependencies (monad.each ! (|>> product.right (method_dependencies archive)) overriden_methods)
+ .let [all_dependencies (dependency.all ($_ list#composite
+ all_input_dependencies
+ all_closure_dependencies
+ all_method_dependencies))]]
+ (do [! phase.monad]
+ [[context _] (generation.with_new_context
+ archive
+ all_dependencies
+ (in []))
+ .let [[module_id artifact_id] context
+ anonymous_class_name (///.class_name context)
+ class (type.class anonymous_class_name (list))
+ total_environment (|> overriden_methods
+ ... Get all the environments.
+ (list#each product.left)
+ ... Combine them.
+ list#conjoint
+ ... Remove duplicates.
+ (set.of_list synthesis.hash)
+ set.list)
+ global_mapping (|> total_environment
+ ... Give them names as "foreign" variables.
+ list.enumeration
+ (list#each (function (_ [id capture])
+ [capture {variable.#Foreign id}]))
+ (dictionary.of_list synthesis.hash))
+ normalized_methods (list#each (function (_ [environment
+ [ownerT name
+ strict_fp? annotations vars
+ self_name arguments returnT exceptionsT
+ body]])
+ (let [local_mapping (|> environment
+ list.enumeration
+ (list#each (function (_ [foreign_id capture])
+ [(synthesis.variable/foreign foreign_id)
+ (|> global_mapping
+ (dictionary.value capture)
+ maybe.trusted)]))
+ (dictionary.of_list synthesis.hash))]
+ [ownerT name
+ strict_fp? annotations vars
+ self_name arguments returnT exceptionsT
+ (normalize_method_body local_mapping body)]))
+ overriden_methods)]
+ inputsTI (monad.each ! (generate_input generate archive) inputsTS)
+ method_definitions (|> normalized_methods
+ (monad.each ! (function (_ [ownerT name
+ strict_fp? annotations varsT
+ self_name arguments returnT exceptionsT
+ bodyS])
+ (do !
+ [bodyG (generation.with_context artifact_id
+ (generate archive bodyS))
+ .let [argumentsT (list#each product.right arguments)]]
+ (in (_def.method {$.#Public}
+ (if strict_fp?
+ ($_ $.++M $.finalM $.strictM)
+ $.finalM)
+ name
+ (type.method [varsT argumentsT returnT exceptionsT])
+ (|>> (prepare_arguments 1 argumentsT)
+ bodyG
+ (returnI returnT)))))))
+ (# ! each _def.fuse))
+ .let [directive [anonymous_class_name
+ (_def.class {$.#V1_6} {$.#Public} $.finalC
+ anonymous_class_name (list)
+ super_class super_interfaces
+ (|>> (///function.with_environment total_environment)
+ (..with_anonymous_init class total_environment super_class inputsTI)
+ method_definitions))]]
+ _ (generation.execute! directive)
+ _ (generation.save! artifact_id {.#None} directive)]
+ (..anonymous_instance generate archive class total_environment))))]))
(def: class_bundle
Bundle
diff --git a/lux-jvm/source/luxc/lang/translation/jvm/function.lux b/lux-jvm/source/luxc/lang/translation/jvm/function.lux
index 6d2d3e8f9..7932360a3 100644
--- a/lux-jvm/source/luxc/lang/translation/jvm/function.lux
+++ b/lux-jvm/source/luxc/lang/translation/jvm/function.lux
@@ -33,7 +33,8 @@
[synthesis {"+" Synthesis Abstraction Apply}]
["[0]" generation {"+" Context}]]]
[meta
- [archive {"+" Archive}]]]]]]
+ [archive {"+" Archive}
+ ["[0]" dependency]]]]]]]
[luxc
[lang
[host
@@ -307,6 +308,7 @@
(-> (Maybe Context) (Generator Abstraction))
(do [! phase.monad]
[@begin _.make_label
+ dependencies (dependency.dependencies archive bodyS)
[function_context bodyI] (case forced_context
{.#Some function_context}
(do !
@@ -316,7 +318,7 @@
without_context]))
{.#None}
- (generation.with_new_context archive
+ (generation.with_new_context archive dependencies
(generation.with_anchor [@begin 1]
(generate archive bodyS))))
.let [function_class (//.class_name function_context)]
diff --git a/lux-jvm/source/luxc/lang/translation/jvm/runtime.lux b/lux-jvm/source/luxc/lang/translation/jvm/runtime.lux
index dc2cb5053..33cf199ea 100644
--- a/lux-jvm/source/luxc/lang/translation/jvm/runtime.lux
+++ b/lux-jvm/source/luxc/lang/translation/jvm/runtime.lux
@@ -11,7 +11,8 @@
["%" format {"+" format}]]
[collection
["[0]" list ("[1]@[0]" functor)]
- ["[0]" sequence]]]
+ ["[0]" sequence]
+ ["[0]" set]]]
["[0]" math
[number
["n" nat]]]
@@ -411,10 +412,11 @@
... function_payload ..translate_function
]
(in [(|> artifact.empty
- artifact.resource
+ (artifact.resource true artifact.no_dependencies)
product.right
- artifact.resource
- product.right)
+ ... (artifact.resource true artifact.no_dependencies)
+ ... product.right
+ )
(sequence.sequence runtime_payload
... function_payload
)])))
diff --git a/stdlib/commands.md b/stdlib/commands.md
index 37241c077..79982596b 100644
--- a/stdlib/commands.md
+++ b/stdlib/commands.md
@@ -36,8 +36,8 @@ cd ~/lux/stdlib/ && lein install
cd ~/lux/stdlib/ && mvn install:install-file -Dfile=target/library.tar -DgroupId=com.github.luxlang -DartifactId=stdlib -Dversion=0.6.0-SNAPSHOT -Dpackaging=tar
cd ~/lux/stdlib/ && mvn deploy:deploy-file \
--Durl=https://<username>:<password>@oss.sonatype.org/content/repositories/snapshots/ \
--Dfile=target/library.tar \
+-Durl=https://USERNAME:PASSWORD@oss.sonatype.org/content/repositories/snapshots/ \
+-Dfile=library.tar \
-DgroupId=com.github.luxlang \
-DartifactId=stdlib \
-Dversion=0.6.5-SNAPSHOT \
diff --git a/stdlib/source/library/lux/data/collection/dictionary.lux b/stdlib/source/library/lux/data/collection/dictionary.lux
index ac9fe8002..ee7b7cb7d 100644
--- a/stdlib/source/library/lux/data/collection/dictionary.lux
+++ b/stdlib/source/library/lux/data/collection/dictionary.lux
@@ -534,29 +534,34 @@
(array.size colls)
))
-(def: (node#entries node)
- (All (_ k v) (-> (Node k v) (List [k v])))
+(def: (node#mix f init node)
+ (All (_ k v a) (-> (-> [k v] a a) a (Node k v) a))
(case node
{#Hierarchy _size hierarchy}
- (array#mix (function (_ sub_node tail) (list#composite (node#entries sub_node) tail))
- {.#End}
+ (array#mix (function (_ sub_node current)
+ (node#mix f current sub_node))
+ init
hierarchy)
{#Base bitmap base}
- (array#mix (function (_ branch tail)
+ (array#mix (function (_ branch current)
(case branch
{.#Left sub_node}
- (list#composite (node#entries sub_node) tail)
+ (node#mix f current sub_node)
- {.#Right [key' val']}
- {.#Item [key' val'] tail}))
- {.#End}
+ {.#Right kv}
+ (f kv current)))
+ init
base)
{#Collisions hash colls}
- (array#mix (function (_ [key' val'] tail) {.#Item [key' val'] tail})
- {.#End}
- colls)))
+ (array#mix f init colls)))
+
+(def: node#entries
+ (All (_ k v) (-> (Node k v) (List [k v])))
+ (node#mix (function (_ head tail)
+ {.#Item head tail})
+ {.#End}))
(type: .public (Dictionary k v)
(Record
@@ -619,7 +624,7 @@
(def: .public size
(All (_ k v) (-> (Dictionary k v) Nat))
- (|>> product.right ..node#size))
+ (|>> (value@ #root) ..node#size))
(def: .public empty?
(All (_ k v) (-> (Dictionary k v) Bit))
@@ -627,7 +632,7 @@
(def: .public entries
(All (_ k v) (-> (Dictionary k v) (List [k v])))
- (|>> product.right ..node#entries))
+ (|>> (value@ #root) ..node#entries))
(def: .public (of_list key_hash kvs)
(All (_ k v) (-> (Hash k) (List [k v]) (Dictionary k v)))
@@ -639,8 +644,8 @@
(template [<side> <name>]
[(def: .public <name>
(All (_ k v) (-> (Dictionary k v) (List <side>)))
- (|>> ..entries
- (list#mix (function (_ [k v] bundle)
+ (|>> (value@ #root)
+ (node#mix (function (_ [k v] bundle)
{.#Item <side> bundle})
{.#End})))]
@@ -650,13 +655,14 @@
(def: .public (merged dict2 dict1)
(All (_ k v) (-> (Dictionary k v) (Dictionary k v) (Dictionary k v)))
- (list#mix (function (_ [key val] dict) (has key val dict))
+ (node#mix (function (_ [key val] dict)
+ (has key val dict))
dict1
- (entries dict2)))
+ (value@ #root dict2)))
(def: .public (merged_with f dict2 dict1)
(All (_ k v) (-> (-> v v v) (Dictionary k v) (Dictionary k v) (Dictionary k v)))
- (list#mix (function (_ [key val2] dict)
+ (node#mix (function (_ [key val2] dict)
(case (value key dict)
{.#None}
(has key val2 dict)
@@ -664,7 +670,7 @@
{.#Some val1}
(has key (f val2 val1) dict)))
dict1
- (entries dict2)))
+ (value@ #root dict2)))
(def: .public (re_bound from_key to_key dict)
(All (_ k v) (-> k k (Dictionary k v) (Dictionary k v)))
diff --git a/stdlib/source/library/lux/program.lux b/stdlib/source/library/lux/program.lux
index 0d9576d79..469aa68e6 100644
--- a/stdlib/source/library/lux/program.lux
+++ b/stdlib/source/library/lux/program.lux
@@ -1,19 +1,19 @@
(.using
- [library
- [lux "*"
- ["@" target]
- [abstract
- [monad {"+" do}]]
- [control
- ["[0]" io]
- [concurrency
- ["[0]" thread]]
- ["<>" parser
- ["<[0]>" code]
- ["<[0]>" cli]]]
- [macro {"+" with_symbols}
- [syntax {"+" syntax:}]
- ["[0]" code]]]])
+ [library
+ [lux "*"
+ ["@" target]
+ [abstract
+ [monad {"+" do}]]
+ [control
+ ["[0]" io]
+ [concurrency
+ ["[0]" thread]]
+ ["<>" parser
+ ["<[0]>" code]
+ ["<[0]>" cli]]]
+ [macro {"+" with_symbols}
+ [syntax {"+" syntax:}]
+ ["[0]" code]]]])
(type: Arguments
(Variant
@@ -28,15 +28,14 @@
(syntax: .public (program: [args ..arguments^
body <code>.any])
(with_symbols [g!program g!args g!_ g!output g!message]
- (let [initialization+event_loop
- (` ((~! do) (~! io.monad)
- [(~ g!output) (~ body)
- (~+ (for [@.old (list)
- @.jvm (list)
- @.js (list)
- @.python (list)]
- (list g!_ (` (~! thread.run!)))))]
- ((~' in) (~ g!output))))]
+ (let [initialization+event_loop (for [@.old body
+ @.jvm body
+ @.js body
+ @.python body]
+ (` ((~! do) (~! io.monad)
+ [(~ g!output) (~ body)
+ (~ g!_) (~! thread.run!)]
+ ((~' in) (~ g!output)))))]
(in (list (` ("lux def program"
(~ (case args
{#Raw args}
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux b/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux
index b2a99c6a4..ac37f48aa 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/generation.lux
@@ -1,35 +1,38 @@
(.using
- [library
- [lux {"-" Module symbol}
- [abstract
- [monad {"+" do}]]
- [control
- ["[0]" try {"+" Try}]
- ["[0]" exception {"+" exception:}]
- ["[0]" function]]
- [data
- [binary {"+" Binary}]
- ["[0]" product]
- ["[0]" text ("[1]#[0]" equivalence)
- ["%" format {"+" format}]]
- [collection
- ["[0]" sequence {"+" Sequence}]
- ["[0]" list ("[1]#[0]" functor)]]]
- [math
- [number
- ["n" nat]]]
- [meta
- ["[0]" symbol]]]]
- [//
- [synthesis {"+" Synthesis}]
- [phase
- ["[0]" extension]]
- [///
- ["[0]" phase]
- [meta
- ["[0]" archive {"+" Archive}
- ["[0]" descriptor {"+" Module}]
- ["[0]" artifact]]]]])
+ [library
+ [lux {"-" Module symbol}
+ [abstract
+ [monad {"+" do}]]
+ [control
+ ["[0]" try {"+" Try}]
+ ["[0]" exception {"+" exception:}]
+ ["[0]" function]]
+ [data
+ [binary {"+" Binary}]
+ ["[0]" product]
+ ["[0]" text ("[1]#[0]" equivalence)
+ ["%" format {"+" format}]]
+ [collection
+ ["[0]" sequence {"+" Sequence}]
+ ["[0]" list ("[1]#[0]" functor mix)]
+ ["[0]" set {"+" Set}]]]
+ [macro
+ ["[0]" template]]
+ [math
+ [number
+ ["n" nat]]]
+ [meta
+ ["[0]" symbol]]]]
+ [//
+ [synthesis {"+" Synthesis}]
+ [phase
+ ["[0]" extension]]
+ [///
+ ["[0]" phase]
+ [meta
+ ["[0]" archive {"+" Archive}
+ ["[0]" descriptor {"+" Module}]
+ ["[0]" artifact]]]]])
(type: .public Context
[archive.ID artifact.ID])
@@ -75,7 +78,8 @@
#registry artifact.Registry
#counter Nat
#context (Maybe artifact.ID)
- #log (Sequence Text)]))
+ #log (Sequence Text)
+ #interim_artifacts (List artifact.ID)]))
(template [<special> <general>]
[(type: .public (<special> anchor expression directive)
@@ -101,7 +105,8 @@
#registry artifact.empty
#counter 0
#context {.#None}
- #log sequence.empty])
+ #log sequence.empty
+ #interim_artifacts (list)])
(def: .public empty_buffer
Buffer
@@ -241,21 +246,21 @@
{.#None}
(phase.except ..no_buffer_for_saving_code [artifact_id]))))
-(template [<name> <artifact>]
- [(def: .public (<name> name)
- (All (_ anchor expression directive)
- (-> Text (Operation anchor expression directive artifact.ID)))
- (function (_ (^@ stateE [bundle state]))
- (let [[id registry'] (<artifact> name (value@ #registry state))]
- {try.#Success [[bundle (with@ #registry registry' state)]
- id]})))]
-
- [learn artifact.definition]
- [learn_custom artifact.custom]
- [learn_analyser artifact.analyser]
- [learn_synthesizer artifact.synthesizer]
- [learn_generator artifact.generator]
- [learn_directive artifact.directive]
+(template [<mandatory?> <inputs> <input_types> <name> <artifact>]
+ [(`` (def: .public (<name> name (~~ (template.spliced <inputs>)) dependencies)
+ (All (_ anchor expression directive)
+ (-> Text (~~ (template.spliced <input_types>)) (Set artifact.Dependency) (Operation anchor expression directive artifact.ID)))
+ (function (_ (^@ stateE [bundle state]))
+ (let [[id registry'] (<artifact> name <mandatory?> dependencies (value@ #registry state))]
+ {try.#Success [[bundle (with@ #registry registry' state)]
+ id]}))))]
+
+ [mandatory? [mandatory?] [Bit] learn artifact.definition]
+ [#1 [] [] learn_custom artifact.custom]
+ [#0 [] [] learn_analyser artifact.analyser]
+ [#0 [] [] learn_synthesizer artifact.synthesizer]
+ [#0 [] [] learn_generator artifact.generator]
+ [#0 [] [] learn_directive artifact.directive]
)
(exception: .public (unknown_definition [name Symbol
@@ -318,16 +323,17 @@
(in [[bundle' (with@ #context (value@ #context state) state')]
output]))))
-(def: .public (with_new_context archive body)
+(def: .public (with_new_context archive dependencies body)
(All (_ anchor expression directive a)
- (-> Archive (Operation anchor expression directive a)
+ (-> Archive (Set artifact.Dependency) (Operation anchor expression directive a)
(Operation anchor expression directive [Context a])))
(function (_ (^@ stateE [bundle state]))
- (let [[id registry'] (artifact.resource (value@ #registry state))]
+ (let [[id registry'] (artifact.resource false dependencies (value@ #registry state))]
(do try.monad
[[[bundle' state'] output] (body [bundle (|> state
(with@ #registry registry')
- (with@ #context {.#Some id}))])
+ (with@ #context {.#Some id})
+ (revised@ #interim_artifacts (|>> {.#Item id})))])
module_id (archive.id (value@ #module state) archive)]
(in [[bundle' (with@ #context (value@ #context state) state')]
[[module_id id]
@@ -340,3 +346,21 @@
{try.#Success [[bundle
(revised@ #log (sequence.suffix message) state)]
[]]}))
+
+(def: .public (with_interim_artifacts archive body)
+ (All (_ anchor expression directive a)
+ (-> Archive (Operation anchor expression directive a)
+ (Operation anchor expression directive [(Set Context) a])))
+ (do phase.monad
+ [module (extension.read (value@ #module))]
+ (function (_ state+)
+ (do try.monad
+ [module_id (archive.id module archive)
+ [[bundle' state'] output] (body state+)]
+ (in [[bundle'
+ (with@ #interim_artifacts (list) state')]
+ [(list#mix (function (_ artifact_id dependencies)
+ (set.has [module_id artifact_id] dependencies))
+ artifact.no_dependencies
+ (value@ #interim_artifacts state'))
+ output]])))))
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux
index 12a13781c..49e889381 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/directive/lux.lux
@@ -1,51 +1,54 @@
(.using
- [library
- [lux "*"
- ["@" target]
- ["[0]" meta]
- [abstract
- ["[0]" monad {"+" do}]]
- [control
- [io {"+" IO}]
- ["[0]" try]
- ["[0]" exception {"+" exception:}]
- ["<>" parser
- ["<[0]>" code {"+" Parser}]]]
- [data
- ["[0]" binary]
- ["[0]" product]
- ["[0]" text
- ["%" format {"+" format}]]
- [collection
- ["[0]" dictionary]
- ["[0]" array]
- ["[0]" list ("[1]#[0]" functor)]]]
- [macro
- ["[0]" code]]
- [math
- [number
- ["n" nat]]]
- ["[0]" type {"+" :sharing} ("[1]#[0]" equivalence)
- ["[0]" check]]]]
- ["[0]" /// {"+" Extender}
- ["[1][0]" bundle]
- ["[1][0]" analysis]
+ [library
+ [lux "*"
+ ["@" target]
+ ["[0]" meta]
+ [abstract
+ ["[0]" monad {"+" do}]]
+ [control
+ [io {"+" IO}]
+ ["[0]" try]
+ ["[0]" exception {"+" exception:}]
+ ["<>" parser
+ ["<[0]>" code {"+" Parser}]]]
+ [data
+ ["[0]" binary]
+ ["[0]" product]
+ ["[0]" text
+ ["%" format {"+" format}]]
+ [collection
+ ["[0]" dictionary]
+ ["[0]" array]
+ ["[0]" list ("[1]#[0]" functor mix)]
+ ["[0]" set {"+" Set}]]]
+ [macro
+ ["[0]" code]]
+ [math
+ [number
+ ["n" nat]]]
+ ["[0]" type {"+" :sharing} ("[1]#[0]" equivalence)
+ ["[0]" check]]]]
+ ["[0]" /// {"+" Extender}
+ ["[1][0]" bundle]
+ ["[1][0]" analysis]
+ ["/[1]" // "_"
+ [analysis
+ ["[0]" module]
+ ["[0]A" type]]
["/[1]" // "_"
- [analysis
- ["[0]" module]
- ["[0]A" type]]
- ["/[1]" // "_"
- ["[1][0]" analysis
- [macro {"+" Expander}]
- ["[1]/[0]" evaluation]]
- ["[1][0]" synthesis {"+" Synthesis}]
- ["[1][0]" generation {"+" Context}]
- ["[1][0]" directive {"+" Import Requirements Phase Operation Handler Bundle}]
- ["[1][0]" program {"+" Program}]
- [///
- ["[0]" phase]
- [meta
- ["[0]" archive {"+" Archive}]]]]]])
+ ["[1][0]" analysis
+ [macro {"+" Expander}]
+ ["[1]/[0]" evaluation]]
+ ["[1][0]" synthesis {"+" Synthesis}]
+ ["[1][0]" generation {"+" Context}]
+ ["[1][0]" directive {"+" Import Requirements Phase Operation Handler Bundle}]
+ ["[1][0]" program {"+" Program}]
+ [///
+ ["[0]" phase]
+ [meta
+ ["[0]" archive {"+" Archive}
+ ["[0]" artifact]
+ ["[0]" dependency]]]]]]])
(def: .public (custom [syntax handler])
(All (_ anchor expression directive s)
@@ -114,9 +117,11 @@
(Operation anchor expression directive [Type expression Any])))
(/////directive.lifted_generation
(do phase.monad
- [codeG (generate archive codeS)
- id (/////generation.learn name)
+ [[interim_artifacts codeG] (/////generation.with_interim_artifacts archive
+ (generate archive codeS))
+ dependencies (dependency.dependencies archive codeS)
module_id (phase.lifted (archive.id module archive))
+ id (/////generation.learn name false (set.union interim_artifacts dependencies))
[target_name value directive] (/////generation.define! [module_id id] {.#None} codeG)
_ (/////generation.save! id {.#None} directive)]
(in [code//type codeG value]))))
@@ -166,9 +171,11 @@
(///.lifted meta.current_module_name))]
(/////directive.lifted_generation
(do phase.monad
- [codeG (generate archive codeS)
+ [[interim_artifacts codeG] (/////generation.with_interim_artifacts archive
+ (generate archive codeS))
+ dependencies (dependency.dependencies archive codeS)
module_id (phase.lifted (archive.id current_module archive))
- id (<learn> extension)
+ id (<learn> extension (set.union interim_artifacts dependencies))
[target_name value directive] (/////generation.define! [module_id id] {.#None} codeG)
_ (/////generation.save! id {.#None} directive)]
(in [codeG value])))))
@@ -489,8 +496,10 @@
Synthesis
(/////generation.Operation anchor expression directive Any)))
(do phase.monad
- [programG (generate archive programS)
- artifact_id (/////generation.learn /////program.name)]
+ [[interim_artifacts programG] (/////generation.with_interim_artifacts archive
+ (generate archive programS))
+ dependencies (dependency.dependencies archive programS)
+ artifact_id (/////generation.learn /////program.name true (set.union interim_artifacts dependencies))]
(/////generation.save! artifact_id {.#None} (program [module_id artifact_id] programG))))
(def: (def::program program)
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux
index 32c78830d..1c4bee276 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/function.lux
@@ -29,7 +29,8 @@
[variable {"+" Register Variable}]]
[meta
[archive {"+" Archive}
- ["[0]" artifact]]]]]]])
+ ["[0]" artifact]
+ ["[0]" dependency]]]]]]])
(def: .public (apply expression archive [functionS argsS+])
(Generator (Application Synthesis))
@@ -66,7 +67,8 @@
(def: .public (function statement expression archive [environment arity bodyS])
(-> Phase! (Generator (Abstraction Synthesis)))
(do [! ///////phase.monad]
- [[[function_module function_artifact] body!] (/////generation.with_new_context archive
+ [dependencies (dependency.dependencies archive bodyS)
+ [[function_module function_artifact] body!] (/////generation.with_new_context archive dependencies
(/////generation.with_anchor 1
(statement expression archive bodyS)))
closureO+ (monad.each ! (expression archive) environment)
diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux
index 19ef21fbf..936d40b2e 100644
--- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux
+++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/ruby/runtime.lux
@@ -283,13 +283,16 @@
(|>> (_.bit_and (_.manual "+0x80000000"))
(_.= (_.int +0))))
+(def: i32##up
+ (_.bit_shl (_.int +32)))
+
(template: (i64 @high @low)
[(|> (_.? (i32##positive? @high)
@high
(|> (_.manual "+0xFFFFFFFF")
(_.- @high)
_.bit_not))
- (_.bit_shl (_.int +32))
+ i32##up
(_.bit_or @low))])
(template [<runtime> <host>]
@@ -347,11 +350,9 @@
(_.set (list low) (|> input i32##low (_.bit_shr shift)
(_.bit_or (|> input i32##high (_.bit_shl (_.- shift (_.int +32)))))))
(_.return (..i64 high low))))
- ($_ _.then
- (_.set (list low) (_.? (|> shift (_.= (_.int +32)))
- (i32##high input)
- (|> input i32##high (_.bit_shr (_.- (_.int +32) shift)))))
- (_.return (..i64 (_.int +0) low)))))))
+ (_.return (_.? (|> shift (_.= (_.int +32)))
+ (i32##high input)
+ (|> input i32##high (_.bit_shr (_.- (_.int +32) shift)))))))))
(runtime: (i64##/ parameter subject)
(let [extra (_.do "remainder" (list parameter) {.#None} subject)]
@@ -580,7 +581,7 @@
[_ (/////generation.execute! ..runtime)
_ (/////generation.save! ..module_id {.#None} ..runtime)]
(in [(|> artifact.empty
- artifact.resource
+ (artifact.resource true artifact.no_dependencies)
product.right)
(sequence.sequence [..module_id
{.#None}
diff --git a/stdlib/source/library/lux/tool/compiler/meta/archive.lux b/stdlib/source/library/lux/tool/compiler/meta/archive.lux
index cbcdd36b3..c09aff7e6 100644
--- a/stdlib/source/library/lux/tool/compiler/meta/archive.lux
+++ b/stdlib/source/library/lux/tool/compiler/meta/archive.lux
@@ -5,6 +5,7 @@
["[0]" equivalence {"+" Equivalence}]
["[0]" monad {"+" do}]]
[control
+ ["[0]" maybe]
["[0]" try {"+" Try}]
["[0]" exception {"+" exception:}]
["[0]" function]
@@ -132,6 +133,14 @@
{.#None}
(exception.except ..module_must_be_reserved_before_it_can_be_added [module]))))
+ (def: .public entries
+ (-> Archive (List [Module [ID [Descriptor (Document Any) Output]]]))
+ (|>> :representation
+ (value@ #resolver)
+ dictionary.entries
+ (list.all (function (_ [module [module_id entry]])
+ (# maybe.monad each (|>> [module_id] [module]) entry)))))
+
(def: .public (find module archive)
(-> Module Archive (Try [Descriptor (Document Any) Output]))
(let [(^open "_[0]") (:representation archive)]
diff --git a/stdlib/source/library/lux/tool/compiler/meta/archive/artifact.lux b/stdlib/source/library/lux/tool/compiler/meta/archive/artifact.lux
index 9bb7c3914..8f636a0b2 100644
--- a/stdlib/source/library/lux/tool/compiler/meta/archive/artifact.lux
+++ b/stdlib/source/library/lux/tool/compiler/meta/archive/artifact.lux
@@ -1,25 +1,29 @@
(.using
- [library
- [lux "*"
- [abstract
- [monad {"+" do}]]
- [control
- [pipe {"+" case>}]
- ["[0]" exception {"+" exception:}]
- ["<>" parser
- ["<[0]>" binary {"+" Parser}]]]
- [data
- ["[0]" product]
- ["[0]" text
- ["%" format {"+" format}]]
- [collection
- ["[0]" list]
- ["[0]" sequence {"+" Sequence} ("[1]#[0]" functor mix)]
- ["[0]" dictionary {"+" Dictionary}]]
- [format
- ["[0]" binary {"+" Writer}]]]
- [type
- abstract]]])
+ [library
+ [lux "*"
+ [abstract
+ [monad {"+" do}]]
+ [control
+ [pipe {"+" case>}]
+ ["[0]" exception {"+" exception:}]
+ ["<>" parser
+ ["<[0]>" binary {"+" Parser}]]]
+ [data
+ ["[0]" product]
+ ["[0]" text
+ ["%" format {"+" format}]]
+ [collection
+ ["[0]" list]
+ ["[0]" sequence {"+" Sequence} ("[1]#[0]" functor mix)]
+ ["[0]" dictionary {"+" Dictionary}]
+ ["[0]" set {"+" Set}]]
+ [format
+ ["[0]" binary {"+" Writer}]]]
+ [math
+ [number
+ ["[0]" nat]]]
+ [type
+ abstract]]])
(type: .public ID
Nat)
@@ -34,10 +38,22 @@
{#Directive Text}
{#Custom Text}))
+(type: .public Dependency
+ [Nat ID])
+
+(def: dependency_hash
+ (product.hash nat.hash nat.hash))
+
+(def: .public no_dependencies
+ (Set Dependency)
+ (set.empty dependency_hash))
+
(type: .public Artifact
(Record
[#id ID
- #category Category]))
+ #category Category
+ #mandatory? Bit
+ #dependencies (Set Dependency)]))
(abstract: .public Registry
(Record
@@ -57,25 +73,29 @@
(-> Registry ID)
(|>> ..artifacts sequence.size))
- (def: .public (resource registry)
- (-> Registry [ID Registry])
+ (def: .public (resource mandatory? dependencies registry)
+ (-> Bit (Set Dependency) Registry [ID Registry])
(let [id (..next registry)]
[id
(|> registry
:representation
(revised@ #artifacts (sequence.suffix [#id id
- #category {#Anonymous}]))
+ #category {#Anonymous}
+ #mandatory? mandatory?
+ #dependencies dependencies]))
:abstraction)]))
(template [<tag> <create> <fetch>]
- [(def: .public (<create> name registry)
- (-> Text Registry [ID Registry])
+ [(def: .public (<create> name mandatory? dependencies registry)
+ (-> Text Bit (Set Dependency) Registry [ID Registry])
(let [id (..next registry)]
[id
(|> registry
:representation
(revised@ #artifacts (sequence.suffix [#id id
- #category {<tag> name}]))
+ #category {<tag> name}
+ #mandatory? mandatory?
+ #dependencies dependencies]))
(revised@ #resolver (dictionary.has name id))
:abstraction)]))
@@ -118,11 +138,19 @@
[4 #Generator binary.text]
[5 #Directive binary.text]
[6 #Custom binary.text]))))
- artifacts (: (Writer (Sequence Category))
- (binary.sequence/64 category))]
+ mandatory? binary.bit
+ dependency (: (Writer Dependency)
+ (binary.and binary.nat binary.nat))
+ dependencies (: (Writer (Set Dependency))
+ (binary.set dependency))
+ artifacts (: (Writer (Sequence [Category Bit (Set Dependency)]))
+ (binary.sequence/64 ($_ binary.and category mandatory? dependencies)))]
(|>> :representation
(value@ #artifacts)
- (sequence#each (value@ #category))
+ (sequence#each (function (_ it)
+ [(value@ #category it)
+ (value@ #mandatory? it)
+ (value@ #dependencies it)]))
artifacts)))
(exception: .public (invalid_category [tag Nat])
@@ -146,17 +174,22 @@
[5 #Directive <binary>.text]
[6 #Custom <binary>.text])
- _ (<>.failure (exception.error ..invalid_category [tag])))))]
- (|> (<binary>.sequence/64 category)
- (# <>.monad each (sequence#mix (function (_ artifact registry)
+ _ (<>.failure (exception.error ..invalid_category [tag])))))
+ mandatory? <binary>.bit
+ dependency (: (Parser Dependency)
+ (<>.and <binary>.nat <binary>.nat))
+ dependencies (: (Parser (Set Dependency))
+ (<binary>.set ..dependency_hash dependency))]
+ (|> (<binary>.sequence/64 ($_ <>.and category mandatory? dependencies))
+ (# <>.monad each (sequence#mix (function (_ [category mandatory? dependencies] registry)
(product.right
- (case artifact
+ (case category
{#Anonymous}
- (..resource registry)
+ (..resource mandatory? dependencies registry)
(^template [<tag> <create>]
[{<tag> name}
- (<create> name registry)])
+ (<create> name mandatory? dependencies registry)])
([#Definition ..definition]
[#Analyser ..analyser]
[#Synthesizer ..synthesizer]
diff --git a/stdlib/source/library/lux/tool/compiler/meta/archive/dependency.lux b/stdlib/source/library/lux/tool/compiler/meta/archive/dependency.lux
new file mode 100644
index 000000000..70f5b5744
--- /dev/null
+++ b/stdlib/source/library/lux/tool/compiler/meta/archive/dependency.lux
@@ -0,0 +1,215 @@
+... https://en.wikipedia.org/wiki/Tree_shaking
+(.using
+ [library
+ [lux "*"
+ [abstract
+ [hash {"+" Hash}]
+ ["[0]" monad {"+" do}]]
+ [data
+ ["[0]" product]
+ [collection
+ ["[0]" list ("[1]#[0]" monoid mix monad)]
+ ["[0]" set {"+" Set}]
+ ["[0]" dictionary {"+" Dictionary}]
+ ["[0]" sequence]]]
+ [math
+ [number
+ ["[0]" nat]]]
+ [meta
+ ["[0]" symbol]]
+ [tool
+ [compiler
+ ["[0]" phase]
+ ["[0]" reference {"+" Constant}]
+ [language
+ [lux
+ ["[0]" analysis]
+ ["[0]" synthesis {"+" Synthesis Path}]
+ ["[0]" generation {"+" Context Operation}]]]
+ [meta
+ ["[0]" archive {"+" Archive}
+ ["[0]" artifact]
+ ["[0]" descriptor]]]]]]])
+
+(def: (path_references references)
+ (-> (-> Synthesis (List Constant))
+ (-> Path (List Constant)))
+ (function (again path)
+ (case path
+ (^or {synthesis.#Pop}
+ {synthesis.#Access _}
+ {synthesis.#Bind _})
+ (list)
+
+ (^template [<tag>]
+ [{<tag> left right}
+ ($_ list#composite
+ (again left)
+ (again right))])
+ ([synthesis.#Alt]
+ [synthesis.#Seq])
+
+ {synthesis.#Bit_Fork when then else}
+ (case else
+ {.#Some else}
+ ($_ list#composite
+ (again then)
+ (again else))
+
+ {.#None}
+ (again then))
+
+ (^template [<tag>]
+ [{<tag> fork}
+ (|> {.#Item fork}
+ (list#each (|>> product.right again))
+ list#conjoint)])
+ ([synthesis.#I64_Fork]
+ [synthesis.#F64_Fork]
+ [synthesis.#Text_Fork])
+
+ {synthesis.#Then then}
+ (references then))))
+
+(def: (references value)
+ (-> Synthesis (List Constant))
+ (case value
+ {synthesis.#Primitive value}
+ (list)
+
+ {synthesis.#Structure value}
+ (case value
+ {analysis.#Variant value}
+ (|> value
+ (value@ analysis.#value)
+ references)
+
+ {analysis.#Tuple value}
+ (|> value
+ (list#each references)
+ list#conjoint))
+
+ {synthesis.#Reference value}
+ (case value
+ {reference.#Variable _}
+ (list)
+
+ {reference.#Constant value}
+ (list value))
+
+ {synthesis.#Control value}
+ (case value
+ {synthesis.#Branch value}
+ (case value
+ {synthesis.#Let input _ body}
+ ($_ list#composite
+ (references input)
+ (references body))
+
+ {synthesis.#If test then else}
+ ($_ list#composite
+ (references test)
+ (references then)
+ (references else))
+
+ {synthesis.#Get _ record}
+ (references record)
+
+ {synthesis.#Case input path}
+ ($_ list#composite
+ (references input)
+ (path_references references path)))
+
+ {synthesis.#Loop value}
+ (case value
+ {synthesis.#Scope value}
+ (|> value
+ (value@ synthesis.#iteration)
+ references)
+
+ {synthesis.#Again value}
+ (|> value
+ (list#each references)
+ list#conjoint))
+
+ {synthesis.#Function value}
+ (case value
+ {synthesis.#Abstraction value}
+ (|> value
+ (value@ synthesis.#body)
+ references)
+
+ {synthesis.#Apply function arguments}
+ (|> (list& function arguments)
+ (list#each references)
+ list#conjoint)))
+
+ {synthesis.#Extension [name parameters]}
+ (|> parameters
+ (list#each references)
+ list#conjoint)))
+
+(def: context_hash
+ (Hash Context)
+ (product.hash nat.hash nat.hash))
+
+(def: .public (dependencies archive value)
+ (All (_ anchor expression directive)
+ (-> Archive Synthesis (Operation anchor expression directive (Set artifact.Dependency))))
+ (let [! phase.monad]
+ (|> value
+ ..references
+ (set.of_list symbol.hash)
+ set.list
+ (monad.each ! (generation.remember archive))
+ (# ! each (set.of_list context_hash)))))
+
+(def: .public all
+ (-> (List (Set artifact.Dependency))
+ (Set artifact.Dependency))
+ (list#mix set.union artifact.no_dependencies))
+
+(def: (immediate_dependencies archive)
+ (-> Archive [(List artifact.Dependency)
+ (Dictionary artifact.Dependency (Set artifact.Dependency))])
+ (|> archive
+ archive.entries
+ (list#each (function (_ [module [module_id [descriptor document output]]])
+ (|> descriptor
+ (value@ descriptor.#registry)
+ artifact.artifacts
+ sequence.list
+ (list#each (function (_ artifact)
+ [[module_id (value@ artifact.#id artifact)]
+ (value@ artifact.#mandatory? artifact)
+ (value@ artifact.#dependencies artifact)])))))
+ list.together
+ (list#mix (function (_ [artifact_id mandatory? dependencies]
+ [mandatory_dependencies
+ all_dependencies])
+ [(if mandatory?
+ (list& artifact_id mandatory_dependencies)
+ mandatory_dependencies)
+ (dictionary.has artifact_id dependencies all_dependencies)])
+ [(list)
+ (dictionary.empty context_hash)])))
+
+(def: .public (necessary_dependencies archive)
+ (-> Archive (Set artifact.Dependency))
+ (let [[mandatory immediate] (immediate_dependencies archive)]
+ (loop [pending mandatory
+ minimum artifact.no_dependencies]
+ (case pending
+ {.#Item head tail}
+ (if (set.member? minimum head)
+ (again tail minimum)
+ (again (case (dictionary.value head immediate)
+ {.#Some additional}
+ (list#composite (set.list additional) tail)
+
+ {.#None}
+ tail)
+ (set.has head minimum)))
+
+ {.#End}
+ minimum))))
diff --git a/stdlib/source/library/lux/tool/compiler/meta/cache/dependency.lux b/stdlib/source/library/lux/tool/compiler/meta/cache/dependency.lux
index 1cf11fda6..6e8a800ec 100644
--- a/stdlib/source/library/lux/tool/compiler/meta/cache/dependency.lux
+++ b/stdlib/source/library/lux/tool/compiler/meta/cache/dependency.lux
@@ -7,7 +7,7 @@
["[0]" maybe ("[1]#[0]" functor)]
["[0]" try {"+" Try}]
["[0]" state]
- ["[0]" function
+ [function
["[0]" memo {"+" Memo}]]]
[data
["[0]" text
diff --git a/stdlib/source/library/lux/tool/compiler/meta/io/archive.lux b/stdlib/source/library/lux/tool/compiler/meta/io/archive.lux
index f5243e5d2..ee222ea36 100644
--- a/stdlib/source/library/lux/tool/compiler/meta/io/archive.lux
+++ b/stdlib/source/library/lux/tool/compiler/meta/io/archive.lux
@@ -223,7 +223,7 @@
output (: Output sequence.empty)]
(let [[analysers synthesizers generators directives] bundles]
(case input
- {.#Item [[artifact_id artifact_category] input']}
+ {.#Item [[artifact_id artifact_category mandatory_artifact? artifact_dependencies] input']}
(case (do !
[data (try.of_maybe (dictionary.value (format (%.nat artifact_id) extension) actual))
.let [context [module_id artifact_id]
diff --git a/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux b/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux
index af39e83e9..bab2f6ed9 100644
--- a/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux
+++ b/stdlib/source/library/lux/tool/compiler/meta/packager/jvm.lux
@@ -33,7 +33,8 @@
[//
["[0]" archive {"+" Output}
["[0]" descriptor {"+" Module}]
- ["[0]" artifact]]
+ ["[0]" artifact]
+ ["tree_shaking" dependency]]
[cache
["[0]" dependency]]
["[0]" io "_"
@@ -151,14 +152,17 @@
(java/io/Flushable::flush)
(java/util/zip/ZipOutputStream::closeEntry))))))
-(def: (write_module static [module output] sink)
- (-> Static [archive.ID Output] java/util/jar/JarOutputStream
+(def: (write_module static necessary_dependencies [module output] sink)
+ (-> Static (Set Context) [archive.ID Output] java/util/jar/JarOutputStream
(Try java/util/jar/JarOutputStream))
- (monad.mix try.monad
- (function (_ [artifact custom content] sink)
- (..write_class static module artifact custom content sink))
- sink
- (sequence.list output)))
+ (let [! try.monad]
+ (monad.mix try.monad
+ (function (_ [artifact custom content] sink)
+ (if (set.member? necessary_dependencies [module artifact])
+ (..write_class static module artifact custom content sink)
+ (# ! in sink)))
+ sink
+ (sequence.list output))))
(def: (read_jar_entry_with_unknown_size input)
(-> java/util/jar/JarInputStream [Nat Binary])
@@ -248,12 +252,13 @@
(-> Static Packager)
(function (_ host_dependencies archive program)
(do [! try.monad]
- [order (dependency.load_order $.key archive)
+ [.let [necessary_dependencies (tree_shaking.necessary_dependencies archive)]
+ order (dependency.load_order $.key archive)
.let [buffer (java/io/ByteArrayOutputStream::new (.int ..mebi_byte))]
sink (|> order
(list#each (function (_ [module [module_id [descriptor document output]]])
[module_id output]))
- (monad.mix ! (..write_module static)
+ (monad.mix ! (..write_module static necessary_dependencies)
(java/util/jar/JarOutputStream::new buffer (..manifest program))))
[entries duplicates sink] (|> host_dependencies
dictionary.values
diff --git a/stdlib/source/test/lux/extension.lux b/stdlib/source/test/lux/extension.lux
index 1fcec22de..7422823e9 100644
--- a/stdlib/source/test/lux/extension.lux
+++ b/stdlib/source/test/lux/extension.lux
@@ -34,6 +34,9 @@
[tool
[compiler
["[0]" phase]
+ [meta
+ [archive
+ ["[0]" artifact]]]
[language
[lux
["[0]" analysis]
@@ -139,7 +142,7 @@
(generation_phase archive expressionS))
_ (directive.lifted_generation
- (generation.with_new_context archive
+ (generation.with_new_context archive artifact.no_dependencies
(do !
[[module_id artifact_id] (generation.context archive)
.let [commentary (format "Successfully installed directive " (%.text self) "!")]