shithub: mc

Download patch

ref: d42f32137f5a59e229b6b0e086e9b2502f5c729d
parent: d2a4d99cee1cbff164e6b80560a0930043ba38a4
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Sep 14 08:39:04 EDT 2015

Expand testing for std.fmt

--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -194,6 +194,9 @@
 	var o, a, ha : bool, gotarg : bool
 
 	opts = [][:]
+	if optdesc.len == 0 && paramstr.len > 0
+		std.fatal("invalid format options {}\n")
+	;;
 	params = strsplit(paramstr, ",")
 	for p in params
 		/* parse out the key/value pair */
--- a/lib/std/test/fmt.myr
+++ b/lib/std/test/fmt.myr
@@ -1,5 +1,9 @@
 use std
 
+pkg =
+	type pair
+;;
+
 const check = {expected, fmt, args : ...
 	var buf : byte[2048]
 	var sl, ap
@@ -12,6 +16,11 @@
 }
 
 const main = {
+	builtins()
+	installed()
+}
+
+const builtins = {
 	check("      abcd", "{w=10}", "abcd")
 	check("00000bdcae", "{p=0,w=10}", "bdcae")
 	check("abcdefghijkl", "{p=0,w=10}", "abcdefghijkl")
@@ -32,3 +41,64 @@
 	check("0x7b", "0x{x}", 123)
 }
 
+const installed = {
+	var x : int
+	var p : pair
+
+	std.fmtinstall(std.typeof(x), intfmt, [][:])
+	std.fmtinstall(std.typeof(p), pairfmt, [
+		("x", true),
+		("y", false)
+	][:])
+
+	/* single value */
+	check("formatted an int: 0", "{}", 0)
+	check("formatted an int: -10", "{}", -10)
+
+	/* multiple values */
+	check("formatted an int: 0, formatted an int: 10", "{}, {}", 0, 10)
+	check("formatted an int: -10, formatted an int: 20", "{}, {}", -10, 20)
+
+	/* single value, no options */
+	p = [.x=0, .y=0]
+	check("formatted a pair: [0, 0]", "{}", p)
+	/* single value, option combos */
+	p = [.x=-10, .y=-10]
+	check("formatted a pair: [-10, -10]", "{}", p)
+	check("formatted a pair: [-10, -10] x=foo", "{x=foo}", p)
+	check("formatted a pair: [-10, -10] y present", "{y}", p)
+	check("formatted a pair: [-10, -10] x=bar y present", "{x=bar,y}", p)
+
+	/* multiple values */
+	check("formatted a pair: [-10, -10], formatted a pair: [-10, -10]", "{}, {}", p, p)
+
+}
+
+type pair = struct
+	x : int16
+	y : int32
+;;
+
+const intfmt = {sb, ap, opts
+	var x : int
+
+	std.assert(opts.len == 0, "options passed where none should be")
+	x = std.vanext(ap)
+	/* cast to other int type so we don't recurse */
+	std.sbfmt(sb, "formatted an int: {}", x castto(int32))
+}
+
+const pairfmt = {sb, ap, opts
+	var x : pair
+
+	x = std.vanext(ap)
+	std.sbfmt(sb, "formatted a pair: [{}, {}]", x.x, x.y)
+	for opt in opts
+		std.sbputc(sb, ' ')
+		match opt
+		| ("x", val):	std.sbfmt(sb, "x={}", val)
+		| ("y", ""):	std.sbfmt(sb, "y present")
+		| _:	std.fatal("unknown option")
+		;;
+	;;
+}
--- a/lib/std/varargs.myr
+++ b/lib/std/varargs.myr
@@ -77,9 +77,6 @@
 	-> sl
 }
 
-const inspectarg = {x
-}
-
 generic vanext = {ap -> @a
 	var v : @a
 	var ti
@@ -90,15 +87,13 @@
 
 	/* apply the alignment to the arg pointer */
 	align = ti.align castto(intptr)
-	inspectarg(align)
 	p = ap.args castto(intptr)
 	p = (p + align - 1) & ~(align - 1)
-	ap.args = p castto(byte#)
 
-	v = (ap.args castto(@a#))#
+	v = (p castto(@a#))#
+
 	/* 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#)
 	-> v