aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux
diff options
context:
space:
mode:
authorEduardo Julian2019-03-29 22:58:33 -0400
committerEduardo Julian2019-03-29 22:58:33 -0400
commit6bb6029f426ecb2da772f6f9c70cdb81c897f0db (patch)
tree0e33d20265838704b9c2be556f9c09c86e86b4da /stdlib/source/lux
parenta869f51e0ea3fe0c224de1188ad5bbd5db080f47 (diff)
Fixed more tests.
Diffstat (limited to 'stdlib/source/lux')
-rw-r--r--stdlib/source/lux/data/collection/row.lux133
-rw-r--r--stdlib/source/lux/data/number/frac.lux16
-rw-r--r--stdlib/source/lux/data/number/nat.lux10
-rw-r--r--stdlib/source/lux/data/number/ratio.lux119
-rw-r--r--stdlib/source/lux/data/number/rev.lux59
-rw-r--r--stdlib/source/lux/data/text/format.lux4
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]