diff options
author | Araq <rumpf_a@web.de> | 2015-02-12 14:56:42 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-02-12 14:56:57 +0100 |
commit | c4eddb3fdafe3494fa1b1300bcbf1314b7540490 (patch) | |
tree | 87ebc8d8f759efedf09f127f0c2acebc0c87bf0e | |
parent | 41385f3aaf4da7a13df64ec98a2b0b713c88c1d6 (diff) | |
download | Nim-c4eddb3fdafe3494fa1b1300bcbf1314b7540490.tar.gz |
ordinary parameters can follow a varargs parameter
-rw-r--r-- | compiler/sigmatch.nim | 22 | ||||
-rw-r--r-- | tests/overload/tparams_after_varargs.nim | 17 | ||||
-rw-r--r-- | todo.txt | 2 | ||||
-rw-r--r-- | web/news.txt | 12 |
4 files changed, 44 insertions, 9 deletions
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 9a99d5200..544011f2d 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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 diff --git a/tests/overload/tparams_after_varargs.nim b/tests/overload/tparams_after_varargs.nim new file mode 100644 index 000000000..a93e280b9 --- /dev/null +++ b/tests/overload/tparams_after_varargs.nim @@ -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" diff --git a/todo.txt b/todo.txt index 57cfea017..15521eae1 100644 --- a/todo.txt +++ b/todo.txt @@ -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}' diff --git a/web/news.txt b/web/news.txt index 5cc3a6ed6..7ead5a70e 100644 --- a/web/news.txt +++ b/web/news.txt @@ -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 ================================== |