summaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorS. Gilles <sgilles@umd.edu>2019-11-25 16:19:54 -0500
committerOri Bernstein <ori@eigenstate.org>2019-12-04 22:27:33 -0800
commitebeb642003c6fdbf331968cff9d2e3d769fd6b02 (patch)
tree0db3b6755f9942c1f7e9f0258e1bcf58dd6330f0 /lib/std
parent6a113c23192c0877185aadddbc58b943ed68dd7b (diff)
downloadmc-ebeb642003c6fdbf331968cff9d2e3d769fd6b02.tar.gz
Allow specifying padding width from variable
So I can write std.put("{w=?}{w=?}\n", field_a, max_width, field_b, max_width)
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/fmt.myr99
-rw-r--r--lib/std/test/fmt.myr48
2 files changed, 125 insertions, 22 deletions
diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr
index b7155f6..4178524 100644
--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -283,43 +283,43 @@ const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
sbputc(sb, val)
| `Tyint8:
var val : int8 = vanext(ap)
- intfmt(sb, intparams(params), true, (val : uint64), 8)
+ intfmt(sb, intparams(ap, params), true, (val : uint64), 8)
| `Tyint16:
var val : int16 = vanext(ap)
- intfmt(sb, intparams(params), true, (val : uint64), 16)
+ intfmt(sb, intparams(ap, params), true, (val : uint64), 16)
| `Tyint:
var val : int = vanext(ap)
- intfmt(sb, intparams(params), true, (val : uint64), 32)
+ intfmt(sb, intparams(ap, params), true, (val : uint64), 32)
| `Tyint32:
var val : int32 = vanext(ap)
- intfmt(sb, intparams(params), true, (val : uint64), 32)
+ intfmt(sb, intparams(ap, params), true, (val : uint64), 32)
| `Tyint64:
var val : int64 = vanext(ap)
- intfmt(sb, intparams(params), true, (val : uint64), 64)
+ intfmt(sb, intparams(ap, params), true, (val : uint64), 64)
| `Tybyte:
var val : byte = vanext(ap)
- intfmt(sb, intparams(params), false, (val : uint64), 8)
+ intfmt(sb, intparams(ap, params), false, (val : uint64), 8)
| `Tyuint8:
var val : uint8 = vanext(ap)
- intfmt(sb, intparams(params), false, (val : uint64), 8)
+ intfmt(sb, intparams(ap, params), false, (val : uint64), 8)
| `Tyuint16:
var val : uint16 = vanext(ap)
- intfmt(sb, intparams(params), false, (val : uint64), 16)
+ intfmt(sb, intparams(ap, params), false, (val : uint64), 16)
| `Tyuint:
var val : uint = vanext(ap)
- intfmt(sb, intparams(params), false, (val : uint64), 32)
+ intfmt(sb, intparams(ap, params), false, (val : uint64), 32)
| `Tyuint32:
var val : uint32 = vanext(ap)
- intfmt(sb, intparams(params), false, (val : uint64), 32)
+ intfmt(sb, intparams(ap, params), false, (val : uint64), 32)
| `Tyuint64:
var val : uint64 = vanext(ap)
- intfmt(sb, intparams(params), false, (val : uint64), 64)
+ intfmt(sb, intparams(ap, params), false, (val : uint64), 64)
| `Tyflt32:
var val : flt32 = vanext(ap)
- flt32bfmt(sb, fltparams(params), val)
+ flt32bfmt(sb, fltparams(ap, params), val)
| `Tyflt64:
var val : flt64 = vanext(ap)
- flt64bfmt(sb, fltparams(params), val)
+ flt64bfmt(sb, fltparams(ap, params), val)
| `Tyvalist:
sbputs(sb, "...")
@@ -334,7 +334,7 @@ const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
match typedesc(desc)
| `Tybyte:
var val : byte[:] = vanext(ap)
- strfmt(sb, val, params)
+ strfmt(sb, val, ap, params)
| _:
subap = vaenter(ap)
fmtslice(sb, subap, params)
@@ -449,7 +449,7 @@ const fmtslice = {sb, subap, params
;;
}
-const fltparams = {params
+const fltparams = {ap, params
var fp : fltparams
fp = [
@@ -463,7 +463,12 @@ const fltparams = {params
for p : params
match p
| ("e", ""): fp.scientific = true
- | ("w", wid): fp.padto = getint(wid, "fmt: width must be integer")
+ | ("w", wid):
+ if eq(wid, "?")
+ fp.padto = pullint(ap, "fmt: width = ? must be integer")
+ else
+ fp.padto = getint(wid, "fmt: width must be integer")
+ ;;
| ("p", pad): fp.padfill = decode(pad)
| ("s", sig):
fp.mode = MRelative
@@ -480,7 +485,7 @@ const fltparams = {params
-> fp
}
-const intparams = {params
+const intparams = {ap, params
var ip : intparams
ip = [
@@ -493,7 +498,12 @@ const intparams = {params
match p
| ("b", bas): ip.base = getint(bas, "fmt: base must be integer")
| ("x", ""): ip.base = 16
- | ("w", wid): ip.padto = getint(wid, "fmt: width must be integer")
+ | ("w", wid):
+ if eq(wid, "?")
+ ip.padto = pullint(ap, "fmt: width = ? must be integer")
+ else
+ ip.padto = getint(wid, "fmt: width must be integer")
+ ;;
| ("p", pad): ip.padfill = decode(pad)
| (opt, arg):
std.write(2, "fmt: ")
@@ -507,7 +517,7 @@ const intparams = {params
-> ip
}
-const strfmt = {sb, str, params
+const strfmt = {sb, str, ap, params
var w, p, i, raw, esc
p = ' '
@@ -517,7 +527,12 @@ const strfmt = {sb, str, params
for pp : params
match pp
- | ("w", wid): w = getint(wid, "fmt: width must be integer")
+ | ("w", wid):
+ if eq(wid, "?")
+ w = pullint(ap, "fmt: width = ? must be integer")
+ else
+ w = getint(wid, "fmt: width must be integer")
+ ;;
| ("p", pad): p = decode(pad)
| ("r", ""): raw = true
| ("e", ""): esc = true
@@ -576,3 +591,47 @@ const getint = {s, msg
| `None: die(msg)
;;
}
+
+const pullint = {ap, msg
+ match typedesc(vatype(ap))
+ | `Tyint8:
+ var val : int8 = vanext(ap)
+ -> val < 0 ? 0 : (val : size)
+ | `Tyint16:
+ var val : int16 = vanext(ap)
+ -> val < 0 ? 0 : (val : size)
+ | `Tyint:
+ var val : int = vanext(ap)
+ -> val < 0 ? 0 : (val : size)
+ | `Tyint32:
+ var val : int32 = vanext(ap)
+ -> val < 0 ? 0 : (val : size)
+ | `Tyint64:
+ var val : int64 = vanext(ap)
+ -> val < 0 ? 0 : (val : size)
+ | `Tyuint8:
+ var val : uint8 = vanext(ap)
+ -> (val : size)
+ | `Tyuint16:
+ var val : uint16 = vanext(ap)
+ -> (val : size)
+ | `Tyuint:
+ var val : uint = vanext(ap)
+ -> (val : size)
+ | `Tyuint32:
+ var val : uint32 = vanext(ap)
+ -> (val : size)
+ | `Tyuint64:
+ var val : uint64 = vanext(ap)
+ -> (val : size)
+ | `Tyname (_, desc):
+ /* This is primarily for handling std.size */
+ var subap = vaenter(ap)
+ var ret = pullint(&subap, msg)
+ vabytes(ap) /* Pull one element out to keep ap synchronized with subap */
+ -> ret
+ | _: die(msg)
+ ;;
+
+ -> 0
+}
diff --git a/lib/std/test/fmt.myr b/lib/std/test/fmt.myr
index b80bafc..0d0385d 100644
--- a/lib/std/test/fmt.myr
+++ b/lib/std/test/fmt.myr
@@ -4,8 +4,11 @@ use testr
const main = {
testr.run([
- [.name="builtins", .fn=builtins ],
- [.name="installed", .fn=installed],
+ [.name="builtins", .fn=builtins ],
+ [.name="variable-width", .fn=variablewidth ],
+
+ /* Must come last -- clobbers builtins */
+ [.name="installed", .fn=installed],
][:])
}
@@ -115,6 +118,47 @@ const builtins = {c
check(c, "[void, void]", "{}", v[:2])
}
+const variablewidth = {c
+ check(c, "....xyz", "{p=.,w=7}", "xyz")
+ check(c, "....xyz", "{w=7,p=.}", "xyz")
+ check(c, "....xyz", "{p=.,w=?}", "xyz", 7)
+ check(c, "....xyz", "{w=?,p=.}", "xyz", 7)
+ check(c, "=====xyz", "{p==,w=?}", "xyz", 8)
+ check(c, "=====xyz", "{w=?,p==}", "xyz", 8)
+ check(c, "=====xyz", "{p==,w=?}", "xyz", (8 : uint8))
+ check(c, "=====xyz", "{w=?,p==}", "xyz", (8 : uint8))
+ check(c, "=====xyz", "{p==,w=?}", "xyz", (8 : std.size))
+ check(c, "=====xyz", "{w=?,p==}", "xyz", (8 : std.size))
+ check(c, "=====xyz", "{p==,w=?}", "xyz", (8 : uint64))
+ check(c, "=====xyz", "{w=?,p==}", "xyz", (8 : uint64))
+ check(c, "=====xyz", "{p==,w=?}", "xyz", (8 : int16))
+ check(c, "=====xyz", "{w=?,p==}", "xyz", (8 : int16))
+ check(c, "xyz", "{w=?,p==}", "xyz", (-34 : int16))
+
+ check(c, " 1", "{w=?}", 1, 6)
+ check(c, "77", "{w=?}", 77, (-1 : int8))
+ check(c, "77", "{w=?}", 77, (-1 : int16))
+ check(c, "77", "{w=?}", 77, (-1 : int32))
+ check(c, "77", "{w=?}", 77, (-4294967294 : int32))
+ check(c, "77", "{w=?}", 77, (-1 : int64))
+ check(c, "77", "{w=?}", 77, (-18446744073709551614 : int64))
+ check(c, "77", "{w=?}", 77, (0 : int8))
+ check(c, "77", "{w=?}", 77, (0 : int16))
+ check(c, "77", "{w=?}", 77, (0 : int32))
+ check(c, "77", "{w=?}", 77, (0 : int64))
+ check(c, "______________________________77", "{p=_,w=?}", 77, (32 : int8))
+
+ check(c, "1.0", "{w=?,p=X}", 1.0, (0 : int16))
+ check(c, "1.0", "{w=?,p=X}", 1.0, (1 : int16))
+ check(c, "1.0", "{w=?,p=X}", 1.0, (2 : int16))
+ check(c, "1.0", "{w=?,p=X}", 1.0, (3 : int16))
+ check(c, "X1.0", "{w=?,p=X}", 1.0, (4 : int16))
+ check(c, "XXXXX1.0", "{w=?,p=X}", (1.0 : flt32), (8 : int16))
+ check(c, "XXXXX1.0", "{w=?,p=X}", (1.0 : flt64), (8 : int16))
+
+ check(c, "XXab cd YYde ZZZZ1.0", "{w=4,p=X} {w=?,p=0} {p=Y,w=?} {w=?,p=Z}", "ab", "cd", (-99 : std.size), "de", (4 : uint64), (1.0 : flt32), (7 : std.size))
+}
+
const installed = {c
var x : int
var p : pair