diff options
Diffstat (limited to 'compiler/semstmts.nim')
-rw-r--r-- | compiler/semstmts.nim | 679 |
1 files changed, 336 insertions, 343 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 3cdf1efb2..3abee2faf 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -42,10 +42,10 @@ const proc semDiscard(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1, c.config) - if n.sons[0].kind != nkEmpty: - n.sons[0] = semExprWithType(c, n.sons[0]) - let sonType = n.sons[0].typ - let sonKind = n.sons[0].kind + if n[0].kind != nkEmpty: + n[0] = semExprWithType(c, n[0]) + let sonType = n[0].typ + let sonKind = n[0].kind if isEmptyType(sonType) or sonType.kind in {tyNone, tyTypeDesc} or sonKind == nkTypeOfExpr: localError(c.config, n.info, errInvalidDiscard) if sonType.kind == tyProc and sonKind notin nkCallKinds: @@ -55,19 +55,19 @@ proc semDiscard(c: PContext, n: PNode): PNode = proc semBreakOrContinue(c: PContext, n: PNode): PNode = result = n checkSonsLen(n, 1, c.config) - if n.sons[0].kind != nkEmpty: + if n[0].kind != nkEmpty: if n.kind != nkContinueStmt: var s: PSym - case n.sons[0].kind - of nkIdent: s = lookUp(c, n.sons[0]) - of nkSym: s = n.sons[0].sym + case n[0].kind + of nkIdent: s = lookUp(c, n[0]) + of nkSym: s = n[0].sym else: illFormedAst(n, c.config) s = getGenSym(c, s) if s.kind == skLabel and s.owner.id == c.p.owner.id: var x = newSymNode(s) x.info = n.info incl(s.flags, sfUsed) - n.sons[0] = x + n[0] = x suggestSym(c.config, x.info, s, c.graph.usageSym) onUse(x.info, s) else: @@ -80,7 +80,7 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode = proc semAsm(c: PContext, n: PNode): PNode = checkSonsLen(n, 2, c.config) - var marker = pragmaAsm(c, n.sons[0]) + var marker = pragmaAsm(c, n[0]) if marker == '\0': marker = '`' # default marker result = semAsmOrEmit(c, n, marker) @@ -88,12 +88,12 @@ proc semWhile(c: PContext, n: PNode; flags: TExprFlags): PNode = result = n checkSonsLen(n, 2, c.config) openScope(c) - n.sons[0] = forceBool(c, semExprWithType(c, n.sons[0])) + n[0] = forceBool(c, semExprWithType(c, n[0])) inc(c.p.nestedLoopCounter) - n.sons[1] = semStmt(c, n.sons[1], flags) + n[1] = semStmt(c, n[1], flags) dec(c.p.nestedLoopCounter) closeScope(c) - if n.sons[1].typ == c.enforceVoidContext: + if n[1].typ == c.enforceVoidContext: result.typ = c.enforceVoidContext elif efInTypeof in flags: result.typ = n[1].typ @@ -121,8 +121,8 @@ proc implicitlyDiscardable(n: PNode): bool = var n = n while n.kind in skipForDiscardable: n = n.lastSon result = n.kind == nkRaiseStmt or - (isCallExpr(n) and n.sons[0].kind == nkSym and - sfDiscardable in n.sons[0].sym.flags) + (isCallExpr(n) and n[0].kind == nkSym and + sfDiscardable in n[0].sym.flags) proc fixNilType(c: PContext; n: PNode) = if isAtom(n): @@ -156,18 +156,18 @@ proc semIf(c: PContext, n: PNode; flags: TExprFlags): PNode = result = n var typ = commonTypeBegin var hasElse = false - 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] = forceBool(c, semExprWithType(c, it.sons[0])) - it.sons[1] = semExprBranch(c, it.sons[1]) - typ = commonType(typ, it.sons[1]) + it[0] = forceBool(c, semExprWithType(c, it[0])) + it[1] = semExprBranch(c, it[1]) + typ = commonType(typ, it[1]) closeScope(c) elif it.len == 1: hasElse = true - it.sons[0] = semExprBranchScope(c, it.sons[0]) - typ = commonType(typ, it.sons[0]) + it[0] = semExprBranchScope(c, it[0]) + typ = commonType(typ, it[0]) else: illFormedAst(it, c.config) if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped} or (not hasElse and efInTypeof notin flags): @@ -178,8 +178,8 @@ proc semIf(c: PContext, n: PNode; flags: TExprFlags): PNode = else: for it in n: let j = it.len-1 - if not endsInNoReturn(it.sons[j]): - it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info) + if not endsInNoReturn(it[j]): + it[j] = fitNode(c, typ, it[j], it[j].info) result.kind = nkIfExpr result.typ = typ @@ -207,11 +207,11 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode = n[0] = semExprBranchScope(c, n[0]) typ = commonType(typ, n[0].typ) - var last = len(n) - 1 + var last = n.len - 1 var catchAllExcepts = 0 - for i in 1 .. last: - let a = n.sons[i] + for i in 1..last: + let a = n[i] checkMinSonsLen(a, 1, c.config) openScope(c) if a.kind == nkExceptBranch: @@ -241,7 +241,7 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode = # cannot be followed by a ``except KeyError, ... : body`` block inc catchAllExcepts var isNative, isImported: bool - for j in 0..a.len-2: + for j in 0..<a.len-1: let tmp = semExceptBranchType(a[j]) if tmp: isImported = true else: isNative = true @@ -269,24 +269,24 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode = dec c.p.inTryStmt if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped}: - discardCheck(c, n.sons[0], flags) - for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon, flags) + discardCheck(c, n[0], flags) + for i in 1..<n.len: discardCheck(c, n[i].lastSon, flags) if typ == c.enforceVoidContext: result.typ = c.enforceVoidContext else: if n.lastSon.kind == nkFinally: discardCheck(c, n.lastSon.lastSon, flags) - n.sons[0] = fitNode(c, typ, n.sons[0], n.sons[0].info) + n[0] = fitNode(c, typ, n[0], n[0].info) for i in 1..last: - var it = n.sons[i] + var it = n[i] let j = it.len-1 - if not endsInNoReturn(it.sons[j]): - it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info) + if not endsInNoReturn(it[j]): + it[j] = fitNode(c, typ, it[j], it[j].info) result.typ = typ proc fitRemoveHiddenConv(c: PContext, typ: PType, n: PNode): PNode = result = fitNode(c, typ, n, n.info) if result.kind in {nkHiddenStdConv, nkHiddenSubConv}: - let r1 = result.sons[1] + let r1 = result[1] if r1.kind in {nkCharLit..nkUInt64Lit} and typ.skipTypes(abstractRange).kind in {tyFloat..tyFloat128}: result = newFloatNode(nkFloatLit, BiggestFloat r1.intVal) result.info = n.info @@ -307,8 +307,8 @@ proc findShadowedVar(c: PContext, v: PSym): PSym = return shadowed proc identWithin(n: PNode, s: PIdent): bool = - for i in 0 .. n.safeLen-1: - if identWithin(n.sons[i], s): return true + for i in 0..n.safeLen-1: + if identWithin(n[i], s): return true result = n.kind == nkSym and n.sym.name.id == s.id proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym = @@ -326,9 +326,9 @@ proc semIdentDef(c: PContext, n: PNode, kind: TSymKind): PSym = proc getLineInfo(n: PNode): TLineInfo = case n.kind of nkPostfix: - getLineInfo(n.sons[1]) + getLineInfo(n[1]) of nkAccQuoted, nkPragmaExpr: - getLineInfo(n.sons[0]) + getLineInfo(n[0]) else: n.info let info = getLineInfo(n) @@ -345,8 +345,7 @@ proc checkNilable(c: PContext; v: PSym) = #include liftdestructors proc addToVarSection(c: PContext; result: PNode; orig, identDefs: PNode) = - let L = identDefs.len - let value = identDefs[L-1] + let value = identDefs[^1] if result.kind == nkStmtList: let o = copyNode(orig) o.add identDefs @@ -362,17 +361,16 @@ proc isDiscardUnderscore(v: PSym): bool = proc semUsing(c: PContext; n: PNode): PNode = result = c.graph.emptyNode if not isTopLevel(c): localError(c.config, n.info, errXOnlyAtModuleScope % "using") - for i in 0 ..< len(n): - var a = n.sons[i] + for i in 0..<n.len: + var a = n[i] if c.config.cmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a, c.config) checkMinSonsLen(a, 3, c.config) - var length = len(a) - if a.sons[length-2].kind != nkEmpty: - let typ = semTypeNode(c, a.sons[length-2], nil) - for j in 0 .. length-3: - let v = semIdentDef(c, a.sons[j], skParam) + if a[^2].kind != nkEmpty: + let typ = semTypeNode(c, a[^2], nil) + for j in 0..<a.len-2: + let v = semIdentDef(c, a[j], skParam) styleCheckDef(c.config, v) onDef(a[j].info, v) v.typ = typ @@ -380,7 +378,7 @@ proc semUsing(c: PContext; n: PNode): PNode = else: localError(c.config, a.info, "'using' section must have a type") var def: PNode - if a.sons[length-1].kind != nkEmpty: + if a[^1].kind != nkEmpty: localError(c.config, a.info, "'using' sections cannot contain assignments") proc hasEmpty(typ: PType): bool = @@ -397,14 +395,14 @@ proc makeDeref(n: PNode): PNode = t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned}) result = n if t.kind in {tyVar, tyLent}: - result = newNodeIT(nkHiddenDeref, n.info, t.sons[0]) - addSon(result, n) - t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink, tyOwned}) + result = newNodeIT(nkHiddenDeref, n.info, t[0]) + result.add n + t = skipTypes(t[0], {tyGenericInst, tyAlias, tySink, tyOwned}) while t.kind in {tyPtr, tyRef}: var a = result let baseTyp = t.lastSon result = newNodeIT(nkHiddenDeref, n.info, baseTyp) - addSon(result, a) + result.add a t = skipTypes(baseTyp, {tyGenericInst, tyAlias, tySink, tyOwned}) proc fillPartialObject(c: PContext; n: PNode; typ: PType) = @@ -415,10 +413,10 @@ proc fillPartialObject(c: PContext; n: PNode; typ: PType) = if obj.kind == tyObject and tfPartial in obj.flags: let field = newSym(skField, getIdent(c.cache, y.s), obj.sym, n[1].info) field.typ = skipIntLit(typ) - field.position = len(obj.n) - addSon(obj.n, newSymNode(field)) - n.sons[0] = makeDeref x - n.sons[1] = newSymNode(field) + field.position = obj.n.len + obj.n.add newSymNode(field) + n[0] = makeDeref x + n[1] = newSymNode(field) n.typ = field.typ else: localError(c.config, n.info, "implicit object field construction " & @@ -436,21 +434,20 @@ proc setVarType(c: PContext; v: PSym, typ: PType) = proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = var b: PNode result = copyNode(n) - for i in 0 ..< len(n): - var a = n.sons[i] + for i in 0..<n.len: + var a = n[i] if c.config.cmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue if a.kind notin {nkIdentDefs, nkVarTuple, nkConstDef}: illFormedAst(a, c.config) checkMinSonsLen(a, 3, c.config) - var length = len(a) var typ: PType = nil - if a.sons[length-2].kind != nkEmpty: - typ = semTypeNode(c, a.sons[length-2], nil) + if a[^2].kind != nkEmpty: + typ = semTypeNode(c, a[^2], nil) var def: PNode = c.graph.emptyNode - if a.sons[length-1].kind != nkEmpty: - def = semExprWithType(c, a.sons[length-1], {efAllowDestructor}) + if a[^1].kind != nkEmpty: + def = semExprWithType(c, a[^1], {efAllowDestructor}) if def.typ.kind == tyProc and def.kind == nkSym: if def.sym.kind == skMacro: localError(c.config, def.info, errCannotAssignMacroSymbol % "variable") @@ -498,26 +495,26 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if a.kind == nkVarTuple: if tup.kind != tyTuple: localError(c.config, a.info, errXExpected, "tuple") - elif length-2 != len(tup): + elif a.len-2 != tup.len: localError(c.config, a.info, errWrongNumberOfVariables) b = newNodeI(nkVarTuple, a.info) - newSons(b, length) + newSons(b, a.len) # keep type desc for doc generator # NOTE: at the moment this is always ast.emptyNode, see parser.nim - b.sons[length-2] = a.sons[length-2] - b.sons[length-1] = def + b[^2] = a[^2] + b[^1] = def addToVarSection(c, result, n, b) elif tup.kind == tyTuple and def.kind in {nkPar, nkTupleConstr} and a.kind == nkIdentDefs and a.len > 3: message(c.config, a.info, warnEachIdentIsTuple) - for j in 0 .. length-3: + for j in 0..<a.len-2: if a[j].kind == nkDotExpr: fillPartialObject(c, a[j], - if a.kind != nkVarTuple: typ else: tup.sons[j]) + if a.kind != nkVarTuple: typ else: tup[j]) addToVarSection(c, result, n, a) continue - var v = semIdentDef(c, a.sons[j], symkind) + var v = semIdentDef(c, a[j], symkind) styleCheckDef(c.config, v) onDef(a[j].info, v) if sfGenSym notin v.flags: @@ -540,10 +537,10 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if importantComments(c.config): # keep documentation information: b.comment = a.comment - addSon(b, newSymNode(v)) + b.add newSymNode(v) # keep type desc for doc generator - addSon(b, a.sons[length-2]) - addSon(b, copyTree(def)) + b.add a[^2] + b.add copyTree(def) addToVarSection(c, result, n, b) if optOldAst in c.config.options: if def.kind != nkEmpty: @@ -559,19 +556,19 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = ast.add p else: ast.add newSymNode(v) - ast.add a.sons[length-2].copyTree + ast.add a[^2].copyTree ast.add def v.ast = ast else: if def.kind in {nkPar, nkTupleConstr}: v.ast = def[j] # bug #7663, for 'nim check' this can be a non-tuple: - if tup.kind == tyTuple: setVarType(c, v, tup.sons[j]) + if tup.kind == tyTuple: setVarType(c, v, tup[j]) else: v.typ = tup - b.sons[j] = newSymNode(v) + b[j] = newSymNode(v) checkNilable(c, v) if sfCompileTime in v.flags: var x = newNodeI(result.kind, v.info) - addSon(x, result[i]) + x.add result[i] vm.setupCompileTimeVar(c.module, c.graph, x) if v.flags * {sfGlobal, sfThread} == {sfGlobal}: message(c.config, v.info, hintGlobalVar) @@ -579,17 +576,16 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = proc semConst(c: PContext, n: PNode): PNode = result = copyNode(n) inc c.inStaticContext - for i in 0 ..< len(n): - var a = n.sons[i] + for i in 0..<n.len: + var a = n[i] if c.config.cmd == cmdIdeTools: suggestStmt(c, a) if a.kind == nkCommentStmt: continue if a.kind notin {nkConstDef, nkVarTuple}: illFormedAst(a, c.config) checkMinSonsLen(a, 3, c.config) - var length = len(a) var typ: PType = nil - if a.sons[length-2].kind != nkEmpty: - typ = semTypeNode(c, a.sons[length-2], nil) + if a[^2].kind != nkEmpty: + typ = semTypeNode(c, a[^2], nil) # don't evaluate here since the type compatibility check below may add a converter var def = semExprWithType(c, a[^1]) @@ -615,7 +611,7 @@ proc semConst(c: PContext, n: PNode): PNode = # evaluate the node def = semConstExpr(c, def) if def == nil: - localError(c.config, a.sons[length-1].info, errConstExprExpected) + localError(c.config, a[^1].info, errConstExprExpected) continue if typeAllowed(typ, skConst) != nil and def.kind != nkNilLit: localError(c.config, a.info, "invalid type for const: " & typeToString(typ)) @@ -625,15 +621,15 @@ proc semConst(c: PContext, n: PNode): PNode = if a.kind == nkVarTuple: if typ.kind != tyTuple: localError(c.config, a.info, errXExpected, "tuple") - elif length-2 != len(typ): + elif a.len-2 != typ.len: localError(c.config, a.info, errWrongNumberOfVariables) b = newNodeI(nkVarTuple, a.info) - newSons(b, length) - b.sons[length-2] = a.sons[length-2] - b.sons[length-1] = def + newSons(b, a.len) + b[^2] = a[^2] + b[^1] = def - for j in 0 ..< length-2: - var v = semIdentDef(c, a.sons[j], skConst) + for j in 0..<a.len-2: + var v = semIdentDef(c, a[j], skConst) if sfGenSym notin v.flags: addInterfaceDecl(c, v) elif v.owner == nil: v.owner = getCurrOwner(c) styleCheckDef(c.config, v) @@ -644,77 +640,76 @@ proc semConst(c: PContext, n: PNode): PNode = v.ast = def # no need to copy b = newNodeI(nkConstDef, a.info) if importantComments(c.config): b.comment = a.comment - addSon(b, newSymNode(v)) - addSon(b, a.sons[1]) - addSon(b, copyTree(def)) + b.add newSymNode(v) + b.add a[1] + b.add copyTree(def) else: - setVarType(c, v, typ.sons[j]) + setVarType(c, v, typ[j]) v.ast = if def[j].kind != nkExprColonExpr: def[j] - else: def[j].sons[1] - b.sons[j] = newSymNode(v) - addSon(result,b) + else: def[j][1] + b[j] = newSymNode(v) + result.add b dec c.inStaticContext include semfields proc symForVar(c: PContext, n: PNode): PSym = - let m = if n.kind == nkPragmaExpr: n.sons[0] else: n + let m = if n.kind == nkPragmaExpr: n[0] else: n result = newSymG(skForVar, m, c) styleCheckDef(c.config, result) onDef(n.info, result) if n.kind == nkPragmaExpr: - pragma(c, result, n.sons[1], forVarPragmas) + pragma(c, result, n[1], forVarPragmas) proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = result = n - var length = len(n) - let iterBase = n.sons[length-2].typ + let iterBase = n[^2].typ var iter = skipTypes(iterBase, {tyGenericInst, tyAlias, tySink, tyOwned}) var iterAfterVarLent = iter.skipTypes({tyLent, tyVar}) - # length == 3 means that there is one for loop variable + # n.len == 3 means that there is one for loop variable # and thus no tuple unpacking: - if iterAfterVarLent.kind != tyTuple or length == 3: - if length == 3: - if n.sons[0].kind == nkVarTuple: - if len(n[0])-1 != len(iterAfterVarLent): + if iterAfterVarLent.kind != tyTuple or n.len == 3: + if n.len == 3: + if n[0].kind == nkVarTuple: + if n[0].len-1 != iterAfterVarLent.len: localError(c.config, n[0].info, errWrongNumberOfVariables) - for i in 0 ..< len(n[0])-1: + for i in 0..<n[0].len-1: var v = symForVar(c, n[0][i]) if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal) case iter.kind of tyVar: v.typ = newTypeS(tyVar, c) - v.typ.sons.add iterAfterVarLent[i] + v.typ.add iterAfterVarLent[i] if tfVarIsPtr in iter.flags: v.typ.flags.incl tfVarIsPtr of tyLent: v.typ = newTypeS(tyLent, c) - v.typ.sons.add iterAfterVarLent[i] + v.typ.add iterAfterVarLent[i] if tfVarIsPtr in iter.flags: v.typ.flags.incl tfVarIsPtr else: - v.typ = iter.sons[i] - n.sons[0][i] = newSymNode(v) + v.typ = iter[i] + n[0][i] = newSymNode(v) if sfGenSym notin v.flags: addDecl(c, v) elif v.owner == nil: v.owner = getCurrOwner(c) else: - var v = symForVar(c, n.sons[0]) + var v = symForVar(c, n[0]) if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal) # BUGFIX: don't use `iter` here as that would strip away # the ``tyGenericInst``! See ``tests/compile/tgeneric.nim`` # for an example: v.typ = iterBase - n.sons[0] = newSymNode(v) + n[0] = newSymNode(v) if sfGenSym notin v.flags: addDecl(c, v) elif v.owner == nil: v.owner = getCurrOwner(c) else: localError(c.config, n.info, errWrongNumberOfVariables) - elif length-2 != len(iterAfterVarLent): + elif n.len-2 != iterAfterVarLent.len: localError(c.config, n.info, errWrongNumberOfVariables) else: - for i in 0 .. length - 3: - if n.sons[i].kind == nkVarTuple: + for i in 0..<n.len - 2: + if n[i].kind == nkVarTuple: var mutable = false var isLent = false case iter[i].kind @@ -726,47 +721,47 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = iter[i] = iter[i].skipTypes({tyLent}) else: discard - if len(n[i])-1 != len(iter[i]): + if n[i].len-1 != iter[i].len: localError(c.config, n[i].info, errWrongNumberOfVariables) - for j in 0 ..< len(n[i])-1: + for j in 0..<n[i].len-1: var v = symForVar(c, n[i][j]) if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal) if mutable: v.typ = newTypeS(tyVar, c) - v.typ.sons.add iter[i][j] + v.typ.add iter[i][j] elif isLent: v.typ = newTypeS(tyLent, c) - v.typ.sons.add iter[i][j] + v.typ.add iter[i][j] else: v.typ = iter[i][j] - n.sons[i][j] = newSymNode(v) + n[i][j] = newSymNode(v) if not isDiscardUnderscore(v): addDecl(c, v) elif v.owner == nil: v.owner = getCurrOwner(c) else: - var v = symForVar(c, n.sons[i]) + var v = symForVar(c, n[i]) if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal) case iter.kind of tyVar: v.typ = newTypeS(tyVar, c) - v.typ.sons.add iterAfterVarLent[i] + v.typ.add iterAfterVarLent[i] if tfVarIsPtr in iter.flags: v.typ.flags.incl tfVarIsPtr of tyLent: v.typ = newTypeS(tyLent, c) - v.typ.sons.add iterAfterVarLent[i] + v.typ.add iterAfterVarLent[i] if tfVarIsPtr in iter.flags: v.typ.flags.incl tfVarIsPtr else: - v.typ = iter.sons[i] - n.sons[i] = newSymNode(v) + v.typ = iter[i] + n[i] = newSymNode(v) if sfGenSym notin v.flags: if not isDiscardUnderscore(v): addDecl(c, v) elif v.owner == nil: v.owner = getCurrOwner(c) inc(c.p.nestedLoopCounter) openScope(c) - n.sons[length-1] = semExprBranch(c, n.sons[length-1], flags) + n[^1] = semExprBranch(c, n[^1], flags) if efInTypeof notin flags: - discardCheck(c, n.sons[length-1], flags) + discardCheck(c, n[^1], flags) closeScope(c) dec(c.p.nestedLoopCounter) @@ -780,7 +775,7 @@ proc implicitIterator(c: PContext, it: string, arg: PNode): PNode = result = semExprNoDeref(c, result, {efWantIterator}) proc isTrivalStmtExpr(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 @@ -838,7 +833,7 @@ proc handleCaseStmtMacro(c: PContext; n: PNode): PNode = onUse(n[0].info, match) # but pass 'n' to the 'match' macro, not 'n[0]': - r.call.sons[1] = n + r.call[1] = n let toExpand = semResolvedCall(c, r, r.call, {}) case match.kind of skMacro: result = semMacroExpr(c, toExpand, toExpand, match, {}) @@ -852,41 +847,40 @@ proc handleCaseStmtMacro(c: PContext; n: PNode): PNode = proc semFor(c: PContext, n: PNode; flags: TExprFlags): PNode = checkMinSonsLen(n, 3, c.config) - var length = len(n) if forLoopMacros in c.features: result = handleForLoopMacro(c, n) if result != nil: return result openScope(c) result = n - n.sons[length-2] = semExprNoDeref(c, n.sons[length-2], {efWantIterator}) - var call = n.sons[length-2] + n[^2] = semExprNoDeref(c, n[^2], {efWantIterator}) + var call = n[^2] if call.kind == nkStmtListExpr and isTrivalStmtExpr(call): call = call.lastSon - n.sons[length-2] = call + n[^2] = call let isCallExpr = call.kind in nkCallKinds if isCallExpr and call[0].kind == nkSym and call[0].sym.magic in {mFields, mFieldPairs, mOmpParFor}: - if call.sons[0].sym.magic == mOmpParFor: + if call[0].sym.magic == mOmpParFor: result = semForVars(c, n, flags) result.kind = nkParForStmt else: - result = semForFields(c, n, call.sons[0].sym.magic) - elif isCallExpr and isClosureIterator(call.sons[0].typ.skipTypes(abstractInst)): + result = semForFields(c, n, call[0].sym.magic) + elif isCallExpr and isClosureIterator(call[0].typ.skipTypes(abstractInst)): # first class iterator: result = semForVars(c, n, flags) - elif not isCallExpr or call.sons[0].kind != nkSym or - call.sons[0].sym.kind != skIterator: - if length == 3: - n.sons[length-2] = implicitIterator(c, "items", n.sons[length-2]) - elif length == 4: - n.sons[length-2] = implicitIterator(c, "pairs", n.sons[length-2]) + elif not isCallExpr or call[0].kind != nkSym or + call[0].sym.kind != skIterator: + if n.len == 3: + n[^2] = implicitIterator(c, "items", n[^2]) + elif n.len == 4: + n[^2] = implicitIterator(c, "pairs", n[^2]) else: - localError(c.config, n.sons[length-2].info, "iterator within for loop context expected") + localError(c.config, n[^2].info, "iterator within for loop context expected") result = semForVars(c, n, flags) else: result = semForVars(c, n, flags) # propagate any enforced VoidContext: - if n.sons[length-1].typ == c.enforceVoidContext: + if n[^1].typ == c.enforceVoidContext: result.typ = c.enforceVoidContext elif efInTypeof in flags: result.typ = result.lastSon.typ @@ -897,18 +891,18 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = checkMinSonsLen(n, 2, c.config) openScope(c) pushCaseContext(c, n) - n.sons[0] = semExprWithType(c, n.sons[0]) + n[0] = semExprWithType(c, n[0]) var chckCovered = false var covered: Int128 = toInt128(0) var typ = commonTypeBegin var hasElse = false - let caseTyp = skipTypes(n.sons[0].typ, abstractVar-{tyTypeDesc}) + let caseTyp = skipTypes(n[0].typ, abstractVar-{tyTypeDesc}) const shouldChckCovered = {tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32, tyBool} case caseTyp.kind of shouldChckCovered: chckCovered = true of tyRange: - if skipTypes(caseTyp.sons[0], abstractInst).kind in shouldChckCovered: + if skipTypes(caseTyp[0], abstractInst).kind in shouldChckCovered: chckCovered = true of tyFloat..tyFloat128, tyString, tyError: discard @@ -919,11 +913,11 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = result = handleCaseStmtMacro(c, n) if result != nil: return result - localError(c.config, n.sons[0].info, errSelectorMustBeOfCertainTypes) + localError(c.config, n[0].info, errSelectorMustBeOfCertainTypes) return - for i in 1 ..< len(n): + for i in 1..<n.len: setCaseContextIdx(c, i) - var x = n.sons[i] + var x = n[i] when defined(nimsuggest): if c.config.ideCmd == ideSug and exactEquals(c.config.m.trackPos, x.info) and caseTyp.kind == tyEnum: suggestEnum(c, x, caseTyp) @@ -931,31 +925,31 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = of nkOfBranch: checkMinSonsLen(x, 2, c.config) semCaseBranch(c, n, x, i, covered) - var last = len(x)-1 - x.sons[last] = semExprBranchScope(c, x.sons[last]) - typ = commonType(typ, x.sons[last]) + var last = x.len-1 + x[last] = semExprBranchScope(c, x[last]) + typ = commonType(typ, x[last]) of nkElifBranch: chckCovered = false checkSonsLen(x, 2, c.config) openScope(c) - x.sons[0] = forceBool(c, semExprWithType(c, x.sons[0])) - x.sons[1] = semExprBranch(c, x.sons[1]) - typ = commonType(typ, x.sons[1]) + x[0] = forceBool(c, semExprWithType(c, x[0])) + x[1] = semExprBranch(c, x[1]) + typ = commonType(typ, x[1]) closeScope(c) of nkElse: checkSonsLen(x, 1, c.config) - x.sons[0] = semExprBranchScope(c, x.sons[0]) - typ = commonType(typ, x.sons[0]) + x[0] = semExprBranchScope(c, x[0]) + typ = commonType(typ, x[0]) hasElse = true - if chckCovered and covered == toCover(c, n.sons[0].typ): + if chckCovered and covered == toCover(c, n[0].typ): localError(c.config, x.info, "invalid else, all cases are already covered") chckCovered = false else: illFormedAst(x, c.config) if chckCovered: - if covered == toCover(c, n.sons[0].typ): + if covered == toCover(c, n[0].typ): hasElse = true - elif n.sons[0].typ.kind == tyEnum: + elif n[0].typ.kind == tyEnum: localError(c.config, n.info, "not all cases are covered; missing: {$1}" % formatMissingEnums(n)) else: @@ -964,16 +958,16 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = closeScope(c) if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped} or (not hasElse and efInTypeof notin flags): - for i in 1..n.len-1: discardCheck(c, n.sons[i].lastSon, flags) + for i in 1..<n.len: discardCheck(c, n[i].lastSon, flags) # propagate any enforced VoidContext: if typ == c.enforceVoidContext: result.typ = c.enforceVoidContext else: - for i in 1..n.len-1: - var it = n.sons[i] + for i in 1..<n.len: + var it = n[i] let j = it.len-1 - if not endsInNoReturn(it.sons[j]): - it.sons[j] = fitNode(c, typ, it.sons[j], it.sons[j].info) + if not endsInNoReturn(it[j]): + it[j] = fitNode(c, typ, it[j], it[j].info) result.typ = typ proc semRaise(c: PContext, n: PNode): PNode = @@ -992,15 +986,15 @@ proc semRaise(c: PContext, n: PNode): PNode = proc addGenericParamListToScope(c: PContext, n: PNode) = if n.kind != nkGenericParams: illFormedAst(n, c.config) - for i in 0 ..< len(n): - var a = n.sons[i] + for i in 0..<n.len: + var a = n[i] if a.kind == nkSym: addDecl(c, a.sym) else: illFormedAst(a, c.config) proc typeSectionTypeName(c: PContext; n: PNode): PNode = if n.kind == nkPragmaExpr: if n.len == 0: illFormedAst(n, c.config) - result = n.sons[0] + result = n[0] else: result = n if result.kind != nkSym: illFormedAst(n, c.config) @@ -1009,8 +1003,8 @@ proc typeSectionTypeName(c: PContext; n: PNode): PNode = proc typeSectionLeftSidePass(c: PContext, n: PNode) = # process the symbols on the left side for the whole type section, before # we even look at the type definitions on the right - for i in 0 ..< len(n): - var a = n.sons[i] + for i in 0..<n.len: + var a = n[i] when defined(nimsuggest): if c.config.cmd == cmdIdeTools: inc c.inTypeContext @@ -1019,7 +1013,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = if a.kind == nkCommentStmt: continue if a.kind != nkTypeDef: illFormedAst(a, c.config) checkSonsLen(a, 3, c.config) - let name = a.sons[0] + let name = a[0] var s: PSym if name.kind == nkDotExpr and a[2].kind == nkObjectTy: let pkgName = considerQuotedIdent(c, name[0]) @@ -1049,7 +1043,7 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = s.typ = newTypeS(tyForward, c) s.typ.sym = s # process pragmas: if name.kind == nkPragmaExpr: - pragma(c, s, name.sons[1], typePragmas) + pragma(c, s, name[1], typePragmas) if sfForward in s.flags: # check if the symbol already exists: let pkg = c.module.owner @@ -1070,9 +1064,9 @@ proc typeSectionLeftSidePass(c: PContext, n: PNode) = elif s.owner == nil: s.owner = getCurrOwner(c) if name.kind == nkPragmaExpr: - a.sons[0].sons[0] = newSymNode(s) + a[0][0] = newSymNode(s) else: - a.sons[0] = newSymNode(s) + a[0] = newSymNode(s) proc checkCovariantParamsUsages(c: PContext; genericType: PType) = var body = genericType[^1] @@ -1103,7 +1097,7 @@ proc checkCovariantParamsUsages(c: PContext; genericType: PType) = return traverseSubTypes(c, t[0]) of tyGenericInvocation: let targetBody = t[0] - for i in 1 ..< t.len: + for i in 1..<t.len: let param = t[i] if param.kind == tyGenericParam: if tfCovariant in param.flags: @@ -1141,17 +1135,17 @@ proc checkCovariantParamsUsages(c: PContext; genericType: PType) = discard traverseSubTypes(c, body) proc typeSectionRightSidePass(c: PContext, n: PNode) = - 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.config) checkSonsLen(a, 3, c.config) - let name = typeSectionTypeName(c, a.sons[0]) + let name = typeSectionTypeName(c, a[0]) var s = name.sym - if s.magic == mNone and a.sons[2].kind == nkEmpty: + if s.magic == mNone and a[2].kind == nkEmpty: localError(c.config, a.info, errImplOfXexpected % s.name.s) if s.magic != mNone: processMagicType(c, s) - if a.sons[1].kind != nkEmpty: + if a[1].kind != nkEmpty: # We have a generic type declaration here. In generic types, # symbol lookup needs to be done here. openScope(c) @@ -1164,8 +1158,8 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = # TGObj[T] = object # TAlias[T] = TGObj[T] # - s.typ.n = semGenericParamList(c, a.sons[1], s.typ) - a.sons[1] = s.typ.n + s.typ.n = semGenericParamList(c, a[1], s.typ) + a[1] = s.typ.n s.typ.size = -1 # could not be computed properly # we fill it out later. For magic generics like 'seq', it won't be filled # so we use tyNone instead of nil to not crash for strange conversions @@ -1173,12 +1167,12 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = rawAddSon(s.typ, newTypeS(tyNone, c)) s.ast = a inc c.inGenericContext - var body = semTypeNode(c, a.sons[2], nil) + var body = semTypeNode(c, a[2], nil) dec c.inGenericContext if body != nil: body.sym = s body.size = -1 # could not be computed properly - s.typ.sons[len(s.typ) - 1] = body + s.typ[^1] = body if tfCovariant in s.typ.flags: checkCovariantParamsUsages(c, s.typ) # XXX: This is a temporary limitation: @@ -1200,10 +1194,10 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = popOwner(c) closeScope(c) - elif a.sons[2].kind != nkEmpty: + elif a[2].kind != nkEmpty: # process the type's body: pushOwner(c, s) - var t = semTypeNode(c, a.sons[2], s.typ) + var t = semTypeNode(c, a[2], s.typ) if s.typ == nil: s.typ = t elif t != s.typ and (s.typ == nil or s.typ.kind != tyAlias): @@ -1222,9 +1216,9 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = if tfBorrowDot in s.typ.flags and s.typ.kind != tyDistinct: excl s.typ.flags, tfBorrowDot localError(c.config, name.info, "only a 'distinct' type can borrow `.`") - let aa = a.sons[2] + let aa = a[2] if aa.kind in {nkRefTy, nkPtrTy} and aa.len == 1 and - aa.sons[0].kind == nkObjectTy: + aa[0].kind == nkObjectTy: # give anonymous object a dummy symbol: var st = s.typ if st.kind == tyGenericBody: st = st.lastSon @@ -1242,7 +1236,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = proc checkForMetaFields(c: PContext; n: PNode) = proc checkMeta(c: PContext; n: PNode; t: PType) = if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags: - if t.kind == tyBuiltInTypeClass and t.len == 1 and t.sons[0].kind == tyProc: + if t.kind == tyBuiltInTypeClass and t.len == 1 and t[0].kind == tyProc: localError(c.config, n.info, ("'$1' is not a concrete type; " & "for a callback without parameters use 'proc()'") % t.typeToString) else: @@ -1260,23 +1254,23 @@ proc checkForMetaFields(c: PContext; n: PNode) = of tySequence, tySet, tyArray, tyOpenArray, tyVar, tyLent, tyPtr, tyRef, tyProc, tyGenericInvocation, tyGenericInst, tyAlias, tySink, tyOwned: let start = ord(t.kind in {tyGenericInvocation, tyGenericInst}) - for i in start ..< t.len: - checkMeta(c, n, t.sons[i]) + for i in start..<t.len: + checkMeta(c, n, t[i]) else: checkMeta(c, n, t) else: internalAssert c.config, false proc typeSectionFinalPass(c: PContext, n: PNode) = - 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 - let name = typeSectionTypeName(c, a.sons[0]) + let name = typeSectionTypeName(c, a[0]) var s = name.sym # check the style here after the pragmas have been processed: styleCheckDef(c.config, s) # compute the type's size and check for illegal recursions: - if a.sons[1].kind == nkEmpty: + if a[1].kind == nkEmpty: var x = a[2] if x.kind in nkCallKinds and nfSem in x.flags: discard "already semchecked, see line marked with bug #10548" @@ -1307,7 +1301,7 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode = case n.kind of nkIncludeStmt: for i in 0..<n.len: - var f = checkModuleName(c.config, n.sons[i]) + var f = checkModuleName(c.config, n[i]) if f != InvalidFileIdx: if containsOrIncl(c.includedFiles, f.int): localError(c.config, n.info, errRecursiveDependencyX % toMsgFilename(c.config, f)) @@ -1316,8 +1310,8 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode = gatherStmts c, code, result excl(c.includedFiles, f.int) of nkStmtList: - for i in 0 ..< n.len: - gatherStmts(c, n.sons[i], result) + for i in 0..<n.len: + gatherStmts(c, n[i], result) of nkTypeSection: incl n.flags, nfSem typeSectionLeftSidePass(c, n) @@ -1329,7 +1323,7 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode = gatherStmts(c, n, result) template rec(name) = - for i in 0 ..< result.len: + for i in 0..<result.len: if result[i].kind == nkTypeSection: name(c, result[i]) @@ -1343,8 +1337,8 @@ proc semAllTypeSections(c: PContext; n: PNode): PNode = when setbit: incl n.flags, nfSem name(c, n) elif n.kind == nkStmtList: - for i in 0 ..< n.len: - `name rec`(c, n.sons[i]) + for i in 0..<n.len: + `name rec`(c, n[i]) `name rec`(c, n) rec typeSectionLeftSidePass, true rec typeSectionRightSidePass @@ -1366,8 +1360,8 @@ proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) = s.typ = semProcTypeNode(c, n, genericParams, nil, s.kind) proc addParams(c: PContext, n: PNode, kind: TSymKind) = - for i in 1 ..< len(n): - if n.sons[i].kind == nkSym: addParamOrResult(c, n.sons[i].sym, kind) + for i in 1..<n.len: + if n[i].kind == nkSym: addParamOrResult(c, n[i].sym, kind) else: illFormedAst(n, c.config) proc semBorrow(c: PContext, n: PNode, s: PSym) = @@ -1375,7 +1369,7 @@ proc semBorrow(c: PContext, n: PNode, s: PSym) = var b = searchForBorrowProc(c, c.currentScope.parent, s) if b != nil: # store the alias: - n.sons[bodyPos] = newSymNode(b) + n[bodyPos] = newSymNode(b) # Carry over the original symbol magic, this is necessary in order to ensure # the semantic pass is correct s.magic = b.magic @@ -1391,20 +1385,20 @@ proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) = c.p.resultSym = s proc addResultNode(c: PContext, n: PNode) = - if c.p.resultSym != nil: addSon(n, newSymNode(c.p.resultSym)) + if c.p.resultSym != nil: n.add newSymNode(c.p.resultSym) proc copyExcept(n: PNode, i: int): PNode = result = copyNode(n) for j in 0..<n.len: - if j != i: result.add(n.sons[j]) + if j != i: result.add(n[j]) proc semProcAnnotation(c: PContext, prc: PNode; validPragmas: TSpecialWords): PNode = - var n = prc.sons[pragmasPos] + var n = prc[pragmasPos] if n == nil or n.kind == nkEmpty: return - for i in 0 ..< n.len: - var it = n.sons[i] - var key = if it.kind in nkPragmaCallKinds and it.len >= 1: it.sons[0] else: it + for i in 0..<n.len: + var it = n[i] + var key = if it.kind in nkPragmaCallKinds and it.len >= 1: it[0] else: it if whichPragma(it) != wInvalid: # Not a custom pragma @@ -1421,13 +1415,13 @@ proc semProcAnnotation(c: PContext, prc: PNode; if it.kind in nkPragmaCallKinds and it.len > 1: # pass pragma arguments to the macro too: for i in 1..<it.len: - x.add(it.sons[i]) + x.add(it[i]) # Drop the pragma from the list, this prevents getting caught in endless # recursion when the nkCall is semanticized - prc.sons[pragmasPos] = copyExcept(n, i) + prc[pragmasPos] = copyExcept(n, i) if prc[pragmasPos].kind != nkEmpty and prc[pragmasPos].len == 0: - prc.sons[pragmasPos] = c.graph.emptyNode + prc[pragmasPos] = c.graph.emptyNode x.add(prc) @@ -1435,18 +1429,18 @@ proc semProcAnnotation(c: PContext, prc: PNode; var r = semOverloadedCall(c, x, x, {skMacro, skTemplate}, {efNoUndeclared}) if r == nil: # Restore the old list of pragmas since we couldn't process this - prc.sons[pragmasPos] = n + prc[pragmasPos] = n # No matching macro was found but there's always the possibility this may # be a .pragma. template instead continue - doAssert r.sons[0].kind == nkSym - let m = r.sons[0].sym + doAssert r[0].kind == nkSym + let m = r[0].sym case m.kind of skMacro: result = semMacroExpr(c, r, r, m, {}) of skTemplate: result = semTemplateExpr(c, r, m, {}) else: - prc.sons[pragmasPos] = n + prc[pragmasPos] = n continue doAssert result != nil @@ -1460,15 +1454,15 @@ proc semProcAnnotation(c: PContext, prc: PNode; return proc setGenericParamsMisc(c: PContext; n: PNode): PNode = - let orig = n.sons[genericParamsPos] + let orig = n[genericParamsPos] # we keep the original params around for better error messages, see # issue https://github.com/nim-lang/Nim/issues/1713 result = semGenericParamList(c, orig) - if n.sons[miscPos].kind == nkEmpty: - n.sons[miscPos] = newTree(nkBracket, c.graph.emptyNode, orig) + if n[miscPos].kind == nkEmpty: + n[miscPos] = newTree(nkBracket, c.graph.emptyNode, orig) else: - n.sons[miscPos].sons[1] = orig - n.sons[genericParamsPos] = result + n[miscPos][1] = orig + n[genericParamsPos] = result proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = # XXX semProcAux should be good enough for this now, we will eventually @@ -1481,38 +1475,38 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = if n[namePos].kind != nkSym: s = newSym(skProc, c.cache.idAnon, getCurrOwner(c), n.info) s.ast = n - n.sons[namePos] = newSymNode(s) + n[namePos] = newSymNode(s) else: s = n[namePos].sym pushOwner(c, s) openScope(c) var gp: PNode - if n.sons[genericParamsPos].kind != nkEmpty: + if n[genericParamsPos].kind != nkEmpty: gp = setGenericParamsMisc(c, n) else: gp = newNodeI(nkGenericParams, n.info) - if n.sons[paramsPos].kind != nkEmpty: - semParamList(c, n.sons[paramsPos], gp, s) + if n[paramsPos].kind != nkEmpty: + semParamList(c, n[paramsPos], gp, s) # paramsTypeCheck(c, s.typ) - if len(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty: + if gp.len > 0 and n[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: - n.sons[genericParamsPos] = gp + n[genericParamsPos] = gp else: s.typ = newProcType(c, n.info) - if n.sons[pragmasPos].kind != nkEmpty: - pragma(c, s, n.sons[pragmasPos], lambdaPragmas) + if n[pragmasPos].kind != nkEmpty: + pragma(c, s, n[pragmasPos], lambdaPragmas) s.options = c.config.options - if n.sons[bodyPos].kind != nkEmpty: + if n[bodyPos].kind != nkEmpty: if sfImportc in s.flags: - localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s) + localError(c.config, n[bodyPos].info, errImplOfXNotAllowed % s.name.s) #if efDetermineType notin flags: # XXX not good enough; see tnamedparamanonproc.nim if gp.len == 0 or (gp.len == 1 and tfRetType in gp[0].typ.flags): pushProcCon(c, s) - addResult(c, s.typ.sons[0], n.info, skProc) + addResult(c, s.typ[0], n.info, skProc) addResultNode(c, n) - s.ast[bodyPos] = hloBody(c, semProcBody(c, n.sons[bodyPos])) + s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos])) trackProc(c, s, s.ast[bodyPos]) popProcCon(c) elif efOperand notin flags: @@ -1529,7 +1523,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = var n = n - let original = n.sons[namePos].sym + let original = n[namePos].sym let s = original #copySym(original, false) #incl(s.flags, sfFromGeneric) #s.owner = original @@ -1537,11 +1531,11 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = n = replaceTypesInBody(c, pt, n, original) result = n s.ast = result - n.sons[namePos].sym = s - n.sons[genericParamsPos] = c.graph.emptyNode + n[namePos].sym = s + n[genericParamsPos] = c.graph.emptyNode # for LL we need to avoid wrong aliasing let params = copyTree n.typ.n - n.sons[paramsPos] = params + n[paramsPos] = params s.typ = n.typ for i in 1..<params.len: if params[i].typ.kind in {tyTypeDesc, tyGenericParam, @@ -1553,9 +1547,9 @@ proc semInferredLambda(c: PContext, pt: TIdTable, n: PNode): PNode = pushOwner(c, s) addParams(c, params, skProc) pushProcCon(c, s) - addResult(c, n.typ.sons[0], n.info, skProc) + addResult(c, n.typ[0], n.info, skProc) addResultNode(c, n) - s.ast[bodyPos] = hloBody(c, semProcBody(c, n.sons[bodyPos])) + s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos])) trackProc(c, s, s.ast[bodyPos]) popProcCon(c) popOwner(c) @@ -1577,7 +1571,7 @@ proc activate(c: PContext, n: PNode) = of nkLambdaKinds: discard semLambda(c, n, {}) of nkCallKinds: - for i in 1 ..< n.len: activate(c, n[i]) + for i in 1..<n.len: activate(c, n[i]) else: discard @@ -1586,8 +1580,8 @@ proc maybeAddResult(c: PContext, s: PSym, n: PNode) = let resultType = sysTypeFromName(c.graph, n.info, "NimNode") addResult(c, resultType, n.info, s.kind) addResultNode(c, n) - elif s.typ.sons[0] != nil and not isInlineIterator(s.typ): - addResult(c, s.typ.sons[0], n.info, s.kind) + elif s.typ[0] != nil and not isInlineIterator(s.typ): + addResult(c, s.typ[0], n.info, s.kind) addResultNode(c, n) proc canonType(c: PContext, t: PType): PType = @@ -1610,12 +1604,12 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = of "=destroy": let t = s.typ var noError = false - if t.len == 2 and t.sons[0] == nil and t.sons[1].kind == tyVar: - var obj = t.sons[1].sons[0] + if t.len == 2 and t[0] == nil and t[1].kind == tyVar: + var obj = t[1][0] while true: incl(obj.flags, tfHasAsgn) if obj.kind in {tyGenericBody, tyGenericInst}: obj = obj.lastSon - elif obj.kind == tyGenericInvocation: obj = obj.sons[0] + elif obj.kind == tyGenericInvocation: obj = obj[0] else: break if obj.kind in {tyObject, tyDistinct, tySequence, tyString}: obj = canonType(c, obj) @@ -1636,14 +1630,14 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = incl(s.flags, sfOverriden) of "deepcopy", "=deepcopy": if s.typ.len == 2 and - s.typ.sons[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and - sameType(s.typ.sons[1], s.typ.sons[0]): + s.typ[1].skipTypes(abstractInst).kind in {tyRef, tyPtr} and + sameType(s.typ[1], s.typ[0]): # Note: we store the deepCopy in the base of the pointer to mitigate # the problem that pointers are structural types: - var t = s.typ.sons[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst) + var t = s.typ[1].skipTypes(abstractInst).lastSon.skipTypes(abstractInst) while true: if t.kind == tyGenericBody: t = t.lastSon - elif t.kind == tyGenericInvocation: t = t.sons[0] + elif t.kind == tyGenericInvocation: t = t[0] else: break if t.kind in {tyObject, tyDistinct, tyEnum, tySequence, tyString}: if t.attachedOps[attachedDeepCopy].isNil: t.attachedOps[attachedDeepCopy] = s @@ -1668,18 +1662,18 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = incl(s.flags, sfUsed) incl(s.flags, sfOverriden) let t = s.typ - if t.len == 3 and t.sons[0] == nil and t.sons[1].kind == tyVar: - var obj = t.sons[1].sons[0] + if t.len == 3 and t[0] == nil and t[1].kind == tyVar: + var obj = t[1][0] while true: incl(obj.flags, tfHasAsgn) if obj.kind == tyGenericBody: obj = obj.lastSon - elif obj.kind == tyGenericInvocation: obj = obj.sons[0] + elif obj.kind == tyGenericInvocation: obj = obj[0] else: break - var objB = t.sons[2] + var objB = t[2] while true: if objB.kind == tyGenericBody: objB = objB.lastSon elif objB.kind in {tyGenericInvocation, tyGenericInst}: - objB = objB.sons[0] + objB = objB[0] else: break if obj.kind in {tyObject, tyDistinct, tySequence, tyString} and sameType(obj, objB): # attach these ops to the canonical tySequence @@ -1721,8 +1715,8 @@ type proc hasObjParam(s: PSym): bool = var t = s.typ - for col in 1 ..< len(t): - if skipTypes(t.sons[col], skipPtrs).kind == tyObject: + for col in 1..<t.len: + if skipTypes(t[col], skipPtrs).kind == tyObject: return true proc finishMethod(c: PContext, s: PSym) = @@ -1735,13 +1729,13 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) = var foundObj = false # we start at 1 for now so that tparsecombnum continues to compile. # XXX Revisit this problem later. - for col in 1 ..< len(tt): - let t = tt.sons[col] + for col in 1..<tt.len: + let t = tt[col] if t != nil and t.kind == tyGenericInvocation: - var x = skipTypes(t.sons[0], {tyVar, tyLent, tyPtr, tyRef, tyGenericInst, + var x = skipTypes(t[0], {tyVar, tyLent, tyPtr, tyRef, tyGenericInst, tyGenericInvocation, tyGenericBody, tyAlias, tySink, tyOwned}) - if x.kind == tyObject and t.len-1 == n.sons[genericParamsPos].len: + if x.kind == tyObject and t.len-1 == n[genericParamsPos].len: foundObj = true x.methods.add((col,s)) message(c.config, n.info, warnDeprecated, "generic methods are deprecated") @@ -1750,7 +1744,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) = else: # why check for the body? bug #2400 has none. Checking for sfForward makes # no sense either. - # and result.sons[bodyPos].kind != nkEmpty: + # and result[bodyPos].kind != nkEmpty: if hasObjParam(s): methodDef(c.graph, s, fromCache=false) else: @@ -1774,8 +1768,8 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, incl(s.flags, sfUsed) isAnon = true else: - s = semIdentDef(c, n.sons[0], kind) - n.sons[namePos] = newSymNode(s) + s = semIdentDef(c, n[0], kind) + n[namePos] = newSymNode(s) s.ast = n #s.scope = c.currentScope when false: @@ -1801,24 +1795,24 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, pushOwner(c, s) openScope(c) var gp: PNode - if n.sons[genericParamsPos].kind != nkEmpty: + if n[genericParamsPos].kind != nkEmpty: gp = setGenericParamsMisc(c, n) else: gp = newNodeI(nkGenericParams, n.info) # process parameters: - if n.sons[paramsPos].kind != nkEmpty: - semParamList(c, n.sons[paramsPos], gp, s) - if len(gp) > 0: - if n.sons[genericParamsPos].kind == nkEmpty: + if n[paramsPos].kind != nkEmpty: + semParamList(c, n[paramsPos], gp, s) + if gp.len > 0: + if n[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: - n.sons[genericParamsPos] = gp + n[genericParamsPos] = gp # check for semantics again: - # semParamList(c, n.sons[ParamsPos], nil, s) + # semParamList(c, n[ParamsPos], nil, s) else: s.typ = newProcType(c, n.info) if tfTriggersCompileTime in s.typ.flags: incl(s.flags, sfCompileTime) - 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]) if s.kind == skIterator: s.typ.flags.incl(tfIterator) elif s.kind == skFunc: @@ -1841,15 +1835,15 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, else: if not typeIsDetermined: addInterfaceDeclAt(c, oldScope, s) - if n.sons[pragmasPos].kind != nkEmpty: - pragma(c, s, n.sons[pragmasPos], validPragmas) + if n[pragmasPos].kind != nkEmpty: + pragma(c, s, n[pragmasPos], validPragmas) else: implicitPragmas(c, s, n, validPragmas) styleCheckDef(c.config, s) onDef(n[namePos].info, s) else: - if n.sons[pragmasPos].kind != nkEmpty: - pragma(c, s, n.sons[pragmasPos], validPragmas) + if n[pragmasPos].kind != nkEmpty: + pragma(c, s, n[pragmasPos], validPragmas) # To ease macro generation that produce forwarded .async procs we now # allow a bit redudancy in the pragma declarations. The rule is # a prototype's pragma list must be a superset of the current pragma @@ -1857,7 +1851,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # XXX This needs more checks eventually, for example that external # linking names do agree: if proto.typ.callConv != s.typ.callConv or proto.typ.flags < s.typ.flags: - localError(c.config, n.sons[pragmasPos].info, errPragmaOnlyInHeaderOfProcX % + localError(c.config, n[pragmasPos].info, errPragmaOnlyInHeaderOfProcX % ("'" & proto.name.s & "' from " & c.config$proto.info)) styleCheckDef(c.config, s) onDefResolveForward(n[namePos].info, proto) @@ -1866,18 +1860,18 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, excl(proto.flags, sfForward) closeScope(c) # close scope with wrong parameter symbols openScope(c) # open scope for old (correct) parameter symbols - if proto.ast.sons[genericParamsPos].kind != nkEmpty: - addGenericParamListToScope(c, proto.ast.sons[genericParamsPos]) + if proto.ast[genericParamsPos].kind != nkEmpty: + addGenericParamListToScope(c, proto.ast[genericParamsPos]) addParams(c, proto.typ.n, proto.kind) proto.info = s.info # more accurate line information s.typ = proto.typ proto.options = s.options s = proto - n.sons[genericParamsPos] = proto.ast.sons[genericParamsPos] - n.sons[paramsPos] = proto.ast.sons[paramsPos] - n.sons[pragmasPos] = proto.ast.sons[pragmasPos] - if n.sons[namePos].kind != nkSym: internalError(c.config, n.info, "semProcAux") - n.sons[namePos].sym = proto + n[genericParamsPos] = proto.ast[genericParamsPos] + n[paramsPos] = proto.ast[paramsPos] + n[pragmasPos] = proto.ast[pragmasPos] + if n[namePos].kind != nkSym: internalError(c.config, n.info, "semProcAux") + n[namePos].sym = proto if importantComments(c.config) and proto.ast.comment.len > 0: n.comment = proto.ast.comment proto.ast = n # needed for code generation @@ -1893,44 +1887,44 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, localError(c.config, n.info, "the overloaded " & s.name.s & " operator has to be enabled with {.experimental: \"callOperator\".}") - if n.sons[bodyPos].kind != nkEmpty and sfError notin s.flags: + if n[bodyPos].kind != nkEmpty and sfError notin s.flags: # for DLL generation we allow sfImportc to have a body, for use in VM if sfBorrow in s.flags: - localError(c.config, n.sons[bodyPos].info, errImplOfXNotAllowed % s.name.s) + localError(c.config, n[bodyPos].info, errImplOfXNotAllowed % s.name.s) let usePseudoGenerics = kind in {skMacro, skTemplate} # Macros and Templates can have generic parameters, but they are # only used for overload resolution (there is no instantiation of # the symbol, so we must process the body now) if not usePseudoGenerics and c.config.ideCmd in {ideSug, ideCon} and not - cursorInProc(c.config, n.sons[bodyPos]): + cursorInProc(c.config, n[bodyPos]): discard "speed up nimsuggest" if s.kind == skMethod: semMethodPrototype(c, s, n) else: pushProcCon(c, s) - if n.sons[genericParamsPos].kind == nkEmpty or usePseudoGenerics: + if n[genericParamsPos].kind == nkEmpty or usePseudoGenerics: if not usePseudoGenerics and s.magic == mNone: paramsTypeCheck(c, s.typ) c.p.wasForwarded = proto != nil maybeAddResult(c, s, n) # semantic checking also needed with importc in case used in VM - s.ast[bodyPos] = hloBody(c, semProcBody(c, n.sons[bodyPos])) + s.ast[bodyPos] = hloBody(c, semProcBody(c, n[bodyPos])) # unfortunately we cannot skip this step when in 'system.compiles' # context as it may even be evaluated in 'system.compiles': trackProc(c, s, s.ast[bodyPos]) if s.kind == skMethod: semMethodPrototype(c, s, n) else: - if (s.typ.sons[0] != nil and kind != skIterator) or kind == skMacro: + if (s.typ[0] != nil and kind != skIterator) or kind == skMacro: addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nil, n.info)) openScope(c) - n.sons[bodyPos] = semGenericStmt(c, n.sons[bodyPos]) + n[bodyPos] = semGenericStmt(c, n[bodyPos]) closeScope(c) if s.magic == mNone: fixupInstantiatedSymbols(c, s) if s.kind == skMethod: semMethodPrototype(c, s, n) if sfImportc in s.flags: # don't ignore the body in case used in VM - # n.sons[bodyPos] = c.graph.emptyNode + # n[bodyPos] = c.graph.emptyNode discard popProcCon(c) else: @@ -1947,7 +1941,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, closeScope(c) # close scope for parameters # c.currentScope = oldScope popOwner(c) - if n.sons[patternPos].kind != nkEmpty: + if n[patternPos].kind != nkEmpty: c.patterns.add(s) if isAnon: n.kind = nkLambda @@ -1975,9 +1969,9 @@ proc semIterator(c: PContext, n: PNode): PNode = # nkIteratorDef aynmore, return. The iterator then might have been # sem'checked already. (Or not, if the macro skips it.) if result.kind != n.kind: return - var s = result.sons[namePos].sym + var s = result[namePos].sym var t = s.typ - if t.sons[0] == nil and s.typ.callConv != ccClosure: + if t[0] == nil and s.typ.callConv != ccClosure: localError(c.config, n.info, "iterator needs a return type") # iterators are either 'inline' or 'closure'; for backwards compatibility, # we require first class iterators to be marked with 'closure' explicitly @@ -1986,7 +1980,7 @@ proc semIterator(c: PContext, n: PNode): PNode = incl(s.typ.flags, tfCapturesEnv) else: s.typ.callConv = ccInline - if n.sons[bodyPos].kind == nkEmpty and s.magic == mNone: + if n[bodyPos].kind == nkEmpty and s.magic == mNone: localError(c.config, n.info, errImplOfXexpected % s.name.s) if optOwnedRefs in c.config.globalOptions and result.typ != nil: result.typ = makeVarType(c, result.typ, tyOwned) @@ -2007,16 +2001,16 @@ proc semMethod(c: PContext, n: PNode): PNode = # nkIteratorDef aynmore, return. The iterator then might have been # sem'checked already. (Or not, if the macro skips it.) if result.kind != nkMethodDef: return - var s = result.sons[namePos].sym + var s = result[namePos].sym # we need to fix the 'auto' return type for the dispatcher here (see tautonotgeneric # test case): let disp = getDispatcher(s) # auto return type? - if disp != nil and disp.typ.sons[0] != nil and disp.typ.sons[0].kind == tyUntyped: - let ret = s.typ.sons[0] - disp.typ.sons[0] = ret + if disp != nil and disp.typ[0] != nil and disp.typ[0].kind == tyUntyped: + let ret = s.typ[0] + disp.typ[0] = ret if disp.ast[resultPos].kind == nkSym: - if isEmptyType(ret): disp.ast.sons[resultPos] = c.graph.emptyNode + if isEmptyType(ret): disp.ast[resultPos] = c.graph.emptyNode else: disp.ast[resultPos].sym.typ = ret proc semConverterDef(c: PContext, n: PNode): PNode = @@ -2029,10 +2023,10 @@ proc semConverterDef(c: PContext, n: PNode): PNode = # nkIteratorDef aynmore, return. The iterator then might have been # sem'checked already. (Or not, if the macro skips it.) if result.kind != nkConverterDef: return - var s = result.sons[namePos].sym + var s = result[namePos].sym var t = s.typ - if t.sons[0] == nil: localError(c.config, n.info, errXNeedsReturnType % "converter") - if len(t) != 2: localError(c.config, n.info, "a converter takes exactly one argument") + if t[0] == nil: localError(c.config, n.info, errXNeedsReturnType % "converter") + if t.len != 2: localError(c.config, n.info, "a converter takes exactly one argument") addConverter(c, s) proc semMacroDef(c: PContext, n: PNode): PNode = @@ -2044,14 +2038,14 @@ proc semMacroDef(c: PContext, n: PNode): PNode = # nkIteratorDef aynmore, return. The iterator then might have been # sem'checked already. (Or not, if the macro skips it.) if result.kind != nkMacroDef: return - var s = result.sons[namePos].sym + var s = result[namePos].sym var t = s.typ var allUntyped = true - for i in 1 .. t.n.len-1: - let param = t.n.sons[i].sym + for i in 1..<t.n.len: + let param = t.n[i].sym if param.typ.kind != tyUntyped: allUntyped = false if allUntyped: incl(s.flags, sfAllUntyped) - if n.sons[bodyPos].kind == nkEmpty: + if n[bodyPos].kind == nkEmpty: localError(c.config, n.info, errImplOfXexpected % s.name.s) proc incMod(c: PContext, n: PNode, it: PNode, includeStmtResult: PNode) = @@ -2060,15 +2054,15 @@ proc incMod(c: PContext, n: PNode, it: PNode, includeStmtResult: PNode) = if containsOrIncl(c.includedFiles, f.int): localError(c.config, n.info, errRecursiveDependencyX % toMsgFilename(c.config, f)) else: - addSon(includeStmtResult, semStmt(c, c.graph.includeFileCallback(c.graph, c.module, f), {})) + includeStmtResult.add semStmt(c, c.graph.includeFileCallback(c.graph, c.module, f), {}) excl(c.includedFiles, f.int) proc evalInclude(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) - addSon(result, n) - for i in 0 ..< len(n): + result.add n + for i in 0..<n.len: var imp: PNode - let it = n.sons[i] + let it = n[i] if it.kind == nkInfix and it.len == 3 and it[0].ident.s != "/": localError(c.config, it.info, "Cannot use '" & it[0].ident.s & "' in 'include'.") if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket: @@ -2079,25 +2073,25 @@ proc evalInclude(c: PContext, n: PNode): PNode = imp.add dir imp.add sep # dummy entry, replaced in the loop for x in it[2]: - imp.sons[2] = x + imp[2] = x incMod(c, n, imp, result) else: incMod(c, n, it, result) proc setLine(n: PNode, info: TLineInfo) = - for i in 0 ..< safeLen(n): setLine(n.sons[i], info) + for i in 0..<n.safeLen: setLine(n[i], info) n.info = info proc semPragmaBlock(c: PContext, n: PNode): PNode = checkSonsLen(n, 2, c.config) - let pragmaList = n.sons[0] + let pragmaList = n[0] pragma(c, nil, pragmaList, exprPragmas) n[1] = semExpr(c, n[1]) result = n result.typ = n[1].typ - for i in 0 ..< pragmaList.len: - case whichPragma(pragmaList.sons[i]) - of wLine: setLine(result, pragmaList.sons[i].info) + for i in 0..<pragmaList.len: + case whichPragma(pragmaList[i]) + of wLine: setLine(result, pragmaList[i].info) of wNoRewrite: incl(result.flags, nfNoRewrite) else: discard @@ -2106,17 +2100,17 @@ proc semStaticStmt(c: PContext, n: PNode): PNode = #writeStackTrace() inc c.inStaticContext openScope(c) - let a = semStmt(c, n.sons[0], {}) + let a = semStmt(c, n[0], {}) closeScope(c) dec c.inStaticContext - n.sons[0] = a + n[0] = a evalStaticStmt(c.module, c.graph, a, c.p.owner) when false: # for incremental replays, keep the AST as required for replays: result = n else: result = newNodeI(nkDiscardStmt, n.info, 1) - result.sons[0] = c.graph.emptyNode + result[0] = c.graph.emptyNode proc usesResult(n: PNode): bool = # nkStmtList(expr) properly propagates the void context, @@ -2147,19 +2141,18 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} result = n result.kind = nkStmtList - var length = len(n) var voidContext = false - var last = length-1 + var last = n.len-1 # by not allowing for nkCommentStmt etc. we ensure nkStmtListExpr actually # really *ends* in the expression that produces the type: The compiler now # relies on this fact and it's too much effort to change that. And arguably # 'R(); #comment' shouldn't produce R's type anyway. - #while last > 0 and n.sons[last].kind in {nkPragma, nkCommentStmt, + #while last > 0 and n[last].kind in {nkPragma, nkCommentStmt, # nkNilLit, nkEmpty}: # dec last - for i in 0 ..< length: - var expr = semExpr(c, n.sons[i], flags) - n.sons[i] = expr + for i in 0..<n.len: + var expr = semExpr(c, n[i], flags) + n[i] = expr if c.matchedConcept != nil and expr.typ != nil and (nfFromTemplate notin n.flags or i != last): case expr.typ.kind @@ -2179,25 +2172,25 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = localError(c.config, result.info, "concept predicate failed") of tyUnknown: continue else: discard - if n.sons[i].typ == c.enforceVoidContext: #or usesResult(n.sons[i]): + if n[i].typ == c.enforceVoidContext: #or usesResult(n[i]): voidContext = true n.typ = c.enforceVoidContext - if i == last and (length == 1 or ({efWantValue, efInTypeof} * flags != {})): - n.typ = n.sons[i].typ + if i == last and (n.len == 1 or ({efWantValue, efInTypeof} * flags != {})): + n.typ = n[i].typ if not isEmptyType(n.typ): n.kind = nkStmtListExpr elif i != last or voidContext: - discardCheck(c, n.sons[i], flags) + discardCheck(c, n[i], flags) else: - n.typ = n.sons[i].typ + n.typ = n[i].typ if not isEmptyType(n.typ): n.kind = nkStmtListExpr - if n.sons[i].kind in LastBlockStmts or - n.sons[i].kind in nkCallKinds and n.sons[i][0].kind == nkSym and - sfNoReturn in n.sons[i][0].sym.flags: - for j in i + 1 ..< length: - case n.sons[j].kind + if n[i].kind in LastBlockStmts or + n[i].kind in nkCallKinds and n[i][0].kind == nkSym and + sfNoReturn in n[i][0].sym.flags: + for j in i + 1..<n.len: + case n[j].kind of nkPragma, nkCommentStmt, nkNilLit, nkEmpty, nkBlockExpr, nkBlockStmt, nkState: discard - else: localError(c.config, n.sons[j].info, + else: localError(c.config, n[j].info, "unreachable statement after 'return' statement or '{.noReturn.}' proc") else: discard @@ -2207,8 +2200,8 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = # also, don't make life complicated for macros. # they will always expect a proper stmtlist: nfBlockArg notin n.flags and - result.sons[0].kind != nkDefer: - result = result.sons[0] + result[0].kind != nkDefer: + result = result[0] when defined(nimfix): if result.kind == nkCommentStmt and not result.comment.isNil and |