aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lux/analyser/case.clj49
-rw-r--r--src/lux/base.clj33
-rw-r--r--src/lux/compiler/case.clj2
3 files changed, 69 insertions, 15 deletions
diff --git a/src/lux/analyser/case.clj b/src/lux/analyser/case.clj
index 34cbf8b48..148e2822a 100644
--- a/src/lux/analyser/case.clj
+++ b/src/lux/analyser/case.clj
@@ -223,13 +223,14 @@
value-type* (adjust-type value-type)
;; :let [_ (println "#02")]
idx (&module/tag-index =module =name)
+ group (&module/tag-group =module =name)
;; :let [_ (println "#03")]
case-type (&type/variant-case idx value-type*)
;; :let [_ (println "#04")]
[=test =kont] (analyse-pattern case-type unit kont)
;; :let [_ (println "#05")]
]
- (return (&/T (&/V $VariantTestAC (&/T idx =test)) =kont)))
+ (return (&/T (&/V $VariantTestAC (&/T idx (&/|length group) =test)) =kont)))
(&/$FormS (&/$Cons (&/$Meta _ (&/$TagS ?ident))
?values))
@@ -239,6 +240,7 @@
value-type* (adjust-type value-type)
;; :let [_ (println "#12" (&type/show-type value-type*))]
idx (&module/tag-index =module =name)
+ group (&module/tag-group =module =name)
;; :let [_ (println "#13")]
case-type (&type/variant-case idx value-type*)
;; :let [_ (println "#14" (&type/show-type case-type))]
@@ -249,7 +251,7 @@
(analyse-pattern case-type (&/V &/$Meta (&/T (&/T "" -1 -1) (&/V &/$TupleS ?values))) kont))
;; :let [_ (println "#15")]
]
- (return (&/T (&/V $VariantTestAC (&/T idx =test)) =kont)))
+ (return (&/T (&/V $VariantTestAC (&/T idx (&/|length group) =test)) =kont)))
)))
(defn ^:private analyse-branch [analyse exo-type value-type pattern body patterns]
@@ -311,21 +313,40 @@
(return (&/V $TupleTotal (&/T total? structs))))
(fail "[Pattern-matching Error] Inconsistent tuple-size."))
- [($DefaultTotal total?) ($VariantTestAC ?tag ?test)]
+ [($DefaultTotal total?) ($VariantTestAC ?tag ?count ?test)]
(|do [sub-struct (merge-total (&/V $DefaultTotal total?)
- (&/T ?test ?body))]
- (return (&/V $VariantTotal (&/T total? (&/|put ?tag sub-struct (&/|table))))))
-
- [($VariantTotal total? ?branches) ($VariantTestAC ?tag ?test)]
- (|do [sub-struct (merge-total (or (&/|get ?tag ?branches)
- (&/V $DefaultTotal total?))
- (&/T ?test ?body))]
- (return (&/V $VariantTotal (&/T total? (&/|put ?tag sub-struct ?branches)))))
+ (&/T ?test ?body))
+ structs (|case (&/|list-put ?tag sub-struct (&/|repeat ?count (&/V $DefaultTotal total?)))
+ (&/$Some list)
+ (return list)
+
+ (&/$None)
+ (fail "[Pattern-matching Error] YOLO"))]
+ (return (&/V $VariantTotal (&/T total? structs))))
+
+ [($VariantTotal total? ?branches) ($VariantTestAC ?tag ?count ?test)]
+ (|do [sub-struct (merge-total (|case (&/|at ?tag ?branches)
+ (&/$Some sub)
+ sub
+
+ (&/$None)
+ (&/V $DefaultTotal total?))
+ (&/T ?test ?body))
+ structs (|case (&/|list-put ?tag sub-struct ?branches)
+ (&/$Some list)
+ (return list)
+
+ (&/$None)
+ (fail "[Pattern-matching Error] YOLO"))]
+ (return (&/V $VariantTotal (&/T total? structs))))
))))
(defn ^:private check-totality [value-type struct]
;; (prn 'check-totality (&type/show-type value-type) (&/adt->text struct))
(|case struct
+ ($DefaultTotal ?total)
+ (return ?total)
+
($BoolTotal ?total ?values)
(return (or ?total
(= #{true false} (set (&/->seq ?values)))))
@@ -369,6 +390,9 @@
(|case value-type*
(&/$VariantT ?members)
(|do [totals (&/map2% (fn [sub-struct ?member]
+ ;; (prn '$VariantTotal
+ ;; (&/adt->text sub-struct)
+ ;; (&type/show-type ?member))
(check-totality ?member sub-struct))
?structs ?members)]
(return (&/fold #(and %1 %2) true totals)))
@@ -376,9 +400,6 @@
_
(fail "[Pattern-maching Error] Variant is not total."))))
- ($DefaultTotal ?total)
- (return ?total)
-
;; _
;; (assert false (prn-str 'check-totality (&type/show-type value-type)
;; (&/adt->text struct)))
diff --git a/src/lux/base.clj b/src/lux/base.clj
index b8b7118f4..89620ce97 100644
--- a/src/lux/base.clj
+++ b/src/lux/base.clj
@@ -116,6 +116,13 @@
(defn R [& kvs]
(to-array kvs))
+;; Constructors
+(def None$ (V $None nil))
+(defn Some$ [x] (V $Some x))
+
+(def Nil$ (V $Nil nil))
+(defn Cons$ [h t] (V $Cons (T h t)))
+
(defn get$ [slot ^objects record]
(aget record slot))
@@ -894,3 +901,29 @@
[ymodule yname] y]
(and (= xmodule ymodule)
(= xname yname))))
+
+;; (defn |list-put [idx val xs]
+;; (|case [idx xs]
+;; [_ ($Nil)]
+;; (V $None nil)
+
+;; [0 ($Cons x xs*)]
+;; (V $Some (V $Cons (T val xs*)))
+
+;; [_ ($Cons x xs*)]
+;; (|case (|list-put idx val xs*)
+;; ($None) (V $None nil)
+;; ($Some xs**) (V $Some (V $Cons (T x xs**))))))
+
+(defn |list-put [idx val xs]
+ (|case xs
+ ($Nil)
+ (V $None nil)
+
+ ($Cons x xs*)
+ (if (= idx 0)
+ (V $Some (V $Cons (T val xs*)))
+ (|case (|list-put (dec idx) val xs*)
+ ($None) (V $None nil)
+ ($Some xs**) (V $Some (V $Cons (T x xs**))))
+ )))
diff --git a/src/lux/compiler/case.clj b/src/lux/compiler/case.clj
index 4d8ac2190..dd3258059 100644
--- a/src/lux/compiler/case.clj
+++ b/src/lux/compiler/case.clj
@@ -102,7 +102,7 @@
(.visitInsn Opcodes/POP)
(.visitJumpInsn Opcodes/GOTO $target))
- (&a-case/$VariantTestAC ?tag ?test)
+ (&a-case/$VariantTestAC ?tag ?count ?test)
(doto writer
(.visitTypeInsn Opcodes/CHECKCAST "[Ljava/lang/Object;")
(.visitInsn Opcodes/DUP)