ordinary parameters can follow a varargs parameter

This commit is contained in:
Araq
2015-02-12 14:56:42 +01:00
parent 41385f3aaf
commit c4eddb3fda
4 changed files with 44 additions and 9 deletions

View File

@@ -1441,13 +1441,14 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
return
checkConstraint(n.sons[a].sons[1])
if m.baseTypeMatch:
assert(container == nil)
#assert(container == nil)
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
addSon(container, arg)
setSon(m.call, formal.position + 1, container)
if f != formalLen - 1: container = nil
else:
else:
setSon(m.call, formal.position + 1, arg)
inc f
else:
# unnamed param
if f >= formalLen:
@@ -1466,7 +1467,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
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])
if (arg != nil) and m.baseTypeMatch and (container != nil):
if arg != nil and m.baseTypeMatch and container != nil:
addSon(container, arg)
incrIndexType(container.typ)
else:
@@ -1480,7 +1481,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
internalError(n.sons[a].info, "matches")
return
formal = m.callee.n.sons[f].sym
if containsOrIncl(marker, formal.position):
if containsOrIncl(marker, formal.position) and container.isNil:
# already in namedParams:
localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
m.state = csNoMatch
@@ -1493,17 +1494,22 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
m.state = csNoMatch
return
if m.baseTypeMatch:
assert(container == nil)
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
#assert(container == nil)
if container.isNil:
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
addSon(container, arg)
setSon(m.call, formal.position + 1,
implicitConv(nkHiddenStdConv, formal.typ, container, m, c))
if f != formalLen - 1: container = nil
#if f != formalLen - 1: container = nil
# pick the formal from the end, so that 'x, y, varargs, z' works:
f = max(f, formalLen - n.len + a + 1)
else:
setSon(m.call, formal.position + 1, arg)
inc(f)
container = nil
checkConstraint(n.sons[a])
inc(a)
inc(f)
proc semFinishOperands*(c: PContext, n: PNode) =
# this needs to be called to ensure that after overloading resolution every

View File

@@ -0,0 +1,17 @@
discard """
output: '''a 1 b 2 x @[3, 4, 5] y 6 z 7
yay
12'''
"""
proc test(a, b: int, x: varargs[int]; y, z: int) =
echo "a ", a, " b ", b, " x ", @x, " y ", y, " z ", z
test 1, 2, 3, 4, 5, 6, 7
template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) =
blck
echo a, b
takesBlock 1, 2, "some", 0.90, "random stuff":
echo "yay"

View File

@@ -1,8 +1,8 @@
version 0.10.4
==============
- make 'nil' work for 'add' and 'len'
- improve GC-unsafety warnings
- make 'nil' work for 'add' and 'len'
- get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}'

View File

@@ -43,6 +43,18 @@ News
foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable()
- Ordinary parameters can follow after a varargs parameter. This means the
following is finally accepted by the compiler:
.. code-block:: nim
template takesBlock(a, b: int, x: varargs[expr]; blck: stmt) =
blck
echo a, b
takesBlock 1, 2, "some", 0.90, "random stuff":
echo "yay"
2014-12-29 Version 0.10.2 released
==================================