Cosmetic compiler cleanup (#12718)

* Cleanup compiler code base

* Unify add calls

* Unify len invocations

* Unify range operators

* Fix oversight

* Remove {.procvar.} pragma

* initCandidate -> newCandidate where reasonable

* Unify safeLen calls
This commit is contained in:
Clyybber 2019-11-28 17:13:04 +01:00 • committed by Andreas Rumpf
commit 7e747d11c6
109 changed files with 6115 additions and 6254 deletions

View file

@ -34,9 +34,9 @@ type
spNone, spGenSym, spInject
proc symBinding(n: PNode): TSymBinding =
for i in 0 ..< len(n):
var it = n.sons[i]
var key = if it.kind == nkExprColonExpr: it.sons[0] else: it
for i in 0..<n.len:
var it = n[i]
var key = if it.kind == nkExprColonExpr: it[0] else: it
if key.kind == nkIdent:
case whichKeyword(key.ident)
of wGensym: return spGenSym
@ -81,13 +81,13 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule;
if a.kind != skModule and (not isField or sfGenSym notin s.flags):
incl(a.flags, sfUsed)
markOwnerModuleAsUsed(c, a)
addSon(result, newSymNode(a, info))
result.add newSymNode(a, info)
onUse(info, a)
a = nextOverloadIter(o, c, n)
proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode =
for i in 0 ..< n.len:
var a = n.sons[i]
for i in 0..<n.len:
var a = n[i]
# If 'a' is an overloaded symbol, we used to use the first symbol
# as a 'witness' and use the fact that subsequent lookups will yield
# the same symbol!
@ -106,14 +106,14 @@ proc semBindStmt(c: PContext, n: PNode, toBind: var IntSet): PNode =
result = newNodeI(nkEmpty, n.info)
proc semMixinStmt(c: PContext, n: PNode, toMixin: var IntSet): PNode =
for i in 0 ..< n.len:
toMixin.incl(considerQuotedIdent(c, n.sons[i]).id)
for i in 0..<n.len:
toMixin.incl(considerQuotedIdent(c, n[i]).id)
result = newNodeI(nkEmpty, n.info)
proc replaceIdentBySym(c: PContext; n: var PNode, s: PNode) =
case n.kind
of nkPostfix: replaceIdentBySym(c, n.sons[1], s)
of nkPragmaExpr: replaceIdentBySym(c, n.sons[0], s)
of nkPostfix: replaceIdentBySym(c, n[1], s)
of nkPragmaExpr: replaceIdentBySym(c, n[0], s)
of nkIdent, nkAccQuoted, nkSym: n = s
else: illFormedAst(n, c.config)
@ -132,8 +132,8 @@ template withBracketExpr(ctx, x, body: untyped) =
proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
case n.kind
of nkPostfix: result = getIdentNode(c, n.sons[1])
of nkPragmaExpr: result = getIdentNode(c, n.sons[0])
of nkPostfix: result = getIdentNode(c, n[1])
of nkPragmaExpr: result = getIdentNode(c, n[0])
of nkIdent:
result = n
let s = qualifiedLookUp(c.c, n, {})
@ -175,8 +175,8 @@ proc onlyReplaceParams(c: var TemplCtx, n: PNode): PNode =
result = newSymNode(s, n.info)
onUse(n.info, s)
else:
for i in 0 ..< n.safeLen:
result.sons[i] = onlyReplaceParams(c, n.sons[i])
for i in 0..<n.safeLen:
result[i] = onlyReplaceParams(c, n[i])
proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
result = newSym(kind, considerQuotedIdent(c.c, n), c.owner, n.info)
@ -185,7 +185,7 @@ proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
# locals default to 'gensym':
if n.kind == nkPragmaExpr and symBinding(n.sons[1]) == spInject:
if n.kind == nkPragmaExpr and symBinding(n[1]) == spInject:
# even if injected, don't produce a sym choice here:
#n = semTemplBody(c, n)
var x = n[0]
@ -207,11 +207,11 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
else:
replaceIdentBySym(c.c, n, ident)
else:
if (n.kind == nkPragmaExpr and len(n) >= 2 and n.sons[1].kind == nkPragma):
let pragmaNode = n.sons[1]
for i in 0..<pragmaNode.sons.len:
if (n.kind == nkPragmaExpr and n.len >= 2 and n[1].kind == nkPragma):
let pragmaNode = n[1]
for i in 0..<pragmaNode.len:
openScope(c)
pragmaNode.sons[i] = semTemplBody(c,pragmaNode.sons[i])
pragmaNode[i] = semTemplBody(c,pragmaNode[i])
closeScope(c)
let ident = getIdentNode(c, n)
if not isTemplParam(c, ident):
@ -272,41 +272,41 @@ proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
result = newSymNode(s, n.info)
onUse(n.info, s)
else:
for i in 0 ..< safeLen(n):
result.sons[i] = semRoutineInTemplName(c, n.sons[i])
for i in 0..<n.safeLen:
result[i] = semRoutineInTemplName(c, n[i])
proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
result = n
checkSonsLen(n, bodyPos + 1, c.c.config)
# routines default to 'inject':
if n.kind notin nkLambdaKinds and symBinding(n.sons[pragmasPos]) == spGenSym:
let ident = getIdentNode(c, n.sons[namePos])
if n.kind notin nkLambdaKinds and symBinding(n[pragmasPos]) == spGenSym:
let ident = getIdentNode(c, n[namePos])
if not isTemplParam(c, ident):
var s = newGenSym(k, ident, c)
s.ast = n
addPrelimDecl(c.c, s)
styleCheckDef(c.c.config, n.info, s)
onDef(n.info, s)
n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
n[namePos] = newSymNode(s, n[namePos].info)
else:
n.sons[namePos] = ident
n[namePos] = ident
else:
n.sons[namePos] = semRoutineInTemplName(c, n.sons[namePos])
n[namePos] = semRoutineInTemplName(c, n[namePos])
# open scope for parameters
openScope(c)
for i in patternPos..paramsPos-1:
n.sons[i] = semTemplBody(c, n.sons[i])
n[i] = semTemplBody(c, n[i])
if k == skTemplate: inc(c.inTemplateHeader)
n.sons[paramsPos] = semTemplBody(c, n.sons[paramsPos])
n[paramsPos] = semTemplBody(c, n[paramsPos])
if k == skTemplate: dec(c.inTemplateHeader)
for i in paramsPos+1..miscPos:
n.sons[i] = semTemplBody(c, n.sons[i])
n[i] = semTemplBody(c, n[i])
# open scope for locals
inc c.scopeN
openScope(c)
n.sons[bodyPos] = semTemplBody(c, n.sons[bodyPos])
n[bodyPos] = semTemplBody(c, n[bodyPos])
# close scope for locals
closeScope(c)
dec c.scopeN
@ -314,27 +314,26 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
closeScope(c)
proc semTemplSomeDecl(c: var TemplCtx, n: PNode, symKind: TSymKind; start=0) =
for i in start ..< len(n):
var a = n.sons[i]
for i in start..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a, c.c.config)
checkMinSonsLen(a, 3, c.c.config)
var L = len(a)
when defined(nimsuggest):
inc c.c.inTypeContext
a.sons[L-2] = semTemplBody(c, a.sons[L-2])
a[^2] = semTemplBody(c, a[^2])
when defined(nimsuggest):
dec c.c.inTypeContext
a.sons[L-1] = semTemplBody(c, a.sons[L-1])
for j in 0 .. L-3:
addLocalDecl(c, a.sons[j], symKind)
a[^1] = semTemplBody(c, a[^1])
for j in 0..<a.len-2:
addLocalDecl(c, a[j], symKind)
proc semPattern(c: PContext, n: PNode): PNode
proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode =
result = n
for i in 0 ..< n.len:
result.sons[i] = semTemplBody(c, n.sons[i])
for i in 0..<n.len:
result[i] = semTemplBody(c, n[i])
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
result = n
@ -362,7 +361,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
else:
result = semTemplSymbol(c.c, n, s, c.noGenSym > 0)
of nkBind:
result = semTemplBody(c, n.sons[0])
result = semTemplBody(c, n[0])
of nkBindStmt:
result = semBindStmt(c.c, n, c.toBind)
of nkMixinStmt:
@ -371,109 +370,106 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
of nkEmpty, nkSym..nkNilLit, nkComesFrom:
discard
of nkIfStmt:
for i in 0 ..< len(n):
var it = n.sons[i]
for i in 0..<n.len:
var it = n[i]
if it.len == 2:
openScope(c)
it.sons[0] = semTemplBody(c, it.sons[0])
it.sons[1] = semTemplBody(c, it.sons[1])
it[0] = semTemplBody(c, it[0])
it[1] = semTemplBody(c, it[1])
closeScope(c)
else:
n.sons[i] = semTemplBodyScope(c, it)
n[i] = semTemplBodyScope(c, it)
of nkWhileStmt:
openScope(c)
for i in 0 ..< len(n):
n.sons[i] = semTemplBody(c, n.sons[i])
for i in 0..<n.len:
n[i] = semTemplBody(c, n[i])
closeScope(c)
of nkCaseStmt:
openScope(c)
n.sons[0] = semTemplBody(c, n.sons[0])
for i in 1 ..< len(n):
var a = n.sons[i]
n[0] = semTemplBody(c, n[0])
for i in 1..<n.len:
var a = n[i]
checkMinSonsLen(a, 1, c.c.config)
var L = len(a)
for j in 0 .. L-2:
a.sons[j] = semTemplBody(c, a.sons[j])
a.sons[L-1] = semTemplBodyScope(c, a.sons[L-1])
for j in 0..<a.len-1:
a[j] = semTemplBody(c, a[j])
a[^1] = semTemplBodyScope(c, a[^1])
closeScope(c)
of nkForStmt, nkParForStmt:
var L = len(n)
openScope(c)
n.sons[L-2] = semTemplBody(c, n.sons[L-2])
for i in 0 .. L - 3:
n[^2] = semTemplBody(c, n[^2])
for i in 0..<n.len - 2:
if n[i].kind == nkVarTuple:
for j in 0 ..< len(n[i])-1:
for j in 0..<n[i].len-1:
addLocalDecl(c, n[i][j], skForVar)
else:
addLocalDecl(c, n.sons[i], skForVar)
addLocalDecl(c, n[i], skForVar)
openScope(c)
n.sons[L-1] = semTemplBody(c, n.sons[L-1])
n[^1] = semTemplBody(c, n[^1])
closeScope(c)
closeScope(c)
of nkBlockStmt, nkBlockExpr, nkBlockType:
checkSonsLen(n, 2, c.c.config)
openScope(c)
if n.sons[0].kind != nkEmpty:
addLocalDecl(c, n.sons[0], skLabel)
if n[0].kind != nkEmpty:
addLocalDecl(c, n[0], skLabel)
when false:
# labels are always 'gensym'ed:
let s = newGenSym(skLabel, n.sons[0], c)
let s = newGenSym(skLabel, n[0], c)
addPrelimDecl(c.c, s)
styleCheckDef(c.c.config, s)
onDef(n[0].info, s)
n.sons[0] = newSymNode(s, n.sons[0].info)
n.sons[1] = semTemplBody(c, n.sons[1])
n[0] = newSymNode(s, n[0].info)
n[1] = semTemplBody(c, n[1])
closeScope(c)
of nkTryStmt, nkHiddenTryStmt:
checkMinSonsLen(n, 2, c.c.config)
n.sons[0] = semTemplBodyScope(c, n.sons[0])
for i in 1 ..< len(n):
var a = n.sons[i]
n[0] = semTemplBodyScope(c, n[0])
for i in 1..<n.len:
var a = n[i]
checkMinSonsLen(a, 1, c.c.config)
var L = len(a)
openScope(c)
for j in 0 .. L-2:
if a.sons[j].isInfixAs():
addLocalDecl(c, a.sons[j].sons[2], skLet)
a.sons[j].sons[1] = semTemplBody(c, a.sons[j][1])
for j in 0..<a.len-1:
if a[j].isInfixAs():
addLocalDecl(c, a[j][2], skLet)
a[j][1] = semTemplBody(c, a[j][1])
else:
a.sons[j] = semTemplBody(c, a.sons[j])
a.sons[L-1] = semTemplBodyScope(c, a.sons[L-1])
a[j] = semTemplBody(c, a[j])
a[^1] = semTemplBodyScope(c, a[^1])
closeScope(c)
of nkVarSection: semTemplSomeDecl(c, n, skVar)
of nkLetSection: semTemplSomeDecl(c, n, skLet)
of nkFormalParams:
checkMinSonsLen(n, 1, c.c.config)
n.sons[0] = semTemplBody(c, n.sons[0])
n[0] = semTemplBody(c, n[0])
semTemplSomeDecl(c, n, skParam, 1)
of nkConstSection:
for i in 0 ..< len(n):
var a = n.sons[i]
for i in 0..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkConstDef): illFormedAst(a, c.c.config)
checkSonsLen(a, 3, c.c.config)
addLocalDecl(c, a.sons[0], skConst)
a.sons[1] = semTemplBody(c, a.sons[1])
a.sons[2] = semTemplBody(c, a.sons[2])
addLocalDecl(c, a[0], skConst)
a[1] = semTemplBody(c, a[1])
a[2] = semTemplBody(c, a[2])
of nkTypeSection:
for i in 0 ..< len(n):
var a = n.sons[i]
for i in 0..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkTypeDef): illFormedAst(a, c.c.config)
checkSonsLen(a, 3, c.c.config)
addLocalDecl(c, a.sons[0], skType)
for i in 0 ..< len(n):
var a = n.sons[i]
addLocalDecl(c, a[0], skType)
for i in 0..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkTypeDef): illFormedAst(a, c.c.config)
checkSonsLen(a, 3, c.c.config)
if a.sons[1].kind != nkEmpty:
if a[1].kind != nkEmpty:
openScope(c)
a.sons[1] = semTemplBody(c, a.sons[1])
a.sons[2] = semTemplBody(c, a.sons[2])
a[1] = semTemplBody(c, a[1])
a[2] = semTemplBody(c, a[2])
closeScope(c)
else:
a.sons[2] = semTemplBody(c, a.sons[2])
a[2] = semTemplBody(c, a[2])
of nkProcDef, nkLambdaKinds:
result = semRoutineInTemplBody(c, n, skProc)
of nkFuncDef:
@ -489,44 +485,44 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
of nkConverterDef:
result = semRoutineInTemplBody(c, n, skConverter)
of nkPragmaExpr:
result.sons[0] = semTemplBody(c, n.sons[0])
result[0] = semTemplBody(c, n[0])
of nkPostfix:
result.sons[1] = semTemplBody(c, n.sons[1])
result[1] = semTemplBody(c, n[1])
of nkPragma:
for x in n:
if x.kind == nkExprColonExpr:
x.sons[1] = semTemplBody(c, x.sons[1])
x[1] = semTemplBody(c, x[1])
of nkBracketExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.c.cache, "[]"), n.info)
for i in 0 ..< n.len: result.add(n[i])
let n0 = semTemplBody(c, n.sons[0])
for i in 0..<n.len: result.add(n[i])
let n0 = semTemplBody(c, n[0])
withBracketExpr c, n0:
result = semTemplBodySons(c, result)
of nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.c.cache, "{}"), n.info)
for i in 0 ..< n.len: result.add(n[i])
for i in 0..<n.len: result.add(n[i])
result = semTemplBodySons(c, result)
of nkAsgn, nkFastAsgn:
checkSonsLen(n, 2, c.c.config)
let a = n.sons[0]
let b = n.sons[1]
let a = n[0]
let b = n[1]
let k = a.kind
case k
of nkBracketExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.c.cache, "[]="), n.info)
for i in 0 ..< a.len: result.add(a[i])
for i in 0..<a.len: result.add(a[i])
result.add(b)
let a0 = semTemplBody(c, a.sons[0])
let a0 = semTemplBody(c, a[0])
withBracketExpr c, a0:
result = semTemplBodySons(c, result)
of nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.c.cache, "{}="), n.info)
for i in 0 ..< a.len: result.add(a[i])
for i in 0..<a.len: result.add(a[i])
result.add(b)
result = semTemplBodySons(c, result)
else:
@ -554,18 +550,18 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
return symChoice(c.c, n, s, scOpen, c.noGenSym > 0)
if n.kind == nkDotExpr:
result = n
result.sons[0] = semTemplBody(c, n.sons[0])
result[0] = semTemplBody(c, n[0])
if optNimV019 notin c.c.config.globalOptions: inc c.noGenSym
result.sons[1] = semTemplBody(c, n.sons[1])
result[1] = semTemplBody(c, n[1])
if optNimV019 notin c.c.config.globalOptions: dec c.noGenSym
else:
result = semTemplBodySons(c, n)
of nkExprColonExpr, nkExprEqExpr:
if n.len == 2:
if optNimV019 notin c.c.config.globalOptions: inc c.noGenSym
result.sons[0] = semTemplBody(c, n.sons[0])
result[0] = semTemplBody(c, n[0])
if optNimV019 notin c.c.config.globalOptions: dec c.noGenSym
result.sons[1] = semTemplBody(c, n.sons[1])
result[1] = semTemplBody(c, n[1])
else:
result = semTemplBodySons(c, n)
else:
@ -583,7 +579,7 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
elif contains(c.toBind, s.id):
result = symChoice(c.c, n, s, scClosed)
of nkBind:
result = semTemplBodyDirty(c, n.sons[0])
result = semTemplBodyDirty(c, n[0])
of nkBindStmt:
result = semBindStmt(c.c, n, c.toBind)
of nkEmpty, nkSym..nkNilLit, nkComesFrom:
@ -596,16 +592,16 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
if s != nil and contains(c.toBind, s.id):
return symChoice(c.c, n, s, scClosed)
result = n
for i in 0 ..< len(n):
result.sons[i] = semTemplBodyDirty(c, n.sons[i])
for i in 0..<n.len:
result[i] = semTemplBodyDirty(c, n[i])
proc semTemplateDef(c: PContext, n: PNode): PNode =
var s: PSym
if isTopLevel(c):
s = semIdentVis(c, skTemplate, n.sons[0], {sfExported})
s = semIdentVis(c, skTemplate, n[0], {sfExported})
incl(s.flags, sfGlobal)
else:
s = semIdentVis(c, skTemplate, n.sons[0], {})
s = semIdentVis(c, skTemplate, n[0], {})
if s.owner != nil:
const names = ["!=", ">=", ">", "incl", "excl", "in", "notin", "isnot"]
@ -619,41 +615,41 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
#s.scope = c.currentScope
pushOwner(c, s)
openScope(c)
n.sons[namePos] = newSymNode(s, n.sons[namePos].info)
if n.sons[pragmasPos].kind != nkEmpty:
pragma(c, s, n.sons[pragmasPos], templatePragmas)
n[namePos] = newSymNode(s, n[namePos].info)
if n[pragmasPos].kind != nkEmpty:
pragma(c, s, n[pragmasPos], templatePragmas)
var gp: PNode
if n.sons[genericParamsPos].kind != nkEmpty:
n.sons[genericParamsPos] = semGenericParamList(c, n.sons[genericParamsPos])
gp = n.sons[genericParamsPos]
if n[genericParamsPos].kind != nkEmpty:
n[genericParamsPos] = semGenericParamList(c, n[genericParamsPos])
gp = n[genericParamsPos]
else:
gp = newNodeI(nkGenericParams, n.info)
# process parameters:
var allUntyped = true
if n.sons[paramsPos].kind != nkEmpty:
semParamList(c, n.sons[paramsPos], gp, s)
if n[paramsPos].kind != nkEmpty:
semParamList(c, n[paramsPos], gp, s)
# a template's parameters are not gensym'ed even if that was originally the
# case as we determine whether it's a template parameter in the template
# body by the absence of the sfGenSym flag:
for i in 1 .. s.typ.n.len-1:
let param = s.typ.n.sons[i].sym
for i in 1..<s.typ.n.len:
let param = s.typ.n[i].sym
param.flags.incl sfTemplateParam
param.flags.excl sfGenSym
if param.typ.kind != tyUntyped: allUntyped = false
if len(gp) > 0:
if n.sons[genericParamsPos].kind == nkEmpty:
if gp.len > 0:
if n[genericParamsPos].kind == nkEmpty:
# we have a list of implicit type parameters:
n.sons[genericParamsPos] = gp
n[genericParamsPos] = gp
else:
s.typ = newTypeS(tyProc, c)
# XXX why do we need tyTyped as a return type again?
s.typ.n = newNodeI(nkFormalParams, n.info)
rawAddSon(s.typ, newTypeS(tyTyped, c))
addSon(s.typ.n, newNodeIT(nkType, n.info, s.typ.sons[0]))
s.typ.n.add newNodeIT(nkType, n.info, s.typ[0])
if allUntyped: incl(s.flags, sfAllUntyped)
if n.sons[patternPos].kind != nkEmpty:
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
if n[patternPos].kind != nkEmpty:
n[patternPos] = semPattern(c, n[patternPos])
var ctx: TemplCtx
ctx.toBind = initIntSet()
ctx.toMixin = initIntSet()
@ -661,26 +657,26 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
ctx.c = c
ctx.owner = s
if sfDirty in s.flags:
n.sons[bodyPos] = semTemplBodyDirty(ctx, n.sons[bodyPos])
n[bodyPos] = semTemplBodyDirty(ctx, n[bodyPos])
else:
n.sons[bodyPos] = semTemplBody(ctx, n.sons[bodyPos])
n[bodyPos] = semTemplBody(ctx, n[bodyPos])
# only parameters are resolved, no type checking is performed
semIdeForTemplateOrGeneric(c, n.sons[bodyPos], ctx.cursorInBody)
semIdeForTemplateOrGeneric(c, n[bodyPos], ctx.cursorInBody)
closeScope(c)
popOwner(c)
s.ast = n
result = n
if sfCustomPragma in s.flags:
if n.sons[bodyPos].kind != nkEmpty:
localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s)
elif n.sons[bodyPos].kind == nkEmpty:
if n[bodyPos].kind != nkEmpty:
localError(c.config, n[bodyPos].info, errImplOfXNotAllowed % s.name.s)
elif n[bodyPos].kind == nkEmpty:
localError(c.config, n.info, "implementation of '$1' expected" % s.name.s)
var proto = searchForProc(c, c.currentScope, s)
if proto == nil:
addInterfaceOverloadableSymAt(c, c.currentScope, s)
else:
symTabReplace(c.currentScope.symbols, proto, s)
if n.sons[patternPos].kind != nkEmpty:
if n[patternPos].kind != nkEmpty:
c.patterns.add(s)
proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
@ -694,7 +690,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
# to use the param with the proper type though:
incl(s.flags, sfUsed)
onUse(n.info, s)
let x = c.owner.typ.n.sons[s.position+1].sym
let x = c.owner.typ.n[s.position+1].sym
assert x.name == s.name
result = newSymNode(x, n.info)
@ -721,7 +717,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
result = n
proc stupidStmtListExpr(n: PNode): bool =
for i in 0 .. n.len-2:
for i in 0..<n.len-1:
if n[i].kind notin {nkEmpty, nkCommentStmt}: return false
result = true
@ -738,14 +734,14 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
# '(pattern){|x}' does the same but the matches will be gathered in 'x'
if n.len != 2:
localError(c.c.config, n.info, "invalid expression")
elif n.sons[1].kind == nkIdent:
n.sons[0] = semPatternBody(c, n.sons[0])
n.sons[1] = expectParam(c, n.sons[1])
elif n.sons[1].kind == nkPrefix and n.sons[1].sons[0].kind == nkIdent:
let opr = n.sons[1].sons[0]
elif n[1].kind == nkIdent:
n[0] = semPatternBody(c, n[0])
n[1] = expectParam(c, n[1])
elif n[1].kind == nkPrefix and n[1][0].kind == nkIdent:
let opr = n[1][0]
if opr.ident.s == "|":
n.sons[0] = semPatternBody(c, n.sons[0])
n.sons[1].sons[1] = expectParam(c, n.sons[1].sons[1])
n[0] = semPatternBody(c, n[0])
n[1][1] = expectParam(c, n[1][1])
else:
localError(c.c.config, n.info, "invalid expression")
else:
@ -754,10 +750,10 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
if stupidStmtListExpr(n):
result = semPatternBody(c, n.lastSon)
else:
for i in 0 ..< len(n):
result.sons[i] = semPatternBody(c, n.sons[i])
for i in 0..<n.len:
result[i] = semPatternBody(c, n[i])
of nkCallKinds:
let s = qualifiedLookUp(c.c, n.sons[0], {})
let s = qualifiedLookUp(c.c, n[0], {})
if s != nil:
if s.owner == c.owner and s.kind == skParam: discard
elif contains(c.toBind, s.id): discard
@ -769,26 +765,26 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
# infix notation, so that '`*`(a, b)' can be used for verbatim matching:
if id.s == "*" or id.s == "**":
result = newNodeI(nkPattern, n.info, n.len)
result.sons[0] = newIdentNode(id, n.info)
result.sons[1] = semPatternBody(c, n.sons[1])
result.sons[2] = expectParam(c, n.sons[2])
result[0] = newIdentNode(id, n.info)
result[1] = semPatternBody(c, n[1])
result[2] = expectParam(c, n[2])
return
elif id.s == "|":
result = newNodeI(nkPattern, n.info, n.len)
result.sons[0] = newIdentNode(id, n.info)
result.sons[1] = semPatternBody(c, n.sons[1])
result.sons[2] = semPatternBody(c, n.sons[2])
result[0] = newIdentNode(id, n.info)
result[1] = semPatternBody(c, n[1])
result[2] = semPatternBody(c, n[2])
return
if n.kind == nkPrefix and (let id = considerQuotedIdent(c.c, n[0]); id != nil):
if id.s == "~":
result = newNodeI(nkPattern, n.info, n.len)
result.sons[0] = newIdentNode(id, n.info)
result.sons[1] = semPatternBody(c, n.sons[1])
result[0] = newIdentNode(id, n.info)
result[1] = semPatternBody(c, n[1])
return
for i in 0 ..< len(n):
result.sons[i] = semPatternBody(c, n.sons[i])
for i in 0..<n.len:
result[i] = semPatternBody(c, n[i])
else:
# dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
# so we use the generic code for nkDotExpr too
@ -801,10 +797,10 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
else:
return newIdentNode(s.name, n.info)
of nkPar:
if n.len == 1: return semPatternBody(c, n.sons[0])
if n.len == 1: return semPatternBody(c, n[0])
else: discard
for i in 0 ..< len(n):
result.sons[i] = semPatternBody(c, n.sons[i])
for i in 0..<n.len:
result[i] = semPatternBody(c, n[i])
proc semPattern(c: PContext, n: PNode): PNode =
openScope(c)
@ -817,7 +813,7 @@ proc semPattern(c: PContext, n: PNode): PNode =
result = flattenStmts(semPatternBody(ctx, n))
if result.kind in {nkStmtList, nkStmtListExpr}:
if result.len == 1:
result = result.sons[0]
result = result[0]
elif result.len == 0:
localError(c.config, n.info, "a pattern cannot be empty")
closeScope(c)