diff options
Diffstat (limited to 'stdlib/source/lux/lang/analysis.lux')
-rw-r--r-- | stdlib/source/lux/lang/analysis.lux | 50 |
1 files changed, 42 insertions, 8 deletions
diff --git a/stdlib/source/lux/lang/analysis.lux b/stdlib/source/lux/lang/analysis.lux index 46927bae1..6b2ba097d 100644 --- a/stdlib/source/lux/lang/analysis.lux +++ b/stdlib/source/lux/lang/analysis.lux @@ -48,10 +48,12 @@ (#Constant Ident) (#Special (Special Text))) -## Variants get analysed as binary sum types for the sake of semantic -## simplicity. -## This is because you can encode a variant of any size using just -## binary sums by nesting them. +(type: #export Variant + {#lefts Nat + #right? Bool + #value Analysis}) + +(type: #export Tuple (List Analysis)) (do-template [<name> <tag>] [(def: <name> @@ -71,8 +73,8 @@ (let [identity (#Function (list) (#Variable (#Local +1)))] (#Apply value identity))) -(def: #export (sum tag size temp value) - (-> Tag Nat Register Analysis Analysis) +(def: #export (sum size tag value) + (-> Nat Tag Analysis Analysis) (if (last? size tag) (if (n/= +1 tag) (..right value) @@ -88,8 +90,8 @@ value) (list.n/range +0 tag)))) -(def: #export (tuple members) - (-> (List Analysis) Analysis) +(def: #export (product members) + (-> Tuple Analysis) (case (list.reverse members) #.Nil (#Primitive #Unit) @@ -107,3 +109,35 @@ (type: #export Analyser (-> Code (Meta Analysis))) + +(def: #export (tuple analysis) + (-> Analysis Tuple) + (case analysis + (#Structure (#Product left right)) + (#.Cons left (tuple right)) + + _ + (list analysis))) + +(def: #export (variant analysis) + (-> Analysis (Maybe Variant)) + (loop [lefts +0 + variantA analysis] + (case variantA + (#Structure (#Sum (#.Left valueA))) + (case valueA + (#Structure (#Sum _)) + (recur (inc lefts) valueA) + + _ + (#.Some {#lefts lefts + #right? false + #value valueA})) + + (#Structure (#Sum (#.Right valueA))) + (#.Some {#lefts lefts + #right? true + #value valueA}) + + _ + #.None))) |