diff options
-rw-r--r-- | compiler/sigmatch.nim | 2 | ||||
-rw-r--r-- | tests/macros/tvarargsuntyped.nim | 79 |
2 files changed, 81 insertions, 0 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index e4eaeb903..7a5aa8dbb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1622,6 +1622,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, while a < n.len: if a >= formalLen-1 and formal != nil and formal.typ.isVarargsUntyped: + incl(marker, formal.position) if container.isNil: container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, n.info)) setSon(m.call, formal.position + 1, container) @@ -1684,6 +1685,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, # beware of the side-effects in 'prepareOperand'! So only do it for # varargs matching. See tests/metatype/tstatic_overloading. m.baseTypeMatch = false + incl(marker, formal.position) n.sons[a] = prepareOperand(c, formal.typ, n.sons[a]) var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, n.sons[a], nOrig.sons[a]) diff --git a/tests/macros/tvarargsuntyped.nim b/tests/macros/tvarargsuntyped.nim new file mode 100644 index 000000000..b7d2bc001 --- /dev/null +++ b/tests/macros/tvarargsuntyped.nim @@ -0,0 +1,79 @@ +discard """ + output: '''Let's go! +(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8) +(left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 1, g: 7, b: 8) +(left: 2, r: 7, x: 8, height: 4, s: text, width: 3, y: 9, top: 4, g: 7, b: 8) +(left: 2, r: 7, x: 8, height: 4, s: test, width: 3, y: 9, top: 1, g: 7, b: 8)''' +""" + +import macros + +proc internalBar(top, left, width, height: cint, s: string, x, y: int, r,g,b: int) = + echo locals() + +# we need these dummy constructors due to the wrong implementation +# of 'varargs[untyped]' in the compiler: + +proc point(x, y: int): int = discard +proc color(r, g, b: int): int = discard +proc rect(a, b, c, d: int): int = discard + +template declareUnpackingMacro(nimname,extname) = + macro nimname(n: varargs[untyped]): untyped = + var s: string = astToStr(extname) & "(" + var first = true + echo repr n + for x in n.children: + var unpack = false + if x.kind in nnkCallKinds: + case $x[0] + of "point": + expectLen(x, 3) + unpack = true + of "rect": + expectLen(x, 5) + unpack = true + of "color": + expectLen(x, 4) + unpack = true + else: discard + if unpack: + for i in 1..<x.len: + if first: + first = false + else: + add(s, ", ") + add(s, repr(x[i])) + else: + if first: + first = false + else: + add(s, ", ") + add(s, repr(x)) + + add(s, ")") + echo s + result = parseStmt(s) + +declareUnpackingMacro(bar,internalBar) + +type MyInt = distinct int + +proc myInt(i: int): MyInt = cast[MyInt](i) + +converter toCInt(mi: MyInt): cint = cast[cint](mi) + +echo "Let's go!" + +bar(rect(1, 2, 3, 4), "test", point(8, 9), color(7,7,8)) + +bar(1,2,3,4,"text",8,9,7,7,8) + +bar(myInt(4),2,3,4,"text",8,9,7,7,8) + +let top: cint = 1 +let left: cint = 2 +let width: cint = 3 +let height: cint = 4 + +bar(rect(top, left, width, height), "test", point(8, 9), color(7,7,8)) |