[PATCH v2 3/3] Allow specifying padding width from variable
[Thread Prev] | [Thread Next]
- Subject: [PATCH v2 3/3] Allow specifying padding width from variable
- From: "S. Gilles" <sgilles@xxxxxxx>
- Reply-to: myrddin-dev@xxxxxxxxxxxxxx
- Date: Mon, 25 Nov 2019 16:19:54 -0500
- To: "myrddin-dev" <myrddin-dev@xxxxxxxxxxxxxx>
- Cc: "S. Gilles" <sgilles@xxxxxxx>
So I can write std.put("{w=?}{w=?}\n", field_a, max_width, field_b, max_width) --- My apologies -- this one didn't seem to go through the first time I sent it. I'm not sure why the others did. lib/std/fmt.myr | 99 +++++++++++++++++++++++++++++++++++--------- lib/std/test/fmt.myr | 48 ++++++++++++++++++++- 2 files changed, 125 insertions(+), 22 deletions(-) diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr index b7155f68..41785244 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 b80bafc6..0d0385d2 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 -- 2.24.0
[PATCH v2 0/3] Use ? for width specifiers | "S. Gilles" <sgilles@xxxxxxx> |
- Prev by Date: [PATCH] Document variable-length padding in {w=?}
- Next by Date: [PATCH] Force correct sign for intermediate steps of bigmul
- Previous by thread: [PATCH v2 2/3] Make vanext decrement tc.nelt unconditionally
- Next by thread: [PATCH] Document variable-length padding in {w=?}
- Index(es):