diff options
author | Eduardo Julian | 2019-03-29 22:58:33 -0400 |
---|---|---|
committer | Eduardo Julian | 2019-03-29 22:58:33 -0400 |
commit | 6bb6029f426ecb2da772f6f9c70cdb81c897f0db (patch) | |
tree | 0e33d20265838704b9c2be556f9c09c86e86b4da /stdlib/source/lux | |
parent | a869f51e0ea3fe0c224de1188ad5bbd5db080f47 (diff) |
Fixed more tests.
Diffstat (limited to 'stdlib/source/lux')
-rw-r--r-- | stdlib/source/lux/data/collection/row.lux | 133 | ||||
-rw-r--r-- | stdlib/source/lux/data/number/frac.lux | 16 | ||||
-rw-r--r-- | stdlib/source/lux/data/number/nat.lux | 10 | ||||
-rw-r--r-- | stdlib/source/lux/data/number/ratio.lux | 119 | ||||
-rw-r--r-- | stdlib/source/lux/data/number/rev.lux | 59 | ||||
-rw-r--r-- | stdlib/source/lux/data/text/format.lux | 4 |
6 files changed, 160 insertions, 181 deletions
diff --git a/stdlib/source/lux/data/collection/row.lux b/stdlib/source/lux/data/collection/row.lux index dff272a91..16ad5b51a 100644 --- a/stdlib/source/lux/data/collection/row.lux +++ b/stdlib/source/lux/data/collection/row.lux @@ -15,13 +15,12 @@ [number ["." i64]] [collection - ["." list ("#;." fold functor monoid)] - ["." array (#+ Array) ("#;." functor fold)]]] + ["." list ("#@." fold functor monoid)] + ["." array (#+ Array) ("#@." functor fold)]]] [macro (#+ with-gensyms) ["." code] ["s" syntax (#+ syntax: Syntax)]]]) -## [Utils] (type: (Node a) (#Base (Array a)) (#Hierarchy (Array (Node a)))) @@ -66,11 +65,11 @@ (All [a] (-> Any (Hierarchy a))) (array.new full-node-size)) -(def: (tail-off vec-size) +(def: (tail-off row-size) (-> Nat Nat) - (if (n/< full-node-size vec-size) + (if (n/< full-node-size row-size) 0 - (|> (dec vec-size) + (|> (dec row-size) (i64.logic-right-shift branching-exponent) (i64.left-shift branching-exponent)))) @@ -169,17 +168,15 @@ (|> hierarchy array.to-list list.reverse - (list;fold (function (_ sub acc) (list;compose (to-list' sub) acc)) + (list@fold (function (_ sub acc) (list@compose (to-list' sub) acc)) #.Nil)))) -## [Types] (type: #export (Row a) {#level Level #size Nat #root (Hierarchy a) #tail (Base a)}) -## [Exports] (def: #export empty Row {#level (level-up root-level) @@ -191,48 +188,48 @@ (All [a] (-> (Row a) Nat)) (get@ #size row)) -(def: #export (add val vec) +(def: #export (add val row) (All [a] (-> a (Row a) (Row a))) ## Check if there is room in the tail. - (let [vec-size (get@ #size vec)] - (if (|> vec-size (n/- (tail-off vec-size)) (n/< full-node-size)) + (let [row-size (get@ #size row)] + (if (|> row-size (n/- (tail-off row-size)) (n/< full-node-size)) ## If so, append to it. - (|> vec + (|> row (update@ #size inc) (update@ #tail (expand-tail val))) ## Otherwise, push tail into the tree ## -------------------------------------------------------- ## Will the root experience an overflow with this addition? - (|> (if (n/> (i64.left-shift (get@ #level vec) 1) - (i64.logic-right-shift branching-exponent vec-size)) + (|> (if (n/> (i64.left-shift (get@ #level row) 1) + (i64.logic-right-shift branching-exponent row-size)) ## If so, a brand-new root must be established, that is ## 1-level taller. - (|> vec + (|> row (set@ #root (|> (: (Hierarchy ($ 0)) (new-hierarchy [])) ## TODO: Remove version above once new-luxc becomes the standard compiler. ## (new-hierarchy []) - (array.write 0 (#Hierarchy (get@ #root vec))) - (array.write 1 (new-path (get@ #level vec) (get@ #tail vec))))) + (array.write 0 (#Hierarchy (get@ #root row))) + (array.write 1 (new-path (get@ #level row) (get@ #tail row))))) (update@ #level level-up)) ## Otherwise, just push the current tail onto the root. - (|> vec - (update@ #root (push-tail vec-size (get@ #level vec) (get@ #tail vec))))) + (|> row + (update@ #root (push-tail row-size (get@ #level row) (get@ #tail row))))) ## Finally, update the size of the row and grow a new ## tail with the new element as it's sole member. (update@ #size inc) (set@ #tail (new-tail val))) ))) -(def: (base-for idx vec) +(def: (base-for idx row) (All [a] (-> Index (Row a) (Maybe (Base a)))) - (let [vec-size (get@ #size vec)] + (let [row-size (get@ #size row)] (if (and (n/>= 0 idx) - (n/< vec-size idx)) - (if (n/>= (tail-off vec-size) idx) - (#.Some (get@ #tail vec)) - (loop [level (get@ #level vec) - hierarchy (get@ #root vec)] + (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))] @@ -248,61 +245,61 @@ (error! "Incorrect row structure.")))) #.None))) -(def: #export (nth idx vec) +(def: #export (nth idx row) (All [a] (-> Nat (Row a) (Maybe a))) (do maybe.monad - [base (base-for idx vec)] + [base (base-for idx row)] (array.read (branch-idx idx) base))) -(def: #export (put idx val vec) +(def: #export (put idx val row) (All [a] (-> Nat a (Row a) (Row a))) - (let [vec-size (get@ #size vec)] + (let [row-size (get@ #size row)] (if (and (n/>= 0 idx) - (n/< vec-size idx)) - (if (n/>= (tail-off vec-size) idx) - (|> vec + (n/< row-size idx)) + (if (n/>= (tail-off row-size) idx) + (|> row ## (update@ #tail (|>> array.clone (array.write (branch-idx idx) val))) ## TODO: Remove once new-luxc becomes the standard compiler. (update@ #tail (: (-> (Base ($ 0)) (Base ($ 0))) (|>> array.clone (array.write (branch-idx idx) val)))) ) - (|> vec - (update@ #root (put' (get@ #level vec) idx val)))) - vec))) + (|> row + (update@ #root (put' (get@ #level row) idx val)))) + row))) -(def: #export (update idx f vec) +(def: #export (update idx f row) (All [a] (-> Nat (-> a a) (Row a) (Row a))) - (case (nth idx vec) + (case (nth idx row) (#.Some val) - (put idx (f val) vec) + (put idx (f val) row) #.None - vec)) + row)) -(def: #export (pop vec) +(def: #export (pop row) (All [a] (-> (Row a) (Row a))) - (case (get@ #size vec) + (case (get@ #size row) 0 empty 1 empty - vec-size - (if (|> vec-size (n/- (tail-off vec-size)) (n/> 1)) - (let [old-tail (get@ #tail vec) + row-size + (if (|> row-size (n/- (tail-off row-size)) (n/> 1)) + (let [old-tail (get@ #tail row) new-tail-size (dec (array.size old-tail))] - (|> vec + (|> row (update@ #size dec) (set@ #tail (|> (array.new new-tail-size) (array.copy new-tail-size 0 old-tail 0))))) (maybe.assume (do maybe.monad - [new-tail (base-for (n/- 2 vec-size) vec) - #let [[level' root'] (let [init-level (get@ #level vec)] + [new-tail (base-for (n/- 2 row-size) row) + #let [[level' root'] (let [init-level (get@ #level row)] (loop [level init-level root (maybe.default (new-hierarchy []) - (pop-tail vec-size init-level (get@ #root vec)))] + (pop-tail row-size init-level (get@ #root row)))] (if (n/> branching-exponent level) (case [(array.read 1 root) (array.read 0 root)] [#.None (#.Some (#Hierarchy sub-node))] @@ -314,37 +311,35 @@ _ [level root]) [level root])))]] - (wrap (|> vec + (wrap (|> row (update@ #size dec) (set@ #level level') (set@ #root root') (set@ #tail new-tail)))))) )) -(def: #export (to-list vec) +(def: #export (to-list row) (All [a] (-> (Row a) (List a))) - (list;compose (to-list' (#Hierarchy (get@ #root vec))) - (to-list' (#Base (get@ #tail vec))))) + (list@compose (to-list' (#Hierarchy (get@ #root row))) + (to-list' (#Base (get@ #tail row))))) (def: #export from-list (All [a] (-> (List a) (Row a))) - (list;fold ..add ..empty)) + (list@fold ..add ..empty)) -(def: #export (member? a/Equivalence vec val) +(def: #export (member? a/Equivalence row val) (All [a] (-> (Equivalence a) (Row a) a Bit)) - (list.member? a/Equivalence (to-list vec) val)) + (list.member? a/Equivalence (to-list row) val)) (def: #export empty? (All [a] (-> (Row a) Bit)) (|>> (get@ #size) (n/= 0))) -## [Syntax] (syntax: #export (row {elems (p.some s.any)}) {#.doc (doc "Row literals." (row +10 +20 +30 +40))} (wrap (list (` (from-list (list (~+ elems))))))) -## [Structures] (structure: #export (node-equivalence Equivalence<a>) (All [a] (-> (Equivalence a) (Equivalence (Node a)))) (def: (= v1 v2) (case [v1 v2] @@ -370,10 +365,10 @@ (def: (fold f init xs) (case xs (#Base base) - (array;fold f init base) + (array@fold f init base) (#Hierarchy hierarchy) - (array;fold (function (_ node init') (fold f init' node)) + (array@fold (function (_ node init') (fold f init' node)) init hierarchy)))) @@ -390,23 +385,23 @@ (def: identity ..empty) (def: (compose xs ys) - (list;fold add xs (..to-list ys)))) + (list@fold add xs (..to-list ys)))) (structure: node-functor (Functor Node) (def: (map f xs) (case xs (#Base base) - (#Base (array;map f base)) + (#Base (array@map f base)) (#Hierarchy hierarchy) - (#Hierarchy (array;map (map f) hierarchy))))) + (#Hierarchy (array@map (map f) hierarchy))))) (structure: #export functor (Functor Row) (def: (map f xs) {#level (get@ #level xs) #size (get@ #size xs) - #root (|> xs (get@ #root) (array;map (:: node-functor map f))) - #tail (|> xs (get@ #tail) (array;map f))})) + #root (|> xs (get@ #root) (array@map (:: node-functor map f))) + #tail (|> xs (get@ #tail) (array@map f))})) (structure: #export apply (Apply Row) (def: &functor ..functor) @@ -429,13 +424,9 @@ (^open ".") ..monoid] (fold (function (_ post pre) (compose pre post)) identity)))) -## TODO: This definition of 'reverse' shouldn't work correctly. -## Investigate if/why it does. (def: #export reverse (All [a] (-> (Row a) (Row a))) - (let [(^open ".") ..fold - (^open ".") ..monoid] - (fold add identity))) + (|>> ..to-list list.reverse (list@fold add ..empty))) (do-template [<name> <array> <init> <op>] [(def: #export <name> diff --git a/stdlib/source/lux/data/number/frac.lux b/stdlib/source/lux/data/number/frac.lux index d67d582f6..02f7b4d88 100644 --- a/stdlib/source/lux/data/number/frac.lux +++ b/stdlib/source/lux/data/number/frac.lux @@ -3,8 +3,6 @@ [control [hash (#+ Hash)] [number (#+ Number)] - [enum (#+ Enum)] - [interval (#+ Interval)] [monoid (#+ Monoid)] [equivalence (#+ Equivalence)] ["." order (#+ Order)] @@ -29,16 +27,6 @@ (def: > f/>) (def: >= f/>=)) -(structure: #export enum (Enum Frac) - (def: &order ..order) - (def: succ (f/+ ("lux frac smallest"))) - (def: pred (f/- ("lux frac smallest")))) - -(structure: #export interval (Interval Frac) - (def: &enum ..enum) - (def: top ("lux frac max")) - (def: bottom ("lux frac min"))) - (structure: #export number (Number Frac) (def: + f/+) (def: - f/-) @@ -64,8 +52,8 @@ [addition f/+ +0.0] [multiplication f/* +1.0] - [maximum f/max (:: ..interval bottom)] - [minimum f/min (:: ..interval top)] + [maximum f/max ("lux frac min")] + [minimum f/min ("lux frac max")] ) (do-template [<name> <numerator> <doc>] diff --git a/stdlib/source/lux/data/number/nat.lux b/stdlib/source/lux/data/number/nat.lux index 8126bc0c3..70f8df0bd 100644 --- a/stdlib/source/lux/data/number/nat.lux +++ b/stdlib/source/lux/data/number/nat.lux @@ -177,10 +177,12 @@ (loop [input value output ""] (let [digit (maybe.assume (<to-character> (n/% <base> input))) - output' ("lux text concat" digit output) - input' (n// <base> input)] - (if (n/= 0 input') + output' ("lux text concat" digit output)] + (case (n// <base> input) + 0 output' + + input' (recur input' output'))))) (def: (decode repr) @@ -201,7 +203,7 @@ [binary 2 binary-character binary-value "Invalid binary syntax for Nat: "] [octal 8 octal-character octal-value "Invalid octal syntax for Nat: "] - [decimal 10 decimal-character decimal-value "Invalid syntax for Nat: "] + [decimal 10 decimal-character decimal-value "Invalid decimal syntax for Nat: "] [hex 16 hexadecimal-character hexadecimal-value "Invalid hexadecimal syntax for Nat: "] ) diff --git a/stdlib/source/lux/data/number/ratio.lux b/stdlib/source/lux/data/number/ratio.lux index 21176e998..9c7baaab8 100644 --- a/stdlib/source/lux/data/number/ratio.lux +++ b/stdlib/source/lux/data/number/ratio.lux @@ -3,6 +3,7 @@ [control [equivalence (#+ Equivalence)] [order (#+ Order)] + [monoid (#+ Monoid)] number codec monad @@ -12,9 +13,8 @@ ["." product] ["." maybe] [number - ["." nat ("#;." decimal)]] - ["." text ("#;." monoid) - format]] + ["." nat ("#@." decimal)]] + ["." text ("#@." monoid)]] ["." function] ["." math] ["." macro @@ -25,6 +25,13 @@ {#numerator Nat #denominator Nat}) +(def: (equalize parameter subject) + (-> Ratio Ratio [Nat Nat]) + [(n/* (get@ #denominator subject) + (get@ #numerator parameter)) + (n/* (get@ #denominator parameter) + (get@ #numerator subject))]) + (def: (normalize (^slots [#numerator #denominator])) (-> Ratio Ratio) (let [common (math.n/gcd numerator denominator)] @@ -32,21 +39,19 @@ #denominator (n// common denominator)})) (structure: #export equivalence (Equivalence Ratio) - (def: (= param input) - (and (n/= (get@ #numerator param) - (get@ #numerator input)) - (n/= (get@ #denominator param) - (get@ #denominator input))))) + (def: (= parameter subject) + (and (n/= (get@ #numerator parameter) + (get@ #numerator subject)) + (n/= (get@ #denominator parameter) + (get@ #denominator subject))))) (`` (structure: #export order (Order Ratio) (def: &equivalence ..equivalence) (~~ (do-template [<name> <op>] - [(def: (<name> param input) - (and (<op> (n/* (get@ #denominator input) - (get@ #numerator param)) - (n/* (get@ #denominator param) - (get@ #numerator input)))))] + [(def: (<name> parameter subject) + (let [[parameter' subject'] (..equalize parameter subject)] + (<op> parameter' subject')))] [< n/<] [<= n/<=] @@ -66,46 +71,38 @@ [max >] ) -(def: (- param input) - (normalize [(n/- (n/* (get@ #denominator input) - (get@ #numerator param)) - (n/* (get@ #denominator param) - (get@ #numerator input))) - (n/* (get@ #denominator param) - (get@ #denominator input))])) +(def: (- parameter subject) + (let [[parameter' subject'] (..equalize parameter subject)] + (normalize [(n/- parameter' subject') + (n/* (get@ #denominator parameter) + (get@ #denominator subject))]))) (structure: #export number (Number Ratio) - (def: (+ param input) - (normalize [(n/+ (n/* (get@ #denominator input) - (get@ #numerator param)) - (n/* (get@ #denominator param) - (get@ #numerator input))) - (n/* (get@ #denominator param) - (get@ #denominator input))])) + (def: (+ parameter subject) + (let [[parameter' subject'] (..equalize parameter subject)] + (normalize [(n/+ parameter' subject') + (n/* (get@ #denominator parameter) + (get@ #denominator subject))]))) (def: - ..-) - (def: (* param input) - (normalize [(n/* (get@ #numerator param) - (get@ #numerator input)) - (n/* (get@ #denominator param) - (get@ #denominator input))])) - - (def: (/ param input) - (normalize [(n/* (get@ #denominator param) - (get@ #numerator input)) - (n/* (get@ #numerator param) - (get@ #denominator input))])) - - (def: (% param input) - (let [quot (n// (n/* (get@ #denominator input) - (get@ #numerator param)) - (n/* (get@ #denominator param) - (get@ #numerator input)))] - (..- (update@ #numerator (n/* quot) param) - input))) + (def: (* parameter subject) + (normalize [(n/* (get@ #numerator parameter) + (get@ #numerator subject)) + (n/* (get@ #denominator parameter) + (get@ #denominator subject))])) + + (def: (/ parameter subject) + (let [[parameter' subject'] (..equalize parameter subject)] + (normalize [subject' parameter']))) + + (def: (% parameter subject) + (let [[parameter' subject'] (..equalize parameter subject) + quot (n// parameter' subject')] + (..- (update@ #numerator (n/* quot) parameter) + subject))) (def: (negate (^slots [#numerator #denominator])) {#numerator denominator @@ -120,31 +117,39 @@ (def: separator Text ":") -(def: part-encode - (-> Nat Text) - (|>> nat;encode (text.split 1) maybe.assume product.right)) - (structure: #export codec (Codec Text Ratio) (def: (encode (^slots [#numerator #denominator])) - ($_ text;compose (part-encode numerator) separator (part-encode denominator))) + ($_ text@compose (nat@encode numerator) separator (nat@encode denominator))) (def: (decode input) (case (text.split-with separator input) (#.Some [num denom]) (do error.monad - [numerator (nat;decode num) - denominator (nat;decode denom)] + [numerator (nat@decode num) + denominator (nat@decode denom)] (wrap (normalize {#numerator numerator #denominator denominator}))) #.None - (#.Left (text;compose "Invalid syntax for ratio: " input))))) + (#.Left (text@compose "Invalid syntax for ratio: " input))))) (syntax: #export (ratio numerator {?denominator (p.maybe s.any)}) {#.doc (doc "Rational literals." (ratio numerator denominator) "The denominator can be omitted if it's 1." (ratio numerator))} - (wrap (list (` ((~! normalize) {#..numerator (~ numerator) - #..denominator (~ (maybe.default (' 1) - ?denominator))}))))) + (wrap (list (` ((~! ..normalize) {#..numerator (~ numerator) + #..denominator (~ (maybe.default (' 1) + ?denominator))}))))) + +(do-template [<identity> <compose> <name>] + [(structure: #export <name> + (Monoid Ratio) + + (def: identity (..ratio <identity>)) + (def: compose (:: ..number <compose>)) + )] + + [0 + addition] + [1 * multiplication] + ) diff --git a/stdlib/source/lux/data/number/rev.lux b/stdlib/source/lux/data/number/rev.lux index 798844ba7..fcd2e223c 100644 --- a/stdlib/source/lux/data/number/rev.lux +++ b/stdlib/source/lux/data/number/rev.lux @@ -40,37 +40,25 @@ (def: top (.rev -1)) (def: bottom (.rev 0))) -(structure: #export number (Number Rev) - (def: + r/+) - (def: - r/-) - (def: * r/*) - (def: / r//) - (def: % r/%) - (def: (negate x) (r/- x (:coerce Rev -1))) - (def: abs function.identity) - (def: (signum x) - (:coerce Rev -1))) - (do-template [<name> <compose> <identity>] [(structure: #export <name> (Monoid Rev) - (def: identity <identity>) + (def: identity (:: interval <identity>)) (def: compose <compose>))] - [addition r/+ (:: interval bottom)] - [multiplication r/* (:: interval top)] - [maximum r/max (:: interval bottom)] - [minimum r/min (:: interval top)] + [addition r/+ bottom] + [maximum r/max bottom] + [minimum r/min top] ) (def: (de-prefix input) (-> Text Text) ("lux text clip" input 1 ("lux text size" input))) -(do-template [<struct> <nat> <char-bit-size> <error>] +(do-template [<struct> <codec> <char-bit-size> <error>] [(with-expansions [<error-output> (as-is (#error.Failure ("lux text concat" <error> repr)))] (structure: #export <struct> (Codec Text Rev) (def: (encode value) - (let [raw-output (de-prefix (:: <nat> encode (:coerce Nat value))) + (let [raw-output (:: <codec> encode (:coerce Nat value)) max-num-chars (n// <char-bit-size> 64) raw-size ("lux text size" raw-output) zero-padding (loop [zeroes-left (n/- raw-size max-num-chars) @@ -78,16 +66,17 @@ (if (n/= 0 zeroes-left) output (recur (dec zeroes-left) - ("lux text concat" "0" output)))) - padded-output ("lux text concat" zero-padding raw-output)] - ("lux text concat" "." padded-output))) + ("lux text concat" "0" output))))] + (|> raw-output + ("lux text concat" zero-padding) + ("lux text concat" ".")))) (def: (decode repr) (let [repr-size ("lux text size" repr)] - (if (n/>= 2 repr-size) + (if (n/> 1 repr-size) (case ("lux text char" repr 0) (^ (char ".")) - (case (:: <nat> decode (de-prefix repr)) + (case (:: <codec> decode (de-prefix repr)) (#error.Success output) (#error.Success (:coerce Rev output)) @@ -196,7 +185,7 @@ (loop [idx 0 output (make-digits [])] (if (n/< length idx) - (case ("lux text index" "+0123456789" ("lux text clip" input idx (inc idx)) 0) + (case ("lux text index" "0123456789" ("lux text clip" input idx (inc idx)) 0) #.None #.None @@ -239,10 +228,12 @@ (structure: #export decimal (Codec Text Rev) (def: (encode input) - (let [input (:coerce Nat input) - last-idx (dec //i64.width)] - (if (n/= 0 input) - ".0" + (case (:coerce Nat input) + 0 + ".0" + + input + (let [last-idx (dec //i64.width)] (loop [idx last-idx digits (make-digits [])] (if (i/>= +0 (.int idx)) @@ -257,16 +248,16 @@ ))))) (def: (decode input) - (let [length ("lux text size" input) - dotted? (case ("lux text index" input "." 0) + (let [dotted? (case ("lux text index" input "." 0) (#.Some 0) #1 _ - #0)] - (if (and dotted? - (n/<= (inc //i64.width) length)) - (case (text-to-digits ("lux text clip" input 1 length)) + #0) + within-limits? (n/<= (inc //i64.width) + ("lux text size" input))] + (if (and dotted? within-limits?) + (case (text-to-digits (de-prefix input)) (#.Some digits) (loop [digits digits idx 0 diff --git a/stdlib/source/lux/data/text/format.lux b/stdlib/source/lux/data/text/format.lux index f6a53358d..b96606cdc 100644 --- a/stdlib/source/lux/data/text/format.lux +++ b/stdlib/source/lux/data/text/format.lux @@ -10,7 +10,8 @@ ["." nat] ["." int] ["." rev] - ["." frac]] + ["." frac] + ["." ratio]] ["." text] [format ["." xml] @@ -49,6 +50,7 @@ [%i Int (:: int.decimal encode)] [%r Rev (:: rev.decimal encode)] [%f Frac (:: frac.decimal encode)] + [%ratio ratio.Ratio (:: ratio.codec encode)] [%t Text text.encode] [%name Name (:: name.codec encode)] [%code Code code.to-text] |