diff options
author | Eduardo Julian | 2017-11-22 20:37:41 -0400 |
---|---|---|
committer | Eduardo Julian | 2017-11-22 20:37:41 -0400 |
commit | 0e3830be97930a01c38d8bca09a1ac9d5bf55465 (patch) | |
tree | 3078996542de6d53baa43388d0bca96e2b517aa9 /new-luxc/source/luxc/lang/analysis/case.lux | |
parent | e37e3713e080606930a5f8442f03dabc4c26a7f9 (diff) |
- Fixed some bugs.
- Some refactoring.
- Added some alternative snippets of code that new-luxc can handle better.
Diffstat (limited to '')
-rw-r--r-- | new-luxc/source/luxc/lang/analysis/case.lux | 105 |
1 files changed, 68 insertions, 37 deletions
diff --git a/new-luxc/source/luxc/lang/analysis/case.lux b/new-luxc/source/luxc/lang/analysis/case.lux index 5d4c592aa..949e18a26 100644 --- a/new-luxc/source/luxc/lang/analysis/case.lux +++ b/new-luxc/source/luxc/lang/analysis/case.lux @@ -35,6 +35,15 @@ (format " Type: " (%type type) "\n" "Pattern: " (%code pattern))) +(def: (re-quantify envs baseT) + (-> (List (List Type)) Type Type) + (case envs + #;Nil + baseT + + (#;Cons head tail) + (re-quantify tail (#;UnivQ head baseT)))) + ## Type-checking on the input value is done during the analysis of a ## "case" expression, to ensure that the patterns being used make ## sense for the type of the input value. @@ -44,52 +53,74 @@ ## type-check the input with respect to the patterns. (def: (simplify-case-type caseT) (-> Type (Meta Type)) - (case caseT - (#;Var id) - (do macro;Monad<Meta> - [?caseT' (&;with-type-env - (tc;read id))] - (case ?caseT' - (#;Some caseT') - (simplify-case-type caseT') + (loop [envs (: (List (List Type)) + (list)) + caseT caseT] + (case caseT + (#;Var id) + (do macro;Monad<Meta> + [?caseT' (&;with-type-env + (tc;read id))] + (case ?caseT' + (#;Some caseT') + (recur envs caseT') - _ - (&;throw Cannot-Simplify-Type-For-Pattern-Matching (%type caseT)))) + _ + (&;throw Cannot-Simplify-Type-For-Pattern-Matching (%type caseT)))) - (#;Named name unnamedT) - (simplify-case-type unnamedT) + (#;Named name unnamedT) + (recur envs unnamedT) - (^or (#;UnivQ _) (#;ExQ _)) - (do macro;Monad<Meta> - [[ex-id exT] (&;with-type-env - tc;existential)] - (simplify-case-type (maybe;assume (type;apply (list exT) caseT)))) + (#;UnivQ env unquantifiedT) + (recur (#;Cons env envs) unquantifiedT) - (#;Apply inputT funcT) - (case funcT - (#;Var funcT-id) + ## (^template [<tag> <instancer>] + ## (<tag> _) + ## (do macro;Monad<Meta> + ## [[_ instanceT] (&;with-type-env + ## <instancer>)] + ## (recur (maybe;assume (type;apply (list instanceT) caseT))))) + ## ([#;UnivQ tc;var] + ## [#;ExQ tc;existential]) + + (#;ExQ _) (do macro;Monad<Meta> - [funcT' (&;with-type-env - (do tc;Monad<Check> - [?funct' (tc;read funcT-id)] - (case ?funct' - (#;Some funct') - (wrap funct') + [[ex-id exT] (&;with-type-env + tc;existential)] + (recur envs (maybe;assume (type;apply (list exT) caseT)))) - _ - (tc;throw Cannot-Simplify-Type-For-Pattern-Matching (%type caseT)))))] - (simplify-case-type (#;Apply inputT funcT'))) + (#;Apply inputT funcT) + (case funcT + (#;Var funcT-id) + (do macro;Monad<Meta> + [funcT' (&;with-type-env + (do tc;Monad<Check> + [?funct' (tc;read funcT-id)] + (case ?funct' + (#;Some funct') + (wrap funct') - _ - (case (type;apply (list inputT) funcT) - (#;Some outputT) - (:: macro;Monad<Meta> wrap outputT) + _ + (tc;throw Cannot-Simplify-Type-For-Pattern-Matching (%type caseT)))))] + (recur envs (#;Apply inputT funcT'))) - #;None - (&;throw Cannot-Simplify-Type-For-Pattern-Matching (%type caseT)))) + _ + (case (type;apply (list inputT) funcT) + (#;Some outputT) + (recur envs outputT) - _ - (:: macro;Monad<Meta> wrap caseT))) + #;None + (&;throw Cannot-Simplify-Type-For-Pattern-Matching (%type caseT)))) + + (#;Product _) + (|> caseT + type;flatten-tuple + (list/map (re-quantify envs)) + type;tuple + (:: macro;Monad<Meta> wrap)) + + _ + (:: macro;Monad<Meta> wrap (re-quantify envs caseT))))) ## This function handles several concerns at once, but it must be that ## way because those concerns are interleaved when doing |