From 4b22baf63fd2ef2bf141835ab540f7d52168cc84 Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Sun, 30 Jan 2022 05:08:37 -0400 Subject: Fixes for the pure-Lux JVM compiler machinery. [Part 12] --- documentation/bookmark/back_end/c++.md | 1 + stdlib/source/library/lux/math/random.lux | 34 +- stdlib/source/library/lux/test.lux | 14 +- .../compiler/language/lux/analysis/inference.lux | 231 ++++++++++ .../language/lux/phase/analysis/function.lux | 6 +- .../language/lux/phase/analysis/inference.lux | 306 ------------- .../language/lux/phase/analysis/structure.lux | 44 +- .../language/lux/phase/extension/analysis/jvm.lux | 29 +- .../language/lux/phase/extension/directive/jvm.lux | 508 +++++++++++++++++++-- .../lux/tool/compiler/meta/packager/ruby.lux | 10 +- stdlib/source/test/lux/ffi.jvm.lux | 79 ++-- stdlib/source/test/lux/macro/code.lux | 63 +-- stdlib/source/test/lux/target/ruby.lux | 21 +- stdlib/source/test/lux/test.lux | 47 +- .../lux/tool/compiler/language/lux/analysis.lux | 2 + .../compiler/language/lux/analysis/inference.lux | 406 ++++++++++++++++ .../tool/compiler/language/lux/analysis/type.lux | 26 +- stdlib/source/test/lux/world.lux | 34 +- stdlib/source/test/lux/world/file/watch.lux | 108 ++--- 19 files changed, 1361 insertions(+), 608 deletions(-) create mode 100644 stdlib/source/library/lux/tool/compiler/language/lux/analysis/inference.lux delete mode 100644 stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/inference.lux create mode 100644 stdlib/source/test/lux/tool/compiler/language/lux/analysis/inference.lux diff --git a/documentation/bookmark/back_end/c++.md b/documentation/bookmark/back_end/c++.md index 21664d692..d7436b3bb 100644 --- a/documentation/bookmark/back_end/c++.md +++ b/documentation/bookmark/back_end/c++.md @@ -1,5 +1,6 @@ # Reference +0. [Misra Parallelism Safety-critical Guidelines for C++11, 17, Then C++20, 23 - CppCon 2021](https://www.youtube.com/watch?v=hVv7Nc3f4Jo) 0. [Back to Basics: Move Semantics - Nicolai Josuttis - CppCon 2021](https://www.youtube.com/watch?v=Bt3zcJZIalk) 0. [Type-and-resource Safety in Modern C++ - Bjarne Stroustrup - CppCon 2021](https://www.youtube.com/watch?v=l3rvjWfBzZI) 0. [Exceptional C++ - Victor Ciura - CppCon 2021](https://www.youtube.com/watch?v=SjlfhyZn2yA) diff --git a/stdlib/source/library/lux/math/random.lux b/stdlib/source/library/lux/math/random.lux index 13bac71cf..469a17226 100644 --- a/stdlib/source/library/lux/math/random.lux +++ b/stdlib/source/library/lux/math/random.lux @@ -195,30 +195,28 @@ (def: .public (and left right) (All (_ a b) (-> (Random a) (Random b) (Random [a b]))) - (do ..monad - [=left left - =right right] - (in [=left =right]))) + (function (_ prng) + (let [[prng left] (left prng) + [prng right] (right prng)] + [prng [left right]]))) (def: .public (or left right) (All (_ a b) (-> (Random a) (Random b) (Random (Or a b)))) - (do [! ..monad] - [? bit] - (if ? - (do ! - [=left left] - (in {0 #0 =left})) - (do ! - [=right right] - (in {0 #1 =right}))))) + (function (_ prng) + (let [[prng ?] (..bit prng)] + (if ? + (let [[prng left] (left prng)] + [prng {0 #0 left}]) + (let [[prng right] (right prng)] + [prng {0 #1 right}]))))) (def: .public (either left right) (All (_ a) (-> (Random a) (Random a) (Random a))) - (do ..monad - [? bit] - (if ? - left - right))) + (function (_ prng) + (let [[prng ?] (..bit prng)] + (if ? + (left prng) + (right prng))))) (def: .public (rec gen) (All (_ a) (-> (-> (Random a) (Random a)) (Random a))) diff --git a/stdlib/source/library/lux/test.lux b/stdlib/source/library/lux/test.lux index 7f0c76d58..d9555ec44 100644 --- a/stdlib/source/library/lux/test.lux +++ b/stdlib/source/library/lux/test.lux @@ -103,7 +103,7 @@ [left left] (# ! each (..and' left) right))) -(def: .public (context description) +(def: (context' description) (-> Text Test Test) (random#each (async#each (function (_ [tally documentation]) [tally (|> documentation @@ -112,6 +112,10 @@ (text.interposed ..separator) (format description ..separator))])))) +(def: .public context + (-> Text Test Test) + (|>> %.text context')) + (def: failure_prefix "[Failure] ") (def: success_prefix "[Success] ") @@ -131,11 +135,11 @@ (def: .public (test message condition) (-> Text Bit Test) - (random#in (..assertion message condition))) + (random#in (..assertion (%.text message) condition))) (def: .public (lifted message random) (-> Text (Random Bit) Test) - (random#each (..assertion message) random)) + (random#each (..assertion (%.text message)) random)) (def: pcg_32_magic_inc Nat @@ -293,7 +297,7 @@ (random#each (async#each (function (_ [tally documentation]) [(revised@ #actual_coverage (set.union coverage) tally) documentation])) - (..context context test)))) + (..context' context test)))) (def: (symbol_code symbol) (-> Symbol Code) @@ -356,7 +360,7 @@ (def: (covering' module coverage test) (-> Text Text Test Test) (let [coverage (..coverage module coverage)] - (|> (..context module test) + (|> (..context' module test) (random#each (async#each (function (_ [tally documentation]) [(revised@ #expected_coverage (set.union coverage) tally) (|> documentation diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/analysis/inference.lux b/stdlib/source/library/lux/tool/compiler/language/lux/analysis/inference.lux new file mode 100644 index 000000000..1d903e7d6 --- /dev/null +++ b/stdlib/source/library/lux/tool/compiler/language/lux/analysis/inference.lux @@ -0,0 +1,231 @@ +(.using + [library + [lux "*" + ["[0]" meta] + [abstract + [monad {"+" do}]] + [control + [pipe {"+" case>}] + ["[0]" maybe] + ["[0]" exception {"+" exception:}]] + [data + ["[0]" text + ["%" format {"+" format}]] + [collection + ["[0]" list ("[1]#[0]" functor monoid)]]] + [macro + ["[0]" template]] + [math + [number + ["n" nat]]] + ["[0]" type + ["[0]" check]]]] + ["/" // {"+" Analysis Operation Phase} + ["[1][0]" type] + [// + [phase + ["[0]" extension]] + [/// + ["[0]" phase ("[1]#[0]" monad)] + [meta + [archive {"+" Archive}]]]]]) + +(exception: .public (cannot_infer [type Type + arguments (List Code)]) + (exception.report + ["Type" (%.type type)] + ["Arguments" (exception.listing %.code arguments)])) + +(exception: .public (cannot_infer_argument [type Type + argument Code]) + (exception.report + ["Type" (%.type type)] + ["Argument" (%.code argument)])) + +(template [] + [(exception: .public ( [type Type]) + (exception.report + ["Type" (%.type type)]))] + + [not_a_variant] + [not_a_record] + [invalid_type_application] + ) + +(def: prefix + (format (%.symbol (symbol ..type)) "#")) + +(def: .public (existential? type) + (-> Type Bit) + (case type + {.#Primitive actual {.#End}} + (text.starts_with? ..prefix actual) + + _ + false)) + +(def: existential + (Operation Type) + (do phase.monad + [module (extension.lifted meta.current_module_name) + [id _] (/type.check check.existential)] + (in {.#Primitive (format ..prefix module "#" (%.nat id)) (list)}))) + +... Type-inference works by applying some (potentially quantified) type +... to a sequence of values. +... Function types are used for this, although inference is not always +... done for function application (alternative uses may be records and +... tagged variants). +... But, so long as the type being used for the inference can be treated +... as a function type, this method of inference should work. +(def: .public (general archive analyse inferT args) + (-> Archive Phase Type (List Code) (Operation [Type (List Analysis)])) + (case args + {.#End} + (do phase.monad + [_ (/type.inference inferT)] + (in [inferT (list)])) + + {.#Item argC args'} + (case inferT + {.#Named name unnamedT} + (general archive analyse unnamedT args) + + {.#UnivQ _} + (do phase.monad + [[var_id varT] (/type.check check.var)] + (general archive analyse (maybe.trusted (type.applied (list varT) inferT)) args)) + + {.#ExQ _} + (do [! phase.monad] + [exT ..existential] + (general archive analyse (maybe.trusted (type.applied (list exT) inferT)) args)) + + {.#Apply inputT transT} + (case (type.applied (list inputT) transT) + {.#Some outputT} + (general archive analyse outputT args) + + {.#None} + (/.except ..invalid_type_application [inferT])) + + ... Arguments are inferred back-to-front because, by convention, + ... Lux functions take the most important arguments *last*, which + ... means that the most information for doing proper inference is + ... located in the last arguments to a function call. + ... By inferring back-to-front, a lot of type-annotations can be + ... avoided in Lux code, since the inference algorithm can piece + ... things together more easily. + {.#Function inputT outputT} + (do phase.monad + [[outputT' args'A] (general archive analyse outputT args') + argA (<| (/.with_stack ..cannot_infer_argument [inputT argC]) + (/type.expecting inputT) + (analyse archive argC))] + (in [outputT' (list& argA args'A)])) + + {.#Var infer_id} + (do phase.monad + [?inferT' (/type.check (check.peek infer_id))] + (case ?inferT' + {.#Some inferT'} + (general archive analyse inferT' args) + + _ + (/.except ..cannot_infer [inferT args]))) + + _ + (/.except ..cannot_infer [inferT args])) + )) + +(def: (with_recursion @self recursion) + (-> Nat Type Type Type) + (function (again it) + (case it + (^or {.#Parameter index} + {.#Apply {.#Primitive "" {.#End}} + {.#Parameter index}}) + (if (n.= @self index) + recursion + it) + + (^template [] + [{ left right} + { (again left) (again right)}]) + ([.#Sum] [.#Product] [.#Function] [.#Apply]) + + (^template [] + [{ environment quantified} + { (list#each again environment) + (with_recursion (n.+ 2 @self) recursion quantified)}]) + ([.#UnivQ] [.#ExQ]) + + {.#Primitive name parameters} + {.#Primitive name (list#each again parameters)} + + _ + it))) + +(def: parameters + (-> Nat (List Type)) + (|>> list.indices + (list#each (|>> (n.* 2) ++ {.#Parameter})) + list.reversed)) + +(template [ ] + [(`` (def: .public ( (~~ (template.spliced )) complex) + (-> (~~ (template.spliced )) Type (Operation Type)) + (loop [depth 0 + it complex] + (case it + {.#Named name it} + (again depth it) + + (^template [] + [{ env it} + (phase#each (|>> { env}) + (again (++ depth) it))]) + ([.#UnivQ] + [.#ExQ]) + + {.#Apply parameter abstraction} + (case (type.applied (list parameter) abstraction) + {.#Some it} + (again depth it) + + {.#None} + (/.except ..invalid_type_application [it])) + + { _} + + + _ + (/.except [complex])))))] + + [record [Nat] [arity] ..not_a_record + .#Product + (let [[lefts right] (|> it + type.flat_tuple + (list.split_at (-- arity)))] + (phase#in (type.function + (list#each (..with_recursion (|> depth -- (n.* 2)) complex) + (list#composite lefts (list (type.tuple right)))) + (type.application (parameters depth) complex))))] + [variant [Nat Bit] [lefts right?] ..not_a_variant + .#Sum + (|> it + type.flat_variant + (list.after lefts) + (case> {.#Item [head tail]} + (let [case (if right? + (type.variant tail) + head)] + (-> (if (n.= 0 depth) + case + (..with_recursion (|> depth -- (n.* 2)) complex case)) + (type.application (parameters depth) complex))) + + {.#End} + (-> .Nothing complex)) + phase#in)] + ) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux index 8f7a67a0c..5a2018656 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/function.lux @@ -16,12 +16,12 @@ ["[0]" check]]]] ["[0]" // "_" ["[1][0]" scope] - ["[1][0]" inference] ["/[1]" // "_" ["[1][0]" extension] [// ["/" analysis {"+" Analysis Operation Phase} - ["[1][0]" type]] + ["[1][0]" type] + ["[1][0]" inference]] [/// ["[1]" phase] [reference {"+"} @@ -111,5 +111,5 @@ (-> Phase (List Code) Type Analysis Phase) (<| (/.with_stack ..cannot_apply [functionT functionC argsC+]) (do ///.monad - [[applyT argsA+] (//inference.general archive analyse functionT argsC+)]) + [[applyT argsA+] (/inference.general archive analyse functionT argsC+)]) (in (/.reified [functionA argsA+])))) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/inference.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/inference.lux deleted file mode 100644 index ea03f2719..000000000 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/inference.lux +++ /dev/null @@ -1,306 +0,0 @@ -(.using - [library - [lux "*" - ["[0]" meta] - [abstract - [monad {"+" do}]] - [control - ["[0]" maybe] - ["[0]" exception {"+" exception:}]] - [data - ["[0]" text - ["%" format {"+" format}]] - [collection - ["[0]" list ("[1]#[0]" functor monoid)]]] - [math - [number - ["n" nat]]] - ["[0]" type - ["[0]" check]]]] - ["[0]" /// "_" - ["[1][0]" extension] - [// - ["/" analysis {"+" Analysis Operation Phase} - [complex {"+" Tag}] - ["[1][0]" type]] - [/// - ["[1]" phase ("[1]#[0]" monad)] - [meta - [archive {"+" Archive}]]]]]) - -(exception: .public (variant_tag_out_of_bounds [size Nat - tag Tag - type Type]) - (exception.report - ["Tag" (%.nat tag)] - ["Variant size" (%.int (.int size))] - ["Variant type" (%.type type)])) - -(exception: .public (cannot_infer [type Type - args (List Code)]) - (exception.report - ["Type" (%.type type)] - ["Arguments" (exception.listing %.code args)])) - -(exception: .public (cannot_infer_argument [inferred Type - argument Code]) - (exception.report - ["Inferred Type" (%.type inferred)] - ["Argument" (%.code argument)])) - -(exception: .public (smaller_variant_than_expected [expected Nat - actual Nat]) - (exception.report - ["Expected" (%.int (.int expected))] - ["Actual" (%.int (.int actual))])) - -(template [] - [(exception: .public ( [type Type]) - (%.type type))] - - [not_a_variant_type] - [not_a_record_type] - [invalid_type_application] - ) - -(def: (replace parameter_idx replacement type) - (-> Nat Type Type Type) - (case type - {.#Primitive name params} - {.#Primitive name (list#each (replace parameter_idx replacement) params)} - - (^template [] - [{ left right} - { - (replace parameter_idx replacement left) - (replace parameter_idx replacement right)}]) - ([.#Sum] - [.#Product] - [.#Function] - [.#Apply]) - - {.#Parameter idx} - (if (n.= parameter_idx idx) - replacement - type) - - (^template [] - [{ env quantified} - { (list#each (replace parameter_idx replacement) env) - (replace (n.+ 2 parameter_idx) replacement quantified)}]) - ([.#UnivQ] - [.#ExQ]) - - _ - type)) - -(def: (named_type location id) - (-> Location Nat Type) - (let [name (format "{New Type " (%.location location) " " (%.nat id) "}")] - {.#Primitive name (list)})) - -(def: new_named_type - (Operation Type) - (do ///.monad - [location (///extension.lifted meta.location) - [ex_id _] (/type.check check.existential)] - (in (named_type location ex_id)))) - -... Type-inference works by applying some (potentially quantified) type -... to a sequence of values. -... Function types are used for this, although inference is not always -... done for function application (alternative uses may be records and -... tagged variants). -... But, so long as the type being used for the inference can be treated -... as a function type, this method of inference should work. -(def: .public (general archive analyse inferT args) - (-> Archive Phase Type (List Code) (Operation [Type (List Analysis)])) - (case args - {.#End} - (do ///.monad - [_ (/type.inference inferT)] - (in [inferT (list)])) - - {.#Item argC args'} - (case inferT - {.#Named name unnamedT} - (general archive analyse unnamedT args) - - {.#UnivQ _} - (do ///.monad - [[var_id varT] (/type.check check.var)] - (general archive analyse (maybe.trusted (type.applied (list varT) inferT)) args)) - - {.#ExQ _} - (do [! ///.monad] - [[var_id varT] (/type.check check.var) - output (general archive analyse - (maybe.trusted (type.applied (list varT) inferT)) - args) - bound? (/type.check (check.bound? var_id)) - _ (if bound? - (in []) - (do ! - [newT new_named_type] - (/type.check (check.check varT newT))))] - (in output)) - - {.#Apply inputT transT} - (case (type.applied (list inputT) transT) - {.#Some outputT} - (general archive analyse outputT args) - - {.#None} - (/.except ..invalid_type_application inferT)) - - ... Arguments are inferred back-to-front because, by convention, - ... Lux functions take the most important arguments *last*, which - ... means that the most information for doing proper inference is - ... located in the last arguments to a function call. - ... By inferring back-to-front, a lot of type-annotations can be - ... avoided in Lux code, since the inference algorithm can piece - ... things together more easily. - {.#Function inputT outputT} - (do ///.monad - [[outputT' args'A] (general archive analyse outputT args') - argA (<| (/.with_stack ..cannot_infer_argument [inputT argC]) - (/type.expecting inputT) - (analyse archive argC))] - (in [outputT' (list& argA args'A)])) - - {.#Var infer_id} - (do ///.monad - [?inferT' (/type.check (check.peek infer_id))] - (case ?inferT' - {.#Some inferT'} - (general archive analyse inferT' args) - - _ - (/.except ..cannot_infer [inferT args]))) - - _ - (/.except ..cannot_infer [inferT args])) - )) - -(def: (substitute_bound target sub) - (-> Nat Type Type Type) - (function (again base) - (case base - {.#Primitive name parameters} - {.#Primitive name (list#each again parameters)} - - (^template [] - [{ left right} - { (again left) (again right)}]) - ([.#Sum] [.#Product] [.#Function] [.#Apply]) - - {.#Parameter index} - (if (n.= target index) - sub - base) - - (^template [] - [{ environment quantified} - { (list#each again environment) quantified}]) - ([.#UnivQ] [.#ExQ]) - - _ - base))) - -... Turns a record type into the kind of function type suitable for inference. -(def: (record' record_size target originalT inferT) - (-> Nat Nat Type Type (Operation Type)) - (case inferT - {.#Named name unnamedT} - (record' record_size target originalT unnamedT) - - (^template [] - [{ env bodyT} - (do ///.monad - [bodyT+ (record' record_size (n.+ 2 target) originalT bodyT)] - (in { env bodyT+}))]) - ([.#UnivQ] - [.#ExQ]) - - {.#Apply inputT funcT} - (case (type.applied (list inputT) funcT) - {.#Some outputT} - (record' record_size target originalT outputT) - - {.#None} - (/.except ..invalid_type_application inferT)) - - {.#Product _} - (let [[lefts right] (list.split_at (-- record_size) (type.flat_tuple inferT))] - (///#in (|> inferT - (type.function (list#composite lefts (list (type.tuple right)))) - (substitute_bound target originalT)))) - - _ - (/.except ..not_a_record_type inferT))) - -(def: .public (record record_size inferT) - (-> Nat Type (Operation Type)) - (record' record_size (n.- 2 0) inferT inferT)) - -... Turns a variant type into the kind of function type suitable for inference. -(def: .public (variant tag expected_size inferT) - (-> Tag Nat Type (Operation Type)) - (loop [depth 0 - currentT inferT] - (case currentT - {.#Named name unnamedT} - (do ///.monad - [unnamedT+ (again depth unnamedT)] - (in unnamedT+)) - - (^template [] - [{ env bodyT} - (do ///.monad - [bodyT+ (again (++ depth) bodyT)] - (in { env bodyT+}))]) - ([.#UnivQ] - [.#ExQ]) - - {.#Sum _} - (let [cases (type.flat_variant currentT) - actual_size (list.size cases) - boundary (-- expected_size)] - (cond (or (n.= expected_size actual_size) - (and (n.> expected_size actual_size) - (n.< boundary tag))) - (case (list.item tag cases) - {.#Some caseT} - (///#in (if (n.= 0 depth) - (type.function (list caseT) currentT) - (let [replace' (replace (|> depth -- (n.* 2)) inferT)] - (type.function (list (replace' caseT)) - (replace' currentT))))) - - {.#None} - (/.except ..variant_tag_out_of_bounds [expected_size tag inferT])) - - (n.< expected_size actual_size) - (/.except ..smaller_variant_than_expected [expected_size actual_size]) - - (n.= boundary tag) - (let [caseT (type.variant (list.after boundary cases))] - (///#in (if (n.= 0 depth) - (type.function (list caseT) currentT) - (let [replace' (replace (|> depth -- (n.* 2)) inferT)] - (type.function (list (replace' caseT)) - (replace' currentT)))))) - - ... else - (/.except ..variant_tag_out_of_bounds [expected_size tag inferT]))) - - {.#Apply inputT funcT} - (case (type.applied (list inputT) funcT) - {.#Some outputT} - (variant tag expected_size outputT) - - {.#None} - (/.except ..invalid_type_application inferT)) - - _ - (/.except ..not_a_variant_type inferT)))) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/structure.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/structure.lux index 66cf6c80d..cdf65a6ad 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/structure.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/structure.lux @@ -27,26 +27,18 @@ ["[0]" check]]]] ["[0]" // "_" ["[1][0]" simple] - ["[1][0]" inference] ["/[1]" // "_" ["[1][0]" extension] [// ["/" analysis {"+" Analysis Operation Phase} ["[1][0]" complex {"+" Tag}] - ["[1][0]" type]] + ["[1][0]" type] + ["[1][0]" inference]] [/// ["[1]" phase] [meta [archive {"+" Archive}]]]]]]) -(exception: .public (invalid_variant_type [type Type - tag Tag - code Code]) - (exception.report - ["Type" (%.type type)] - ["Tag" (%.nat tag)] - ["Expression" (%.code code)])) - (template [] [(exception: .public ( [type Type members (List Code)]) @@ -59,7 +51,8 @@ ) (exception: .public (not_a_quantified_type [type Type]) - (%.type type)) + (exception.report + ["Type" (%.type type)])) (template [] [(exception: .public ( [type Type @@ -70,6 +63,7 @@ ["Tag" (%.nat tag)] ["Expression" (%.code code)]))] + [invalid_variant_type] [cannot_analyse_variant] [cannot_infer_numeric_tag] ) @@ -78,7 +72,7 @@ [(exception: .public ( [key Symbol record (List [Symbol Code])]) (exception.report - ["Tag" (%.code (code.symbol key))] + ["Slot" (%.code (code.symbol key))] ["Record" (%.code (code.tuple (|> record (list#each (function (_ [keyI valC]) (list (code.symbol keyI) valC))) @@ -90,7 +84,7 @@ (exception: .public (slot_does_not_belong_to_record [key Symbol type Type]) (exception.report - ["Tag" (%.code (code.symbol key))] + ["Slot" (%.code (code.symbol key))] ["Type" (%.type type)])) (exception: .public (record_size_mismatch [expected Nat @@ -117,16 +111,12 @@ (/.with_stack ..cannot_analyse_variant [expectedT' tag valueC] (case expectedT {.#Sum _} - (let [flat (type.flat_variant expectedT)] - (case (list.item tag flat) - {.#Some variant_type} - (do ! - [valueA (<| (/type.expecting variant_type) - (analyse archive valueC))] - (in (/.variant [lefts right? valueA]))) - - {.#None} - (/.except //inference.variant_tag_out_of_bounds [(list.size flat) tag expectedT]))) + (|> (analyse archive valueC) + (# ! each (|>> [lefts right?] /.variant)) + (/type.expecting (|> expectedT + type.flat_variant + (list.item tag) + (maybe.else .Nothing)))) {.#Named name unnamedT} (<| (/type.expecting unnamedT) @@ -289,8 +279,8 @@ (case expectedT {.#Var _} (do ! - [inferenceT (//inference.variant idx case_size variantT) - [inferredT valueA+] (//inference.general archive analyse inferenceT (list valueC))] + [inferenceT (/inference.variant lefts right? variantT) + [inferredT valueA+] (/inference.general archive analyse inferenceT (list valueC))] (in (/.variant [lefts right? (|> valueA+ list.head maybe.trusted)]))) _ @@ -430,8 +420,8 @@ (case expectedT {.#Var _} (do ! - [inferenceT (//inference.record record_size recordT) - [inferredT membersA] (//inference.general archive analyse inferenceT membersC)] + [inferenceT (/inference.record record_size recordT) + [inferredT membersA] (/inference.general archive analyse inferenceT membersC)] (in (/.tuple membersA))) _ diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux index 2bc7d831e..b45be6e93 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/jvm.lux @@ -48,13 +48,13 @@ ["[1][0]" bundle] ["/[1]" // "_" [analysis - ["[0]A" inference] ["[0]" scope]] ["/[1]" // "_" ["[1][0]" analysis {"+" Analysis Operation Phase Handler Bundle} ["[1]/[0]" complex] ["[1]/[0]" pattern] - ["[0]A" type]] + ["[0]A" type] + ["[0]A" inference]] ["[1][0]" synthesis] [/// ["[0]" phase ("[1]#[0]" monad)] @@ -1663,13 +1663,18 @@ (def: .public protected_tag "protected") (def: .public default_tag "default") +(def: .public visibility' + (.Parser Visibility) + ($_ <>.or + (.this ..public_tag) + (.this ..private_tag) + (.this ..protected_tag) + (.this ..default_tag) + )) + (def: .public visibility (Parser Visibility) - ($_ <>.or - (.text! ..public_tag) - (.text! ..private_tag) - (.text! ..protected_tag) - (.text! ..default_tag))) + (.then ..visibility' .text)) (def: .public (visibility_analysis visibility) (-> Visibility Analysis) @@ -1691,7 +1696,7 @@ (Type Return) (List Exception)]) -(def: abstract_tag "abstract") +(def: .public abstract_tag "abstract") (def: .public abstract_method_definition (Parser (Abstract_Method Code)) @@ -1796,9 +1801,9 @@ (/////analysis.bit strict_fp?) (/////analysis.tuple (list#each annotation_analysis annotationsA)) (/////analysis.tuple (list#each var_analysis vars)) + (/////analysis.tuple (list#each class_analysis exceptions)) (/////analysis.text self_name) (/////analysis.tuple (list#each ..argument_analysis arguments)) - (/////analysis.tuple (list#each class_analysis exceptions)) (/////analysis.tuple (list#each typed_analysis super_arguments)) {/////analysis.#Function (list#each (|>> /////analysis.variable) @@ -1819,7 +1824,7 @@ (List Exception) a]) -(def: virtual_tag "virtual") +(def: .public virtual_tag "virtual") (def: .public virtual_method_definition (Parser (Virtual_Method Code)) @@ -2070,7 +2075,7 @@ mapping override_mapping)))) -(def: .public (hide_method_body arity bodyA) +(def: .public (hidden_method_body arity bodyA) (-> Nat Analysis Analysis) (<| /////analysis.tuple (list (/////analysis.unit)) @@ -2145,7 +2150,7 @@ {/////analysis.#Function (list#each (|>> /////analysis.variable) (scope.environment scope)) - (..hide_method_body (list.size arguments) bodyA)} + (..hidden_method_body (list.size arguments) bodyA)} )))))) (type: .public (Method_Definition a) 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 8d23b355c..1e3b1eabc 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 @@ -7,9 +7,11 @@ [control [pipe {"+" case>}] ["[0]" try {"+" Try} ("[1]#[0]" functor)] + ["[0]" exception] ["<>" parser ("[1]#[0]" monad) ["<[0]>" code {"+" Parser}] - ["<[0]>" text]]] + ["<[0]>" text] + ["<[0]>" synthesis]]] [data [binary {"+" Binary}] ["[0]" product] @@ -18,17 +20,19 @@ [collection ["[0]" list ("[1]#[0]" functor mix)] ["[0]" dictionary] - ["[0]" sequence]] + ["[0]" sequence] + ["[0]" set {"+" Set}]] ["[0]" format "_" ["[1]" binary]]] [macro ["[0]" template]] [math [number - ["[0]" i32]]] + ["[0]" i32] + ["n" nat]]] [target [jvm - ["_" bytecode {"+" Bytecode}] + ["_" bytecode {"+" Bytecode} ("[1]#[0]" monad)] ["[0]" modifier {"+" Modifier} ("[1]#[0]" monoid)] ["[0]" attribute] ["[0]" field] @@ -49,21 +53,28 @@ [tool [compiler ["[0]" phase] + [reference + [variable {"+" Register}]] [meta [archive {"+" Archive} ["[0]" artifact] - ["[0]" unit]]] + ["[0]" unit]] + ["[0]" cache "_" + ["[1]" artifact]]] [language [lux - ["[0]" synthesis] + ["[0]" synthesis {"+" Synthesis}] ["[0]" generation] ["[0]" directive {"+" Handler Bundle}] - ["[0]" analysis + ["[0]" analysis {"+" Analysis} ["[0]A" type]] [phase + [analysis + ["[0]A" scope]] [generation [jvm - ["[0]" runtime {"+" Anchor Definition Extender}]]] + ["[0]" runtime {"+" Anchor Definition Extender}] + ["[0]" value]]] ["[0]" extension ["[0]" bundle] [analysis @@ -93,17 +104,21 @@ {ffi.#ProtectedP} method.protected {ffi.#DefaultP} modifier.empty))) -(def: visibility - (Parser (Modifier field.Field)) +(def: visibility' + (.Parser (Modifier field.Field)) (`` ($_ <>.either (~~ (template [