From e4bc4d0e2cd14a955530160c4fc7859e6c46874e Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Thu, 3 Feb 2022 05:55:42 -0400 Subject: Fixes for the pure-Lux JVM compiler machinery. [Part 13 / Done!] --- stdlib/source/library/lux/math/number/i32.lux | 22 +- stdlib/source/library/lux/target/jvm/bytecode.lux | 9 +- .../library/lux/target/jvm/encoding/signed.lux | 13 +- .../tool/compiler/language/lux/phase/analysis.lux | 12 +- .../compiler/language/lux/phase/analysis/case.lux | 6 +- .../language/lux/phase/analysis/complex.lux | 424 ++++++++++++++++++++ .../language/lux/phase/analysis/structure.lux | 428 --------------------- .../language/lux/phase/extension/analysis/jvm.lux | 19 +- .../language/lux/phase/extension/analysis/lua.lux | 156 ++++---- .../language/lux/phase/generation/lua/function.lux | 14 +- .../language/lux/phase/generation/lua/loop.lux | 7 +- .../language/lux/phase/generation/lua/runtime.lux | 7 +- .../lux/phase/generation/lua/structure.lux | 2 +- 13 files changed, 561 insertions(+), 558 deletions(-) create mode 100644 stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/complex.lux delete mode 100644 stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/structure.lux (limited to 'stdlib/source/library') diff --git a/stdlib/source/library/lux/math/number/i32.lux b/stdlib/source/library/lux/math/number/i32.lux index c08f261b1..e8967c412 100644 --- a/stdlib/source/library/lux/math/number/i32.lux +++ b/stdlib/source/library/lux/math/number/i32.lux @@ -1,16 +1,18 @@ (.using - [library - [lux {"-" i64} - [type {"+" :by_example}] - [abstract - [equivalence {"+" Equivalence}]] - [control - ["[0]" maybe]]]] - [// - ["[0]" i64 {"+" Sub}]]) + [library + [lux {"-" i64} + [type {"+" :by_example}] + [abstract + [equivalence {"+" Equivalence}]] + [control + ["[0]" maybe]]]] + [// + ["[0]" i64 {"+" Sub}]]) (def: sub - (maybe.trusted (i64.sub 32))) + ... TODO: Stop needing this coercion. + (:as (Sub (I64 (Primitive "#I32"))) + (maybe.trusted (i64.sub 32)))) (def: .public I32 Type diff --git a/stdlib/source/library/lux/target/jvm/bytecode.lux b/stdlib/source/library/lux/target/jvm/bytecode.lux index d7a29db73..17f2dd229 100644 --- a/stdlib/source/library/lux/target/jvm/bytecode.lux +++ b/stdlib/source/library/lux/target/jvm/bytecode.lux @@ -750,11 +750,10 @@ (do [! try.monad] [jump (# ! each //signed.value (/address.jump @from @to))] - (let [big? (n.> (//unsigned.value //unsigned.maximum/2) - (.nat (i.* (if (i.< +0 jump) - -1 - +1) - jump)))] + (let [big? (or (i.> (//signed.value //signed.maximum/2) + jump) + (i.< (//signed.value //signed.minimum/2) + jump))] (if big? (# ! each (|>> {.#Left}) (//signed.s4 jump)) (# ! each (|>> {.#Right}) (//signed.s2 jump)))))) diff --git a/stdlib/source/library/lux/target/jvm/encoding/signed.lux b/stdlib/source/library/lux/target/jvm/encoding/signed.lux index f4f664878..d33321b60 100644 --- a/stdlib/source/library/lux/target/jvm/encoding/signed.lux +++ b/stdlib/source/library/lux/target/jvm/encoding/signed.lux @@ -47,7 +47,7 @@ ["Value" (%.int value)] ["Scope (in bytes)" (%.nat scope)])) - (template [ <+> <->] + (template [ <+> <->] [(with_expansions [ (template.symbol [ "'"])] (abstract: Any) (type: .public (Signed ))) @@ -57,6 +57,11 @@ (def: .public (|> (n.* i64.bits_per_byte) -- i64.mask :abstraction)) + + (def: .public + + (let [it (:representation )] + (:abstraction (-- (i.- it +0))))) (def: .public (-> Int (Try )) @@ -81,9 +86,9 @@ [<-> i.-] )] - [1 S1 bytes/1 s1 maximum/1 +/1 -/1] - [2 S2 bytes/2 s2 maximum/2 +/2 -/2] - [4 S4 bytes/4 s4 maximum/4 +/4 -/4] + [1 S1 bytes/1 s1 maximum/1 minimum/1 +/1 -/1] + [2 S2 bytes/2 s2 maximum/2 minimum/2 +/2 -/2] + [4 S4 bytes/4 s4 maximum/4 minimum/4 +/4 -/4] ) (template [ ] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux index d4f217dd0..657096c10 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis.lux @@ -17,7 +17,7 @@ ["[0]" location]]]] ["[0]" / "_" ["[1][0]" simple] - ["[1][0]" structure] + ["[1][0]" complex] ["[1][0]" reference] ["[1][0]" case] ["[1][0]" function] @@ -60,22 +60,22 @@ values)}) (case values {.#Item value {.#End}} - (/structure.tagged_sum compile tag archive value) + (/complex.variant compile tag archive value) _ - (/structure.tagged_sum compile tag archive (` [(~+ values)]))) + (/complex.variant compile tag archive (` [(~+ values)]))) (^ {.#Variant (list& [_ {.#Nat lefts}] [_ {.#Bit right?}] values)}) (case values {.#Item value {.#End}} - (/structure.sum compile lefts right? archive value) + (/complex.sum compile lefts right? archive value) _ - (/structure.sum compile lefts right? archive (` [(~+ values)]))) + (/complex.sum compile lefts right? archive (` [(~+ values)]))) (^ {.#Tuple elems}) - (/structure.record archive compile elems) + (/complex.record compile archive elems) _ (else code'))) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux index 2b99be974..3eab189d4 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/case.lux @@ -25,7 +25,7 @@ ["[1][0]" coverage {"+" Coverage}] ["/[1]" // "_" ["[1][0]" scope] - ["[1][0]" structure] + ["[1][0]" complex] ["/[1]" // "_" ["[1][0]" extension] [// @@ -247,11 +247,11 @@ [location {.#Tuple sub_patterns}] (/.with_location location (do [! ///.monad] - [record (//structure.normal sub_patterns) + [record (//complex.normal sub_patterns) record_size,members,recordT (: (Operation (Maybe [Nat (List Code) Type])) (.case record {.#Some record} - (//structure.order true record) + (//complex.order true record) {.#None} (in {.#None})))] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/complex.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/complex.lux new file mode 100644 index 000000000..678a626da --- /dev/null +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/complex.lux @@ -0,0 +1,424 @@ +(.using + [library + [lux "*" + ["[0]" meta] + [abstract + ["[0]" monad {"+" do}]] + [control + ["[0]" maybe] + ["[0]" try] + ["[0]" exception {"+" exception:}] + ["[0]" state]] + [data + ["[0]" product] + ["[0]" text ("[1]#[0]" equivalence) + ["%" format {"+" format}]] + [collection + ["[0]" list ("[1]#[0]" monad)] + ["[0]" dictionary {"+" Dictionary}]]] + [macro + ["[0]" code]] + [math + [number + ["n" nat]]] + [meta + ["[0]" symbol]] + ["[0]" type + ["[0]" check]]]] + ["[0]" // "_" + ["[1][0]" simple] + ["/[1]" // "_" + ["[1][0]" extension] + [// + ["/" analysis {"+" Analysis Operation Phase} + ["[1][0]" complex {"+" Tag}] + ["[1][0]" type] + ["[1][0]" inference]] + [/// + ["[1]" phase ("[1]#[0]" monad)] + [meta + [archive {"+" Archive}]]]]]]) + +(exception: .public (not_a_quantified_type [type Type]) + (exception.report + ["Type" (%.type type)])) + +(template [] + [(exception: .public ( [type Type + members (List Code)]) + (exception.report + ["Type" (%.type type)] + ["Expression" (%.code (` [(~+ members)]))]))] + + [invalid_tuple_type] + [cannot_analyse_tuple] + ) + +(template [] + [(exception: .public ( [type Type + lefts Nat + right? Bit + code Code]) + (exception.report + ["Type" (%.type type)] + ["Lefts" (%.nat lefts)] + ["Right?" (%.bit right?)] + ["Expression" (%.code code)]))] + + [invalid_variant_type] + [cannot_analyse_variant] + [cannot_infer_sum] + ) + +(exception: .public (cannot_repeat_slot [key Symbol + record (List [Symbol Code])]) + (exception.report + ["Slot" (%.code (code.symbol key))] + ["Record" (%.code (code.tuple (|> record + (list#each (function (_ [keyI valC]) + (list (code.symbol keyI) valC))) + list#conjoint)))])) + +(exception: .public (slot_does_not_belong_to_record [key Symbol + type Type]) + (exception.report + ["Slot" (%.code (code.symbol key))] + ["Type" (%.type type)])) + +(exception: .public (record_size_mismatch [expected Nat + actual Nat + type Type + record (List [Symbol Code])]) + (exception.report + ["Expected" (%.nat expected)] + ["Actual" (%.nat actual)] + ["Type" (%.type type)] + ["Expression" (%.code (|> record + (list#each (function (_ [keyI valueC]) + (list (code.symbol keyI) valueC))) + list#conjoint + code.tuple))])) + +(def: .public (sum analyse lefts right? archive) + (-> Phase Nat Bit Phase) + (let [tag (/complex.tag right? lefts)] + (function (again valueC) + (do [! ///.monad] + [expectedT (///extension.lifted meta.expected_type) + expectedT' (/type.check (check.clean expectedT))] + (/.with_stack ..cannot_analyse_variant [expectedT' lefts right? valueC] + (case expectedT + {.#Sum _} + (|> (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) + (again valueC)) + + {.#Var id} + (do ! + [?expectedT' (/type.check (check.peek id))] + (case ?expectedT' + {.#Some expectedT'} + (<| (/type.expecting expectedT') + (again valueC)) + + ... Cannot do inference when the tag is numeric. + ... This is because there is no way of knowing how many + ... cases the inferred sum type would have. + _ + (/.except ..cannot_infer_sum [expectedT lefts right? valueC]))) + + (^template [ ] + [{ _} + (do ! + [[@instance :instance:] (/type.check )] + (<| (/type.expecting (maybe.trusted (type.applied (list :instance:) expectedT))) + (again valueC)))]) + ([.#UnivQ check.existential] + [.#ExQ check.var]) + + {.#Apply inputT funT} + (case funT + {.#Var funT_id} + (do ! + [?funT' (/type.check (check.peek funT_id))] + (case ?funT' + {.#Some funT'} + (<| (/type.expecting {.#Apply inputT funT'}) + (again valueC)) + + _ + (/.except ..invalid_variant_type [expectedT lefts right? valueC]))) + + _ + (case (type.applied (list inputT) funT) + {.#Some outputT} + (<| (/type.expecting outputT) + (again valueC)) + + {.#None} + (/.except ..not_a_quantified_type [funT]))) + + _ + (/.except ..invalid_variant_type [expectedT lefts right? valueC]))))))) + +(def: .public (variant analyse tag archive valueC) + (-> Phase Symbol Phase) + (do [! ///.monad] + [tag (///extension.lifted (meta.normal tag)) + [idx group variantT] (///extension.lifted (meta.tag tag)) + .let [case_size (list.size group) + [lefts right?] (/complex.choice case_size idx)] + expectedT (///extension.lifted meta.expected_type)] + (case expectedT + {.#Var _} + (do ! + [inferenceT (/inference.variant lefts right? variantT) + [inferredT valueA+] (/inference.general archive analyse inferenceT (list valueC))] + (in (/.variant [lefts right? (|> valueA+ list.head maybe.trusted)]))) + + _ + (..sum analyse lefts right? archive valueC)))) + +(def: (typed_product analyse expectedT archive members) + (-> Phase Type Archive (List Code) (Operation Analysis)) + (<| (let [! ///.monad]) + (# ! each (|>> /.tuple)) + (: (Operation (List Analysis))) + (loop [membersT+ (type.flat_tuple expectedT) + membersC+ members] + (case [membersT+ membersC+] + [{.#Item memberT {.#End}} {.#Item memberC {.#End}}] + (<| (# ! each (|>> list)) + (/type.expecting memberT) + (analyse archive memberC)) + + [{.#Item memberT {.#End}} _] + (<| (/type.expecting memberT) + (# ! each (|>> list) (analyse archive (code.tuple membersC+)))) + + [_ {.#Item memberC {.#End}}] + (<| (/type.expecting (type.tuple membersT+)) + (# ! each (|>> list) (analyse archive memberC))) + + [{.#Item memberT membersT+'} {.#Item memberC membersC+'}] + (do ! + [memberA (<| (/type.expecting memberT) + (analyse archive memberC)) + memberA+ (again membersT+' membersC+')] + (in {.#Item memberA memberA+})) + + _ + (/.except ..cannot_analyse_tuple [expectedT members]))))) + +(def: .public (product analyse archive membersC) + (-> Phase Archive (List Code) (Operation Analysis)) + (do [! ///.monad] + [expectedT (///extension.lifted meta.expected_type)] + (/.with_stack ..cannot_analyse_tuple [expectedT membersC] + (case expectedT + {.#Product _} + (..typed_product analyse expectedT archive membersC) + + {.#Named name unnamedT} + (<| (/type.expecting unnamedT) + (product analyse archive membersC)) + + {.#Var id} + (do ! + [?expectedT' (/type.check (check.peek id))] + (case ?expectedT' + {.#Some expectedT'} + (<| (/type.expecting expectedT') + (product analyse archive membersC)) + + _ + ... Must infer... + (do ! + [membersTA (monad.each ! (|>> (analyse archive) /type.inferring) + membersC) + _ (/type.check (check.check expectedT + (type.tuple (list#each product.left membersTA))))] + (in (/.tuple (list#each product.right membersTA)))))) + + (^template [ ] + [{ _} + (do ! + [[@instance :instance:] (/type.check )] + (<| (/type.expecting (maybe.trusted (type.applied (list :instance:) expectedT))) + (product analyse archive membersC)))]) + ([.#UnivQ check.existential] + [.#ExQ check.var]) + + {.#Apply inputT funT} + (case funT + {.#Var funT_id} + (do ! + [?funT' (/type.check (check.peek funT_id))] + (case ?funT' + {.#Some funT'} + (<| (/type.expecting {.#Apply inputT funT'}) + (product analyse archive membersC)) + + _ + (/.except ..invalid_tuple_type [expectedT membersC]))) + + _ + (case (type.applied (list inputT) funT) + {.#Some outputT} + (<| (/type.expecting outputT) + (product analyse archive membersC)) + + {.#None} + (/.except ..not_a_quantified_type funT))) + + _ + (/.except ..invalid_tuple_type [expectedT membersC]) + )))) + +... There cannot be any ambiguity or improper syntax when analysing +... records, so they must be normalized for further analysis. +... Normalization just means that all the tags get resolved to their +... canonical form (with their corresponding module identified). +(def: .public (normal record) + (-> (List Code) (Operation (Maybe (List [Symbol Code])))) + (loop [input record + output (: (List [Symbol Code]) + {.#End})] + (case input + (^ (list& [_ {.#Symbol slotH}] valueH tail)) + (do ///.monad + [slotH (///extension.lifted (meta.normal slotH))] + (again tail {.#Item [slotH valueH] output})) + + {.#End} + (///#in {.#Some output}) + + _ + (///#in {.#None})))) + +(def: (local_binding? name) + (-> Text (Meta Bit)) + (# meta.monad each + (list.any? (list.any? (|>> product.left (text#= name)))) + meta.locals)) + +... Lux already possesses the means to analyse tuples, so +... re-implementing the same functionality for records makes no sense. +... Records, thus, get transformed into tuples by ordering the elements. +(def: (order' head_k record) + (-> Symbol (List [Symbol Code]) (Operation (Maybe [Nat (List Code) Type]))) + (do [! ///.monad] + [slotH' (///extension.lifted + (do meta.monad + [head_k (meta.normal head_k)] + (meta.try (meta.slot head_k))))] + (case slotH' + {try.#Success [_ slot_set recordT]} + (do ! + [.let [size_record (list.size record) + size_ts (list.size slot_set)] + _ (if (n.= size_ts size_record) + (in []) + (/.except ..record_size_mismatch [size_ts size_record recordT record])) + .let [tuple_range (list.indices size_ts) + tag->idx (dictionary.of_list symbol.hash (list.zipped/2 slot_set tuple_range))] + idx->val (monad.mix ! + (function (_ [key val] idx->val) + (do ! + [key (///extension.lifted (meta.normal key))] + (case (dictionary.value key tag->idx) + {.#Some idx} + (if (dictionary.key? idx->val idx) + (/.except ..cannot_repeat_slot [key record]) + (in (dictionary.has idx val idx->val))) + + {.#None} + (/.except ..slot_does_not_belong_to_record [key recordT])))) + (: (Dictionary Nat Code) + (dictionary.empty n.hash)) + record) + .let [ordered_tuple (list#each (function (_ idx) + (maybe.trusted (dictionary.value idx idx->val))) + tuple_range)]] + (in {.#Some [size_ts ordered_tuple recordT]})) + + {try.#Failure error} + (in {.#None})))) + +(def: .public (order pattern_matching? record) + (-> Bit (List [Symbol Code]) (Operation (Maybe [Nat (List Code) Type]))) + (case record + ... empty_record = empty_tuple = unit/any = [] + {.#End} + (///#in {.#Some [0 (list) .Any]}) + + {.#Item [head_k head_v] _} + (case head_k + ["" head_k'] + (if pattern_matching? + (///#in {.#None}) + (do ///.monad + [local_binding? (///extension.lifted + (..local_binding? head_k'))] + (if local_binding? + (in {.#None}) + (order' head_k record)))) + + _ + (order' head_k record)))) + +(def: .public (record analyse archive members) + (-> Phase Archive (List Code) (Operation Analysis)) + (case members + (^ (list)) + //simple.unit + + (^ (list singletonC)) + (analyse archive singletonC) + + (^ (list [_ {.#Symbol pseudo_slot}] singletonC)) + (do [! ///.monad] + [head_k (///extension.lifted (meta.normal pseudo_slot)) + slot (///extension.lifted (meta.try (meta.slot head_k)))] + (case slot + {try.#Success [_ slot_set recordT]} + (case (list.size slot_set) + 1 (analyse archive singletonC) + _ (..product analyse archive members)) + + _ + (..product analyse archive members))) + + _ + (do [! ///.monad] + [?members (normal members)] + (case ?members + {.#None} + (..product analyse archive members) + + {.#Some slots} + (do ! + [record_size,membersC,recordT (..order false slots)] + (case record_size,membersC,recordT + {.#None} + (..product analyse archive members) + + {.#Some [record_size membersC recordT]} + (do ! + [expectedT (///extension.lifted meta.expected_type)] + (case expectedT + {.#Var _} + (do ! + [inferenceT (/inference.record record_size recordT) + [inferredT membersA] (/inference.general archive analyse inferenceT membersC)] + (in (/.tuple membersA))) + + _ + (..product analyse archive membersC))))))))) 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 deleted file mode 100644 index cdf65a6ad..000000000 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/analysis/structure.lux +++ /dev/null @@ -1,428 +0,0 @@ -(.using - [library - [lux "*" - ["[0]" meta] - [abstract - ["[0]" monad {"+" do}]] - [control - ["[0]" maybe] - ["[0]" try] - ["[0]" exception {"+" exception:}] - ["[0]" state]] - [data - ["[0]" product] - ["[0]" text ("[1]#[0]" equivalence) - ["%" format {"+" format}]] - [collection - ["[0]" list ("[1]#[0]" monad)] - ["[0]" dictionary {"+" Dictionary}]]] - [macro - ["[0]" code]] - [math - [number - ["n" nat]]] - [meta - ["[0]" symbol]] - ["[0]" type - ["[0]" check]]]] - ["[0]" // "_" - ["[1][0]" simple] - ["/[1]" // "_" - ["[1][0]" extension] - [// - ["/" analysis {"+" Analysis Operation Phase} - ["[1][0]" complex {"+" Tag}] - ["[1][0]" type] - ["[1][0]" inference]] - [/// - ["[1]" phase] - [meta - [archive {"+" Archive}]]]]]]) - -(template [] - [(exception: .public ( [type Type - members (List Code)]) - (exception.report - ["Type" (%.type type)] - ["Expression" (%.code (` [(~+ members)]))]))] - - [invalid_tuple_type] - [cannot_analyse_tuple] - ) - -(exception: .public (not_a_quantified_type [type Type]) - (exception.report - ["Type" (%.type type)])) - -(template [] - [(exception: .public ( [type Type - tag Tag - code Code]) - (exception.report - ["Type" (%.type type)] - ["Tag" (%.nat tag)] - ["Expression" (%.code code)]))] - - [invalid_variant_type] - [cannot_analyse_variant] - [cannot_infer_numeric_tag] - ) - -(template [] - [(exception: .public ( [key Symbol - record (List [Symbol Code])]) - (exception.report - ["Slot" (%.code (code.symbol key))] - ["Record" (%.code (code.tuple (|> record - (list#each (function (_ [keyI valC]) - (list (code.symbol keyI) valC))) - list#conjoint)))]))] - - [cannot_repeat_slot] - ) - -(exception: .public (slot_does_not_belong_to_record [key Symbol - type Type]) - (exception.report - ["Slot" (%.code (code.symbol key))] - ["Type" (%.type type)])) - -(exception: .public (record_size_mismatch [expected Nat - actual Nat - type Type - record (List [Symbol Code])]) - (exception.report - ["Expected" (%.nat expected)] - ["Actual" (%.nat actual)] - ["Type" (%.type type)] - ["Expression" (%.code (|> record - (list#each (function (_ [keyI valueC]) - (list (code.symbol keyI) valueC))) - list#conjoint - code.tuple))])) - -(def: .public (sum analyse lefts right? archive) - (-> Phase Nat Bit Phase) - (let [tag (/complex.tag right? lefts)] - (function (again valueC) - (do [! ///.monad] - [expectedT (///extension.lifted meta.expected_type) - expectedT' (/type.check (check.clean expectedT))] - (/.with_stack ..cannot_analyse_variant [expectedT' tag valueC] - (case expectedT - {.#Sum _} - (|> (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) - (again valueC)) - - {.#Var id} - (do ! - [?expectedT' (/type.check (check.peek id))] - (case ?expectedT' - {.#Some expectedT'} - (<| (/type.expecting expectedT') - (again valueC)) - - ... Cannot do inference when the tag is numeric. - ... This is because there is no way of knowing how many - ... cases the inferred sum type would have. - _ - (/.except ..cannot_infer_numeric_tag [expectedT tag valueC]))) - - (^template [ ] - [{ _} - (do ! - [[instance_id instanceT] (/type.check )] - (<| (/type.expecting (maybe.trusted (type.applied (list instanceT) expectedT))) - (again valueC)))]) - ([.#UnivQ check.existential] - [.#ExQ check.var]) - - {.#Apply inputT funT} - (case funT - {.#Var funT_id} - (do ! - [?funT' (/type.check (check.peek funT_id))] - (case ?funT' - {.#Some funT'} - (<| (/type.expecting {.#Apply inputT funT'}) - (again valueC)) - - _ - (/.except ..invalid_variant_type [expectedT tag valueC]))) - - _ - (case (type.applied (list inputT) funT) - {.#Some outputT} - (<| (/type.expecting outputT) - (again valueC)) - - {.#None} - (/.except ..not_a_quantified_type funT))) - - _ - (/.except ..invalid_variant_type [expectedT tag valueC]))))))) - -(def: (typed_product archive analyse members) - (-> Archive Phase (List Code) (Operation Analysis)) - (do [! ///.monad] - [expectedT (///extension.lifted meta.expected_type) - membersA+ (: (Operation (List Analysis)) - (loop [membersT+ (type.flat_tuple expectedT) - membersC+ members] - (case [membersT+ membersC+] - [{.#Item memberT {.#End}} {.#Item memberC {.#End}}] - (do ! - [memberA (<| (/type.expecting memberT) - (analyse archive memberC))] - (in (list memberA))) - - [{.#Item memberT {.#End}} _] - (<| (/type.expecting memberT) - (# ! each (|>> list) (analyse archive (code.tuple membersC+)))) - - [_ {.#Item memberC {.#End}}] - (<| (/type.expecting (type.tuple membersT+)) - (# ! each (|>> list) (analyse archive memberC))) - - [{.#Item memberT membersT+'} {.#Item memberC membersC+'}] - (do ! - [memberA (<| (/type.expecting memberT) - (analyse archive memberC)) - memberA+ (again membersT+' membersC+')] - (in {.#Item memberA memberA+})) - - _ - (/.except ..cannot_analyse_tuple [expectedT members]))))] - (in (/.tuple membersA+)))) - -(def: .public (product archive analyse membersC) - (-> Archive Phase (List Code) (Operation Analysis)) - (do [! ///.monad] - [expectedT (///extension.lifted meta.expected_type)] - (/.with_stack ..cannot_analyse_tuple [expectedT membersC] - (case expectedT - {.#Product _} - (..typed_product archive analyse membersC) - - {.#Named name unnamedT} - (<| (/type.expecting unnamedT) - (product archive analyse membersC)) - - {.#Var id} - (do ! - [?expectedT' (/type.check (check.peek id))] - (case ?expectedT' - {.#Some expectedT'} - (<| (/type.expecting expectedT') - (product archive analyse membersC)) - - _ - ... Must do inference... - (do ! - [membersTA (monad.each ! (|>> (analyse archive) /type.inferring) - membersC) - _ (/type.check (check.check expectedT - (type.tuple (list#each product.left membersTA))))] - (in (/.tuple (list#each product.right membersTA)))))) - - (^template [ ] - [{ _} - (do ! - [[instance_id instanceT] (/type.check )] - (<| (/type.expecting (maybe.trusted (type.applied (list instanceT) expectedT))) - (product archive analyse membersC)))]) - ([.#UnivQ check.existential] - [.#ExQ check.var]) - - {.#Apply inputT funT} - (case funT - {.#Var funT_id} - (do ! - [?funT' (/type.check (check.peek funT_id))] - (case ?funT' - {.#Some funT'} - (<| (/type.expecting {.#Apply inputT funT'}) - (product archive analyse membersC)) - - _ - (/.except ..invalid_tuple_type [expectedT membersC]))) - - _ - (case (type.applied (list inputT) funT) - {.#Some outputT} - (<| (/type.expecting outputT) - (product archive analyse membersC)) - - {.#None} - (/.except ..not_a_quantified_type funT))) - - _ - (/.except ..invalid_tuple_type [expectedT membersC]) - )))) - -(def: .public (tagged_sum analyse tag archive valueC) - (-> Phase Symbol Phase) - (do [! ///.monad] - [tag (///extension.lifted (meta.normal tag)) - [idx group variantT] (///extension.lifted (meta.tag tag)) - .let [case_size (list.size group) - [lefts right?] (/complex.choice case_size idx)] - expectedT (///extension.lifted meta.expected_type)] - (case expectedT - {.#Var _} - (do ! - [inferenceT (/inference.variant lefts right? variantT) - [inferredT valueA+] (/inference.general archive analyse inferenceT (list valueC))] - (in (/.variant [lefts right? (|> valueA+ list.head maybe.trusted)]))) - - _ - (..sum analyse lefts right? archive valueC)))) - -... There cannot be any ambiguity or improper syntax when analysing -... records, so they must be normalized for further analysis. -... Normalization just means that all the tags get resolved to their -... canonical form (with their corresponding module identified). -(def: .public (normal record) - (-> (List Code) (Operation (Maybe (List [Symbol Code])))) - (loop [input record - output (: (List [Symbol Code]) - {.#End})] - (case input - (^ (list& [_ {.#Symbol slotH}] valueH tail)) - (do ///.monad - [slotH (///extension.lifted (meta.normal slotH))] - (again tail {.#Item [slotH valueH] output})) - - {.#End} - (# ///.monad in {.#Some output}) - - _ - (# ///.monad in {.#None})))) - -(def: (local_binding? name) - (-> Text (Meta Bit)) - (# meta.monad each - (list.any? (list.any? (|>> product.left (text#= name)))) - meta.locals)) - -... Lux already possesses the means to analyse tuples, so -... re-implementing the same functionality for records makes no sense. -... Records, thus, get transformed into tuples by ordering the elements. -(def: (order' head_k record) - (-> Symbol (List [Symbol Code]) (Operation (Maybe [Nat (List Code) Type]))) - (do [! ///.monad] - [slotH' (///extension.lifted - (do meta.monad - [head_k (meta.normal head_k)] - (meta.try (meta.slot head_k))))] - (case slotH' - {try.#Success [_ slot_set recordT]} - (do ! - [.let [size_record (list.size record) - size_ts (list.size slot_set)] - _ (if (n.= size_ts size_record) - (in []) - (/.except ..record_size_mismatch [size_ts size_record recordT record])) - .let [tuple_range (list.indices size_ts) - tag->idx (dictionary.of_list symbol.hash (list.zipped/2 slot_set tuple_range))] - idx->val (monad.mix ! - (function (_ [key val] idx->val) - (do ! - [key (///extension.lifted (meta.normal key))] - (case (dictionary.value key tag->idx) - {.#Some idx} - (if (dictionary.key? idx->val idx) - (/.except ..cannot_repeat_slot [key record]) - (in (dictionary.has idx val idx->val))) - - {.#None} - (/.except ..slot_does_not_belong_to_record [key recordT])))) - (: (Dictionary Nat Code) - (dictionary.empty n.hash)) - record) - .let [ordered_tuple (list#each (function (_ idx) - (maybe.trusted (dictionary.value idx idx->val))) - tuple_range)]] - (in {.#Some [size_ts ordered_tuple recordT]})) - - {try.#Failure error} - (in {.#None})))) - -(def: .public (order pattern_matching? record) - (-> Bit (List [Symbol Code]) (Operation (Maybe [Nat (List Code) Type]))) - (case record - ... empty_record = empty_tuple = unit/any = [] - {.#End} - (# ///.monad in {.#Some [0 (list) Any]}) - - {.#Item [head_k head_v] _} - (case head_k - ["" head_k'] - (if pattern_matching? - (# ///.monad in {.#None}) - (do ///.monad - [local_binding? (///extension.lifted - (local_binding? head_k'))] - (if local_binding? - (order' head_k record) - (in {.#None})))) - - _ - (order' head_k record)))) - -(def: .public (record archive analyse members) - (-> Archive Phase (List Code) (Operation Analysis)) - (case members - (^ (list)) - //simple.unit - - (^ (list singletonC)) - (analyse archive singletonC) - - (^ (list [_ {.#Symbol pseudo_slot}] singletonC)) - (do [! ///.monad] - [head_k (///extension.lifted (meta.normal pseudo_slot)) - slot (///extension.lifted (meta.try (meta.slot head_k)))] - (case slot - {try.#Success [_ slot_set recordT]} - (case (list.size slot_set) - 1 (analyse archive singletonC) - _ (..product archive analyse members)) - - _ - (..product archive analyse members))) - - _ - (do [! ///.monad] - [?members (normal members)] - (case ?members - {.#None} - (..product archive analyse members) - - {.#Some slots} - (do ! - [record_size,membersC,recordT (..order false slots)] - (case record_size,membersC,recordT - {.#None} - (..product archive analyse members) - - {.#Some [record_size membersC recordT]} - (do ! - [expectedT (///extension.lifted meta.expected_type)] - (case expectedT - {.#Var _} - (do ! - [inferenceT (/inference.record record_size recordT) - [inferredT membersA] (/inference.general archive analyse inferenceT membersC)] - (in (/.tuple membersA))) - - _ - (..product archive analyse membersC))))))))) 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 2b146414f..4d6c7e712 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 @@ -2180,19 +2180,18 @@ [[_ parameterT] check.existential] (in [parameterJ parameterT]))))) +(def: (matched? [sub sub_method subJT] [super super_method superJT]) + (-> [(Type Class) Text (Type Method)] [(Type Class) Text (Type Method)] Bit) + (and (# descriptor.equivalence = (jvm.descriptor super) (jvm.descriptor sub)) + (text#= super_method sub_method) + (jvm#= superJT subJT))) + (def: (mismatched_methods super_set sub_set) (-> (List [(Type Class) Text (Type Method)]) (List [(Type Class) Text (Type Method)]) (List [(Type Class) Text (Type Method)])) - (list.only (function (_ [sub sub_name subJT]) - (|> super_set - (list.only (function (_ [super super_name superJT]) - (and (jvm#= super sub) - (text#= super_name sub_name) - (jvm#= superJT subJT)))) - list.size - (n.= 1) - not)) + (list.only (function (_ sub) + (not (list.any? (matched? sub) super_set))) sub_set)) (exception: .public (class_parameter_mismatch [name Text @@ -2254,7 +2253,7 @@ methods) .let [missing_abstract_methods (mismatched_methods overriden_methods required_abstract_methods) invalid_overriden_methods (mismatched_methods available_methods overriden_methods)] - _ (phase.assertion ..missing_abstract_methods [required_abstract_methods missing_abstract_methods] + _ (phase.assertion ..missing_abstract_methods [required_abstract_methods overriden_methods] (list.empty? missing_abstract_methods)) _ (phase.assertion ..invalid_overriden_methods [available_methods invalid_overriden_methods] (list.empty? invalid_overriden_methods))] diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux index e6953ac59..7e286955e 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/extension/analysis/lua.lux @@ -1,32 +1,30 @@ (.using - [library - [lux "*" - ["[0]" ffi] - [abstract - ["[0]" monad {"+" do}]] - [control - ["<>" parser - ["<[0]>" code {"+" Parser}]]] - [data - [collection - ["[0]" array {"+" Array}] - ["[0]" dictionary] - ["[0]" list]]] - ["[0]" type - ["[0]" check]] - ["@" target - ["_" lua]]]] + [library + [lux "*" + ["[0]" ffi] + [abstract + ["[0]" monad {"+" do}]] + [control + ["<>" parser + ["<[0]>" code {"+" Parser}]]] + [data + [collection + ["[0]" array {"+" Array}] + ["[0]" dictionary] + ["[0]" list]]] + ["[0]" type + ["[0]" check]] + ["@" target + ["_" lua]]]] + [// + ["/" lux {"+" custom}] [// - ["/" lux {"+" custom}] - [// - ["[0]" bundle] - [// - ["[0]" analysis "_" - ["[1]/[0]" type]] - [// - ["[0]" analysis {"+" Analysis Operation Phase Handler Bundle}] - [/// - ["[0]" phase]]]]]]) + ["[0]" bundle] + [/// + ["[0]" analysis {"+" Analysis Operation Phase Handler Bundle} + ["[1]/[0]" type]] + [/// + ["[0]" phase]]]]]) (def: Nil (for [@.lua ffi.Nil] @@ -46,10 +44,10 @@ [.any (function (_ extension phase archive lengthC) (do phase.monad - [lengthA (analysis/type.with_type Nat - (phase archive lengthC)) - [var_id varT] (analysis/type.with_env check.var) - _ (analysis/type.infer (type (Array varT)))] + [lengthA (analysis/type.expecting Nat + (phase archive lengthC)) + [var_id varT] (analysis/type.check check.var) + _ (analysis/type.inference (type (Array varT)))] (in {analysis.#Extension extension (list lengthA)})))])) (def: array::length @@ -58,10 +56,10 @@ [.any (function (_ extension phase archive arrayC) (do phase.monad - [[var_id varT] (analysis/type.with_env check.var) - arrayA (analysis/type.with_type (type (Array varT)) - (phase archive arrayC)) - _ (analysis/type.infer Nat)] + [[var_id varT] (analysis/type.check check.var) + arrayA (analysis/type.expecting (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.inference Nat)] (in {analysis.#Extension extension (list arrayA)})))])) (def: array::read @@ -70,12 +68,12 @@ [(<>.and .any .any) (function (_ extension phase archive [indexC arrayC]) (do phase.monad - [indexA (analysis/type.with_type Nat - (phase archive indexC)) - [var_id varT] (analysis/type.with_env check.var) - arrayA (analysis/type.with_type (type (Array varT)) - (phase archive arrayC)) - _ (analysis/type.infer varT)] + [indexA (analysis/type.expecting Nat + (phase archive indexC)) + [var_id varT] (analysis/type.check check.var) + arrayA (analysis/type.expecting (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.inference varT)] (in {analysis.#Extension extension (list indexA arrayA)})))])) (def: array::write @@ -84,14 +82,14 @@ [($_ <>.and .any .any .any) (function (_ extension phase archive [indexC valueC arrayC]) (do phase.monad - [indexA (analysis/type.with_type Nat - (phase archive indexC)) - [var_id varT] (analysis/type.with_env check.var) - valueA (analysis/type.with_type varT - (phase archive valueC)) - arrayA (analysis/type.with_type (type (Array varT)) - (phase archive arrayC)) - _ (analysis/type.infer (type (Array varT)))] + [indexA (analysis/type.expecting Nat + (phase archive indexC)) + [var_id varT] (analysis/type.check check.var) + valueA (analysis/type.expecting varT + (phase archive valueC)) + arrayA (analysis/type.expecting (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.inference (type (Array varT)))] (in {analysis.#Extension extension (list indexA valueA arrayA)})))])) (def: array::delete @@ -100,12 +98,12 @@ [($_ <>.and .any .any) (function (_ extension phase archive [indexC arrayC]) (do phase.monad - [indexA (analysis/type.with_type Nat - (phase archive indexC)) - [var_id varT] (analysis/type.with_env check.var) - arrayA (analysis/type.with_type (type (Array varT)) - (phase archive arrayC)) - _ (analysis/type.infer (type (Array varT)))] + [indexA (analysis/type.expecting Nat + (phase archive indexC)) + [var_id varT] (analysis/type.check check.var) + arrayA (analysis/type.expecting (type (Array varT)) + (phase archive arrayC)) + _ (analysis/type.inference (type (Array varT)))] (in {analysis.#Extension extension (list indexA arrayA)})))])) (def: bundle::array @@ -125,9 +123,9 @@ [($_ <>.and .text .any) (function (_ extension phase archive [fieldC objectC]) (do phase.monad - [objectA (analysis/type.with_type ..Object - (phase archive objectC)) - _ (analysis/type.infer .Any)] + [objectA (analysis/type.expecting ..Object + (phase archive objectC)) + _ (analysis/type.inference .Any)] (in {analysis.#Extension extension (list (analysis.text fieldC) objectA)})))])) @@ -137,10 +135,10 @@ [($_ <>.and .text .any (<>.some .any)) (function (_ extension phase archive [methodC objectC inputsC]) (do [! phase.monad] - [objectA (analysis/type.with_type ..Object - (phase archive objectC)) - inputsA (monad.each ! (|>> (phase archive) (analysis/type.with_type Any)) inputsC) - _ (analysis/type.infer .Any)] + [objectA (analysis/type.expecting ..Object + (phase archive objectC)) + inputsA (monad.each ! (|>> (phase archive) (analysis/type.expecting Any)) inputsC) + _ (analysis/type.inference .Any)] (in {analysis.#Extension extension (list& (analysis.text methodC) objectA inputsA)})))])) @@ -162,9 +160,9 @@ [.any (function (_ extension phase archive inputC) (do [! phase.monad] - [inputA (analysis/type.with_type (type ) - (phase archive inputC)) - _ (analysis/type.infer (type ))] + [inputA (analysis/type.expecting (type ) + (phase archive inputC)) + _ (analysis/type.inference (type ))] (in {analysis.#Extension extension (list inputA)})))]))] [utf8::encode Text (array.Array (I64 Any))] @@ -185,7 +183,7 @@ [.text (function (_ extension phase archive name) (do phase.monad - [_ (analysis/type.infer Any)] + [_ (analysis/type.inference Any)] (in {analysis.#Extension extension (list (analysis.text name))})))])) (def: lua::apply @@ -194,10 +192,10 @@ [($_ <>.and .any (<>.some .any)) (function (_ extension phase archive [abstractionC inputsC]) (do [! phase.monad] - [abstractionA (analysis/type.with_type ..Function - (phase archive abstractionC)) - inputsA (monad.each ! (|>> (phase archive) (analysis/type.with_type Any)) inputsC) - _ (analysis/type.infer Any)] + [abstractionA (analysis/type.expecting ..Function + (phase archive abstractionC)) + inputsA (monad.each ! (|>> (phase archive) (analysis/type.expecting Any)) inputsC) + _ (analysis/type.inference Any)] (in {analysis.#Extension extension (list& abstractionA inputsA)})))])) (def: lua::power @@ -206,11 +204,11 @@ [($_ <>.and .any .any) (function (_ extension phase archive [powerC baseC]) (do [! phase.monad] - [powerA (analysis/type.with_type Frac - (phase archive powerC)) - baseA (analysis/type.with_type Frac - (phase archive baseC)) - _ (analysis/type.infer Frac)] + [powerA (analysis/type.expecting Frac + (phase archive powerC)) + baseA (analysis/type.expecting Frac + (phase archive baseC)) + _ (analysis/type.inference Frac)] (in {analysis.#Extension extension (list powerA baseA)})))])) (def: lua::import @@ -219,7 +217,7 @@ [.text (function (_ extension phase archive name) (do phase.monad - [_ (analysis/type.infer ..Object)] + [_ (analysis/type.inference ..Object)] (in {analysis.#Extension extension (list (analysis.text name))})))])) (def: lua::function @@ -229,9 +227,9 @@ (function (_ extension phase archive [arity abstractionC]) (do phase.monad [.let [inputT (type.tuple (list.repeated arity Any))] - abstractionA (analysis/type.with_type (-> inputT Any) - (phase archive abstractionC)) - _ (analysis/type.infer ..Function)] + abstractionA (analysis/type.expecting (-> inputT Any) + (phase archive abstractionC)) + _ (analysis/type.inference ..Function)] (in {analysis.#Extension extension (list (analysis.nat arity) abstractionA)})))])) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/function.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/function.lux index b5899731b..e2ed832c1 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/function.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/function.lux @@ -20,20 +20,22 @@ ["/[1]" // "_" ["[1][0]" reference] ["//[1]" /// "_" - [analysis {"+" Abstraction Application Analysis}] + [analysis {"+" Abstraction Reification Analysis}] [synthesis {"+" Synthesis}] - ["[1][0]" generation {"+" Context}] + ["[1][0]" generation] ["//[1]" /// "_" [arity {"+" Arity}] ["[1][0]" phase ("[1]#[0]" monad)] [meta [archive - ["[0]" dependency]]] + ["[0]" unit]] + ["[0]" cache "_" + ["[1]" artifact]]] [reference [variable {"+" Register Variable}]]]]]]) (def: .public (apply expression archive [functionS argsS+]) - (Generator (Application Synthesis)) + (Generator (Reification Synthesis)) (do [! ///////phase.monad] [functionO (expression archive functionS) argsO+ (monad.each ! (expression archive) argsS+)] @@ -63,13 +65,13 @@ (|>> ++ //case.register)) (def: (@scope function_name) - (-> Context Label) + (-> unit.ID Label) (_.label (format (///reference.artifact function_name) "_scope"))) (def: .public (function statement expression archive [environment arity bodyS]) (-> Phase! (Generator (Abstraction Synthesis))) (do [! ///////phase.monad] - [dependencies (dependency.dependencies archive bodyS) + [dependencies (cache.dependencies archive bodyS) [function_name body!] (/////generation.with_new_context archive dependencies (do ! [@scope (# ! each ..@scope diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/loop.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/loop.lux index 06135b240..59d88e612 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/loop.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/loop.lux @@ -26,8 +26,9 @@ ["//[1]" /// "_" ["[1][0]" phase] [meta - [archive {"+" Archive} - ["[0]" dependency]]] + [archive {"+" Archive}] + ["[0]" cache "_" + ["[1]" artifact]]] [reference [variable {"+" Register}]]]]]]) @@ -82,7 +83,7 @@ ... true loop _ (do [! ///////phase.monad] - [dependencies (dependency.dependencies archive bodyS) + [dependencies (cache.dependencies archive bodyS) [[artifact_module artifact_id] [initsO+ scope!]] (/////generation.with_new_context archive dependencies (scope! statement expression archive true [start initsS+ bodyS])) .let [@loop (_.var (///reference.artifact [artifact_module artifact_id])) diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux index 40525dd00..794bc1fd7 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/runtime.lux @@ -36,7 +36,8 @@ [variable {"+" Register}]] [meta [archive {"+" Output Archive} - ["[0]" artifact {"+" Registry}]]]]]]) + ["[0]" registry {"+" Registry}] + ["[0]" unit]]]]]]) (template [ ] [(type: .public @@ -425,8 +426,8 @@ (do ///////phase.monad [_ (/////generation.execute! ..runtime) _ (/////generation.save! ..module_id {.#None} ..runtime)] - (in [(|> artifact.empty - (artifact.resource true artifact.no_dependencies) + (in [(|> registry.empty + (registry.resource true unit.none) product.right) (sequence.sequence [..module_id {.#None} diff --git a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/structure.lux b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/structure.lux index 97784804e..80028d75e 100644 --- a/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/structure.lux +++ b/stdlib/source/library/lux/tool/compiler/language/lux/phase/generation/lua/structure.lux @@ -11,7 +11,7 @@ ["///[1]" //// "_" ["[1][0]" synthesis {"+" Synthesis}] [analysis - [composite {"+" Variant Tuple}]] + [complex {"+" Variant Tuple}]] ["//[1]" /// "_" ["[1][0]" phase ("[1]#[0]" monad)]]]]) -- cgit v1.2.3