Eigenstate: myrddin-dev mailing list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 2/3] Make vanext decrement tc.nelt unconditionally


This allows formatting functions to pass off the valist to type-specific
formatters, which may themselves consume elements from the valist, and
still check for correct argument counts without passing around counter
variables.
---
 lib/std/fmt.myr        | 29 ++++++++++++++---------------
 lib/std/introspect.myr |  1 +
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr
index c4c3797e..b7155f68 100644
--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -165,11 +165,9 @@ const sbfmt = {sb, fmt, args
 const sbfmtv = {sb, fmt, ap -> size
 	var buf : byte[256], param : (byte[:], byte[:])[8]
 	var state, startp, endp, starta, nbuf
-	var nfmt, nvarargs, nparam
+	var nparam
 	var b, i
 
-	nvarargs = ap.tc.nelt
-	nfmt = 0
 	startp = 0
 	starta = 0
 	nparam = 0
@@ -216,8 +214,7 @@ const sbfmtv = {sb, fmt, ap -> size
 			if startp != nbuf
 				param[nparam++] = (buf[startp:nbuf], "")
 			;;
-			nfmt++
-			if nfmt > nvarargs
+			if ap.tc.nelt < 1
 				die("too few values for fmt\n")
 			;;
 			fmtval(sb, vatype(ap), ap, param[:nparam])
@@ -237,15 +234,17 @@ const sbfmtv = {sb, fmt, ap -> size
 			if startp != nbuf
 				param[nparam++] = (buf[startp:endp], buf[starta:nbuf])
 			;;
+			if ap.tc.nelt < 1
+				die("too few values for fmt\n")
+			;;
 			fmtval(sb, vatype(ap), ap, param[:nparam])
-			nfmt++
 		| (`ParamArg, '\\'):
 			buf[nbuf++] = fmt[i++]
 		| (`ParamArg, chr):
 			buf[nbuf++] = b
 		;;
 	;;
-	if nfmt != nvarargs
+	if ap.tc.nelt != 0
 		die("too many values for fmt\n")
 	;;
 	-> sb.len
@@ -367,26 +366,26 @@ const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
 	| `Tytuple tc:
 		subap = vaenter(ap)
 		sbfmt(sb, "(")
-		for var i = 0; i < subap.tc.nelt; i++
+		var extracomma = subap.tc.nelt == 1
+		while subap.tc.nelt != 0
 			fmtval(sb, vatype(&subap), &subap, [][:])
-			if subap.tc.nelt == 1
-				sbfmt(sb, ",")
-			elif i != subap.tc.nelt -1
+			if subap.tc.nelt > 0
 				sbfmt(sb, ", ")
 			;;
 		;;
+		if extracomma
+			sbfmt(sb, ",")
+		;;
 		sbfmt(sb, ")")
 		vabytes(ap)
 	| `Tystruct nc:
 		subap = vaenter(ap)
 		sbfmt(sb, "[")
-		for var i = 0; i < subap.tc.nelt; i++
+		while subap.tc.nelt != 0
 			(subname, subenc) = ncpeek(&subap.tc)
 			sbfmt(sb, ".{}=", subname)
 			fmtval(sb, vatype(&subap), &subap, [][:])
-			if subap.tc.nelt == 1
-				sbfmt(sb, ",")
-			elif i != subap.tc.nelt -1
+			if subap.tc.nelt > 0
 				sbfmt(sb, ", ")
 			;;
 		;;
diff --git a/lib/std/introspect.myr b/lib/std/introspect.myr
index aec9e692..5198aeba 100644
--- a/lib/std/introspect.myr
+++ b/lib/std/introspect.myr
@@ -189,6 +189,7 @@ const ncnext = {tc
 	(n, sz) = getipacked(tc.rem)
 	enc = tc.rem[sz:sz+n]
 	tc.rem = tc.rem[sz+n:]
+	tc.nelt--
 	-> (name, enc)
 }
 
-- 
2.24.0


References:
[PATCH v2 0/3] Use ? for width specifiers"S. Gilles" <sgilles@xxxxxxx>