This commit is contained in:
Andreas Rumpf
2019-09-02 15:47:56 +02:00
committed by GitHub
parent fc7fe636e2
commit 7ef85db9a9
3 changed files with 60 additions and 3 deletions

View File

@@ -77,7 +77,6 @@ proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode)
# ---------------------------------------------------------------------------
proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym
proc lookupInRecord*(n: PNode, field: PIdent): PSym
proc mustRehash*(length, counter: int): bool
proc nextTry*(h, maxHash: Hash): Hash {.inline.}
@@ -174,7 +173,7 @@ proc getModule*(s: PSym): PSym =
assert((result.kind == skModule) or (result.owner != result))
while result != nil and result.kind != skModule: result = result.owner
proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym =
for i in start ..< sonsLen(list):
if list.sons[i].kind == nkSym:
result = list.sons[i].sym
@@ -182,6 +181,45 @@ proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
else: return nil
result = nil
proc sameIgnoreBacktickGensymInfo(a, b: string): bool =
if a[0] != b[0]: return false
var last = a.len - 1
while last > 0 and a[last] != '`': dec(last)
var i = 1
var j = 1
while true:
while i < last and a[i] == '_': inc i
while j < b.len and b[j] == '_': inc j
var aa = if i < last: toLowerAscii(a[i]) else: '\0'
var bb = if j < b.len: toLowerAscii(b[j]) else: '\0'
if aa != bb: return false
# the characters are identical:
if i >= last:
# both cursors at the end:
if j >= b.len: return true
# not yet at the end of 'b':
return false
elif j >= b.len:
return false
inc i
inc j
proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym =
## Named parameters are special because a named parameter can be
## gensym'ed and then they have '`<number>' suffix that we need to
## ignore, see compiler / evaltempl.nim, snippet:
##
## .. code-block:: nim
##
## result.add newIdentNode(getIdent(c.ic, x.name.s & "`gensym" & $x.id),
## if c.instLines: actual.info else: templ.info)
for i in 1 ..< len(list):
let it = list[i].sym
if it.name.id == ident.id or
sameIgnoreBacktickGensymInfo(it.name.s, ident.s): return it
proc hashNode(p: RootRef): Hash =
result = hash(cast[pointer](p))

View File

@@ -2363,7 +2363,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
noMatch()
return
formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1)
formal = getNamedParamFromList(m.callee.n, n.sons[a].sons[0].ident)
if formal == nil:
# no error message!
noMatch()

View File

@@ -9,6 +9,11 @@ output: '''
2
3
wth
3
2
1
0
(total: 6)
'''
"""
# bug #1915
@@ -145,3 +150,17 @@ macro m(): untyped =
let meh = m()
meh("wth")
macro foo(body: untyped): untyped =
result = body
template baz(): untyped =
foo:
proc bar2(b: int): int =
echo b
if b > 0: b + bar2(b = b - 1)
else: 0
echo (total: bar2(3))
baz()