summaryrefslogtreecommitdiff
path: root/libstd
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2015-06-18 18:02:09 -0700
committerOri Bernstein <ori@eigenstate.org>2015-06-18 18:02:09 -0700
commit340cbfe1d94aa8065191eac10aec2dbe3922c100 (patch)
tree0f5937bf10c9776cbd5e49a3247558d821f5e206 /libstd
parentcf94e8f3c050f869d11a985f7ac4a4d9a477a9e4 (diff)
downloadmc-340cbfe1d94aa8065191eac10aec2dbe3922c100.tar.gz
Fix and enable all fmt tests.
Diffstat (limited to 'libstd')
-rw-r--r--libstd/fmt.myr76
-rw-r--r--libstd/test/fmt.myr10
2 files changed, 59 insertions, 27 deletions
diff --git a/libstd/fmt.myr b/libstd/fmt.myr
index 0eba9b6..518402f 100644
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -321,7 +321,7 @@ const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
match typedesc(desc)
| `Tybyte:
s_val = vanext(ap)
- sbputs(sb, s_val)
+ strfmt(sb, s_val, params)
| _:
sbputs(sb, "slice[:]")
;;
@@ -349,12 +349,6 @@ const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
;;
}
-type intparams = struct
- base : size
- padto : size
- padfill : char
-;;
-
const getparams = {fmt
var i
@@ -368,9 +362,15 @@ const getparams = {fmt
-> (fmt[:i], fmt[i+1:])
}
+type intparams = struct
+ base : size
+ padto : size
+ padfill : char
+;;
const intparams = {params
var ip : intparams
+ var opts
ip = [
.base = 10,
@@ -378,29 +378,55 @@ const intparams = {params
.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 @@ const writeall = {fd, buf
-> 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)
+ ;;
+}
diff --git a/libstd/test/fmt.myr b/libstd/test/fmt.myr
index e6fcb75..8de3890 100644
--- a/libstd/test/fmt.myr
+++ b/libstd/test/fmt.myr
@@ -12,12 +12,10 @@ const check = {expected, fmt, args : ...
}
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))