ref: 340cbfe1d94aa8065191eac10aec2dbe3922c100
parent: cf94e8f3c050f869d11a985f7ac4a4d9a477a9e4
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Jun 18 14:02:09 EDT 2015
Fix and enable all fmt tests.
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -321,7 +321,7 @@
match typedesc(desc)
| `Tybyte:
s_val = vanext(ap)
- sbputs(sb, s_val)
+ strfmt(sb, s_val, params)
| _:
sbputs(sb, "slice[:]")
;;
@@ -349,12 +349,6 @@
;;
}
-type intparams = struct
- base : size
- padto : size
- padfill : char
-;;
-
const getparams = {fmtvar i
@@ -368,9 +362,15 @@
-> (fmt[:i], fmt[i+1:])
}
+type intparams = struct
+ base : size
+ padto : size
+ padfill : char
+;;
const intparams = {paramsvar ip : intparams
+ var opts
ip = [
.base = 10,
@@ -378,29 +378,55 @@
.padto = 0
]
- var pl = parseparams(params, [
+ opts = parseparams(params, [
("x", false), ("w", true), ("p", true)][:])- for p in pl
- match p
+ for o in opts
+ match o
| ("x", ""): ip.base = 16- | ("w", wid): - /* would use get(), but that's a dep loop */
- match std.intparse(wid)
- | `Some w: ip.padto = w;
- | `None: die("width was not number")- ;;
- | ("p", pad):- std.assert(pad.len == 1, "pad takes one character")
- ip.padfill = decode(pad)
- | _:
+ | ("w", wid): ip.padto = getint(wid, "fmt: width must be integer")+ | ("p", pad): ip.padfill = decode(pad)+ | _: std.die("unreachable");;
;;
- std.slfree(pl)
+ std.assert(ip.padto >= 0, "pad must be >= 0")
+ std.slfree(opts)
-> ip
}
+const strfmt = {sb, str, params+ var opts
+ var w, p, i
+
+ p = ' '
+ w = 0
+ opts = parseparams(params, [
+ ("w", true),+ ("p", true)][:])+ for o in opts
+ match o
+ | ("w", wid): w = getint(wid, "fmt: width must be integer")+ | ("p", pad): p = decode(pad)+ | _: std.die("unreachable")+ ;;
+ ;;
+ std.assert(p >= 0, "pad must be >= 0")
+ std.slfree(opts)
+ for i = 0; i < w - graphemewidth(str); i++
+ sbputc(sb, p)
+ ;;
+ sbputs(sb, str)
+}
+
+/*
+Hah. like we're going to put in the work to actually
+count graphemes.
+*/
+const graphemewidth = {str+ -> str.len
+}
+
const digitchars = [
'0','1','2','3','4',
'5','6','7','8','9',
@@ -466,3 +492,11 @@
-> len
}
+
+/* would use std.get(), but that's a dependency loop */
+const getint = {s, msg+ match std.intparse(s)
+ | `Some w: -> w;
+ | `None: die(msg)
+ ;;
+}
--- a/libstd/test/fmt.myr
+++ b/libstd/test/fmt.myr
@@ -12,12 +12,10 @@
}
const main = {- /* FIXME: make these equivalents tested.
- check(" abcd", "%10s", "abcd")- check("00000bdcae", "%010s", "bdcae")- check("abcdefghijkl", "%010s", "abcdefghijkl")- check("a", "%01s", "a")- */
+ check(" abcd", "{w=10}", "abcd")+ check("00000bdcae", "{p=0,w=10}", "bdcae")+ check("abcdefghijkl", "{p=0,w=10}", "abcdefghijkl")+ check("a", "{w=0,p=1}", "a") check(" 10", "{w=10}", 10) check("0000000010", "{p=0,w=10}", 10) check("4294967295", "{p=0,w=10}", -1 castto(uint))--
⑨