aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/lang/analysis.lux
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/lang/analysis.lux')
-rw-r--r--stdlib/source/lux/lang/analysis.lux50
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)))