shithub: mc

Download patch

ref: 6a113c23192c0877185aadddbc58b943ed68dd7b
parent: 03ef9a246d5f6f8013c19285224323e64206c415
author: S. Gilles <sgilles@umd.edu>
date: Sun Nov 24 13:20:51 EST 2019

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.

--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -165,11 +165,9 @@
 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 @@
 			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,8 +234,10 @@
 			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):
@@ -245,7 +244,7 @@
 			buf[nbuf++] = b
 		;;
 	;;
-	if nfmt != nvarargs
+	if ap.tc.nelt != 0
 		die("too many values for fmt\n")
 	;;
 	-> sb.len
@@ -367,26 +366,26 @@
 	| `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, ", ")
 			;;
 		;;
--- a/lib/std/introspect.myr
+++ b/lib/std/introspect.myr
@@ -189,6 +189,7 @@
 	(n, sz) = getipacked(tc.rem)
 	enc = tc.rem[sz:sz+n]
 	tc.rem = tc.rem[sz+n:]
+	tc.nelt--
 	-> (name, enc)
 }