ref: 4ca93982fdef1ddb426b5595f814f3099adfdc65
parent: ea50af981b8a0472e2e3588c31c51ae927098949
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jun 6 11:53:27 EDT 2015
First cut at formatting.
--- a/libstd/bld.sub
+++ b/libstd/bld.sub
@@ -40,6 +40,7 @@
fltbits.myr
fltfmt.myr
fmt.myr
+ fmt2.myr
getcwd.myr
getint.myr
hashfuncs.myr
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -5,7 +5,6 @@
use "extremum.use"
use "fltfmt.use"
use "introspect.use"
-use "sleq.use"
use "syswrap-ss.use"
use "syswrap.use"
use "types.use"
--- /dev/null
+++ b/libstd/fmt2.myr
@@ -1,0 +1,295 @@
+use "alloc.use"
+use "chartype.use"
+use "die.use"
+use "extremum.use"
+use "fltfmt.use"
+use "introspect.use"
+use "strbuf.use"
+use "syswrap-ss.use"
+use "syswrap.use"
+use "types.use"
+use "utf.use"
+use "varargs.use"
+
+use "fmt.use" /* FOR DEBUGGING */
+
+pkg std =
+ /* 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)
+
+ /* write to buffer */
+ const f2fmt : (fmt : byte[:], args : ... -> 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[:])
+
+ /* write to strbuf */
+ const f2sbfmt : (buf : strbuf#, fmt : byte[:], args : ... -> size)
+ const f2sbfmtv : (buf : strbuf#, fmt : byte[:], ap : valist -> size)
+
+ $noret const f2fatal : (fmt : byte[:], args : ... -> void)
+ $noret const f2fatalv : (fmt : byte[:], ap : valist -> void)
+;;
+
+const f2put = {fmt, args
+ -> f2fputv(1, fmt, vastart(&args))
+}
+
+const f2putv = {fmt, ap
+ -> f2fputv(1, fmt, ap)
+}
+
+const f2fput = {fd, fmt, args
+ -> f2fputv(fd, fmt, vastart(&args))
+}
+
+const f2fputv = {fd, fmt, ap
+ var sb, s
+
+ sb = mksb()
+ f2sbfmtv(sb, fmt, ap)
+ s = sbfin(sb)
+ -> writeall(fd, s)
+}
+
+const f2fmt = {fmt, args
+ -> f2fmtv(fmt, vastart(&args))
+}
+
+const f2fmtv = {fmt, ap
+ var sb
+
+ sb = mksb()
+ f2sbfmtv(sb, fmt, ap)
+ -> sbfin(sb)
+}
+
+const f2bfmt = {buf, fmt, args
+ -> f2bfmtv(buf, fmt, vastart(&args))
+}
+
+const f2bfmtv = {buf, fmt, ap
+ var sb
+
+ sb = mkbufsb(buf)
+ f2sbfmtv(sb, fmt, ap)
+ -> sbfin(sb)
+}
+
+const f2sbfmt = {sb, fmt, args
+ -> f2sbfmtv(sb, fmt, vastart(&args))
+}
+
+const f2sbfmtv = {sb, fmt, ap -> size
+ var c, params
+
+ while fmt.len != 0
+ (c, fmt) = striter(fmt)
+ match c
+ | '%':
+ if fmt.len > 1 && fmt[0] == '{' castto(byte)
+ (params, fmt) = f2getparams(fmt[1:])
+ ;;
+ ap = fallbackfmt(sb, params, vatype(ap), ap)
+ | chr:
+ sbputc(sb, chr)
+ ;;
+ ;;
+ -> sb.len
+}
+
+const fallbackfmt = {sb, params, tyenc, ap
+ /* value types */
+ var t_val : bool
+ var b_val : int8, ub_val : uint8
+ var w_val : int16, uw_val : uint16
+ var i_val : int32, ui_val : uint32
+ var l_val : int64, ul_val : uint64
+ var z_val : size
+ var p_val : byte#
+ var c_val : char
+ var s_val : byte[:]
+ var f32_val : flt32, f64_val : flt64
+ var i8 : int8, i16: int16, i32 : int32
+ var by : byte
+ var i : int, i64 : int64, l : long
+ var ui8 : int8, ui16: int16, ui32 : int32
+ var ui : int, ui64 : int64, ul : long
+
+ match typedesc(tyenc)
+ | `Tynone: /* nothing */
+ /* atomic types */
+ | `Tyvoid:
+ sbputs(sb, "void")
+ | `Tybool:
+ (t_val, ap) = vanext(ap)
+ if t_val
+ sbputs(sb ,"true")
+ else
+ sbputs(sb, "false")
+ ;;
+ | `Tychar:
+ (c_val, ap) = vanext(ap)
+ sbputc(sb, c_val)
+ | `Tyint8:
+ (b_val, ap) = vanext(ap)
+ intfmt(sb, params, true, b_val)
+ | `Tyint16:
+ (w_val, ap) = vanext(ap)
+ intfmt(sb, params, true, w_val)
+ | `Tyint:
+ (i_val, ap) = vanext(ap)
+ intfmt(sb, params, true, i_val)
+ | `Tyint32:
+ (i_val, ap) = vanext(ap)
+ intfmt(sb, params, true, i_val)
+ | `Tyint64:
+ (l_val, ap) = vanext(ap)
+ intfmt(sb, params, true, l_val)
+ | `Tylong:
+ (l_val, ap) = vanext(ap)
+ intfmt(sb, params, true, l_val)
+
+ | `Tybyte:
+ (ub_val, ap) = vanext(ap)
+ intfmt(sb, params, false, ub_val)
+ | `Tyuint8:
+ (ub_val, ap) = vanext(ap)
+ intfmt(sb, params, false, ub_val)
+ | `Tyuint16:
+ (w_val, ap) = vanext(ap)
+ intfmt(sb, params, false, uw_val)
+ | `Tyuint:
+ (i_val, ap) = vanext(ap)
+ intfmt(sb, params, false, ui_val)
+ | `Tyuint32:
+ (i_val, ap) = vanext(ap)
+ intfmt(sb, params, false, ui_val)
+ | `Tyuint64:
+ (l_val, ap) = vanext(ap)
+ intfmt(sb, params, false, ul_val)
+ | `Tyulong:
+ (l_val, ap) = vanext(ap)
+ intfmt(sb, params, false, ul_val)
+ | `Tyflt32:
+ (l_val, ap) = vanext(ap)
+ sbputs(sb, "flt32")
+ | `Tyflt64:
+ sbputs(sb, "flt64")
+ | `Tyvalist:
+ sbputs(sb, "...")
+
+ /* compound types */
+ | `Typtr desc:
+ (p_val, ap) = vanext(ap)
+ intfmt(sb, params, false, p_val castto(intptr))
+ | `Tyslice desc:
+ match typedesc(desc)
+ | `Tybyte:
+ (s_val, ap) = vanext(ap)
+ sbputs(sb, s_val)
+ | _:
+ sbputs(sb, "slice[:]")
+ ;;
+ | `Tyfunc tc:
+ sbputs(sb, "func")
+ | `Tyarray (sz, data):
+ sbputs(sb, "array")
+
+ /* aggregate types */
+ | `Tytuple typecursor:
+ sbputs(sb, "tuple")
+ | `Tystruct namecursor:
+ sbputs(sb, "struct")
+ | `Tyunion namecursor:
+ sbputs(sb, "struct")
+ | `Tyname (name, desc):
+ ap = fallbackfmt(sb, params, desc, ap)
+ ;;
+ -> ap
+}
+
+
+const f2getparams = {fmt
+ var i
+
+ for i = 0; i < fmt.len; i++
+ if fmt[i] == '}' castto(byte)
+ goto foundparams
+ ;;
+ ;;
+ die("invalid format string")
+:foundparams
+ -> (fmt[:i], fmt[i+1:])
+}
+
+const digitchars = [
+ '0','1','2','3','4',
+ '5','6','7','8','9',
+ 'a','b','c','d','e','f'
+]
+generic intfmt = {sb, opts, signed, bits : @a::(integral,numeric)
+ var isneg
+ var val
+ var b : char[32]
+ var i, j, npad
+ var base, padto, padfill
+
+ i = 0
+ base = 10
+ padto = 0
+ padfill = '0'
+ if signed && bits < 0
+ val = -bits castto(uint64)
+ isneg = true
+ else
+ val = bits castto(uint64)
+ val &= ~0 >> (8*(sizeof(uint64)-sizeof(@a)))
+ isneg = false
+ ;;
+
+ if val == 0
+ b[0] = '0'
+ i++
+ ;;
+ while val != 0
+ b[i] = digitchars[val % base]
+ val /= base
+ i++
+ ;;
+
+ npad = clamp(padto - i, 0, padto)
+ if isneg
+ npad--
+ ;;
+ if padfill == '0' && isneg
+ sbputc(sb, '-')
+ ;;
+ for j = 0; j < npad; j++
+ sbputc(sb, padfill)
+ ;;
+ if padfill != '0' && isneg
+ sbputc(sb, '-')
+ ;;
+ for j = i; j != 0; j--
+ sbputc(sb, b[j - 1])
+ ;;
+}
+
+const writeall = {fd, buf
+ var n, len
+
+ len = 0
+ while true
+ n = write(fd, buf)
+ if n <= 0 || n >= len
+ break
+ ;;
+ len += n
+ ;;
+ -> len
+}
+
--- a/libstd/introspect.myr
+++ b/libstd/introspect.myr
@@ -1,6 +1,5 @@
use "types.use"
use "die.use"
-use sys
pkg std =
type typedesc = union
--- a/libstd/varargs.myr
+++ b/libstd/varargs.myr
@@ -7,6 +7,7 @@
type valist
const vastart : (args : ...# -> valist)
+ const vatype : (ap : valist -> byte[:])
generic vanext : (ap : valist -> (@a, valist))
;;
@@ -49,6 +50,10 @@
-> [.args = a, .tc = tc]
}
+const vatype = {ap
+ -> tcpeek(&ap.tc)
+}
+
generic vanext = {ap -> (@a, valist)
var v : @a
var align
@@ -72,13 +77,8 @@
ap.args = p castto(byte#)
v = (ap.args castto(@a#))#
- /* TODO: checked.
-
- Right now, too much is broken with named types.
- if !sleq(typeof(v), tcnext(&ap.tc))
- std.die("wrong type from valist\n")
- ;;
- */
+ /* TODO: check for type mismatch */
+ tcnext(&ap.tc)
/* only move on after we read through the value */
ap.args = ((p castto(intptr)) + sizeof(@a)) castto(byte#)