ordinary parameters can follow a varargs parameter
This commit is contained in:
parent
41385f3aaf
commit
c4eddb3fda
4 changed files with 44 additions and 9 deletions
|
|
@ -1441,13 +1441,14 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
return
|
return
|
||||||
checkConstraint(n.sons[a].sons[1])
|
checkConstraint(n.sons[a].sons[1])
|
||||||
if m.baseTypeMatch:
|
if m.baseTypeMatch:
|
||||||
assert(container == nil)
|
#assert(container == nil)
|
||||||
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
|
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
|
||||||
addSon(container, arg)
|
addSon(container, arg)
|
||||||
setSon(m.call, formal.position + 1, container)
|
setSon(m.call, formal.position + 1, container)
|
||||||
if f != formalLen - 1: container = nil
|
if f != formalLen - 1: container = nil
|
||||||
else:
|
else:
|
||||||
setSon(m.call, formal.position + 1, arg)
|
setSon(m.call, formal.position + 1, arg)
|
||||||
|
inc f
|
||||||
else:
|
else:
|
||||||
# unnamed param
|
# unnamed param
|
||||||
if f >= formalLen:
|
if f >= formalLen:
|
||||||
|
|
@ -1466,7 +1467,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
|
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
|
||||||
var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
var arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
|
||||||
n.sons[a], nOrig.sons[a])
|
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)
|
addSon(container, arg)
|
||||||
incrIndexType(container.typ)
|
incrIndexType(container.typ)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1480,7 +1481,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
internalError(n.sons[a].info, "matches")
|
internalError(n.sons[a].info, "matches")
|
||||||
return
|
return
|
||||||
formal = m.callee.n.sons[f].sym
|
formal = m.callee.n.sons[f].sym
|
||||||
if containsOrIncl(marker, formal.position):
|
if containsOrIncl(marker, formal.position) and container.isNil:
|
||||||
# already in namedParams:
|
# already in namedParams:
|
||||||
localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
|
localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
|
|
@ -1493,17 +1494,22 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
return
|
return
|
||||||
if m.baseTypeMatch:
|
if m.baseTypeMatch:
|
||||||
assert(container == nil)
|
#assert(container == nil)
|
||||||
|
if container.isNil:
|
||||||
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
|
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
|
||||||
addSon(container, arg)
|
addSon(container, arg)
|
||||||
setSon(m.call, formal.position + 1,
|
setSon(m.call, formal.position + 1,
|
||||||
implicitConv(nkHiddenStdConv, formal.typ, container, m, c))
|
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:
|
else:
|
||||||
setSon(m.call, formal.position + 1, arg)
|
setSon(m.call, formal.position + 1, arg)
|
||||||
|
inc(f)
|
||||||
|
container = nil
|
||||||
checkConstraint(n.sons[a])
|
checkConstraint(n.sons[a])
|
||||||
inc(a)
|
inc(a)
|
||||||
inc(f)
|
|
||||||
|
|
||||||
proc semFinishOperands*(c: PContext, n: PNode) =
|
proc semFinishOperands*(c: PContext, n: PNode) =
|
||||||
# this needs to be called to ensure that after overloading resolution every
|
# this needs to be called to ensure that after overloading resolution every
|
||||||
|
|
|
||||||
17
tests/overload/tparams_after_varargs.nim
Normal file
17
tests/overload/tparams_after_varargs.nim
Normal 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"
|
||||||
2
todo.txt
2
todo.txt
|
|
@ -1,8 +1,8 @@
|
||||||
version 0.10.4
|
version 0.10.4
|
||||||
==============
|
==============
|
||||||
|
|
||||||
- make 'nil' work for 'add' and 'len'
|
|
||||||
- improve GC-unsafety warnings
|
- improve GC-unsafety warnings
|
||||||
|
- make 'nil' work for 'add' and 'len'
|
||||||
- get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}'
|
- get rid of 'mget'; aka priority of 'var' needs to be 'var{lvalue}'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
12
web/news.txt
12
web/news.txt
|
|
@ -43,6 +43,18 @@ News
|
||||||
foo = {"ah": "finally", "this": "is", "possible.": "nice!"}.toTable()
|
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
|
2014-12-29 Version 0.10.2 released
|
||||||
==================================
|
==================================
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue