ref: ac965251351332f405c9e5390e00d436fa467ff4
parent: e024022f35c31fa7f9dd85eaeb6719c57d817aba
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jun 7 05:27:06 EDT 2015
Add support for custom formatting.
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -215,13 +215,13 @@
/* format specifiers */
match c
| 's':
- (s_val, ap) = vanext(ap)
+ s_val = vanext(&ap)
n += strfmt(buf[n:], s_val, padto, padfill)
| 't':
- (t_val, ap) = vanext(ap)
+ t_val = vanext(&ap)
n += boolfmt(buf[n:], t_val, padto, padfill)
| 'f':
- (f_val, ap) = vanext(ap)
+ f_val = vanext(&ap)
b = buf[n:]
sb = mkbufsb(b)
flt64bfmt(sb, f_val, 0, b.len)
@@ -228,7 +228,7 @@
n += sb.len
strfmt(buf[n:], sbfin(sb), 0, ' ')
| 'F':
- (F_val, ap) = vanext(ap)
+ F_val = vanext(&ap)
b = buf[n:]
sb = mkbufsb(b)
flt64bfmt(sb, F_val castto(flt64), 0, b.len)
@@ -237,45 +237,45 @@
/* format integers */
| 'b':
if signed
- (b_val, ap) = vanext(ap)
+ b_val = vanext(&ap)
n += intfmt(buf[n:], b_val, base, signed, padto, padfill)
else
- (ub_val, ap) = vanext(ap)
+ ub_val = vanext(&ap)
n += intfmt(buf[n:], ub_val, base, signed, padto, padfill)
;;
| 'w':
if signed
- (w_val, ap) = vanext(ap)
+ w_val = vanext(&ap)
n += intfmt(buf[n:], w_val, base, signed, padto, padfill)
else
- (uw_val, ap) = vanext(ap)
+ uw_val = vanext(&ap)
n += intfmt(buf[n:], uw_val, base, signed, padto, padfill)
;;
| 'i':
if signed
- (i_val, ap) = vanext(ap)
+ i_val = vanext(&ap)
n += intfmt(buf[n:], i_val, base, signed, padto, padfill)
else
- (ui_val, ap) = vanext(ap)
+ ui_val = vanext(&ap)
n += intfmt(buf[n:], ui_val, base, signed, padto, padfill)
;;
| 'l':
if signed
- (l_val, ap) = vanext(ap)
+ l_val = vanext(&ap)
n += intfmt(buf[n:], l_val, base, signed, padto, padfill)
else
- (ul_val, ap) = vanext(ap)
+ ul_val = vanext(&ap)
n += intfmt(buf[n:], ul_val, base, signed, padto, padfill)
;;
| 'z':
- (z_val, ap) = vanext(ap)
+ z_val = vanext(&ap)
n += intfmt(buf[n:], z_val castto(int64), base, signed, padto, padfill)
| 'p':
- (p_val, ap) = vanext(ap)
+ p_val = vanext(&ap)
n += intfmt(buf[n:], p_val castto(int64), 16, false, padto, padfill)
| 'c':
- (c_val, ap) = vanext(ap)
+ c_val = vanext(&ap)
n += encode(buf[n:], c_val)
| '%':
n += encode(buf[n:], '%')
--- a/libstd/fmt2.myr
+++ b/libstd/fmt2.myr
@@ -3,7 +3,10 @@
use "die.use"
use "extremum.use"
use "fltfmt.use"
+use "htab.use"
+use "hashfuncs.use"
use "introspect.use"
+use "option.use"
use "strbuf.use"
use "syswrap-ss.use"
use "syswrap.use"
@@ -17,25 +20,44 @@
/* write to fd */
const f2put : (fmt : byte[:], args : ... -> size)
const f2fput : (fd : fd, fmt : byte[:], args : ... -> size)
- const f2putv : (fmt : byte[:], ap : valist -> size)
- const f2fputv : (fd : fd, fmt : byte[:], ap : valist -> size)
+ const f2putv : (fmt : byte[:], ap : valist# -> size)
+ const f2fputv : (fd : fd, fmt : byte[:], ap : valist# -> size)
/* write to buffer */
const f2fmt : (fmt : byte[:], args : ... -> byte[:])
- const f2fmtv : (fmt : byte[:], ap : valist -> byte[:])
+ const f2fmtv : (fmt : byte[:], ap : valist# -> byte[:])
const f2bfmt : (buf : byte[:], fmt : byte[:], args : ... -> byte[:])
- const f2bfmtv : (buf : byte[:], fmt : byte[:], ap : valist -> byte[:])
+ const f2bfmtv : (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:])
/* write to strbuf */
const f2sbfmt : (buf : strbuf#, fmt : byte[:], args : ... -> size)
- const f2sbfmtv : (buf : strbuf#, fmt : byte[:], ap : valist -> size)
+ const f2sbfmtv : (buf : strbuf#, fmt : byte[:], ap : valist# -> size)
+ /* add a formatter function */
+ const f2fmtinstall : (ty : byte[:], \
+ fn : (sb : strbuf#, ap : valist#, opts : byte[:] -> void) \
+ -> void)
+
$noret const f2fatal : (fmt : byte[:], args : ... -> void)
- $noret const f2fatalv : (fmt : byte[:], ap : valist -> void)
+ $noret const f2fatalv : (fmt : byte[:], ap : valist# -> void)
;;
+var fmtmapinited : bool = false
+var fmtmap : htab(byte[:], (sb : strbuf#, ap : valist#, opts : byte[:] -> void))#
+
+const f2fmtinstall = {ty, fn
+ if !fmtmapinited
+ fmtmapinited = true
+ fmtmap = mkht(strhash, streq)
+ ;;
+ htput(fmtmap, ty, fn)
+}
+
const f2put = {fmt, args
- -> f2fputv(1, fmt, vastart(&args))
+ var ap
+
+ ap = vastart(&args)
+ -> f2fputv(1, fmt, &ap)
}
const f2putv = {fmt, ap
@@ -43,7 +65,10 @@
}
const f2fput = {fd, fmt, args
- -> f2fputv(fd, fmt, vastart(&args))
+ var ap
+
+ ap = vastart(&args)
+ -> f2fputv(fd, fmt, &ap)
}
const f2fputv = {fd, fmt, ap
@@ -56,7 +81,10 @@
}
const f2fmt = {fmt, args
- -> f2fmtv(fmt, vastart(&args))
+ var ap
+
+ ap = vastart(&args)
+ -> f2fmtv(fmt, &ap)
}
const f2fmtv = {fmt, ap
@@ -68,7 +96,10 @@
}
const f2bfmt = {buf, fmt, args
- -> f2bfmtv(buf, fmt, vastart(&args))
+ var ap
+
+ ap = vastart(&args)
+ -> f2bfmtv(buf, fmt, &ap)
}
const f2bfmtv = {buf, fmt, ap
@@ -80,15 +111,22 @@
}
const f2sbfmt = {sb, fmt, args
- -> f2sbfmtv(sb, fmt, vastart(&args))
+ var ap
+
+ ap = vastart(&args)
+ -> f2sbfmtv(sb, fmt, &ap)
}
const f2sbfmtv = {sb, fmt, ap -> size
- var c, params
+ var c, params, ty
var nfmt, nparams
nparams = ap.tc.nelt
nfmt = 0
+ if !fmtmapinited
+ fmtmapinited = true
+ fmtmap = mkht(strhash, streq)
+ ;;
while fmt.len != 0
(c, fmt) = striter(fmt)
match c
@@ -108,8 +146,13 @@
die("too few params for fmt\n")
;;
- ap = fallbackfmt(sb, params, vatype(ap), ap)
-
+ ty = vatype(ap)
+ match htget(fmtmap, ty)
+ | `Some func:
+ func(sb, ap, params)
+ | `None:
+ fallbackfmt(sb, params, ty, ap)
+ ;;
| chr:
sbputc(sb, chr)
;;
@@ -121,7 +164,7 @@
-> sb.len
}
-const fallbackfmt = {sb, params, tyenc, ap
+const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
/* value types */
var t_val : bool
var b_val : int8, ub_val : uint8
@@ -145,7 +188,7 @@
| `Tyvoid:
sbputs(sb, "void")
| `Tybool:
- (t_val, ap) = vanext(ap)
+ t_val = vanext(ap)
if t_val
sbputs(sb ,"true")
else
@@ -152,53 +195,53 @@
sbputs(sb, "false")
;;
| `Tychar:
- (c_val, ap) = vanext(ap)
+ c_val = vanext(ap)
sbputc(sb, c_val)
| `Tyint8:
- (b_val, ap) = vanext(ap)
+ b_val = vanext(ap)
intfmt(sb, intparams(params), true, b_val)
| `Tyint16:
- (w_val, ap) = vanext(ap)
+ w_val = vanext(ap)
intfmt(sb, intparams(params), true, w_val)
| `Tyint:
- (i_val, ap) = vanext(ap)
+ i_val = vanext(ap)
intfmt(sb, intparams(params), true, i_val)
| `Tyint32:
- (i_val, ap) = vanext(ap)
+ i_val = vanext(ap)
intfmt(sb, intparams(params), true, i_val)
| `Tyint64:
- (l_val, ap) = vanext(ap)
+ l_val = vanext(ap)
intfmt(sb, intparams(params), true, l_val)
| `Tylong:
- (l_val, ap) = vanext(ap)
+ l_val = vanext(ap)
intfmt(sb, intparams(params), true, l_val)
| `Tybyte:
- (ub_val, ap) = vanext(ap)
+ ub_val = vanext(ap)
intfmt(sb, intparams(params), false, ub_val)
| `Tyuint8:
- (ub_val, ap) = vanext(ap)
+ ub_val = vanext(ap)
intfmt(sb, intparams(params), false, ub_val)
| `Tyuint16:
- (w_val, ap) = vanext(ap)
+ w_val = vanext(ap)
intfmt(sb, intparams(params), false, uw_val)
| `Tyuint:
- (i_val, ap) = vanext(ap)
+ i_val = vanext(ap)
intfmt(sb, intparams(params), false, ui_val)
| `Tyuint32:
- (i_val, ap) = vanext(ap)
+ i_val = vanext(ap)
intfmt(sb, intparams(params), false, ui_val)
| `Tyuint64:
- (l_val, ap) = vanext(ap)
+ l_val = vanext(ap)
intfmt(sb, intparams(params), false, ul_val)
| `Tyulong:
- (l_val, ap) = vanext(ap)
+ l_val = vanext(ap)
intfmt(sb, intparams(params), false, ul_val)
| `Tyflt32:
- (f32_val, ap) = vanext(ap)
+ f32_val = vanext(ap)
flt32bfmt(sb, f32_val, MNormal, 0)
| `Tyflt64:
- (f64_val, ap) = vanext(ap)
+ f64_val = vanext(ap)
flt64bfmt(sb, f64_val, MNormal, 0)
| `Tyvalist:
sbputs(sb, "...")
@@ -205,7 +248,7 @@
/* compound types */
| `Typtr desc:
- (p_val, ap) = vanext(ap)
+ p_val = vanext(ap)
sbputs(sb, "0x")
intfmt(sb, \
[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
@@ -213,13 +256,13 @@
| `Tyslice desc:
match typedesc(desc)
| `Tybyte:
- (s_val, ap) = vanext(ap)
+ s_val = vanext(ap)
sbputs(sb, s_val)
| _:
sbputs(sb, "slice[:]")
;;
| `Tyfunc tc:
- (p_val, ap) = vanext(ap)
+ p_val = vanext(ap)
sbputs(sb, "func{")
intfmt(sb, \
[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
@@ -235,9 +278,8 @@
| `Tyunion namecursor:
sbputs(sb, "struct")
| `Tyname (name, desc):
- ap = fallbackfmt(sb, params, desc, ap)
+ fallbackfmt(sb, params, desc, ap)
;;
- -> ap
}
type intparams = struct
--- a/libstd/varargs.myr
+++ b/libstd/varargs.myr
@@ -7,9 +7,9 @@
type valist
const vastart : (args : ...# -> valist)
- const vatype : (ap : valist -> byte[:])
- const vaskip : (ap : valist -> byte[:])
- generic vanext : (ap : valist -> (@a, valist))
+ const vatype : (ap : valist# -> byte[:])
+ const vaskip : (ap : valist# -> byte[:])
+ generic vanext : (ap : valist# -> @a)
;;
type valist = struct
@@ -55,7 +55,7 @@
-> tcpeek(&ap.tc)
}
-generic vanext = {ap -> (@a, valist)
+generic vanext = {ap -> @a
var v : @a
var align
var p
@@ -83,5 +83,5 @@
/* only move on after we read through the value */
ap.args = ((p castto(intptr)) + sizeof(@a)) castto(byte#)
- -> (v, ap)
+ -> v
}