diff options
Diffstat (limited to 'stdlib/source/test/lux/meta/compiler/language/lux/phase/analysis.lux')
-rw-r--r-- | stdlib/source/test/lux/meta/compiler/language/lux/phase/analysis.lux | 967 |
1 files changed, 967 insertions, 0 deletions
diff --git a/stdlib/source/test/lux/meta/compiler/language/lux/phase/analysis.lux b/stdlib/source/test/lux/meta/compiler/language/lux/phase/analysis.lux new file mode 100644 index 000000000..91614f4b2 --- /dev/null +++ b/stdlib/source/test/lux/meta/compiler/language/lux/phase/analysis.lux @@ -0,0 +1,967 @@ +(.require + [library + [lux (.except) + ["_" test (.only Test)] + [abstract + [monad (.only do)]] + [control + ["[0]" try] + ["[0]" exception]] + [data + ["[0]" product] + ["[0]" text] + [collection + ["[0]" list]]] + [math + ["[0]" random] + [number + ["n" nat]]] + [meta + ["[0]" code] + ["[0]" macro] + ["[0]" type (.use "[1]#[0]" equivalence) + ["[0]" check]]]]] + [\\library + ["[0]" / (.only) + [// + ["[0]" extension (.only) + ["[1]/[0]" analysis + ["[1]" lux]]] + [// + ["/[1]" analysis (.only Analysis Operation) + [evaluation (.only Eval)] + ["[1][0]" macro] + ["[1][0]" scope] + ["[1][0]" module] + ["[1][0]" pattern] + ["[1][0]" type (.only) + ["$[1]" \\test]]] + [/// + ["[0]" phase (.use "[1]#[0]" monad)] + [meta + ["[0]" archive]]]]]]] + ["[0]" / + ["[1][0]" simple] + ["[1][0]" complex] + ["[1][0]" reference] + ["[1][0]" function] + ["[1][0]" case]]) + +(def (eval archive type term) + Eval + (phase#in [])) + +(def (expander macro inputs state) + //macro.Expander + {try.#Success ((macro.function macro) inputs state)}) + +(def (can_analyse_unit! lux module/0) + (-> Lux Text Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux]] + (|> (do phase.monad + [[:it: it] (|> (' []) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Any :it:) + (case it + (//.unit) + true + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)))) + +(def (can_analyse_simple_literal_or_singleton_tuple! lux module/0 [bit/0 nat/0 int/0 rev/0 frac/0 text/0]) + (-> Lux Text [.Bit .Nat .Int .Rev .Frac .Text] Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux]] + (`` (and (,, (with_template [<expected> <code> <type> <analysis>] + [(|> (do phase.monad + [[:it: it] (|> <expected> + <code> + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= <type> :it:) + (case it + (<analysis> it) + (same? <expected> it) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + + [bit/0 code.bit .Bit //.bit] + [nat/0 code.nat .Nat //.nat] + [int/0 code.int .Int //.int] + [rev/0 code.rev .Rev //.rev] + [frac/0 code.frac .Frac //.frac] + [text/0 code.text .Text //.text] + + ... Singleton tuple + [bit/0 (<| code.tuple list code.bit) .Bit //.bit] + [nat/0 (<| code.tuple list code.nat) .Nat //.nat] + [int/0 (<| code.tuple list code.int) .Int //.int] + [rev/0 (<| code.tuple list code.rev) .Rev //.rev] + [frac/0 (<| code.tuple list code.frac) .Frac //.frac] + [text/0 (<| code.tuple list code.text) .Text //.text] + )) + )))) + +(def (can_analyse_sum! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0] [@left @right]) + (-> Lux Text [.Text .Text .Text .Text .Text .Text .Text] [.Bit .Nat .Int .Rev .Frac .Text] [.Text .Text] Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux] + :record: (And .Any .Bit .Nat .Int .Rev .Frac .Text) + :variant: (Or .Any .Bit .Nat .Int .Rev .Frac .Text) + + can_analyse_unary! + (`` (and (|> (do phase.monad + [it (|> (code.variant (list (code.nat 0) (code.bit #0) (` []))) + (/.phase ..expander archive.empty) + (//type.expecting :variant:))] + (in (case it + (//.variant [0 #0 (//.unit)]) + true + + _ + false))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + (,, (with_template [<lefts> <right> <expected> <tag> <code> <analysis>] + [(|> (do phase.monad + [it (|> (code.variant (list (code.nat <lefts>) (code.bit <right>) (<code> <expected>))) + (/.phase ..expander archive.empty) + (//type.expecting :variant:))] + (in (case it + (//.variant [<lefts> <right> (<analysis> actual)]) + (same? <expected> actual) + + _ + false))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + + [1 #0 bit/0 @bit code.bit //.bit] + [2 #0 nat/0 @nat code.nat //.nat] + [3 #0 int/0 @int code.int //.int] + [4 #0 rev/0 @rev code.rev //.rev] + [5 #0 frac/0 @frac code.frac //.frac] + [5 #1 text/0 @text code.text //.text] + )))) + + can_analyse_nullary! + (|> (do phase.monad + [.let [:either: (Or .Any :record:)] + it (|> (code.variant (list (code.nat 0) (code.bit #0))) + (/.phase ..expander archive.empty) + (//type.expecting :either:))] + (in (case it + (//.variant [0 #0 (//.unit)]) + true + + _ + false))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + can_analyse_multiary! + (|> (do phase.monad + [.let [:either: (Or .Any :record:)] + it (|> (code.variant (list (code.nat 0) + (code.bit #1) + (` []) + (code.bit bit/0) + (code.nat nat/0) + (code.int int/0) + (code.rev rev/0) + (code.frac frac/0) + (code.text text/0))) + (/.phase ..expander archive.empty) + (//type.expecting :either:))] + (in (case it + (//.variant [0 #1 (//.tuple (list (//.unit) + (//.bit bit/?) + (//.nat nat/?) + (//.int int/?) + (//.rev rev/?) + (//.frac frac/?) + (//.text text/?)))]) + (and (same? bit/0 bit/?) + (same? nat/0 nat/?) + (same? int/0 int/?) + (same? rev/0 rev/?) + (same? frac/0 frac/?) + (same? text/0 text/?)) + + _ + false))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + (and can_analyse_unary! + can_analyse_nullary! + can_analyse_multiary! + ))) + +(def (can_analyse_variant! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0] [@left @right]) + (-> Lux Text [.Text .Text .Text .Text .Text .Text .Text] [.Bit .Nat .Int .Rev .Frac .Text] [.Text .Text] Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux] + :record: {.#Named [module/0 @text] + (type_literal [.Any .Bit .Nat .Int .Rev .Frac .Text])} + slots/* (list @any @bit @nat @int @rev @frac @text) + :variant: {.#Named [module/0 @text] + (type_literal (Or .Any .Bit .Nat .Int .Rev .Frac .Text))} + tags/* (list @any @bit @nat @int @rev @frac @text) + + can_analyse_unary! + (`` (and (|> (do phase.monad + [_ (//module.declare_labels false tags/* false :variant:) + [:it: it] (|> (code.variant (list (code.local @any) (` []))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= :variant: + :it:) + (case it + (//.variant [0 #0 (//.unit)]) + true + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + (,, (with_template [<lefts> <right> <expected> <tag> <code> <analysis>] + [(|> (do phase.monad + [_ (//module.declare_labels false tags/* false :variant:) + [:it: it] (|> (code.variant (list (code.local <tag>) (<code> <expected>))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= :variant: + :it:) + (case it + (//.variant [<lefts> <right> (<analysis> actual)]) + (same? <expected> actual) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + + [1 #0 bit/0 @bit code.bit //.bit] + [2 #0 nat/0 @nat code.nat //.nat] + [3 #0 int/0 @int code.int //.int] + [4 #0 rev/0 @rev code.rev //.rev] + [5 #0 frac/0 @frac code.frac //.frac] + [5 #1 text/0 @text code.text //.text] + )))) + + can_analyse_nullary! + (|> (do phase.monad + [_ (//module.declare_labels true slots/* false :record:) + .let [:either: {.#Named [module/0 module/0] + (type_literal (Or .Any :record:))}] + _ (//module.declare_labels false (list @left @right) false :either:) + [:it: it] (|> (code.variant (list (code.local @left))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= :either: + :it:) + (case it + (//.variant [0 #0 (//.unit)]) + true + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + can_analyse_multiary! + (|> (do phase.monad + [_ (//module.declare_labels true slots/* false :record:) + .let [:either: {.#Named [module/0 module/0] + (type_literal (Or .Any :record:))}] + _ (//module.declare_labels false (list @left @right) false :either:) + [:it: it] (|> (code.variant (list (code.local @right) + (` []) + (code.bit bit/0) + (code.nat nat/0) + (code.int int/0) + (code.rev rev/0) + (code.frac frac/0) + (code.text text/0))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= :either: + :it:) + (case it + (//.variant [0 #1 (//.tuple (list (//.unit) + (//.bit bit/?) + (//.nat nat/?) + (//.int int/?) + (//.rev rev/?) + (//.frac frac/?) + (//.text text/?)))]) + (and (same? bit/0 bit/?) + (same? nat/0 nat/?) + (same? int/0 int/?) + (same? rev/0 rev/?) + (same? frac/0 frac/?) + (same? text/0 text/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + (and can_analyse_unary! + can_analyse_nullary! + can_analyse_multiary!))) + +(def (can_analyse_tuple! lux module/0 [bit/0 nat/0 int/0 rev/0 frac/0 text/0]) + (-> Lux Text [.Bit .Nat .Int .Rev .Frac .Text] Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux]] + (|> (do phase.monad + [[:it: it] (|> (code.tuple (list (` []) + (code.bit bit/0) + (code.nat nat/0) + (code.int int/0) + (code.rev rev/0) + (code.frac frac/0) + (code.text text/0))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= (type_literal [.Any .Bit .Nat .Int .Rev .Frac .Text]) + :it:) + (case it + (//.tuple (list (//.unit) + (//.bit bit/?) + (//.nat nat/?) + (//.int int/?) + (//.rev rev/?) + (//.frac frac/?) + (//.text text/?))) + (and (same? bit/0 bit/?) + (same? nat/0 nat/?) + (same? int/0 int/?) + (same? rev/0 rev/?) + (same? frac/0 frac/?) + (same? text/0 text/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)))) + +(def (can_analyse_record! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0]) + (-> Lux Text [.Text .Text .Text .Text .Text .Text .Text] [.Bit .Nat .Int .Rev .Frac .Text] Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux] + :record: {.#Named [module/0 @text] + (type_literal [.Any .Bit .Nat .Int .Rev .Frac .Text])} + slots/* (list @any @bit @nat @int @rev @frac @text)] + (|> (do phase.monad + [_ (//module.declare_labels true slots/* false :record:) + [:it: it] (|> (code.tuple (list (code.local @text) (code.text text/0) + (code.local @bit) (code.bit bit/0) + (code.local @rev) (code.rev rev/0) + (code.local @int) (code.int int/0) + (code.local @nat) (code.nat nat/0) + (code.local @frac) (code.frac frac/0) + (code.local @any) (` []))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= :record: + :it:) + (case it + (//.tuple (list (//.unit) + (//.bit bit/?) + (//.nat nat/?) + (//.int int/?) + (//.rev rev/?) + (//.frac frac/?) + (//.text text/?))) + (and (same? bit/0 bit/?) + (same? nat/0 nat/?) + (same? int/0 int/?) + (same? rev/0 rev/?) + (same? frac/0 frac/?) + (same? text/0 text/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)))) + +(def (can_analyse_function! lux module/0 nat/0 [$abstraction/0 $parameter/0 $abstraction/1 $parameter/1]) + (-> Lux Text Nat [Code Code Code Code] Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux] + + can_make_abstraction! + (|> (do phase.monad + [[:it: it] (|> (` ([(, $abstraction/0) (, $parameter/0)] (, (code.nat nat/0)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= (All (_ a) (-> a .Nat)) + :it:) + (case it + {//.#Function (list) (//.nat nat/?)} + (same? nat/0 nat/?) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + can_nest_abstraction! + (|> (do phase.monad + [[:it: it] (|> (` ([(, $abstraction/0) (, $parameter/0)] + ([(, $abstraction/1) (, $parameter/1)] + (, (code.nat nat/0))))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= (All (_ a) (-> a (All (_ b) (-> b .Nat)))) + :it:) + (case it + {//.#Function (list) {//.#Function (list) (//.nat nat/?)}} + (same? nat/0 nat/?) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + can_refer_to_parameter! + (|> (do phase.monad + [[:it: it] (|> (` ([(, $abstraction/0) (, $parameter/0)] + ([(, $abstraction/1) (, $parameter/1)] + (, $parameter/1)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= (All (_ a) (-> a (All (_ b) (-> b b)))) + :it:) + (case it + {//.#Function (list) {//.#Function (list) (//.local 1)}} + true + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + can_refer_to_closure! + (|> (do phase.monad + [[:it: it] (|> (` ([(, $abstraction/0) (, $parameter/0)] + ([(, $abstraction/1) (, $parameter/1)] + (, $parameter/0)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (case it + {//.#Function (list) {//.#Function (list (//.local 1)) (//.foreign 0)}} + true + + _ + false) + ... TODO: Un-comment + ... (type#= (All (_ a) (-> a (All (_ b) (-> b a)))) + ... :it:) + ))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + (and can_make_abstraction! + can_nest_abstraction! + can_refer_to_parameter! + can_refer_to_closure! + ... TODO: Un-comment + ... (|> (do phase.monad + ... [[:it: it] (|> (` ([(, $abstraction/0) (, $parameter/0)] + ... ([(, $abstraction/1) (, $parameter/1)] + ... (, $abstraction/1)))) + ... (/.phase ..expander archive.empty) + ... //type.inferring)] + ... (in (case it + ... {//.#Function (list) {//.#Function (list) (//.local 0)}} + ... true + + ... _ + ... false))) + ... //scope.with + ... (//module.with 0 module/0) + ... (phase#each (|>> product.right product.right)) + ... (phase.result state) + ... (try.else false)) + ... TODO: Un-comment + ... (|> (do phase.monad + ... [[:it: it] (|> (` ([(, $abstraction/0) (, $parameter/0)] + ... ([(, $abstraction/1) (, $parameter/1)] + ... (, $abstraction/0)))) + ... (/.phase ..expander archive.empty) + ... //type.inferring)] + ... (in (case it + ... {//.#Function (list) {//.#Function (list (//.local 0)) (//.foreign 0)}} + ... true + + ... _ + ... false))) + ... //scope.with + ... (//module.with 0 module/0) + ... (phase#each (|>> product.right product.right)) + ... (phase.result state) + ... (try.else false)) + ))) + +(def (can_analyse_apply! lux module/0 bit/0 nat/0 [$abstraction/0 $parameter/0 $abstraction/1 $parameter/1]) + (-> Lux Text Bit Nat [Code Code Code Code] Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux] + + constant! + (|> (do phase.monad + [[:it: it] (|> (` (([(, $abstraction/0) (, $parameter/0)] (, (code.bit bit/0))) + (, (code.nat nat/0)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Bit :it:) + (case it + {//.#Apply (//.nat nat/?) + {//.#Function (list) (//.bit bit/?)}} + (and (same? bit/0 bit/?) + (same? nat/0 nat/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + variable! + (|> (do phase.monad + [[:it: it] (|> (` (([(, $abstraction/0) (, $parameter/0)] (, $parameter/0)) + (, (code.nat nat/0)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Nat :it:) + (case it + {//.#Apply (//.nat nat/?) + {//.#Function (list) (//.local 1)}} + (same? nat/0 nat/?) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + partial! + (|> (do phase.monad + [[:it: it] (|> (` (([(, $abstraction/0) (, $parameter/0)] + ([(, $abstraction/1) (, $parameter/1)] + (, (code.bit bit/0)))) + (, (code.nat nat/0)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (check.subsumes? (All (_ a) (-> a Bit)) :it:) + (case it + {//.#Apply (//.nat nat/?) + {//.#Function (list) + {//.#Function (list) (//.bit bit/?)}}} + (and (same? bit/0 bit/?) + (same? nat/0 nat/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + (and constant! + variable! + partial!))) + +(def (can_analyse_extension! lux module/0 text/0) + (-> Lux Text Text Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux]] + (|> (do phase.monad + [[:it: it] (|> (` ("lux text concat" (, (code.text text/0)) (, (code.text text/0)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Text :it:) + (case it + {//.#Extension "lux text concat" (list (//.text left) (//.text right))} + (and (same? text/0 left) + (same? text/0 right)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)))) + +(def (can_analyse_pattern_matching! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0] $parameter/0) + (-> Lux Text [.Text .Text .Text .Text .Text .Text .Text] [.Bit .Nat .Int .Rev .Frac .Text] Code Bit) + (let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux] + + :variant: {.#Named [module/0 module/0] + (type_literal (Or .Any .Bit .Nat .Int .Rev .Frac .Text))} + tags/* (list @any @bit @nat @int @rev @frac @text) + + :record: {.#Named [module/0 module/0] + (type_literal (And .Any .Bit .Nat .Int .Rev .Frac .Text))} + slots/* (list @any @bit @nat @int @rev @frac @text) + + simple! + (`` (and (,, (with_template [<input> <code> <analysis> <pattern>] + [(|> (do phase.monad + [[:it: it] (|> (` ({(, $parameter/0) (, (code.frac frac/0))} (, (<code> <input>)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Frac :it:) + (case it + {//.#Case (<analysis> input/?) + [[//.#when (//pattern.bind 0) + //.#then (//.frac frac/?)] + (list)]} + (and (same? <input> input/?) + (same? frac/0 frac/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + (|> (do phase.monad + [[:it: it] (|> (` ({(, (<code> <input>)) + (, (code.frac frac/0)) + + (, $parameter/0) + (, (code.frac frac/0))} + (, (<code> <input>)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Frac :it:) + (case it + {//.#Case (<analysis> input/?) + [[//.#when (<pattern> pattern/?) + //.#then (//.frac frac/?)] + (list [//.#when (//pattern.bind 0) + //.#then (//.frac frac/?)])]} + (and (same? <input> input/?) + (same? <input> pattern/?) + (same? frac/0 frac/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + + [bit/0 code.bit //.bit //pattern.bit] + [nat/0 code.nat //.nat //pattern.nat] + [int/0 code.int //.int //pattern.int] + [rev/0 code.rev //.rev //pattern.rev] + [frac/0 code.frac //.frac //pattern.frac] + [text/0 code.text //.text //pattern.text] + )))) + + bit! + (|> (do phase.monad + [[:it: it] (|> (` ({#0 + (, (code.frac frac/0)) + + #1 + (, (code.frac frac/0))} + (, (code.bit bit/0)))) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Frac :it:) + (case it + {//.#Case (//.bit bit/?) + [[//.#when (//pattern.bit #0) + //.#then (//.frac false/?)] + (list [//.#when (//pattern.bit #1) + //.#then (//.frac true/?)])]} + (and (same? bit/0 bit/?) + (same? frac/0 false/?) + (same? frac/0 true/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + variant! + (`` (and (,, (with_template [<lefts> <right?> <expected> <tag> <code> <analysis> <pattern>] + [(|> (do phase.monad + [_ (//module.declare_labels false tags/* false :variant:) + [:it: it] (|> (` ({{(, (code.local <tag>)) (, (<code> <expected>))} + (, (code.frac frac/0)) + + (, $parameter/0) + (, (code.frac frac/0))} + {(, (code.local <tag>)) (, (<code> <expected>))})) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Frac :it:) + (case it + {//.#Case (//.variant [<lefts> <right?> (<analysis> analysis/?)]) + [[//.#when (//pattern.variant [<lefts> <right?> (<pattern> pattern/?)]) + //.#then (//.frac match/?)] + (list [//.#when (//pattern.bind 0) + //.#then (//.frac mismatch/?)])]} + (and (same? <expected> analysis/?) + (same? <expected> pattern/?) + (same? frac/0 match/?) + (same? frac/0 mismatch/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + + [1 #0 bit/0 @bit code.bit //.bit //pattern.bit] + [2 #0 nat/0 @nat code.nat //.nat //pattern.nat] + [3 #0 int/0 @int code.int //.int //pattern.int] + [4 #0 rev/0 @rev code.rev //.rev //pattern.rev] + [5 #0 frac/0 @frac code.frac //.frac //pattern.frac] + [5 #1 text/0 @text code.text //.text //pattern.text] + )))) + + tuple! + (|> (do phase.monad + [[:it: it] (|> (` ({[#0 (, $parameter/0)] + (, (code.frac frac/0)) + + [#1 (, $parameter/0)] + (, (code.frac frac/0))} + [(, (code.bit bit/0)) + (, (code.nat nat/0))])) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Frac :it:) + (case it + {//.#Case (//.tuple (list (//.bit bit/?) (//.nat nat/?))) + [[//.#when (//pattern.tuple (list (//pattern.bit #0) (//pattern.bind 0))) + //.#then (//.frac false/?)] + (list [//.#when (//pattern.tuple (list (//pattern.bit #1) (//pattern.bind 0))) + //.#then (//.frac true/?)])]} + (and (same? bit/0 bit/?) + (same? nat/0 nat/?) + (same? frac/0 false/?) + (same? frac/0 true/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false)) + + record! + (|> (do phase.monad + [_ (//module.declare_labels true slots/* false :record:) + [:it: it] (|> (` ({[(, (code.symbol [module/0 @any])) [] + (, (code.symbol [module/0 @bit])) (, (code.bit bit/0)) + (, (code.symbol [module/0 @nat])) (, (code.nat nat/0)) + (, (code.symbol [module/0 @int])) (, (code.int int/0)) + (, (code.symbol [module/0 @rev])) (, (code.rev rev/0)) + (, (code.symbol [module/0 @frac])) (, (code.frac frac/0)) + (, (code.symbol [module/0 @text])) (, (code.text text/0))] + (, (code.frac frac/0)) + + (, $parameter/0) + (, (code.frac frac/0))} + [(, (code.local @any)) [] + (, (code.local @bit)) (, (code.bit bit/0)) + (, (code.local @nat)) (, (code.nat nat/0)) + (, (code.local @int)) (, (code.int int/0)) + (, (code.local @rev)) (, (code.rev rev/0)) + (, (code.local @frac)) (, (code.frac frac/0)) + (, (code.local @text)) (, (code.text text/0))])) + (/.phase ..expander archive.empty) + //type.inferring)] + (in (and (type#= .Frac :it:) + (case it + {//.#Case (//.tuple (list (//.unit) + (//.bit bit/?) + (//.nat nat/?) + (//.int int/?) + (//.rev rev/?) + (//.frac frac/?) + (//.text text/?))) + [[//.#when (//pattern.tuple (list (//pattern.unit) + (//pattern.bit bit/?') + (//pattern.nat nat/?') + (//pattern.int int/?') + (//pattern.rev rev/?') + (//pattern.frac frac/?') + (//pattern.text text/?'))) + //.#then (//.frac match/?)] + (list [//.#when (//pattern.bind 0) + //.#then (//.frac mismatch/?)])]} + (and (same? bit/0 bit/?) (same? bit/0 bit/?') + (same? nat/0 nat/?) (same? nat/0 nat/?') + (same? int/0 int/?) (same? int/0 int/?') + (same? rev/0 rev/?) (same? rev/0 rev/?') + (same? frac/0 frac/?) (same? frac/0 frac/?') + (same? text/0 text/?) (same? text/0 text/?') + (same? frac/0 match/?) + (same? frac/0 mismatch/?)) + + _ + false)))) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (try.else false))] + (and simple! + bit! + variant! + tuple! + record!))) + +(def .public test + Test + (<| (_.covering /._) + (do [! random.monad] + [lux $//type.random_state + .let [state [extension.#bundle (extension/analysis.bundle ..eval) + extension.#state lux]] + + .let [[module/0 _] (symbol ._)] + + bit/0 random.bit + nat/0 random.nat + int/0 random.int + rev/0 random.rev + frac/0 random.frac + text/0 (random.lower_case 1) + + @any (random.lower_case 2) + @bit (random.lower_case 3) + @nat (random.lower_case 4) + @int (random.lower_case 5) + @rev (random.lower_case 6) + @frac (random.lower_case 7) + @text (random.lower_case 8) + + @left (random.lower_case 9) + @right (random.lower_case 10) + + $abstraction/0 (at ! each code.local (random.lower_case 11)) + $parameter/0 (at ! each code.local (random.lower_case 12)) + $abstraction/1 (at ! each code.local (random.lower_case 13)) + $parameter/1 (at ! each code.local (random.lower_case 14))]) + (all _.and + (_.coverage [/.phase] + (and (..can_analyse_unit! lux module/0) + (..can_analyse_simple_literal_or_singleton_tuple! lux module/0 [bit/0 nat/0 int/0 rev/0 frac/0 text/0]) + (..can_analyse_sum! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0] [@left @right]) + (..can_analyse_variant! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0] [@left @right]) + (..can_analyse_tuple! lux module/0 [bit/0 nat/0 int/0 rev/0 frac/0 text/0]) + (..can_analyse_record! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0]) + (..can_analyse_function! lux module/0 nat/0 [$abstraction/0 $parameter/0 $abstraction/1 $parameter/1]) + (..can_analyse_apply! lux module/0 bit/0 nat/0 [$abstraction/0 $parameter/0 $abstraction/1 $parameter/1]) + (..can_analyse_extension! lux module/0 text/0) + (..can_analyse_pattern_matching! lux module/0 [@any @bit @nat @int @rev @frac @text] [bit/0 nat/0 int/0 rev/0 frac/0 text/0] $parameter/0) + )) + (_.coverage [/.invalid] + (`` (and (,, (with_template [<syntax>] + [(|> (do phase.monad + [_ (|> <syntax> + (/.phase ..expander archive.empty) + (//type.expecting .Any))] + (in false)) + //scope.with + (//module.with 0 module/0) + (phase#each (|>> product.right product.right)) + (phase.result state) + (exception.otherwise (text.contains? (the exception.#label /.invalid))))] + + [(` ({#0} (, (code.bit bit/0))))] + [(` ({#0 [] #1} (, (code.bit bit/0))))] + [(` {(, (code.bit bit/0)) (, (code.nat nat/0)) (, (code.int int/0)) (, (code.rev rev/0)) (, (code.frac frac/0)) (, (code.text text/0))})] + [(` {(, (code.nat nat/0)) (, (code.int int/0)) (, (code.rev rev/0)) (, (code.frac frac/0)) (, (code.text text/0)) (, (code.bit bit/0))})] + [(` {(, (code.int int/0)) (, (code.rev rev/0)) (, (code.frac frac/0)) (, (code.text text/0)) (, (code.bit bit/0)) (, (code.nat nat/0))})] + [(` {(, (code.rev rev/0)) (, (code.frac frac/0)) (, (code.text text/0)) (, (code.bit bit/0)) (, (code.nat nat/0)) (, (code.int int/0))})] + [(` {(, (code.frac frac/0)) (, (code.text text/0)) (, (code.bit bit/0)) (, (code.nat nat/0)) (, (code.int int/0)) (, (code.rev rev/0))})] + [(` {(, (code.text text/0)) (, (code.bit bit/0)) (, (code.nat nat/0)) (, (code.int int/0)) (, (code.rev rev/0)) (, (code.frac frac/0))})] + )) + ))) + + /simple.test + /complex.test + /reference.test + /function.test + /case.test + ))) |