aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/data
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/source/lux/data')
-rw-r--r--stdlib/source/lux/data/collection/dictionary.lux11
-rw-r--r--stdlib/source/lux/data/collection/row.lux102
-rw-r--r--stdlib/source/lux/data/maybe.lux1
3 files changed, 67 insertions, 47 deletions
diff --git a/stdlib/source/lux/data/collection/dictionary.lux b/stdlib/source/lux/data/collection/dictionary.lux
index 195640d66..c4c8efeb1 100644
--- a/stdlib/source/lux/data/collection/dictionary.lux
+++ b/stdlib/source/lux/data/collection/dictionary.lux
@@ -4,6 +4,9 @@
[hash (#+ Hash)]
[equivalence (#+ Equivalence)]
[functor (#+ Functor)]]
+ [control
+ ["." try (#+ Try)]
+ ["." exception (#+ exception:)]]
[data
["." maybe]
["." product]
@@ -569,12 +572,14 @@
#.None #0
(#.Some _) #1))
+(exception: #export key-already-exists)
+
(def: #export (try-put key val dict)
{#.doc "Only puts the KV-pair if the key is not already present."}
- (All [k v] (-> k v (Dictionary k v) (Dictionary k v)))
+ (All [k v] (-> k v (Dictionary k v) (Try (Dictionary k v))))
(case (get key dict)
- #.None (put key val dict)
- (#.Some _) dict))
+ #.None (#try.Success (put key val dict))
+ (#.Some _) (exception.throw ..key-already-exists [])))
(def: #export (update key f dict)
{#.doc "Transforms the value located at key (if available), using the given function."}
diff --git a/stdlib/source/lux/data/collection/row.lux b/stdlib/source/lux/data/collection/row.lux
index d73f8bbf5..2b7b555be 100644
--- a/stdlib/source/lux/data/collection/row.lux
+++ b/stdlib/source/lux/data/collection/row.lux
@@ -10,6 +10,8 @@
[fold (#+ Fold)]
[predicate (#+ Predicate)]]
[control
+ ["." try (#+ Try)]
+ ["." exception (#+ exception:)]
["p" parser
["s" code (#+ Parser)]]]
[data
@@ -225,59 +227,71 @@
(set@ #tail (new-tail val)))
)))
+(exception: incorrect-row-structure)
+
+(exception: #export [a] (index-out-of-bounds {row (Row a)} {index Nat})
+ (exception.report ["Size" (:: n.decimal encode (get@ #size row))]
+ ["Index" (:: n.decimal encode index)]))
+
+(exception: base-was-not-found)
+
+(def: #export (within-bounds? row idx)
+ (All [a] (-> (Row a) Nat Bit))
+ (and (n.>= 0 idx)
+ (n.< (get@ #size row) idx)))
+
(def: (base-for idx row)
- (All [a] (-> Index (Row a) (Maybe (Base a))))
- (let [row-size (get@ #size row)]
- (if (and (n.>= 0 idx)
- (n.< row-size idx))
- (if (n.>= (tail-off row-size) idx)
- (#.Some (get@ #tail row))
- (loop [level (get@ #level row)
- hierarchy (get@ #root row)]
- (case [(n.> branching-exponent level)
- (array.read (branch-idx (i64.logic-right-shift level idx)) hierarchy)]
- [#1 (#.Some (#Hierarchy sub))]
- (recur (level-down level) sub)
-
- [#0 (#.Some (#Base base))]
- (#.Some base)
-
- [_ #.None]
- #.None
-
- _
- (error! "Incorrect row structure."))))
- #.None)))
+ (All [a] (-> Index (Row a) (Try (Base a))))
+ (if (within-bounds? row idx)
+ (if (n.>= (tail-off (get@ #size row)) idx)
+ (#try.Success (get@ #tail row))
+ (loop [level (get@ #level row)
+ hierarchy (get@ #root row)]
+ (case [(n.> branching-exponent level)
+ (array.read (branch-idx (i64.logic-right-shift level idx)) hierarchy)]
+ [#1 (#.Some (#Hierarchy sub))]
+ (recur (level-down level) sub)
+
+ [#0 (#.Some (#Base base))]
+ (#try.Success base)
+
+ [_ #.None]
+ (exception.throw ..base-was-not-found [])
+
+ _
+ (exception.throw ..incorrect-row-structure []))))
+ (exception.throw ..index-out-of-bounds [row idx])))
(def: #export (nth idx row)
- (All [a] (-> Nat (Row a) (Maybe a)))
- (do maybe.monad
+ (All [a] (-> Nat (Row a) (Try a)))
+ (do try.monad
[base (base-for idx row)]
- (array.read (branch-idx idx) base)))
+ (case (array.read (branch-idx idx) base)
+ (#.Some value)
+ (#try.Success value)
+
+ #.None
+ (exception.throw ..incorrect-row-structure []))))
(def: #export (put idx val row)
- (All [a] (-> Nat a (Row a) (Row a)))
+ (All [a] (-> Nat a (Row a) (Try (Row a))))
(let [row-size (get@ #size row)]
- (if (and (n.>= 0 idx)
- (n.< row-size idx))
- (if (n.>= (tail-off row-size) idx)
- (update@ #tail (`` (for {(~~ (static @.old))
- (: (-> (Base ($ 0)) (Base ($ 0)))
- (|>> array.clone (array.write (branch-idx idx) val)))}
- (|>> array.clone (array.write (branch-idx idx) val))))
- row)
- (update@ #root (put' (get@ #level row) idx val)
- row))
- row)))
+ (if (within-bounds? row idx)
+ (#try.Success (if (n.>= (tail-off row-size) idx)
+ (update@ #tail (`` (for {(~~ (static @.old))
+ (: (-> (Base ($ 0)) (Base ($ 0)))
+ (|>> array.clone (array.write (branch-idx idx) val)))}
+ (|>> array.clone (array.write (branch-idx idx) val))))
+ row)
+ (update@ #root (put' (get@ #level row) idx val)
+ row)))
+ (exception.throw ..index-out-of-bounds [row idx]))))
(def: #export (update idx f row)
- (All [a] (-> Nat (-> a a) (Row a) (Row a)))
- (case (nth idx row)
- (#.Some val)
- (put idx (f val) row)
-
- #.None
- row))
+ (All [a] (-> Nat (-> a a) (Row a) (Try (Row a))))
+ (do try.monad
+ [val (nth idx row)]
+ (put idx (f val) row)))
(def: #export (pop row)
(All [a] (-> (Row a) (Row a)))
diff --git a/stdlib/source/lux/data/maybe.lux b/stdlib/source/lux/data/maybe.lux
index 3a8bc8497..6d425011c 100644
--- a/stdlib/source/lux/data/maybe.lux
+++ b/stdlib/source/lux/data/maybe.lux
@@ -89,6 +89,7 @@
(macro: #export (default tokens state)
{#.doc (doc "Allows you to provide a default value that will be used"
"if a (Maybe x) value turns out to be #.None."
+ "Note: the expression for the default value will not be computed if the base computation succeeds."
(default +20 (#.Some +10))
"=>"
+10