diff options
103 files changed, 1553 insertions, 1136 deletions
diff --git a/changelog.md b/changelog.md index f135fa585..7a14c6c28 100644 --- a/changelog.md +++ b/changelog.md @@ -31,6 +31,8 @@ type ``` +- `exportc` now uses C instead of C++ mangling with `nim cpp`, matching behavior of `importc`, see #10578 + Use the new `exportcpp` to mangle as C++ when using `nim cpp`. ### Breaking changes in the compiler @@ -45,6 +47,10 @@ type - Added `system.getOsFileHandle` which is usually more useful than `system.getFileHandle`. This distinction is only meaningful on Windows. +- Added a `json.parseJsonFragments` iterator that can be used to speedup + JSON processing substantially when there are JSON fragments separated + by whitespace. + ## Library changes diff --git a/compiler/aliases.nim b/compiler/aliases.nim index a09c4077d..fb2a39bc5 100644 --- a/compiler/aliases.nim +++ b/compiler/aliases.nim @@ -22,14 +22,14 @@ proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult = result = arNo case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = isPartOfAux(n.sons[i], b, marker) if result == arYes: return of nkRecCase: assert(n.sons[0].kind == nkSym) result = isPartOfAux(n.sons[0], b, marker) if result == arYes: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: result = isPartOfAux(lastSon(n.sons[i]), b, marker) @@ -52,7 +52,7 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult = of tyGenericInst, tyDistinct, tyAlias, tySink: result = isPartOfAux(lastSon(a), b, marker) of tyArray, tySet, tyTuple: - for i in 0 ..< sonsLen(a): + for i in 0 ..< len(a): result = isPartOfAux(a.sons[i], b, marker) if result == arYes: return else: discard diff --git a/compiler/ast.nim b/compiler/ast.nim index db0321f6c..addb2c33b 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -228,7 +228,7 @@ type TNodeKinds* = set[TNodeKind] type - TSymFlag* = enum # already 36 flags! + TSymFlag* = enum # already 38 flags! sfUsed, # read access of sym (for warnings) or simply used sfExported, # symbol is exported from module sfFromGeneric, # symbol is instantiation of a generic; this is needed @@ -239,6 +239,7 @@ type sfForward, # symbol is forward declared sfImportc, # symbol is external; imported sfExportc, # symbol is exported (under a specified name) + sfMangleCpp, # mangle as cpp (combines with `sfExportc`) sfVolatile, # variable is volatile sfRegister, # variable should be placed in a register sfPure, # object is "pure" that means it has no type-information @@ -282,6 +283,7 @@ type sfGeneratedOp # proc is a generated '='; do not inject destructors in it # variable is generated closure environment; requires early # destruction for --newruntime. + sfTemplateParam # symbol is a template parameter TSymFlags* = set[TSymFlag] @@ -1021,7 +1023,9 @@ proc isCallExpr*(n: PNode): bool = proc discardSons*(father: PNode) -proc len*(n: PNode): int {.inline.} = +type Indexable = PNode | PType + +proc len*(n: Indexable): int {.inline.} = when defined(nimNoNilSeqs): result = len(n.sons) else: @@ -1045,8 +1049,6 @@ proc add*(father, son: PNode) = if isNil(father.sons): father.sons = @[] add(father.sons, son) -type Indexable = PNode | PType - template `[]`*(n: Indexable, i: int): Indexable = n.sons[i] template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x @@ -1236,7 +1238,7 @@ proc newIntNode*(kind: TNodeKind, intVal: Int128): PNode = result = newNode(kind) result.intVal = castToInt64(intVal) -proc lastSon*(n: PType): PType = n.sons[^1] +proc lastSon*(n: Indexable): Indexable = n.sons[^1] proc skipTypes*(t: PType, kinds: TTypeKinds): PType = ## Used throughout the compiler code to test whether a type tree contains or @@ -1340,7 +1342,7 @@ proc mergeLoc(a: var TLoc, b: TLoc) = if a.lode == nil: a.lode = b.lode if a.r == nil: a.r = b.r -proc newSons*(father: PNode, length: int) = +proc newSons*(father: Indexable, length: int) = when defined(nimNoNilSeqs): setLen(father.sons, length) else: @@ -1349,20 +1351,6 @@ proc newSons*(father: PNode, length: int) = else: setLen(father.sons, length) -proc newSons*(father: PType, length: int) = - when defined(nimNoNilSeqs): - setLen(father.sons, length) - else: - if isNil(father.sons): - newSeq(father.sons, length) - else: - setLen(father.sons, length) - -proc sonsLen*(n: PType): int = n.sons.len -proc len*(n: PType): int = n.sons.len -proc sonsLen*(n: PNode): int = n.sons.len -proc lastSon*(n: PNode): PNode = n.sons[^1] - proc assignType*(dest, src: PType) = dest.kind = src.kind dest.flags = src.flags @@ -1380,8 +1368,8 @@ proc assignType*(dest, src: PType) = mergeLoc(dest.sym.loc, src.sym.loc) else: dest.sym = src.sym - newSons(dest, sonsLen(src)) - for i in 0 ..< sonsLen(src): dest.sons[i] = src.sons[i] + newSons(dest, len(src)) + for i in 0 ..< len(src): dest.sons[i] = src.sons[i] proc copyType*(t: PType, owner: PSym, keepId: bool): PType = result = newType(t.kind, owner) @@ -1535,7 +1523,7 @@ proc delSon*(father: PNode, idx: int) = if father.len == 0: return else: if isNil(father.sons): return - var length = sonsLen(father) + var length = len(father) for i in idx .. length - 2: father.sons[i] = father.sons[i + 1] setLen(father.sons, length - 1) @@ -1576,7 +1564,7 @@ proc shallowCopy*(src: PNode): PNode = of nkSym: result.sym = src.sym of nkIdent: result.ident = src.ident of nkStrLit..nkTripleStrLit: result.strVal = src.strVal - else: newSeq(result.sons, sonsLen(src)) + else: newSeq(result.sons, len(src)) proc copyTree*(src: PNode): PNode = # copy a whole syntax tree; performs deep copying @@ -1597,12 +1585,12 @@ proc copyTree*(src: PNode): PNode = of nkIdent: result.ident = src.ident of nkStrLit..nkTripleStrLit: result.strVal = src.strVal else: - newSeq(result.sons, sonsLen(src)) - for i in 0 ..< sonsLen(src): + newSeq(result.sons, len(src)) + for i in 0 ..< len(src): result.sons[i] = copyTree(src.sons[i]) proc hasSonWith*(n: PNode, kind: TNodeKind): bool = - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if n.sons[i].kind == kind: return true result = false @@ -1620,14 +1608,14 @@ proc containsNode*(n: PNode, kinds: TNodeKinds): bool = case n.kind of nkEmpty..nkNilLit: result = n.kind in kinds else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if n.kind in kinds or containsNode(n.sons[i], kinds): return true proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool = case n.kind of nkEmpty..nkNilLit: result = n.kind == kind else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if (n.sons[i].kind == kind) or hasSubnodeWith(n.sons[i], kind): return true result = false diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 06611313c..0efa096be 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -31,6 +31,15 @@ when declared(echo): proc debug*(n: PType; conf: ConfigRef = nil) {.exportc: "debugType", deprecated.} proc debug*(n: PNode; conf: ConfigRef = nil) {.exportc: "debugNode", deprecated.} + proc typekinds*(t: PType) {.deprecated.} = + var t = t + var s = "" + while t != nil and t.len > 0: + s.add $t.kind + s.add " " + t = t.lastSon + echo s + template debug*(x: PSym|PType|PNode) {.deprecated.} = when compiles(c.config): debug(c.config, x) @@ -151,14 +160,14 @@ proc lookupInRecord(n: PNode, field: PIdent): PSym = result = nil case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = lookupInRecord(n.sons[i], field) if result != nil: return of nkRecCase: if (n.sons[0].kind != nkSym): return nil result = lookupInRecord(n.sons[0], field) if result != nil: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: result = lookupInRecord(lastSon(n.sons[i]), field) @@ -174,7 +183,7 @@ proc getModule*(s: PSym): PSym = while result != nil and result.kind != skModule: result = result.owner proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym = - for i in start ..< sonsLen(list): + for i in start ..< len(list): if list.sons[i].kind == nkSym: result = list.sons[i].sym if result.name.id == ident.id: return @@ -185,6 +194,7 @@ 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) + if last == 0: last = a.len - 1 var i = 1 var j = 1 @@ -317,9 +327,9 @@ proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet, indent: int, sonsRope = "\"$1 @$2\"" % [rope($n.kind), rope( strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))] else: - if sonsLen(n) > 0: + if len(n) > 0: sonsRope = rope("[") - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if i > 0: add(sonsRope, ",") addf(sonsRope, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, n.sons[i], marker, indent + 4, maxRecDepth - 1)]) @@ -366,9 +376,9 @@ proc treeToYamlAux(conf: ConfigRef; n: PNode, marker: var IntSet, indent: int, else: addf(result, ",$N$1\"ident\": null", [istr]) else: - if sonsLen(n) > 0: + if len(n) > 0: addf(result, ",$N$1\"sons\": [", [istr]) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if i > 0: add(result, ",") addf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(conf, n.sons[i], marker, indent + 4, maxRecDepth - 1)]) @@ -553,12 +563,12 @@ proc value(this: var DebugPrinter; value: PType) = this.key "n" this.value value.n - if sonsLen(value) > 0: + if len(value) > 0: this.key "sons" this.openBracket - for i in 0 ..< sonsLen(value): + for i in 0 ..< len(value): this.value value.sons[i] - if i != sonsLen(value) - 1: + if i != len(value) - 1: this.comma this.closeBracket @@ -606,12 +616,12 @@ proc value(this: var DebugPrinter; value: PNode) = if this.renderSymType and value.typ != nil: this.key "typ" this.value value.typ - if sonsLen(value) > 0: + if len(value) > 0: this.key "sons" this.openBracket - for i in 0 ..< sonsLen(value): + for i in 0 ..< len(value): this.value value.sons[i] - if i != sonsLen(value) - 1: + if i != len(value) - 1: this.comma this.closeBracket diff --git a/compiler/canonicalizer.nim b/compiler/canonicalizer.nim index 8c418b790..1cf6171c1 100644 --- a/compiler/canonicalizer.nim +++ b/compiler/canonicalizer.nim @@ -120,7 +120,7 @@ proc hashType(c: var MD5Context, t: PType) = case t.kind of tyGenericBody, tyGenericInst, tyGenericInvocation: - for i in 0 ..< sonsLen(t)-ord(t.kind != tyGenericInvocation): + for i in 0 ..< len(t)-ord(t.kind != tyGenericInvocation): c.hashType t.sons[i] of tyUserTypeClass: internalAssert t.sym != nil and t.sym.owner != nil @@ -128,7 +128,7 @@ proc hashType(c: var MD5Context, t: PType) = of tyUserTypeClassInst: let body = t.base c.hashSym body.sym - for i in 1 .. sonsLen(t) - 2: + for i in 1 .. len(t) - 2: c.hashType t.sons[i] of tyFromExpr: c.hashTree(t.n) @@ -137,15 +137,15 @@ proc hashType(c: var MD5Context, t: PType) = c.hashType(t.sons[1]) of tyTuple: if t.n != nil: - assert(sonsLen(t.n) == sonsLen(t)) - for i in 0 ..< sonsLen(t.n): + assert(len(t.n) == len(t)) + for i in 0 ..< len(t.n): assert(t.n.sons[i].kind == nkSym) c &= t.n.sons[i].sym.name.s c &= ":" c.hashType(t.sons[i]) c &= "," else: - for i in 0 ..< sonsLen(t): c.hashType t.sons[i] + for i in 0 ..< len(t): c.hashType t.sons[i] of tyRange: c.hashTree(t.n) c.hashType(t.sons[0]) @@ -238,7 +238,7 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode, encodeVInt(n.sym.id, result) pushSym(w, n.sym) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): encodeNode(w, n.info, n.sons[i], result) add(result, ')') @@ -304,7 +304,7 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) = add(result, '=') encodeVInt(t.align, result) encodeLoc(w, t.loc, result) - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): if t.sons[i] == nil: add(result, "^()") else: diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 53ebc2806..686eb8fde 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -186,7 +186,7 @@ proc genArgNoParam(p: BProc, n: PNode): Rope = result = rdLoc(a) template genParamLoop(params) {.dirty.} = - if i < sonsLen(typ): + if i < len(typ): assert(typ.n.sons[i].kind == nkSym) let paramType = typ.n.sons[i] if not paramType.typ.isCompileTimeOnly: @@ -209,8 +209,8 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) = # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInstOwned) assert(typ.kind == tyProc) - assert(sonsLen(typ) == sonsLen(typ.n)) - var length = sonsLen(ri) + assert(len(typ) == len(typ.n)) + var length = len(ri) for i in 1 ..< length: genParamLoop(params) var callee = rdLoc(op) @@ -234,9 +234,9 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = var typ = skipTypes(ri.sons[0].typ, abstractInst) assert(typ.kind == tyProc) - var length = sonsLen(ri) + var length = len(ri) for i in 1 ..< length: - assert(sonsLen(typ) == sonsLen(typ.n)) + assert(len(typ) == len(typ.n)) genParamLoop(pl) template genCallPattern {.dirty.} = @@ -248,7 +248,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = let rawProc = getRawProcType(p, typ) if typ.sons[0] != nil: if isInvalidReturnType(p.config, typ.sons[0]): - if sonsLen(ri) > 1: add(pl, ~", ") + if len(ri) > 1: add(pl, ~", ") # beware of 'result = p(result)'. We may need to allocate a temporary: if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri): # Great, we can use 'd': @@ -280,7 +280,7 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = genCallPattern() proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): Rope = - if i < sonsLen(typ): + if i < len(typ): # 'var T' is 'T&' in C++. This means we ignore the request of # any nkHiddenAddr when it's a 'var T'. let paramType = typ.n.sons[i] @@ -357,7 +357,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): Rope = # for better or worse c2nim translates the 'this' argument to a 'var T'. # However manual wrappers may also use 'ptr T'. In any case we support both # for convenience. - internalAssert p.config, i < sonsLen(typ) + internalAssert p.config, i < len(typ) assert(typ.n.sons[i].kind == nkSym) # if the parameter is lying (tyVar) and thus we required an additional deref, # skip the deref: @@ -394,11 +394,14 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope = while i < pat.len: case pat[i] of '@': - if j < ri.len: - result.add genOtherArg(p, ri, j, typ) - for k in j+1 ..< ri.len: - result.add(~", ") - result.add genOtherArg(p, ri, k, typ) + var first = true + for k in j ..< ri.len: + let arg = genOtherArg(p, ri, k, typ) + if arg.len > 0: + if not first: + result.add(~", ") + first = false + result.add arg inc i of '#': if i+1 < pat.len and pat[i+1] in {'+', '@'}: @@ -448,8 +451,8 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) = # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInst) assert(typ.kind == tyProc) - var length = sonsLen(ri) - assert(sonsLen(typ) == sonsLen(typ.n)) + var length = len(ri) + assert(len(typ) == len(typ.n)) # don't call '$' here for efficiency: let pat = ri.sons[0].sym.loc.r.data internalAssert p.config, pat.len > 0 @@ -484,7 +487,7 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) = var params: Rope for i in 2 ..< length: if params != nil: params.add(~", ") - assert(sonsLen(typ) == sonsLen(typ.n)) + assert(len(typ) == len(typ.n)) add(params, genOtherArg(p, ri, i, typ)) fixupCall(p, le, ri, d, pl, params) @@ -496,8 +499,8 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInst) assert(typ.kind == tyProc) - var length = sonsLen(ri) - assert(sonsLen(typ) == sonsLen(typ.n)) + var length = len(ri) + assert(len(typ) == len(typ.n)) # don't call '$' here for efficiency: let pat = ri.sons[0].sym.loc.r.data @@ -519,8 +522,8 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = add(pl, ~": ") add(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri)) for i in start ..< length: - assert(sonsLen(typ) == sonsLen(typ.n)) - if i >= sonsLen(typ): + assert(len(typ) == len(typ.n)) + if i >= len(typ): internalError(p.config, ri.info, "varargs for objective C method?") assert(typ.n.sons[i].kind == nkSym) var param = typ.n.sons[i].sym @@ -530,7 +533,7 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = add(pl, genArg(p, ri.sons[i], param, ri)) if typ.sons[0] != nil: if isInvalidReturnType(p.config, typ.sons[0]): - if sonsLen(ri) > 1: add(pl, ~" ") + if len(ri) > 1: add(pl, ~" ") # beware of 'result = p(result)'. We always allocate a temporary: if d.k in {locTemp, locNone}: # We already got a temp. Great, special case it: diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 0902e2e19..f29995202 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -797,7 +797,7 @@ proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) proc genFieldCheck(p: BProc, e: PNode, obj: Rope, field: PSym) = var test, u, v: TLoc - for i in 1 ..< sonsLen(e): + for i in 1 ..< len(e): var it = e.sons[i] assert(it.kind in nkCallKinds) assert(it.sons[0].kind == nkSym) @@ -1087,7 +1087,7 @@ proc genStrConcat(p: BProc, e: PNode, d: var TLoc) = var L = 0 var appends: Rope = nil var lens: Rope = nil - for i in 0 .. sonsLen(e) - 2: + for i in 0 .. len(e) - 2: # compute the length expression: initLocExpr(p, e.sons[i + 1], a) if skipTypes(e.sons[i + 1].typ, abstractVarRange).kind == tyChar: @@ -1126,7 +1126,7 @@ proc genStrAppend(p: BProc, e: PNode, d: var TLoc) = assert(d.k == locNone) var L = 0 initLocExpr(p, e.sons[1], dest) - for i in 0 .. sonsLen(e) - 3: + for i in 0 .. len(e) - 3: # compute the length expression: initLocExpr(p, e.sons[i + 2], a) if skipTypes(e.sons[i + 2].typ, abstractVarRange).kind == tyChar: @@ -1193,6 +1193,8 @@ proc genDefault(p: BProc; n: PNode; d: var TLoc) = if d.k == locNone: getTemp(p, n.typ, d, needsInit=true) else: resetLoc(p, d) +proc trivialDestructor(s: PSym): bool {.inline.} = s.ast[bodyPos].len == 0 + proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = var sizeExpr = sizeExpr let typ = a.t @@ -1210,7 +1212,7 @@ proc rawGenNew(p: BProc, a: TLoc, sizeExpr: Rope) = genAssignment(p, a, b, {}) else: let ti = genTypeInfo(p.module, typ, a.lode.info) - if bt.destructor != nil: + if bt.destructor != nil and not trivialDestructor(bt.destructor): # the prototype of a destructor is ``=destroy(x: var T)`` and that of a # finalizer is: ``proc (x: ref T) {.nimcall.}``. We need to check the calling # convention at least: @@ -1400,7 +1402,7 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) = elif d.k == locNone: getTemp(p, n.typ, d) - let l = intLiteral(sonsLen(n)) + let l = intLiteral(len(n)) if p.config.selectedGC == gcDestructors: let seqtype = n.typ linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n", @@ -1410,7 +1412,7 @@ proc genSeqConstr(p: BProc, n: PNode, d: var TLoc) = # generate call to newSeq before adding the elements per hand: genNewSeqAux(p, dest[], l, optNilSeqs notin p.options and n.len == 0) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): initLoc(arr, locExpr, n[i], OnHeap) arr.r = ropecg(p.module, "$1$3[$2]", [rdLoc(dest[]), intLiteral(i), dataField(p)]) arr.storage = OnHeap # we know that sequences are on the heap @@ -1726,7 +1728,7 @@ proc fewCmps(conf: ConfigRef; s: PNode): bool = elif elemType(s.typ).kind in {tyInt, tyInt16..tyInt64}: result = true # better not emit the set if int is basetype! else: - result = sonsLen(s) <= 8 # 8 seems to be a good value + result = len(s) <= 8 # 8 seems to be a good value template binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) = putIntoDest(p, d, e, frmt % [rdLoc(a), rdSetElemLoc(p.config, b, a.t)]) @@ -1759,7 +1761,7 @@ proc genInOp(p: BProc, e: PNode, d: var TLoc) = e.sons[2] initLocExpr(p, ea, a) initLoc(b, locExpr, e, OnUnknown) - var length = sonsLen(e.sons[1]) + var length = len(e.sons[1]) if length > 0: b.r = rope("(") for i in 0 ..< length: @@ -2321,7 +2323,7 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) = let t = n.typ discard getTypeDesc(p.module, t) # so that any fields are initialized if d.k == locNone: getTemp(p, t, d) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it.kind == nkExprColonExpr: it = it.sons[1] initLoc(rec, locExpr, it, d.storage) @@ -2363,7 +2365,7 @@ proc genArrayConstr(p: BProc, n: PNode, d: var TLoc) = var arr: TLoc if not handleConstExpr(p, n, d): if d.k == locNone: getTemp(p, n.typ, d) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): initLoc(arr, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), d.storage) arr.r = "$1[$2]" % [rdLoc(d), intLiteral(i)] expr(p, n.sons[i], arr) @@ -2533,6 +2535,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = of skVar, skForVar, skResult, skLet: if {sfGlobal, sfThread} * sym.flags != {}: genVarPrototype(p.module, n) + if sfCompileTime in sym.flags: + genSingleVar(p, sym, n, astdef(sym)) + if sym.loc.r == nil or sym.loc.t == nil: #echo "FAILED FOR PRCO ", p.prc.name.s #echo renderTree(p.prc.ast, {renderIds}) @@ -2743,7 +2748,7 @@ proc getNullValueAux(p: BProc; t: PType; obj, cons: PNode, getNullValueAux(p, t, it, cons, result, count) of nkRecCase: getNullValueAux(p, t, obj.sons[0], cons, result, count) - for i in 1 ..< sonsLen(obj): + for i in 1 ..< len(obj): getNullValueAux(p, t, lastSon(obj.sons[i]), cons, result, count) of nkSym: if count > 0: result.add ", " @@ -2791,7 +2796,7 @@ proc genConstObjConstr(p: BProc; n: PNode): Rope = result = "{$1}$n" % [result] proc genConstSimpleList(p: BProc, n: PNode): Rope = - var length = sonsLen(n) + var length = len(n) result = rope("{") for i in 0 .. length - 2: addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])]) diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index ffeeb0db9..ec579d9e7 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -62,7 +62,7 @@ proc endBlock(p: BProc) proc genVarTuple(p: BProc, n: PNode) = var tup, field: TLoc if n.kind != nkVarTuple: internalError(p.config, n.info, "genVarTuple") - var L = sonsLen(n) + var L = len(n) # if we have a something that's been captured, use the lowering instead: for i in 0 .. L-3: @@ -271,19 +271,16 @@ proc genGotoVar(p: BProc; value: PNode) = else: lineF(p, cpsStmts, "goto NIMSTATE_$#;$n", [value.intVal.rope]) -proc genSingleVar(p: BProc, a: PNode) = - let vn = a.sons[0] - let v = vn.sym - if sfCompileTime in v.flags: return +proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) = if sfGoto in v.flags: # translate 'var state {.goto.} = X' into 'goto LX': - genGotoVar(p, a.sons[2]) + genGotoVar(p, value) return var targetProc = p var traverseProc: Rope if sfGlobal in v.flags: if v.flags * {sfImportc, sfExportc} == {sfImportc} and - a.sons[2].kind == nkEmpty and + value.kind == nkEmpty and v.loc.flags * {lfHeader, lfNoDecl} != {}: return if sfPure in v.flags: @@ -313,14 +310,13 @@ proc genSingleVar(p: BProc, a: PNode) = if traverseProc != nil and not p.hcrOn: registerTraverseProc(p, v, traverseProc) else: - let value = a.sons[2] let imm = isAssignedImmediately(p.config, value) if imm and p.module.compileToCpp and p.splitDecls == 0 and not containsHiddenPointer(v.typ): # C++ really doesn't like things like 'Foo f; f = x' as that invokes a # parameterless constructor followed by an assignment operator. So we # generate better code here: 'Foo f = x;' - genLineDir(p, a) + genLineDir(p, vn) let decl = localVarDecl(p, vn) var tmp: TLoc if value.kind in nkCallKinds and value[0].kind == nkSym and @@ -330,7 +326,7 @@ proc genSingleVar(p: BProc, a: PNode) = assert(typ.kind == tyProc) for i in 1..<value.len: if params != nil: params.add(~", ") - assert(sonsLen(typ) == sonsLen(typ.n)) + assert(len(typ) == len(typ.n)) add(params, genOtherArg(p, value, i, typ)) if params == nil: lineF(p, cpsStmts, "$#;$n", [decl]) @@ -363,12 +359,17 @@ proc genSingleVar(p: BProc, a: PNode) = lineCg(targetProc, cpsStmts, "if (hcrRegisterGlobal($3, \"$1\", sizeof($2), $4, (void**)&$1))$N", [v.loc.r, rdLoc(v.loc), getModuleDllPath(p.module, v), traverseProc]) startBlock(targetProc) - if a.sons[2].kind != nkEmpty: - genLineDir(targetProc, a) - loadInto(targetProc, a.sons[0], a.sons[2], v.loc) + if value.kind != nkEmpty: + genLineDir(targetProc, vn) + loadInto(targetProc, vn, value, v.loc) if forHcr: endBlock(targetProc) +proc genSingleVar(p: BProc, a: PNode) = + let v = a[0].sym + if sfCompileTime in v.flags: return + genSingleVar(p, v, a[0], a.sons[2]) + proc genClosureVar(p: BProc, a: PNode) = var immediateAsgn = a.sons[2].kind != nkEmpty var v: TLoc @@ -428,7 +429,7 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) = else: expr(p, it.sons[1], d) endBlock(p) - if sonsLen(n) > 1: + if len(n) > 1: lineF(p, cpsStmts, "goto $1;$n", [lend]) fixLabel(p, lelse) elif it.len == 1: @@ -436,7 +437,7 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) = expr(p, it.sons[0], d) endBlock(p) else: internalError(p.config, n.info, "genIf()") - if sonsLen(n) > 1: fixLabel(p, lend) + if len(n) > 1: fixLabel(p, lend) proc genReturnStmt(p: BProc, t: PNode) = if nfPreventCg in t.flags: return @@ -564,7 +565,7 @@ proc genWhileStmt(p: BProc, t: PNode) = # significantly worse code var a: TLoc - assert(sonsLen(t) == 2) + assert(len(t) == 2) inc(p.withinLoop) genLineDir(p, t) @@ -611,7 +612,7 @@ proc genBlock(p: BProc, n: PNode, d: var TLoc) = endBlock(p) proc genParForStmt(p: BProc, t: PNode) = - assert(sonsLen(t) == 3) + assert(len(t) == 3) inc(p.withinLoop) genLineDir(p, t) @@ -622,12 +623,12 @@ proc genParForStmt(p: BProc, t: PNode) = #initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack) #discard mangleName(forLoopVar) let call = t.sons[1] - assert(sonsLen(call) in {4, 5}) + assert(len(call) in {4, 5}) initLocExpr(p, call.sons[1], rangeA) initLocExpr(p, call.sons[2], rangeB) # $n at the beginning because of #9710 - if call.sonsLen == 4: # `||`(a, b, annotation) + if call.len == 4: # `||`(a, b, annotation) lineF(p, cpsStmts, "$n#pragma omp $4$n" & "for ($1 = $2; $1 <= $3; ++$1)", [forLoopVar.loc.rdLoc, @@ -705,7 +706,7 @@ template genCaseGenericBranch(p: BProc, b: PNode, e: TLoc, rangeFormat, eqFormat: FormatStr, labl: TLabel) = var x, y: TLoc - var length = sonsLen(b) + var length = len(b) for i in 0 .. length - 2: if b.sons[i].kind == nkRange: initLocExpr(p, b.sons[i].sons[0], x) @@ -724,7 +725,7 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc, if d.k == locTemp and isEmptyType(t.typ): d.k = locNone lineF(p, cpsStmts, "LA$1_: ;$n", [rope(labId + i)]) if t.sons[i].kind == nkOfBranch: - var length = sonsLen(t.sons[i]) + var length = len(t.sons[i]) exprBlock(p, t.sons[i].sons[length - 1], d) lineF(p, cpsStmts, "goto $1;$n", [lend]) else: @@ -758,13 +759,13 @@ template genCaseGeneric(p: BProc, t: PNode, d: var TLoc, rangeFormat, eqFormat: FormatStr) = var a: TLoc initLocExpr(p, t.sons[0], a) - var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, sonsLen(t)-1, a) + var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, len(t)-1, a) fixLabel(p, lend) proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, branches: var openArray[Rope]) = var x: TLoc - var length = sonsLen(b) + var length = len(b) for i in 0 .. length - 2: assert(b.sons[i].kind != nkRange) initLocExpr(p, b.sons[i], x) @@ -776,8 +777,8 @@ proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, proc genStringCase(p: BProc, t: PNode, d: var TLoc) = # count how many constant strings there are in the case: var strings = 0 - for i in 1 ..< sonsLen(t): - if t.sons[i].kind == nkOfBranch: inc(strings, sonsLen(t.sons[i]) - 1) + for i in 1 ..< len(t): + if t.sons[i].kind == nkOfBranch: inc(strings, len(t.sons[i]) - 1) if strings > stringCaseThreshold: var bitMask = math.nextPowerOfTwo(strings) - 1 var branches: seq[Rope] @@ -785,7 +786,7 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) = var a: TLoc initLocExpr(p, t.sons[0], a) # fist pass: gnerate ifs+goto: var labId = p.labels - for i in 1 ..< sonsLen(t): + for i in 1 ..< len(t): inc(p.labels) if t.sons[i].kind == nkOfBranch: genCaseStringBranch(p, t.sons[i], a, "LA" & rope(p.labels) & "_", @@ -801,16 +802,16 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) = lineF(p, cpsStmts, "case $1: $n$2break;$n", [intLiteral(j), branches[j]]) lineF(p, cpsStmts, "}$n", []) # else statement: - if t.sons[sonsLen(t)-1].kind != nkOfBranch: + if t.sons[len(t)-1].kind != nkOfBranch: lineF(p, cpsStmts, "goto LA$1_;$n", [rope(p.labels)]) # third pass: generate statements - var lend = genCaseSecondPass(p, t, d, labId, sonsLen(t)-1) + var lend = genCaseSecondPass(p, t, d, labId, len(t)-1) fixLabel(p, lend) else: genCaseGeneric(p, t, d, "", "if (#eqStrings($1, $2)) goto $3;$n") proc branchHasTooBigRange(b: PNode): bool = - for i in 0 .. sonsLen(b)-2: + for i in 0 .. len(b)-2: # last son is block if (b.sons[i].kind == nkRange) and b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit: @@ -1022,7 +1023,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = else: linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", [safePoint]) startBlock(p, "if ($1.status == 0) {$n", [safePoint]) - let length = sonsLen(t) + let length = len(t) let fin = if t[^1].kind == nkFinally: t[^1] else: nil add(p.nestedTryStmts, (fin, quirkyExceptions)) expr(p, t.sons[0], d) @@ -1041,7 +1042,7 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = while (i < length) and (t.sons[i].kind == nkExceptBranch): # bug #4230: avoid false sharing between branches: if d.k == locTemp and isEmptyType(t.typ): d.k = locNone - var blen = sonsLen(t.sons[i]) + var blen = len(t.sons[i]) if blen == 1: # general except section: if i > 1: lineF(p, cpsStmts, "else", []) diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim index 221c7a139..9374648c4 100644 --- a/compiler/ccgtrav.nim +++ b/compiler/ccgtrav.nim @@ -28,7 +28,7 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, n: PNode; if n == nil: return case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): genTraverseProc(c, accessor, n.sons[i], typ) of nkRecCase: if (n.sons[0].kind != nkSym): internalError(c.p.config, n.info, "genTraverseProc") @@ -38,7 +38,7 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, n: PNode; if disc.loc.t == nil: internalError(c.p.config, n.info, "genTraverseProc()") lineF(p, cpsStmts, "switch ($1.$2) {$n", [accessor, disc.loc.r]) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): let branch = n.sons[i] assert branch.kind in {nkOfBranch, nkElse} if branch.kind == nkOfBranch: @@ -87,14 +87,14 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) = else: lineF(p, cpsStmts, "}$n", []) of tyObject: - for i in 0 ..< sonsLen(typ): + for i in 0 ..< len(typ): var x = typ.sons[i] if x != nil: x = x.skipTypes(skipPtrs) genTraverseProc(c, accessor.parentObj(c.p.module), x) if typ.n != nil: genTraverseProc(c, accessor, typ.n, typ) of tyTuple: let typ = getUniqueType(typ) - for i in 0 ..< sonsLen(typ): + for i in 0 ..< len(typ): genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", [accessor, i]), typ.sons[i]) of tyRef: lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt]) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 5c5999e82..3b8d93a5a 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -450,7 +450,7 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope, rettype = ~"void" else: rettype = getTypeDescAux(m, t.sons[0], check) - for i in 1 ..< sonsLen(t.n): + for i in 1 ..< len(t.n): if t.n.sons[i].kind != nkSym: internalError(m.config, t.n.info, "genProcParams") var param = t.n.sons[i].sym if isCompileTimeOnly(param.typ): continue @@ -511,7 +511,7 @@ proc genRecordFieldsAux(m: BModule, n: PNode, result = nil case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): add(result, genRecordFieldsAux(m, n.sons[i], rectype, check)) of nkRecCase: if n.sons[0].kind != nkSym: internalError(m.config, n.info, "genRecordFieldsAux") @@ -519,7 +519,7 @@ proc genRecordFieldsAux(m: BModule, n: PNode, # prefix mangled name with "_U" to avoid clashes with other field names, # since identifiers are not allowed to start with '_' var unionBody: Rope = nil - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: let k = lastSon(n.sons[i]) @@ -634,7 +634,7 @@ proc getTupleDesc(m: BModule, typ: PType, name: Rope, check: var IntSet): Rope = result = "$1 $2 {$n" % [structOrUnion(typ), name] var desc: Rope = nil - for i in 0 ..< sonsLen(typ): + for i in 0 ..< len(typ): addf(desc, "$1 Field$2;$n", [getTypeDescAux(m, typ.sons[i], check), rope(i)]) if desc == nil: add(result, "char dummy;\L") @@ -1028,7 +1028,7 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType; proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo) = var base: Rope - if sonsLen(typ) > 0 and typ.lastSon != nil: + if len(typ) > 0 and typ.lastSon != nil: var x = typ.lastSon if typ.kind == tyObject: x = x.skipTypes(skipPtrs) if typ.kind == tyPtr and x.kind == tyObject and incompleteType(x): @@ -1067,7 +1067,7 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope; info: TLineInfo) = case n.kind of nkRecList: - var L = sonsLen(n) + var L = len(n) if L == 1: genObjectFields(m, typ, origType, n.sons[0], expr, info) elif L > 0: @@ -1098,15 +1098,15 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope; makeCString(field.name.s), tmp, rope(L)]) addf(m.s[cfsData], "TNimNode* $1[$2];$n", [tmp, rope(L+1)]) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var b = n.sons[i] # branch var tmp2 = getNimNode(m) genObjectFields(m, typ, origType, lastSon(b), tmp2, info) case b.kind of nkOfBranch: - if sonsLen(b) < 2: + if len(b) < 2: internalError(m.config, b.info, "genObjectFields; nkOfBranch broken") - for j in 0 .. sonsLen(b) - 2: + for j in 0 .. len(b) - 2: if b.sons[j].kind == nkRange: var x = toInt(getOrdValue(b.sons[j].sons[0])) var y = toInt(getOrdValue(b.sons[j].sons[1])) @@ -1155,7 +1155,7 @@ proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo) = genTypeInfoAuxBase(m, typ, typ, name, rope("0"), info) var expr = getNimNode(m) - var length = sonsLen(typ) + var length = len(typ) if length > 0: var tmp = getTempName(m) & "_" & $length genTNimNodeArray(m, tmp, rope(length)) @@ -1181,7 +1181,7 @@ proc genEnumInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) = # anyway. We generate a cstring array and a loop over it. Exceptional # positions will be reset after the loop. genTypeInfoAux(m, typ, typ, name, info) - var length = sonsLen(typ.n) + var length = len(typ.n) var nodePtrs = getTempName(m) & "_" & $length genTNimNodeArray(m, nodePtrs, rope(length)) var enumNames, specialCases: Rope diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 6e79b2d7b..625e48328 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -990,7 +990,7 @@ proc genProcAux(m: BModule, prc: PSym) = #incl(res.loc.flags, lfIndirect) res.loc.storage = OnUnknown - for i in 1 ..< sonsLen(prc.typ.n): + for i in 1 ..< len(prc.typ.n): let param = prc.typ.n.sons[i].sym if param.typ.isCompileTimeOnly: continue assignParam(p, param, prc.typ[0]) @@ -1039,7 +1039,8 @@ proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} = result = (sfCompileToCpp in m.module.flags and sfCompileToCpp notin sym.getModule().flags and m.config.cmd != cmdCompileToCpp) or ( - sym.flags * {sfImportc, sfInfixCall, sfCompilerProc} == {sfImportc} and + sym.flags * {sfInfixCall, sfCompilerProc, sfMangleCpp} == {} and + sym.flags * {sfImportc, sfExportc} != {} and sym.magic == mNone and m.config.cmd == cmdCompileToCpp) diff --git a/compiler/cgmeth.nim b/compiler/cgmeth.nim index d83ca3c55..180cfc334 100644 --- a/compiler/cgmeth.nim +++ b/compiler/cgmeth.nim @@ -48,7 +48,7 @@ proc methodCall*(n: PNode; conf: ConfigRef): PNode = if disp != nil: result.sons[0].sym = disp # change the arguments to up/downcasts to fit the dispatcher's parameters: - for i in 1 ..< sonsLen(result): + for i in 1 ..< len(result): result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true, conf) else: localError(conf, n.info, "'" & $result.sons[0] & "' lacks a dispatcher") @@ -58,10 +58,10 @@ type proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult = if a.name.id != b.name.id: return - if sonsLen(a.typ) != sonsLen(b.typ): + if len(a.typ) != len(b.typ): return - for i in 1 ..< sonsLen(a.typ): + for i in 1 ..< len(a.typ): var aa = a.typ.sons[i] var bb = b.typ.sons[i] while true: @@ -118,7 +118,7 @@ proc createDispatcher(s: PSym): PSym = disp.ast.sons[bodyPos] = newNodeI(nkEmpty, s.info) disp.loc.r = nil if s.typ.sons[0] != nil: - if disp.ast.sonsLen > resultPos: + if disp.ast.len > resultPos: disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym) else: # We've encountered a method prototype without a filled-in @@ -136,7 +136,7 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) = # from later definitions, particularly the resultPos slot. Also, # the lock level of the dispatcher needs to be updated/checked # against that of the method. - if disp.ast.sonsLen > resultPos and meth.ast.sonsLen > resultPos and + if disp.ast.len > resultPos and meth.ast.len > resultPos and disp.ast.sons[resultPos].kind == nkEmpty: disp.ast.sons[resultPos] = copyTree(meth.ast.sons[resultPos]) @@ -198,7 +198,7 @@ proc relevantCol(methods: seq[PSym], col: int): bool = return true proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int = - for col in 1 ..< sonsLen(a.typ): + for col in 1 ..< len(a.typ): if contains(relevantCols, col): var aa = skipTypes(a.typ.sons[col], skipPtrs) var bb = skipTypes(b.typ.sons[col], skipPtrs) @@ -228,7 +228,7 @@ proc sortBucket(a: var seq[PSym], relevantCols: IntSet) = proc genDispatcher(g: ModuleGraph; methods: seq[PSym], relevantCols: IntSet): PSym = var base = methods[0].ast[dispatcherPos].sym result = base - var paramLen = sonsLen(base.typ) + var paramLen = len(base.typ) var nilchecks = newNodeI(nkStmtList, base.info) var disp = newNodeI(nkIfStmt, base.info) var ands = getSysMagic(g, unknownLineInfo(), "and", mAnd) @@ -288,7 +288,7 @@ proc generateMethodDispatchers*(g: ModuleGraph): PNode = result = newNode(nkStmtList) for bucket in 0 ..< len(g.methods): var relevantCols = initIntSet() - for col in 1 ..< sonsLen(g.methods[bucket].methods[0].typ): + for col in 1 ..< len(g.methods[bucket].methods[0].typ): if relevantCol(g.methods[bucket].methods, col): incl(relevantCols, col) if optMultiMethods notin g.config.globalOptions: # if multi-methods are not enabled, we are interested only in the first field diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim index c140b5464..ed4a2857f 100644 --- a/compiler/closureiters.nim +++ b/compiler/closureiters.nim @@ -601,7 +601,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode = result.add(n) result.add(ctx.newEnvVarAccess(tmp)) - of nkCallKinds: + of nkCallKinds, nkChckRange, nkChckRangeF, nkChckRange64: var ns = false for i in 0 ..< n.len: n[i] = ctx.lowerStmtListExprs(n[i], ns) @@ -1286,7 +1286,7 @@ proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode = ctx.fn = fn if getEnvParam(fn).isNil: - # Lambda lifting was not done yet. Use temporary :state sym, which + # Lambda lifting was not done yet. Use temporary :state sym, which will # be handled specially by lambda lifting. Local temp vars (if needed) # should folllow the same logic. ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), fn, fn.info) diff --git a/compiler/depends.nim b/compiler/depends.nim index 603f67e77..15d30dd5b 100644 --- a/compiler/depends.nim +++ b/compiler/depends.nim @@ -34,14 +34,14 @@ proc addDotDependency(c: PPassContext, n: PNode): PNode = let b = Backend(g.graph.backend) case n.kind of nkImportStmt: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var imported = getModuleName(g.config, n.sons[i]) addDependencyAux(b, g.module.name.s, imported) of nkFromStmt, nkImportExceptStmt: var imported = getModuleName(g.config, n.sons[0]) addDependencyAux(b, g.module.name.s, imported) of nkStmtList, nkBlockStmt, nkStmtListExpr, nkBlockExpr: - for i in 0 ..< sonsLen(n): discard addDotDependency(c, n.sons[i]) + for i in 0 ..< len(n): discard addDotDependency(c, n.sons[i]) else: discard diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 3e2e5eac6..dc2e6ab3f 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -872,13 +872,13 @@ proc generateDoc*(d: PDoc, n, orig: PNode) = when useEffectSystem: documentRaises(d.cache, n) genItem(d, n, n.sons[namePos], skConverter) of nkTypeSection, nkVarSection, nkLetSection, nkConstSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if n.sons[i].kind != nkCommentStmt: # order is always 'type var let const': genItem(d, n.sons[i], n.sons[i].sons[0], succ(skType, ord(n.kind)-ord(nkTypeSection))) of nkStmtList: - for i in 0 ..< sonsLen(n): generateDoc(d, n.sons[i], orig) + for i in 0 ..< len(n): generateDoc(d, n.sons[i], orig) of nkWhenStmt: # generate documentation for the first branch only: if not checkForFalse(n.sons[0].sons[0]): @@ -926,13 +926,13 @@ proc generateJson*(d: PDoc, n: PNode, includeComments: bool = true) = when useEffectSystem: documentRaises(d.cache, n) d.add genJsonItem(d, n, n.sons[namePos], skConverter) of nkTypeSection, nkVarSection, nkLetSection, nkConstSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if n.sons[i].kind != nkCommentStmt: # order is always 'type var let const': d.add genJsonItem(d, n.sons[i], n.sons[i].sons[0], succ(skType, ord(n.kind)-ord(nkTypeSection))) of nkStmtList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): generateJson(d, n.sons[i], includeComments) of nkWhenStmt: # generate documentation for the first branch only: @@ -969,13 +969,13 @@ proc generateTags*(d: PDoc, n: PNode, r: var Rope) = when useEffectSystem: documentRaises(d.cache, n) r.add genTagsItem(d, n, n.sons[namePos], skConverter) of nkTypeSection, nkVarSection, nkLetSection, nkConstSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if n.sons[i].kind != nkCommentStmt: # order is always 'type var let const': r.add genTagsItem(d, n.sons[i], n.sons[i].sons[0], succ(skType, ord(n.kind)-ord(nkTypeSection))) of nkStmtList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): generateTags(d, n.sons[i], r) of nkWhenStmt: # generate documentation for the first branch only: diff --git a/compiler/evalffi.nim b/compiler/evalffi.nim index b1decbc82..5fac138ac 100644 --- a/compiler/evalffi.nim +++ b/compiler/evalffi.nim @@ -138,13 +138,13 @@ proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer) proc getField(conf: ConfigRef, n: PNode; position: int): PSym = case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = getField(conf, n.sons[i], position) if result != nil: return of nkRecCase: result = getField(conf, n.sons[0], position) if result != nil: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: result = getField(conf, lastSon(n.sons[i]), position) @@ -158,7 +158,7 @@ proc packObject(conf: ConfigRef, x: PNode, typ: PType, res: pointer) = internalAssert conf, x.kind in {nkObjConstr, nkPar, nkTupleConstr} # compute the field's offsets: discard getSize(conf, typ) - for i in ord(x.kind == nkObjConstr) ..< sonsLen(x): + for i in ord(x.kind == nkObjConstr) ..< len(x): var it = x.sons[i] if it.kind == nkExprColonExpr: internalAssert conf, it.sons[0].kind == nkSym @@ -245,7 +245,7 @@ proc unpack(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode proc unpackObjectAdd(conf: ConfigRef, x: pointer, n, result: PNode) = case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): unpackObjectAdd(conf, x, n.sons[i], result) of nkRecCase: globalError(conf, result.info, "case objects cannot be unpacked") @@ -275,7 +275,7 @@ proc unpackObject(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode = globalError(conf, n.info, "cannot map value from FFI") if typ.n.isNil: globalError(conf, n.info, "cannot unpack unnamed tuple") - for i in ord(n.kind == nkObjConstr) ..< sonsLen(n): + for i in ord(n.kind == nkObjConstr) ..< len(n): var it = n.sons[i] if it.kind == nkExprColonExpr: internalAssert conf, it.sons[0].kind == nkSym diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index d941f6c46..1fc7fd3db 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -38,7 +38,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = of nkSym: var s = templ.sym if (s.owner == nil and s.kind == skParam) or s.owner == c.owner: - if s.kind == skParam and sfGenSym notin s.flags: + if s.kind == skParam and {sfGenSym, sfTemplateParam} * s.flags == {sfTemplateParam}: handleParam actual.sons[s.position] elif (s.owner != nil) and (s.kind == skGenericParam or s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam): @@ -68,7 +68,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = # "declarative" context (bug #9235). if c.isDeclarative: var res = copyNode(c, templ, actual) - for i in 0 ..< sonsLen(templ): + for i in 0 ..< len(templ): evalTemplateAux(templ.sons[i], actual, c, res) result.add res else: @@ -82,7 +82,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) = c.isDeclarative = true isDeclarative = true var res = copyNode(c, templ, actual) - for i in 0 ..< sonsLen(templ): + for i in 0 ..< len(templ): evalTemplateAux(templ.sons[i], actual, c, res) result.add res if isDeclarative: c.isDeclarative = false diff --git a/compiler/filters.nim b/compiler/filters.nim index a2f7b6bbb..36fd25f2f 100644 --- a/compiler/filters.nim +++ b/compiler/filters.nim @@ -20,7 +20,7 @@ proc invalidPragma(conf: ConfigRef; n: PNode) = proc getArg(conf: ConfigRef; n: PNode, name: string, pos: int): PNode = result = nil if n.kind in {nkEmpty..nkNilLit}: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): if n.sons[i].kind == nkExprEqExpr: if n.sons[i].sons[0].kind != nkIdent: invalidPragma(conf, n) if cmpIgnoreStyle(n.sons[i].sons[0].ident.s, name) == 0: diff --git a/compiler/guards.nim b/compiler/guards.nim index be23c1598..52e0a1bdd 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -442,8 +442,8 @@ proc sameTree*(a, b: PNode): bool = of nkType: result = a.typ == b.typ of nkEmpty, nkNilLit: result = true else: - if sonsLen(a) == sonsLen(b): - for i in 0 ..< sonsLen(a): + if len(a) == len(b): + for i in 0 ..< len(a): if not sameTree(a.sons[i], b.sons[i]): return result = true diff --git a/compiler/importer.nim b/compiler/importer.nim index 2471f05aa..8d8034735 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -47,7 +47,7 @@ proc rawImportSymbol(c: PContext, s, origin: PSym) = if s.kind == skType: var etyp = s.typ if etyp.kind in {tyBool, tyEnum}: - for j in 0 ..< sonsLen(etyp.n): + for j in 0 ..< len(etyp.n): var e = etyp.n.sons[j].sym if e.kind != skEnumField: internalError(c.config, s.info, "rawImportSymbol") @@ -191,7 +191,7 @@ proc impMod(c: PContext; it: PNode; importStmtResult: PNode) = proc evalImport*(c: PContext, n: PNode): PNode = result = newNodeI(nkImportStmt, n.info) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): let it = n.sons[i] if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket: let sep = it[0] @@ -221,7 +221,7 @@ proc evalFrom*(c: PContext, n: PNode): PNode = if m != nil: n.sons[0] = newSymNode(m) addDecl(c, m, n.info) # add symbol to symbol table of module - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): if n.sons[i].kind != nkNilLit: importSymbol(c, n.sons[i], m) diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index cd5fc2f11..7c2a15ce3 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -138,6 +138,9 @@ import strutils, options, dfa, lowerings, tables, modulegraphs, msgs, lineinfos, parampatterns, sighashes +const + InterestingSyms = {skVar, skResult, skLet, skForVar, skTemp} + type Con = object owner: PSym @@ -214,6 +217,43 @@ proc isLastRead(n: PNode; c: var Con): bool = dbg: echo "ugh ", c.otherRead.isNil, " ", result + when false: + let s = n.sym + var pcs: seq[int] = @[instr+1] + var takenGotos: IntSet + var takenForks = initIntSet() + while pcs.len > 0: + var pc = pcs.pop + + takenGotos = initIntSet() + while pc < c.g.len: + case c.g[pc].kind + of def: + if c.g[pc].sym == s: + # the path lead to a redefinition of 's' --> abandon it. + break + inc pc + of use: + if c.g[pc].sym == s: + c.otherRead = c.g[pc].n + return false + inc pc + of goto: + # we must leave endless loops eventually: + if not takenGotos.containsOrIncl(pc): + pc = pc + c.g[pc].dest + else: + inc pc + of fork: + # we follow the next instruction but push the dest onto our "work" stack: + if not takenForks.containsOrIncl(pc): + pcs.add pc + c.g[pc].dest + inc pc + of InstrKind.join: + inc pc + #echo c.graph.config $ n.info, " last read here!" + return true + proc initialized(code: ControlFlowGraph; pc: int, init, uninit: var IntSet; comesFrom: int): int = ## Computes the set of definitely initialized variables accross all code paths @@ -250,6 +290,9 @@ proc initialized(code: ControlFlowGraph; pc: int, inc pc return pc +template interestingSym(s: PSym): bool = + s.owner == c.owner and s.kind in InterestingSyms and hasDestructor(s.typ) + template isUnpackedTuple(s: PSym): bool = ## we move out all elements of unpacked tuples, ## hence unpacked tuples themselves don't need to be destroyed @@ -310,8 +353,8 @@ proc canBeMoved(t: PType): bool {.inline.} = let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) result = t.kind != tyRef and t.attachedOps[attachedSink] != nil -proc genSink(c: Con; dest, ri: PNode): PNode = - let t = dest.typ.skipTypes({tyGenericInst, tyAlias, tySink}) +proc genSink(c: Con; t: PType; dest, ri: PNode): PNode = + let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) let k = if t.attachedOps[attachedSink] != nil: attachedSink else: attachedAsgn if t.attachedOps[k] != nil: @@ -322,20 +365,20 @@ proc genSink(c: Con; dest, ri: PNode): PNode = # we generate a fast assignment in this case: result = newTree(nkFastAsgn, dest) -proc genCopyNoCheck(c: Con; dest, ri: PNode): PNode = - let t = dest.typ.skipTypes({tyGenericInst, tyAlias, tySink}) - result = genOp(c, t, attachedAsgn, dest, ri) - -proc genCopy(c: var Con; dest, ri: PNode): PNode = - let t = dest.typ +proc genCopy(c: var Con; t: PType; dest, ri: PNode): PNode = if tfHasOwned in t.flags: # try to improve the error message here: if c.otherRead == nil: discard isLastRead(ri, c) checkForErrorPragma(c, t, ri, "=") - genCopyNoCheck(c, dest, ri) + let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) + result = genOp(c, t, attachedAsgn, dest, ri) + +proc genCopyNoCheck(c: Con; t: PType; dest, ri: PNode): PNode = + let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) + result = genOp(c, t, attachedAsgn, dest, ri) -proc genDestroy(c: Con; dest: PNode): PNode = - let t = dest.typ.skipTypes({tyGenericInst, tyAlias, tySink}) +proc genDestroy(c: Con; t: PType; dest: PNode): PNode = + let t = t.skipTypes({tyGenericInst, tyAlias, tySink}) result = genOp(c, t, attachedDestructor, dest, nil) proc addTopVar(c: var Con; v: PNode) = @@ -347,10 +390,20 @@ proc getTemp(c: var Con; typ: PType; info: TLineInfo): PNode = result = newSymNode(sym) c.addTopVar(result) -proc genWasMoved(n: PNode; c: var Con): PNode = +proc p(n: PNode; c: var Con): PNode + +template recurse(n, dest) = + for i in 0..<n.len: + dest.add p(n[i], c) + +proc genMagicCall(n: PNode; c: var Con; magicname: string; m: TMagic): PNode = result = newNodeI(nkCall, n.info) - result.add(newSymNode(createMagic(c.graph, "wasMoved", mWasMoved))) - result.add n #mWasMoved does not take the address + result.add(newSymNode(createMagic(c.graph, magicname, m))) + result.add n + +proc genWasMoved(n: PNode; c: var Con): PNode = + # The mWasMoved builtin does not take the address. + result = genMagicCall(n, c, "wasMoved", mWasMoved) proc genDefaultCall(t: PType; c: Con; info: TLineInfo): PNode = result = newNodeI(nkCall, info) @@ -369,9 +422,9 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode = let tempAsNode = newSymNode(temp) var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3) - vpart[0] = tempAsNode - vpart[1] = c.emptyNode - vpart[2] = n + vpart.sons[0] = tempAsNode + vpart.sons[1] = c.emptyNode + vpart.sons[2] = n add(v, vpart) result.add v @@ -384,144 +437,6 @@ proc sinkParamIsLastReadCheck(c: var Con, s: PNode) = localError(c.graph.config, c.otherRead.info, "sink parameter `" & $s.sym.name.s & "` is already consumed at " & toFileLineCol(c. graph.config, s.info)) -proc isDangerousSeq(t: PType): bool {.inline.} = - let t = t.skipTypes(abstractInst) - result = t.kind == tySequence and tfHasOwned notin t[0].flags - -proc containsConstSeq(n: PNode): bool = - if n.kind == nkBracket and n.len > 0 and n.typ != nil and isDangerousSeq(n.typ): - return true - result = false - case n.kind - of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv: - result = containsConstSeq(n[1]) - of nkObjConstr, nkClosure: - for i in 1..<n.len: - if containsConstSeq(n[i]): return true - of nkCurly, nkBracket, nkPar, nkTupleConstr: - for son in n: - if containsConstSeq(son): return true - else: discard - -proc pExpr(n: PNode; c: var Con): PNode -proc pArg(arg: PNode; c: var Con; isSink: bool): PNode -proc pStmt(n: PNode; c: var Con): PNode -proc moveOrCopy(dest, ri: PNode; c: var Con): PNode - -template isExpression(n: PNode): bool = - (not isEmptyType(n.typ)) or (n.kind in nkLiterals + {nkNilLit, nkRange}) - -proc recurse(n: PNode, c: var Con, processProc: proc): PNode = - if n.sons.len == 0: return n - case n.kind: - of nkIfStmt, nkIfExpr: - result = copyNode(n) - for son in n: - var branch = copyNode(son) - if son.kind in {nkElifBranch, nkElifExpr}: - if son[0].kind == nkBreakState: - var copy = copyNode(son[0]) - copy.add pExpr(son[0][0], c) - branch.add copy - else: - branch.add pExpr(son[0], c) #The condition - branch.add processProc(son[1], c) - else: - branch.add processProc(son[0], c) - result.add branch - of nkWhen: - # This should be a "when nimvm" node. - result = copyTree(n) - result[1][0] = processProc(result[1][0], c) - of nkStmtList, nkStmtListExpr, nkTryStmt, nkFinally, nkPragmaBlock: - result = copyNode(n) - for i in 0..<n.len-1: - result.add pStmt(n[i], c) - result.add processProc(n[^1], c) - of nkBlockStmt, nkBlockExpr: - result = copyNode(n) - result.add n[0] - result.add processProc(n[1], c) - of nkExceptBranch: - result = copyNode(n) - if n.len == 2: - result.add n[0] - for i in 1..<n.len: - result.add processProc(n[i], c) - else: - for i in 0..<n.len: - result.add processProc(n[i], c) - of nkCaseStmt: - result = copyNode(n) - result.add pExpr(n[0], c) - for i in 1..<n.len: - var branch: PNode - if n[i].kind == nkOfBranch: - branch = n[i] # of branch conditions are constants - branch[^1] = processProc(n[i][^1], c) - elif n[i].kind in {nkElifBranch, nkElifExpr}: - branch = copyNode(n[i]) - branch.add pExpr(n[i][0], c) #The condition - branch.add processProc(n[i][1], c) - else: - branch = copyNode(n[i]) - if n[i][0].kind == nkNilLit: #XXX: Fix semCase to instead gen nkEmpty for cases that are never reached instead - branch.add c.emptyNode - else: - branch.add processProc(n[i][0], c) - result.add branch - else: - assert(false, $n.kind) - -proc pExpr(n: PNode; c: var Con): PNode = - assert(isExpression(n), $n.kind) - case n.kind - of nkCallKinds: - let parameters = n[0].typ - let L = if parameters != nil: parameters.len else: 0 - for i in 1..<n.len: - n[i] = pArg(n[i], c, i < L and isSinkTypeForParam(parameters[i])) - result = n - of nkBracket: - result = copyTree(n) - for i in 0..<n.len: - # everything that is passed to an array constructor is consumed, - # so these all act like 'sink' parameters: - result[i] = pArg(n[i], c, isSink = true) - of nkObjConstr: - result = copyTree(n) - for i in 1..<n.len: - # everything that is passed to an object constructor is consumed, - # so these all act like 'sink' parameters: - result[i][1] = pArg(n[i][1], c, isSink = true) - of nkTupleConstr, nkClosure: - result = copyTree(n) - for i in ord(n.kind == nkClosure)..<n.len: - # everything that is passed to an tuple constructor is consumed, - # so these all act like 'sink' parameters: - if n[i].kind == nkExprColonExpr: - result[i][1] = pArg(n[i][1], c, isSink = true) - else: - result[i] = pArg(n[i], c, isSink = true) - of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv: - result = copyNode(n) - result.add n[0] #Destination type - result.add pExpr(n[1], c) #Analyse inner expression - of nkBracketExpr, nkCurly, nkRange, nkChckRange, nkChckRange64, nkChckRangeF, - nkObjDownConv, nkObjUpConv, nkStringToCString, nkCStringToString, - nkDotExpr, nkCheckedFieldExpr: - result = copyNode(n) - for son in n: - result.add pExpr(son, c) - of nkAddr, nkHiddenAddr, nkDerefExpr, nkHiddenDeref: - result = copyNode(n) - result.add pExpr(n[0], c) - of nkNone..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, - nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef: - result = n - else: - result = recurse(n, c, pExpr) - proc passCopyToSink(n: PNode; c: var Con): PNode = result = newNodeIT(nkStmtListExpr, n.info, n.typ) let tmp = getTemp(c, n.typ, n.info) @@ -529,18 +444,42 @@ proc passCopyToSink(n: PNode; c: var Con): PNode = # out of loops we need to mark it as 'wasMoved'. result.add genWasMoved(tmp, c) if hasDestructor(n.typ): - var m = genCopy(c, tmp, n) - m.add pExpr(n, c) + var m = genCopy(c, n.typ, tmp, n) + m.add p(n, c) result.add m if isLValue(n): message(c.graph.config, n.info, hintPerformance, ("passing '$1' to a sink parameter introduces an implicit copy; " & "use 'move($1)' to prevent it") % $n) else: - result.add newTree(nkAsgn, tmp, pExpr(n, c)) + result.add newTree(nkAsgn, tmp, p(n, c)) result.add tmp +proc isDangerousSeq(t: PType): bool {.inline.} = + let t = t.skipTypes(abstractInst) + result = t.kind == tySequence and tfHasOwned notin t.sons[0].flags + +proc containsConstSeq(n: PNode): bool = + if n.kind == nkBracket and n.len > 0 and n.typ != nil and isDangerousSeq(n.typ): + return true + result = false + case n.kind + of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv: + result = containsConstSeq(n[1]) + of nkObjConstr, nkClosure: + for i in 1 ..< n.len: + if containsConstSeq(n[i]): return true + of nkCurly, nkBracket, nkPar, nkTupleConstr: + for i in 0 ..< n.len: + if containsConstSeq(n[i]): return true + else: discard + proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = + template pArgIfTyped(argPart: PNode): PNode = + # typ is nil if we are in if/case expr branch with noreturn + if argPart.typ == nil: p(argPart, c) + else: pArg(argPart, c, isSink) + if isSink: if arg.kind in nkCallKinds: # recurse but skip the call expression in order to prevent @@ -556,8 +495,8 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = # sink parameter (bug #11524). Note that the string implemenation is # different and can deal with 'const string sunk into var'. result = passCopyToSink(arg, c) - elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr} + nkLiterals: - # object construction to sink parameter: nothing to do + elif arg.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkCharLit..nkTripleStrLit}: + discard "object construction to sink parameter: nothing to do" result = arg elif arg.kind == nkSym and isSinkParam(arg.sym): # Sinked params can be consumed only once. We need to reset the memory @@ -568,218 +507,203 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode = # it is the last read, can be sinked. We need to reset the memory # to disable the destructor which we have not elided result = destructiveMoveVar(arg, c) - elif arg.kind in {nkStmtListExpr, nkBlockExpr, nkBlockStmt}: - result = recurse(arg, c, proc(n: PNode, c: var Con): PNode = pArg(n, c, isSink)) - elif arg.kind in {nkIfExpr, nkIfStmt, nkCaseStmt}: - result = recurse(arg, c, proc(n: PNode, c: var Con): PNode = - if n.typ == nil: pStmt(n, c) #in if/case expr branch with noreturn - else: pArg(n, c, isSink)) + elif arg.kind in {nkBlockExpr, nkBlockStmt}: + result = copyNode(arg) + result.add arg[0] + result.add pArg(arg[1], c, isSink) + elif arg.kind == nkStmtListExpr: + result = copyNode(arg) + for i in 0..arg.len-2: + result.add p(arg[i], c) + result.add pArg(arg[^1], c, isSink) + elif arg.kind in {nkIfExpr, nkIfStmt}: + result = copyNode(arg) + for i in 0..<arg.len: + var branch = copyNode(arg[i]) + if arg[i].kind in {nkElifBranch, nkElifExpr}: + branch.add p(arg[i][0], c) + branch.add pArgIfTyped(arg[i][1]) + else: + branch.add pArgIfTyped(arg[i][0]) + result.add branch + elif arg.kind == nkCaseStmt: + result = copyNode(arg) + result.add p(arg[0], c) + for i in 1..<arg.len: + var branch: PNode + if arg[i].kind == nkOfBranch: + branch = arg[i] # of branch conditions are constants + branch[^1] = pArgIfTyped(arg[i][^1]) + elif arg[i].kind in {nkElifBranch, nkElifExpr}: + branch = copyNode(arg[i]) + branch.add p(arg[i][0], c) + branch.add pArgIfTyped(arg[i][1]) + else: + branch = copyNode(arg[i]) + branch.add pArgIfTyped(arg[i][0]) + result.add branch else: # an object that is not temporary but passed to a 'sink' parameter # results in a copy. result = passCopyToSink(arg, c) - elif arg.kind == nkBracket: - # Treat `f([...])` like `f(...)` - result = copyNode(arg) - for son in arg: - result.add pArg(son, c, isSinkTypeForParam(son.typ)) - elif arg.kind in nkCallKinds and arg.typ != nil and hasDestructor(arg.typ): - # produce temp creation - result = newNodeIT(nkStmtListExpr, arg.info, arg.typ) - let tmp = getTemp(c, arg.typ, arg.info) - let res = pExpr(arg, c) - var sinkExpr = genSink(c, tmp, res) - sinkExpr.add res - result.add sinkExpr - result.add tmp - c.destroys.add genDestroy(c, tmp) - else: - result = pExpr(arg, c) - -proc isCursor(n: PNode): bool {.inline.} = - result = n.kind == nkSym and sfCursor in n.sym.flags - -proc keepVar(n, it: PNode, c: var Con): PNode = - # keep the var but transform 'ri': - result = copyNode(n) - var itCopy = copyNode(it) - for j in 0..<it.len-1: - itCopy.add it[j] - if isExpression(it[^1]): - itCopy.add pExpr(it[^1], c) - else: - itCopy.add pStmt(it[^1], c) - result.add itCopy - -proc pStmt(n: PNode; c: var Con): PNode = - #assert(not isExpression(n) or implicitlyDiscardable(n), $n.kind) - case n.kind - of nkVarSection, nkLetSection: - # transform; var x = y to var x; x op y where op is a move or copy - result = newNodeI(nkStmtList, n.info) - for it in n: - var ri = it[^1] - if it.kind == nkVarTuple and hasDestructor(ri.typ): - let x = lowerTupleUnpacking(c.graph, it, c.owner) - result.add pStmt(x, c) - elif it.kind == nkIdentDefs and hasDestructor(it[0].typ) and not isCursor(it[0]): - for j in 0..<it.len-2: - let v = it[j] - if v.kind == nkSym: - if sfCompileTime in v.sym.flags: continue - # move the variable declaration to the top of the frame: - c.addTopVar v - # make sure it's destroyed at the end of the proc: - if not isUnpackedTuple(it[0].sym): - c.destroys.add genDestroy(c, v) - if ri.kind == nkEmpty and c.inLoop > 0: - ri = genDefaultCall(v.typ, c, v.info) - if ri.kind != nkEmpty: - let r = moveOrCopy(v, ri, c) - result.add r - else: - result.add keepVar(n, it, c) - of nkCallKinds: - let parameters = n[0].typ - let L = if parameters != nil: parameters.len else: 0 - for i in 1..<n.len: - n[i] = pArg(n[i], c, i < L and isSinkTypeForParam(parameters[i])) - result = n - of nkDiscardStmt: - if n[0].kind != nkEmpty: - n[0] = pArg(n[0], c, false) - result = n - of nkReturnStmt: - result = copyNode(n) - result.add pStmt(n[0], c) - of nkYieldStmt: - result = copyNode(n) - result.add pExpr(n[0], c) - of nkAsgn, nkFastAsgn: - if hasDestructor(n[0].typ) and n[1].kind notin {nkProcDef, nkDo, nkLambda}: - # rule (self-assignment-removal): - if n[1].kind == nkSym and n[0].kind == nkSym and n[0].sym == n[1].sym: - result = newNodeI(nkEmpty, n.info) - else: - result = moveOrCopy(n[0], n[1], c) - else: - result = copyNode(n) - result.add n[0] - result.add pExpr(n[1], c) - of nkRaiseStmt: - if optNimV2 in c.graph.config.globalOptions and n[0].kind != nkEmpty: - if n[0].kind in nkCallKinds: - let call = pExpr(n[0], c) #pExpr? - result = copyNode(n) - result.add call - else: - let tmp = getTemp(c, n[0].typ, n.info) - var m = genCopyNoCheck(c, tmp, n[0]) - - m.add pExpr(n[0], c) - result = newTree(nkStmtList, genWasMoved(tmp, c), m) - var toDisarm = n[0] - if toDisarm.kind == nkStmtListExpr: toDisarm = toDisarm.lastSon - if toDisarm.kind == nkSym and toDisarm.sym.owner == c.owner: - result.add genWasMoved(toDisarm, c) - result.add newTree(nkRaiseStmt, tmp) - else: - result = copyNode(n) - result.add if n[0].kind == nkEmpty: n[0] - else: pExpr(n[0], c) - of nkNone..nkType, nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, - nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef, - nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt, nkExportStmt, - nkPragma, nkCommentStmt, nkBreakStmt: - result = n - # Recurse - of nkWhileStmt: - result = copyNode(n) - inc c.inLoop - result.add pExpr(n[0], c) - result.add pStmt(n[1], c) - dec c.inLoop else: - result = recurse(n, c, pStmt) + result = p(arg, c) proc moveOrCopy(dest, ri: PNode; c: var Con): PNode = - assert(isExpression(ri), $ri.kind) # unfortunately, this needs to be kept consistent with the cases # we handle in the 'case of' statement below: const movableNodeKinds = (nkCallKinds + {nkSym, nkTupleConstr, nkObjConstr, nkBracket, nkBracketExpr, nkNilLit}) - #XXX: All these nkStmtList results will cause problems in recursive moveOrCopy calls + template moveOrCopyIfTyped(riPart: PNode): PNode = + # typ is nil if we are in if/case expr branch with noreturn + if riPart.typ == nil: p(riPart, c) + else: moveOrCopy(dest, riPart, c) + case ri.kind of nkCallKinds: - result = genSink(c, dest, ri) - result.add pExpr(ri, c) + result = genSink(c, dest.typ, dest, ri) + # watch out and no not transform 'ri' twice if it's a call: + let ri2 = copyNode(ri) + let parameters = ri[0].typ + let L = if parameters != nil: parameters.len else: 0 + ri2.add ri[0] + for i in 1..<ri.len: + ri2.add pArg(ri[i], c, i < L and isSinkTypeForParam(parameters[i])) + #recurse(ri, ri2) + result.add ri2 of nkBracketExpr: if ri[0].kind == nkSym and isUnpackedTuple(ri[0].sym): # unpacking of tuple: move out the elements - result = genSink(c, dest, ri) - result.add pExpr(ri, c) + result = genSink(c, dest.typ, dest, ri) + result.add p(ri, c) elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c): # Rule 3: `=sink`(x, z); wasMoved(z) - var snk = genSink(c, dest, ri) + var snk = genSink(c, dest.typ, dest, ri) snk.add ri result = newTree(nkStmtList, snk, genWasMoved(ri, c)) else: - result = genCopy(c, dest, ri) - result.add pExpr(ri, c) + result = genCopy(c, dest.typ, dest, ri) + result.add p(ri, c) + of nkStmtListExpr: + result = newNodeI(nkStmtList, ri.info) + for i in 0..ri.len-2: + result.add p(ri[i], c) + result.add moveOrCopy(dest, ri[^1], c) + of nkBlockExpr, nkBlockStmt: + result = newNodeI(nkBlockStmt, ri.info) + result.add ri[0] ## add label + result.add moveOrCopy(dest, ri[1], c) + of nkIfExpr, nkIfStmt: + result = newNodeI(nkIfStmt, ri.info) + for i in 0..<ri.len: + var branch = copyNode(ri[i]) + if ri[i].kind in {nkElifBranch, nkElifExpr}: + branch.add p(ri[i][0], c) + branch.add moveOrCopyIfTyped(ri[i][1]) + else: + branch.add moveOrCopyIfTyped(ri[i][0]) + result.add branch + of nkCaseStmt: + result = newNodeI(nkCaseStmt, ri.info) + result.add p(ri[0], c) + for i in 1..<ri.len: + var branch: PNode + if ri[i].kind == nkOfBranch: + branch = ri[i] # of branch conditions are constants + branch[^1] = moveOrCopyIfTyped(ri[i][^1]) + elif ri[i].kind in {nkElifBranch, nkElifExpr}: + branch = copyNode(ri[i]) + branch.add p(ri[i][0], c) + branch.add moveOrCopyIfTyped(ri[i][1]) + else: + branch = copyNode(ri[i]) + branch.add moveOrCopyIfTyped(ri[i][0]) + result.add branch of nkBracket: # array constructor if ri.len > 0 and isDangerousSeq(ri.typ): - result = genCopy(c, dest, ri) + result = genCopy(c, dest.typ, dest, ri) else: - result = genSink(c, dest, ri) - result.add pExpr(ri, c) - of nkObjConstr, nkTupleConstr, nkClosure, nkCharLit..nkNilLit: - result = genSink(c, dest, ri) - result.add pExpr(ri, c) + result = genSink(c, dest.typ, dest, ri) + let ri2 = copyTree(ri) + for i in 0..<ri.len: + # everything that is passed to an array constructor is consumed, + # so these all act like 'sink' parameters: + ri2[i] = pArg(ri[i], c, isSink = true) + result.add ri2 + of nkObjConstr: + result = genSink(c, dest.typ, dest, ri) + let ri2 = copyTree(ri) + for i in 1..<ri.len: + # everything that is passed to an object constructor is consumed, + # so these all act like 'sink' parameters: + ri2[i].sons[1] = pArg(ri[i][1], c, isSink = true) + result.add ri2 + of nkTupleConstr, nkClosure: + result = genSink(c, dest.typ, dest, ri) + let ri2 = copyTree(ri) + for i in ord(ri.kind == nkClosure)..<ri.len: + # everything that is passed to an tuple constructor is consumed, + # so these all act like 'sink' parameters: + if ri[i].kind == nkExprColonExpr: + ri2[i].sons[1] = pArg(ri[i][1], c, isSink = true) + else: + ri2[i] = pArg(ri[i], c, isSink = true) + result.add ri2 + of nkNilLit: + result = genSink(c, dest.typ, dest, ri) + result.add ri of nkSym: if isSinkParam(ri.sym): # Rule 3: `=sink`(x, z); wasMoved(z) sinkParamIsLastReadCheck(c, ri) - var snk = genSink(c, dest, ri) + var snk = genSink(c, dest.typ, dest, ri) snk.add ri result = newTree(nkStmtList, snk, genWasMoved(ri, c)) elif ri.sym.kind != skParam and ri.sym.owner == c.owner and isLastRead(ri, c) and canBeMoved(dest.typ): # Rule 3: `=sink`(x, z); wasMoved(z) - var snk = genSink(c, dest, ri) + var snk = genSink(c, dest.typ, dest, ri) snk.add ri result = newTree(nkStmtList, snk, genWasMoved(ri, c)) else: - result = genCopy(c, dest, ri) - result.add pExpr(ri, c) - of nkHiddenSubConv, nkHiddenStdConv, nkConv: - result = moveOrCopy(dest, ri[1], c) - if not sameType(ri.typ, ri[1].typ): - let copyRi = copyTree(ri) - copyRi[1] = result[^1] - result[^1] = copyRi + result = genCopy(c, dest.typ, dest, ri) + result.add p(ri, c) + of nkHiddenSubConv, nkHiddenStdConv: + if sameType(ri.typ, ri[1].typ): + result = moveOrCopy(dest, ri[1], c) + elif ri[1].kind in movableNodeKinds: + result = moveOrCopy(dest, ri[1], c) + var b = newNodeIT(ri.kind, ri.info, ri.typ) + b.add ri[0] # add empty node + let L = result.len-1 + b.add result[L] + result[L] = b + else: + result = genCopy(c, dest.typ, dest, ri) + result.add p(ri, c) of nkObjDownConv, nkObjUpConv: - result = moveOrCopy(dest, ri[0], c) - let copyRi = copyTree(ri) - copyRi[0] = result[^1] - result[^1] = copyRi - of nkStmtListExpr, nkBlockExpr: - result = recurse(ri, c, proc(n: PNode, c: var Con): PNode = moveOrCopy(dest, n, c)) - of nkIfExpr, nkCaseStmt: - result = recurse(ri, c, proc(n: PNode, c: var Con): PNode = - if n.typ == nil: pStmt(n, c) #in if/case expr branch with noreturn - else: moveOrCopy(dest, n, c)) + if ri[0].kind in movableNodeKinds: + result = moveOrCopy(dest, ri[0], c) + var b = newNodeIT(ri.kind, ri.info, ri.typ) + let L = result.len-1 + b.add result[L] + result[L] = b + else: + result = genCopy(c, dest.typ, dest, ri) + result.add p(ri, c) else: if isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c) and canBeMoved(dest.typ): # Rule 3: `=sink`(x, z); wasMoved(z) - var snk = genSink(c, dest, ri) + var snk = genSink(c, dest.typ, dest, ri) snk.add ri result = newTree(nkStmtList, snk, genWasMoved(ri, c)) else: - result = genCopy(c, dest, ri) - result.add pExpr(ri, c) + # XXX At least string literals can be moved? + result = genCopy(c, dest.typ, dest, ri) + result.add p(ri, c) proc computeUninit(c: var Con) = if not c.uninitComputed: @@ -791,14 +715,17 @@ proc computeUninit(c: var Con) = proc injectDefaultCalls(n: PNode, c: var Con) = case n.kind of nkVarSection, nkLetSection: - for it in n: - if it.kind == nkIdentDefs and it[^1].kind == nkEmpty: + for i in 0..<n.len: + let it = n[i] + let L = it.len-1 + let ri = it[L] + if it.kind == nkIdentDefs and ri.kind == nkEmpty: computeUninit(c) - for j in 0..<it.len-2: + for j in 0..L-2: let v = it[j] doAssert v.kind == nkSym if c.uninit.contains(v.sym.id): - it[^1] = genDefaultCall(v.sym.typ, c, v.info) + it[L] = genDefaultCall(v.sym.typ, c, v.info) break of nkNone..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef: @@ -807,16 +734,130 @@ proc injectDefaultCalls(n: PNode, c: var Con) = for i in 0..<safeLen(n): injectDefaultCalls(n[i], c) +proc isCursor(n: PNode): bool {.inline.} = + result = n.kind == nkSym and sfCursor in n.sym.flags + +proc keepVar(n, it: PNode, c: var Con): PNode = + # keep the var but transform 'ri': + result = copyNode(n) + var itCopy = copyNode(it) + for j in 0..it.len-2: + itCopy.add it[j] + itCopy.add p(it[it.len-1], c) + result.add itCopy + +proc p(n: PNode; c: var Con): PNode = + case n.kind + of nkVarSection, nkLetSection: + discard "transform; var x = y to var x; x op y where op is a move or copy" + result = newNodeI(nkStmtList, n.info) + + for i in 0..<n.len: + let it = n[i] + let L = it.len + var ri = it[L-1] + if it.kind == nkVarTuple and hasDestructor(ri.typ): + let x = lowerTupleUnpacking(c.graph, it, c.owner) + result.add p(x, c) + elif it.kind == nkIdentDefs and hasDestructor(it[0].typ) and not isCursor(it[0]): + for j in 0..L-3: + let v = it[j] + if v.kind == nkSym: + if sfCompileTime in v.sym.flags: continue + # move the variable declaration to the top of the frame: + c.addTopVar v + # make sure it's destroyed at the end of the proc: + if not isUnpackedTuple(it[0].sym): + c.destroys.add genDestroy(c, v.typ, v) + if ri.kind == nkEmpty and c.inLoop > 0: + ri = genDefaultCall(v.typ, c, v.info) + if ri.kind != nkEmpty: + let r = moveOrCopy(v, ri, c) + result.add r + else: + result.add keepVar(n, it, c) + of nkCallKinds: + let parameters = n[0].typ + let L = if parameters != nil: parameters.len else: 0 + for i in 1 ..< n.len: + n.sons[i] = pArg(n[i], c, i < L and isSinkTypeForParam(parameters[i])) + if n.typ != nil and hasDestructor(n.typ): + discard "produce temp creation" + result = newNodeIT(nkStmtListExpr, n.info, n.typ) + let tmp = getTemp(c, n.typ, n.info) + var sinkExpr = genSink(c, n.typ, tmp, n) + sinkExpr.add n + result.add sinkExpr + result.add tmp + c.destroys.add genDestroy(c, n.typ, tmp) + else: + result = n + of nkAsgn, nkFastAsgn: + if hasDestructor(n[0].typ) and n[1].kind notin {nkProcDef, nkDo, nkLambda}: + # rule (self-assignment-removal): + if n[1].kind == nkSym and n[0].kind == nkSym and n[0].sym == n[1].sym: + result = newNodeI(nkEmpty, n.info) + else: + result = moveOrCopy(n[0], n[1], c) + else: + result = copyNode(n) + recurse(n, result) + of nkNone..nkNilLit, nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, + nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef: + result = n + of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv: + result = copyNode(n) + # Destination type + result.add n[0] + # Analyse the inner expression + result.add p(n[1], c) + of nkWhen: + # This should be a "when nimvm" node. + result = copyTree(n) + result[1][0] = p(result[1][0], c) + of nkRaiseStmt: + if optNimV2 in c.graph.config.globalOptions and n[0].kind != nkEmpty: + if n[0].kind in nkCallKinds: + let call = copyNode(n[0]) + recurse(n[0], call) + result = copyNode(n) + result.add call + else: + let t = n[0].typ + let tmp = getTemp(c, t, n.info) + var m = genCopyNoCheck(c, t, tmp, n[0]) + + m.add p(n[0], c) + result = newTree(nkStmtList, genWasMoved(tmp, c), m) + var toDisarm = n[0] + if toDisarm.kind == nkStmtListExpr: toDisarm = toDisarm.lastSon + if toDisarm.kind == nkSym and toDisarm.sym.owner == c.owner: + result.add genWasMoved(toDisarm, c) + result.add newTree(nkRaiseStmt, tmp) + else: + result = copyNode(n) + recurse(n, result) + of nkForStmt, nkParForStmt, nkWhileStmt: + inc c.inLoop + result = copyNode(n) + recurse(n, result) + dec c.inLoop + else: + result = copyNode(n) + recurse(n, result) + proc extractDestroysForTemporaries(c: Con, destroys: PNode): PNode = result = newNodeI(nkStmtList, destroys.info) - for i in 0..<destroys.len: + for i in 0 ..< destroys.len: if destroys[i][1][0].sym.kind == skTemp: result.add destroys[i] destroys[i] = c.emptyNode -proc reverseDestroys(destroys: seq[PNode]): seq[PNode] = +proc reverseDestroys(destroys: PNode) = + var reversed: seq[PNode] for i in countdown(destroys.len - 1, 0): - result.add destroys[i] + reversed.add(destroys[i]) + destroys.sons = reversed proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = if sfGeneratedOp in owner.flags or isInlineIterator(owner): return n @@ -833,24 +874,23 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = if c.g[i].kind in {goto, fork}: c.jumpTargets.incl(i+c.g[i].dest) dbg: - echo "\n### ", owner.name.s, ":\nCFG:" + echo "injecting into ", n echoCfg(c.g) - echo n if owner.kind in {skProc, skFunc, skMethod, skIterator, skConverter}: let params = owner.typ.n - for i in 1..<params.len: - let t = params[i].sym.typ - if isSinkTypeForParam(t) and hasDestructor(t.skipTypes({tySink})): - c.destroys.add genDestroy(c, params[i]) + for i in 1 ..< params.len: + let param = params[i].sym + if isSinkTypeForParam(param.typ) and hasDestructor(param.typ.skipTypes({tySink})): + c.destroys.add genDestroy(c, param.typ.skipTypes({tyGenericInst, tyAlias, tySink}), params[i]) #if optNimV2 in c.graph.config.globalOptions: # injectDefaultCalls(n, c) - let body = pStmt(n, c) + let body = p(n, c) result = newNodeI(nkStmtList, n.info) if c.topLevelVars.len > 0: result.add c.topLevelVars if c.destroys.len > 0: - c.destroys.sons = reverseDestroys(c.destroys.sons) + reverseDestroys(c.destroys) if owner.kind == skModule: result.add newTryFinally(body, extractDestroysForTemporaries(c, c.destroys)) g.globalDestructors.add c.destroys @@ -860,5 +900,6 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = result.add body dbg: - echo ">---------transformed-to--------->" + echo "------------------------------------" + echo owner.name.s, " transformed to: " echo result diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 78373ea47..9e32805ed 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -528,7 +528,7 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = xLoc,yLoc: Rope let i = ord(optOverflowCheck notin p.options) useMagic(p, jsMagics[op][i]) - if sonsLen(n) > 2: + if len(n) > 2: gen(p, n.sons[1], x) gen(p, n.sons[2], y) xLoc = x.rdLoc @@ -713,7 +713,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = r.res = getTemp(p) inc(p.unique) var i = 1 - var length = sonsLen(n) + var length = len(n) var catchBranchesExist = length > 1 and n.sons[i].kind == nkExceptBranch if catchBranchesExist: add(p.body, "++excHandler;\L") @@ -731,7 +731,7 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) = " lastJSError = EXC;$n --excHandler;$n", []) line(p, "framePtr = $1;$n" % [tmpFramePtr]) while i < length and n.sons[i].kind == nkExceptBranch: - let blen = sonsLen(n.sons[i]) + let blen = len(n.sons[i]) if blen == 1: # general except section: generalCatchBranchExists = true @@ -822,11 +822,11 @@ proc genCaseJS(p: PProc, n: PNode, r: var TCompRes) = if not isEmptyType(n.typ): r.kind = resVal r.res = getTemp(p) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): let it = n.sons[i] case it.kind of nkOfBranch: - for j in 0 .. sonsLen(it) - 2: + for j in 0 .. len(it) - 2: let e = it.sons[j] if e.kind == nkRange: var v = copyNode(e.sons[0]) @@ -894,7 +894,7 @@ proc genBreakStmt(p: PProc, n: PNode) = proc genAsmOrEmitStmt(p: PProc, n: PNode) = genLineDir(p, n) p.body.add p.indentLine(nil) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): let it = n[i] case it.kind of nkStrLit..nkTripleStrLit: @@ -932,9 +932,9 @@ proc genIf(p: PProc, n: PNode, r: var TCompRes) = if not isEmptyType(n.typ): r.kind = resVal r.res = getTemp(p) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): let it = n.sons[i] - if sonsLen(it) != 1: + if len(it) != 1: if i > 0: lineF(p, "else {$n", []) inc(toClose) @@ -951,7 +951,7 @@ proc genIf(p: PProc, n: PNode, r: var TCompRes) = proc generateHeader(p: PProc, typ: PType): Rope = result = nil - for i in 1 ..< sonsLen(typ.n): + for i in 1 ..< len(typ.n): assert(typ.n.sons[i].kind == nkSym) var param = typ.n.sons[i].sym if isCompileTimeOnly(param.typ): continue @@ -964,7 +964,7 @@ proc generateHeader(p: PProc, typ: PType): Rope = add(result, "_Idx") proc countJsParams(typ: PType): int = - for i in 1 ..< sonsLen(typ.n): + for i in 1 ..< len(typ.n): assert(typ.n.sons[i].kind == nkSym) var param = typ.n.sons[i].sym if isCompileTimeOnly(param.typ): continue @@ -1405,13 +1405,13 @@ proc genArgs(p: PProc, n: PNode, r: var TCompRes; start=1) = var typ = skipTypes(n.sons[0].typ, abstractInst) assert(typ.kind == tyProc) - assert(sonsLen(typ) == sonsLen(typ.n)) + assert(len(typ) == len(typ.n)) var emitted = start-1 - for i in start ..< sonsLen(n): + for i in start ..< len(n): let it = n.sons[i] var paramType: PNode = nil - if i < sonsLen(typ): + if i < len(typ): assert(typ.n.sons[i].kind == nkSym) paramType = typ.n.sons[i] if paramType.typ.isCompileTimeOnly: continue @@ -1439,7 +1439,7 @@ proc genOtherArg(p: PProc; n: PNode; i: int; typ: PType; " but got only: " & $(n.len-1)) let it = n[i] var paramType: PNode = nil - if i < sonsLen(typ): + if i < len(typ): assert(typ.n.sons[i].kind == nkSym) paramType = typ.n.sons[i] if paramType.typ.isCompileTimeOnly: return @@ -1527,7 +1527,7 @@ proc genEcho(p: PProc, n: PNode, r: var TCompRes) = useMagic(p, "toJSStr") # Used in rawEcho useMagic(p, "rawEcho") add(r.res, "rawEcho(") - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): let it = n.sons[i] if it.typ.isCompileTimeOnly: continue if i > 0: add(r.res, ", ") @@ -1543,11 +1543,11 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope proc createRecordVarAux(p: PProc, rec: PNode, excludedFieldIDs: IntSet, output: var Rope) = case rec.kind of nkRecList: - for i in 0 ..< sonsLen(rec): + for i in 0 ..< len(rec): createRecordVarAux(p, rec.sons[i], excludedFieldIDs, output) of nkRecCase: createRecordVarAux(p, rec.sons[0], excludedFieldIDs, output) - for i in 1 ..< sonsLen(rec): + for i in 1 ..< len(rec): createRecordVarAux(p, lastSon(rec.sons[i]), excludedFieldIDs, output) of nkSym: # Do not produce code for void types @@ -1619,7 +1619,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): Rope = if indirect: result = "[$1]" % [result] of tyTuple: result = rope("{") - for i in 0..<t.sonsLen: + for i in 0..<t.len: if i > 0: add(result, ", ") addf(result, "Field$1: $2", [i.rope, createVar(p, t.sons[i], false)]) @@ -1720,7 +1720,7 @@ proc genVarInit(p: PProc, v: PSym, n: PNode) = lineF(p, "}$n") proc genVarStmt(p: PProc, n: PNode) = - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind != nkCommentStmt: if a.kind == nkVarTuple: @@ -1778,15 +1778,15 @@ proc genConStrStr(p: PProc, n: PNode, r: var TCompRes) = else: r.res.add("($1 || []).concat(" % [a.res]) - for i in 2 .. sonsLen(n) - 2: + for i in 2 .. len(n) - 2: gen(p, n.sons[i], a) if skipTypes(n.sons[i].typ, abstractVarRange).kind == tyChar: r.res.add("[$1]," % [a.res]) else: r.res.add("$1 || []," % [a.res]) - gen(p, n.sons[sonsLen(n) - 1], a) - if skipTypes(n.sons[sonsLen(n) - 1].typ, abstractVarRange).kind == tyChar: + gen(p, n.sons[len(n) - 1], a) + if skipTypes(n.sons[len(n) - 1].typ, abstractVarRange).kind == tyChar: r.res.add("[$1])" % [a.res]) else: r.res.add("$1 || [])" % [a.res]) @@ -2043,7 +2043,7 @@ proc genSetConstr(p: PProc, n: PNode, r: var TCompRes) = useMagic(p, "setConstr") r.res = rope("setConstr(") r.kind = resExpr - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if i > 0: add(r.res, ", ") var it = n.sons[i] if it.kind == nkRange: @@ -2065,7 +2065,7 @@ proc genArrayConstr(p: PProc, n: PNode, r: var TCompRes) = var a: TCompRes r.res = rope("[") r.kind = resExpr - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if i > 0: add(r.res, ", ") gen(p, n.sons[i], a) if a.typ == etyBaseIndex: @@ -2082,7 +2082,7 @@ proc genTupleConstr(p: PProc, n: PNode, r: var TCompRes) = var a: TCompRes r.res = rope("{") r.kind = resExpr - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if i > 0: add(r.res, ", ") var it = n.sons[i] if it.kind == nkExprColonExpr: it = it.sons[1] @@ -2102,7 +2102,7 @@ proc genObjConstr(p: PProc, n: PNode, r: var TCompRes) = r.kind = resExpr var initList : Rope var fieldIDs = initIntSet() - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): if i > 1: add(initList, ", ") var it = n.sons[i] internalAssert p.config, it.kind == nkExprColonExpr @@ -2436,7 +2436,7 @@ proc gen(p: PProc, n: PNode, r: var TCompRes) = # this shows the distinction is nice for backends and should be kept # in the frontend let isExpr = not isEmptyType(n.typ) - for i in 0 ..< sonsLen(n) - isExpr.ord: + for i in 0 ..< len(n) - isExpr.ord: genStmt(p, n.sons[i]) if isExpr: gen(p, lastSon(n), r) @@ -2573,7 +2573,7 @@ proc wholeCode(graph: ModuleGraph; m: BModule): Rope = attachProc(p, prc) var disp = generateMethodDispatchers(graph) - for i in 0..sonsLen(disp)-1: + for i in 0..len(disp)-1: let prc = disp.sons[i].sym if not globals.generatedSyms.containsOrIncl(prc.id): var p = newProc(globals, m, nil, m.module.options) diff --git a/compiler/jstypes.nim b/compiler/jstypes.nim index c037fd22a..70d6c22ba 100644 --- a/compiler/jstypes.nim +++ b/compiler/jstypes.nim @@ -23,7 +23,7 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope = result = nil case n.kind of nkRecList: - length = sonsLen(n) + length = len(n) if length == 1: result = genObjectFields(p, typ, n.sons[0]) else: @@ -41,7 +41,7 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope = [mangleName(p.module, field), s, makeJSString(field.name.s)] of nkRecCase: - length = sonsLen(n) + length = len(n) if (n.sons[0].kind != nkSym): internalError(p.config, n.info, "genObjectFields") field = n.sons[0].sym s = genTypeInfo(p, field.typ) @@ -50,9 +50,9 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope = u = nil case b.kind of nkOfBranch: - if sonsLen(b) < 2: + if len(b) < 2: internalError(p.config, b.info, "genObjectFields; nkOfBranch broken") - for j in 0 .. sonsLen(b) - 2: + for j in 0 .. len(b) - 2: if u != nil: add(u, ", ") if b.sons[j].kind == nkRange: addf(u, "[$1, $2]", [rope(getOrdValue(b.sons[j].sons[0])), @@ -105,7 +105,7 @@ proc genTupleInfo(p: PProc, typ: PType, name: Rope) = addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)]) proc genEnumInfo(p: PProc, typ: PType, name: Rope) = - let length = sonsLen(typ.n) + let length = len(typ.n) var s: Rope = nil for i in 0 ..< length: if (typ.n.sons[i].kind != nkSym): internalError(p.config, typ.n.info, "genEnumInfo") diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 3574adca0..14bbc3ba7 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -182,8 +182,16 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode; body.add newAsgnCall(c.g, op, x, y) result = true -proc addDestructorCall(c: var TLiftCtx; t: PType; body, x: PNode) = +proc addDestructorCall(c: var TLiftCtx; orig: PType; body, x: PNode) = + let t = orig.skipTypes(abstractInst) var op = t.destructor + + if op != nil and sfOverriden in op.flags: + if op.ast[genericParamsPos].kind != nkEmpty: + # patch generic destructor: + op = instantiateGeneric(c, op, t, t.typeInst) + t.attachedOps[attachedDestructor] = op + if op == nil and useNoGc(c, t): op = produceSym(c.g, c.c, t, attachedDestructor, c.info) doAssert op != nil diff --git a/compiler/lineinfos.nim b/compiler/lineinfos.nim index 01b4a072c..d315f4d33 100644 --- a/compiler/lineinfos.nim +++ b/compiler/lineinfos.nim @@ -13,7 +13,7 @@ import ropes, tables, pathutils const - explanationsBaseUrl* = "https://nim-lang.org/docs/manual" + explanationsBaseUrl* = "https://nim-lang.org/docs" type TMsgKind* = enum diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 4de1fc371..df1d23b9c 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -430,7 +430,7 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = of oimOtherModule: result = nextIdentIter(o.it, o.m.tab).skipAlias(n, c.config) of oimSymChoice: - if o.symChoiceIndex < sonsLen(n): + if o.symChoiceIndex < len(n): result = n.sons[o.symChoiceIndex].sym incl(o.inSymChoice, result.id) inc o.symChoiceIndex diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index fff6c75ca..d372ac0c1 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -152,7 +152,7 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType proc rawAddField*(obj: PType; field: PSym) = assert field.kind == skField - field.position = sonsLen(obj.n) + field.position = len(obj.n) addSon(obj.n, newSymNode(field)) propagateToOwner(obj, field.typ) @@ -179,14 +179,14 @@ proc lookupInRecord(n: PNode, id: int): PSym = result = nil case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = lookupInRecord(n.sons[i], id) if result != nil: return of nkRecCase: if n.sons[0].kind != nkSym: return result = lookupInRecord(n.sons[0], id) if result != nil: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: result = lookupInRecord(lastSon(n.sons[i]), id) @@ -206,7 +206,7 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) = field.typ = t assert t.kind != tyTyped propagateToOwner(obj, t) - field.position = sonsLen(obj.n) + field.position = len(obj.n) addSon(obj.n, newSymNode(field)) proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable.} = @@ -219,7 +219,7 @@ proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable field.typ = t assert t.kind != tyTyped propagateToOwner(obj, t) - field.position = sonsLen(obj.n) + field.position = len(obj.n) addSon(obj.n, newSymNode(field)) result = field diff --git a/compiler/nim.cfg b/compiler/nim.cfg index db6e4f74f..ba90a8284 100644 --- a/compiler/nim.cfg +++ b/compiler/nim.cfg @@ -7,7 +7,7 @@ define:nimcore #define:nimIncremental #import:"$projectpath/testability" -define:staticSqlite +#define:staticSqlite @if windows: cincludes: "$lib/wrappers/libffi/common" diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index bd070f2c7..5ae7ef590 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -17,7 +17,7 @@ proc inSet*(s: PNode, elem: PNode): bool = if s.kind != nkCurly: #internalError(s.info, "inSet") return false - for i in 0 ..< sonsLen(s): + for i in 0 ..< len(s): if s.sons[i].kind == nkRange: if leValue(s.sons[i].sons[0], elem) and leValue(elem, s.sons[i].sons[1]): @@ -47,7 +47,7 @@ proc someInSet*(s: PNode, a, b: PNode): bool = if s.kind != nkCurly: #internalError(s.info, "SomeInSet") return false - for i in 0 ..< sonsLen(s): + for i in 0 ..< len(s): if s.sons[i].kind == nkRange: if leValue(s.sons[i].sons[0], b) and leValue(b, s.sons[i].sons[1]) or leValue(s.sons[i].sons[0], a) and leValue(a, s.sons[i].sons[1]): @@ -62,7 +62,7 @@ proc toBitSet*(conf: ConfigRef; s: PNode, b: var TBitSet) = var first, j: Int128 first = firstOrd(conf, s.typ.sons[0]) bitSetInit(b, int(getSize(conf, s.typ))) - for i in 0 ..< sonsLen(s): + for i in 0 ..< len(s): if s.sons[i].kind == nkRange: j = getOrdValue(s.sons[i].sons[0], first) while j <= getOrdValue(s.sons[i].sons[1], first): @@ -149,7 +149,7 @@ proc setHasRange*(s: PNode): bool = assert s.kind == nkCurly if s.kind != nkCurly: return false - for i in 0 ..< sonsLen(s): + for i in 0 ..< len(s): if s.sons[i].kind == nkRange: return true result = false diff --git a/compiler/options.nim b/compiler/options.nim index 1b9bbb38f..5c7513f6b 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -110,7 +110,7 @@ type cmdJsonScript # compile a .json build file TStringSeq* = seq[string] TGCMode* = enum # the selected GC - gcNone, gcBoehm, gcRegions, gcMarkAndSweep, gcDestructors, + gcUnselected, gcNone, gcBoehm, gcRegions, gcMarkAndSweep, gcDestructors, gcRefc, gcV2, gcGo # gcRefc and the GCs that follow it use a write barrier, # as far as usesWriteBarrier() is concerned diff --git a/compiler/packagehandling.nim b/compiler/packagehandling.nim index b9db61b4d..561d6dfc4 100644 --- a/compiler/packagehandling.nim +++ b/compiler/packagehandling.nim @@ -39,13 +39,11 @@ proc getPackageName*(conf: ConfigRef; path: string): string = if parents <= 0: break proc fakePackageName*(conf: ConfigRef; path: AbsoluteFile): string = - # foo/../bar becomes foo7_7bar - result = relativeTo(path, conf.projectPath, '/').string.multiReplace( - {"/": "7", "..": "_", "7": "77", "_": "__", ":": "8", "8": "88"}) + # foo-#head/../bar becomes @foo-@hhead@s..@sbar + result = "@" & relativeTo(path, conf.projectPath, '/').string.multiReplace({"/": "@s", "#": "@h", "@": "@@"}) proc demanglePackageName*(path: string): string = - result = path.multiReplace( - {"88": "8", "8": ":", "77": "7", "__": "_", "_7": "../", "7": "/"}) + result = path[1 .. ^1].multiReplace({"@@": "@", "@h": "#", "@s": "/"}) proc withPackageName*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile = let x = getPackageName(conf, path.string) diff --git a/compiler/patterns.nim b/compiler/patterns.nim index 3f2e2e86e..7e66ae591 100644 --- a/compiler/patterns.nim +++ b/compiler/patterns.nim @@ -58,8 +58,8 @@ proc sameTrees*(a, b: PNode): bool = of nkEmpty, nkNilLit: result = true of nkType: result = sameTypeOrNil(a.typ, b.typ) else: - if sonsLen(a) == sonsLen(b): - for i in 0 ..< sonsLen(a): + if len(a) == len(b): + for i in 0 ..< len(a): if not sameTrees(a.sons[i], b.sons[i]): return result = true @@ -112,7 +112,7 @@ proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool = rpn: bool): bool = result = true if n.kind in nkCallKinds and matches(c, op.sons[1], n.sons[0]): - for i in 1..sonsLen(n)-1: + for i in 1..len(n)-1: if not matchStarAux(c, op, n[i], arglist, rpn): return false if rpn: arglist.add(n.sons[0]) elif n.kind == nkHiddenStdConv and n.sons[1].kind == nkBracket: @@ -174,35 +174,35 @@ proc matches(c: PPatternContext, p, n: PNode): bool = of nkEmpty, nkNilLit, nkType: result = true else: - var plen = sonsLen(p) + var plen = len(p) # special rule for p(X) ~ f(...); this also works for stuff like # partial case statements, etc! - Not really ... :-/ let v = lastSon(p) if isPatternParam(c, v) and v.sym.typ.kind == tyVarargs: var arglist: PNode - if plen <= sonsLen(n): + if plen <= len(n): for i in 0 .. plen - 2: if not matches(c, p.sons[i], n.sons[i]): return - if plen == sonsLen(n) and lastSon(n).kind == nkHiddenStdConv and + if plen == len(n) and lastSon(n).kind == nkHiddenStdConv and lastSon(n).sons[1].kind == nkBracket: # unpack varargs: let n = lastSon(n).sons[1] arglist = newNodeI(nkArgList, n.info, n.len) for i in 0..<n.len: arglist.sons[i] = n.sons[i] else: - arglist = newNodeI(nkArgList, n.info, sonsLen(n) - plen + 1) + arglist = newNodeI(nkArgList, n.info, len(n) - plen + 1) # f(1, 2, 3) # p(X) - for i in 0 .. sonsLen(n) - plen: + for i in 0 .. len(n) - plen: arglist.sons[i] = n.sons[i + plen - 1] return bindOrCheck(c, v.sym, arglist) - elif plen-1 == sonsLen(n): + elif plen-1 == len(n): for i in 0 .. plen - 2: if not matches(c, p.sons[i], n.sons[i]): return arglist = newNodeI(nkArgList, n.info) return bindOrCheck(c, v.sym, arglist) - if plen == sonsLen(n): - for i in 0 ..< sonsLen(p): + if plen == len(n): + for i in 0 ..< len(p): if not matches(c, p.sons[i], n.sons[i]): return result = true @@ -250,7 +250,7 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode = var ctx: TPatternContext ctx.owner = s ctx.c = c - ctx.formals = sonsLen(s.typ)-1 + ctx.formals = len(s.typ)-1 var m = matchStmtList(ctx, s.ast.sons[patternPos], n) if isNil(m): return nil # each parameter should have been bound; we simply setup a call and diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 3de12cfa9..e9a89bc44 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -19,25 +19,27 @@ const LastCallConv* = wNoconv const - procPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, + declPragmas = {wImportc, wImportObjC, wImportCpp, wExportc, wExportCpp, + wExportNims, wExtern, wDeprecated, wNodecl, wError, wUsed} + ## common pragmas for declarations, to a good approximation + procPragmas* = declPragmas + {FirstCallConv..LastCallConv, wMagic, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader, - wCompilerProc, wNonReloadable, wCore, wProcVar, wDeprecated, wVarargs, wCompileTime, wMerge, - wBorrow, wExtern, wImportCompilerProc, wThread, wImportCpp, wImportObjC, - wAsmNoStackFrame, wError, wDiscardable, wNoInit, wCodegenDecl, + wCompilerProc, wNonReloadable, wCore, wProcVar, wVarargs, wCompileTime, wMerge, + wBorrow, wImportCompilerProc, wThread, + wAsmNoStackFrame, wDiscardable, wNoInit, wCodegenDecl, wGensym, wInject, wRaises, wTags, wLocks, wDelegator, wGcSafe, - wConstructor, wExportNims, wUsed, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy} + wConstructor, wLiftLocals, wStackTrace, wLineTrace, wNoDestroy} converterPragmas* = procPragmas - {wNoDestroy} methodPragmas* = procPragmas+{wBase}-{wImportCpp, wNoDestroy} templatePragmas* = {wDeprecated, wError, wGensym, wInject, wDirty, wDelegator, wExportNims, wUsed, wPragma} - macroPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, - wNodecl, wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wDelegator, - wExportNims, wUsed} - iteratorPragmas* = {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, - wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow, wExtern, - wImportCpp, wImportObjC, wError, wDiscardable, wGensym, wInject, wRaises, - wTags, wLocks, wGcSafe, wExportNims, wUsed} + macroPragmas* = declPragmas + {FirstCallConv..LastCallConv, + wMagic, wNoSideEffect, wCompilerProc, wNonReloadable, wCore, + wDiscardable, wGensym, wInject, wDelegator} + iteratorPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, + wMagic, wBorrow, + wDiscardable, wGensym, wInject, wRaises, + wTags, wLocks, wGcSafe} exprPragmas* = {wLine, wLocks, wNoRewrite, wGcSafe, wNoSideEffect} stmtPragmas* = {wChecks, wObjChecks, wFieldChecks, wRangeChecks, wBoundChecks, wOverflowChecks, wNilChecks, wStyleChecks, wAssertions, @@ -49,25 +51,25 @@ const wDeprecated, wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll, wLinearScanEnd, wPatterns, wTrMacros, wEffects, wNoForward, wReorder, wComputedGoto, - wInjectStmt, wDeprecated, wExperimental, wThis, wUsed} - lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, + wInjectStmt, wExperimental, wThis, wUsed} + lambdaPragmas* = declPragmas + {FirstCallConv..LastCallConv, wNoSideEffect, wSideEffect, wNoreturn, wDynlib, wHeader, - wDeprecated, wExtern, wThread, wImportCpp, wImportObjC, wAsmNoStackFrame, - wRaises, wLocks, wTags, wGcSafe, wCodegenDecl} - typePragmas* = {wImportc, wExportc, wDeprecated, wMagic, wAcyclic, wNodecl, - wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wExtern, wShallow, - wImportCpp, wImportObjC, wError, wIncompleteStruct, wByCopy, wByRef, + wThread, wAsmNoStackFrame, + wRaises, wLocks, wTags, wGcSafe, wCodegenDecl} - {wExportNims, wError, wUsed} # why exclude these? + typePragmas* = declPragmas + {wMagic, wAcyclic, + wPure, wHeader, wCompilerProc, wCore, wFinal, wSize, wShallow, + wIncompleteStruct, wByCopy, wByRef, wInheritable, wGensym, wInject, wRequiresInit, wUnchecked, wUnion, wPacked, - wBorrow, wGcSafe, wExportNims, wPartial, wUsed, wExplain, wPackage} - fieldPragmas* = {wImportc, wExportc, wDeprecated, wExtern, - wImportCpp, wImportObjC, wError, wGuard, wBitsize, wUsed} - varPragmas* = {wImportc, wExportc, wVolatile, wRegister, wThreadVar, wNodecl, - wMagic, wHeader, wDeprecated, wCompilerProc, wCore, wDynlib, wExtern, - wImportCpp, wImportObjC, wError, wNoInit, wCompileTime, wGlobal, - wGensym, wInject, wCodegenDecl, wGuard, wGoto, wExportNims, wUsed, wCursor} - constPragmas* = {wImportc, wExportc, wHeader, wDeprecated, wMagic, wNodecl, - wExtern, wImportCpp, wImportObjC, wError, wGensym, wInject, wExportNims, - wIntDefine, wStrDefine, wBoolDefine, wUsed, wCompilerProc, wCore} + wBorrow, wGcSafe, wPartial, wExplain, wPackage} + fieldPragmas* = declPragmas + { + wGuard, wBitsize} - {wExportNims, wNodecl} # why exclude these? + varPragmas* = declPragmas + {wVolatile, wRegister, wThreadVar, + wMagic, wHeader, wCompilerProc, wCore, wDynlib, + wNoInit, wCompileTime, wGlobal, + wGensym, wInject, wCodegenDecl, wGuard, wGoto, wCursor} + constPragmas* = declPragmas + {wHeader, wMagic, + wGensym, wInject, + wIntDefine, wStrDefine, wBoolDefine, wCompilerProc, wCore} letPragmas* = varPragmas procTypePragmas* = {FirstCallConv..LastCallConv, wVarargs, wNoSideEffect, wThread, wRaises, wLocks, wTags, wGcSafe} @@ -83,7 +85,8 @@ proc getPragmaVal*(procAst: PNode; name: TSpecialWord): PNode = it[0].ident.id == ord(name): return it[1] -proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) +proc pragma*(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords; + isStatement: bool = false) proc recordPragma(c: PContext; n: PNode; key, val: string; val2 = "") = var recorded = newNodeI(nkCommentStmt, n.info) @@ -104,7 +107,7 @@ proc illegalCustomPragma*(c: PContext, n: PNode, s: PSym) = proc pragmaAsm*(c: PContext, n: PNode): char = result = '\0' if n != nil: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): let it = n.sons[i] if it.kind in nkPragmaCallKinds and it.len == 2 and it.sons[0].kind == nkIdent: case whichKeyword(it.sons[0].ident) @@ -423,7 +426,7 @@ proc processPush(c: PContext, n: PNode, start: int) = x.notes = c.config.notes x.features = c.features c.optionStack.add(x) - for i in start ..< sonsLen(n): + for i in start ..< len(n): if not tryProcessOption(c, n.sons[i], c.config.options): # simply store it somewhere: if x.otherPragmas.isNil: @@ -745,7 +748,8 @@ proc semCustomPragma(c: PContext, n: PNode): PNode = result.kind = n.kind proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, - validPragmas: TSpecialWords, comesFromPush: bool) : bool = + validPragmas: TSpecialWords, + comesFromPush, isStatement: bool) : bool = var it = n.sons[i] var key = if it.kind in nkPragmaCallKinds and it.len > 1: it.sons[0] else: it if key.kind == nkBracketExpr: @@ -765,7 +769,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, if c.instCounter > 100: globalError(c.config, it.info, "recursive dependency: " & userPragma.name.s) - pragma(c, sym, userPragma.ast, validPragmas) + pragma(c, sym, userPragma.ast, validPragmas, isStatement) n.sons[i..i] = userPragma.ast.sons # expand user pragma with its content i.inc(userPragma.ast.len - 1) # inc by -1 is ok, user pragmas was empty dec c.instCounter @@ -775,8 +779,13 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, if {optStyleHint, optStyleError} * c.config.globalOptions != {}: checkPragmaUse(c.config, key.info, k, ident.s) case k - of wExportc: + of wExportc, wExportCpp: makeExternExport(c, sym, getOptionalStr(c, it, "$1"), it.info) + if k == wExportCpp: + if c.config.cmd != cmdCompileToCpp: + localError(c.config, it.info, "exportcpp requires `nim cpp`, got " & $c.config.cmd) + else: + incl(sym.flags, sfMangleCpp) incl(sym.flags, sfUsed) # avoid wrong hints of wImportc: let name = getOptionalStr(c, it, "$1") @@ -839,7 +848,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, of wCompileTime: noVal(c, it) incl(sym.flags, sfCompileTime) - incl(sym.loc.flags, lfNoDecl) + #incl(sym.loc.flags, lfNoDecl) of wGlobal: noVal(c, it) incl(sym.flags, sfGlobal) @@ -962,7 +971,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, recordPragma(c, it, "warning", s) message(c.config, it.info, warnUser, s) of wError: - if sym != nil and (sym.isRoutine or sym.kind == skType) and wUsed in validPragmas: + if sym != nil and (sym.isRoutine or sym.kind == skType) and not isStatement: # This is subtle but correct: the error *statement* is only # allowed when 'wUsed' is not in validPragmas. Here this is the easiest way to # distinguish properly between @@ -1131,7 +1140,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, elif comesFromPush and whichKeyword(ident) in {wTags, wRaises}: discard "ignore the .push pragma; it doesn't apply" else: - if sym == nil or (sym != nil and sym.kind in {skVar, skLet, skParam, + if sym == nil or (sym.kind in {skVar, skLet, skParam, skField, skProc, skFunc, skConverter, skMethod, skType}): n.sons[i] = semCustomPragma(c, it) elif sym != nil: @@ -1161,7 +1170,7 @@ proc implicitPragmas*(c: PContext, sym: PSym, n: PNode, pushInfoContext(c.config, n.info) var i = 0 while i < o.len: - if singlePragma(c, sym, o, i, validPragmas, true): + if singlePragma(c, sym, o, i, validPragmas, true, false): internalError(c.config, n.info, "implicitPragmas") inc i popInfoContext(c.config) @@ -1186,14 +1195,16 @@ proc hasPragma*(n: PNode, pragma: TSpecialWord): bool = return false -proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = +proc pragmaRec(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords; + isStatement: bool) = if n == nil: return var i = 0 while i < n.len: - if singlePragma(c, sym, n, i, validPragmas, false): break + if singlePragma(c, sym, n, i, validPragmas, false, isStatement): break inc i -proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) = +proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords; + isStatement: bool) = if n == nil: return - pragmaRec(c, sym, n, validPragmas) + pragmaRec(c, sym, n, validPragmas, isStatement) implicitPragmas(c, sym, n, validPragmas) diff --git a/compiler/procfind.nim b/compiler/procfind.nim index f2f58fb75..7247bb301 100644 --- a/compiler/procfind.nim +++ b/compiler/procfind.nim @@ -14,8 +14,8 @@ import ast, astalgo, msgs, semdata, types, trees, strutils proc equalGenericParams(procA, procB: PNode): bool = - if sonsLen(procA) != sonsLen(procB): return false - for i in 0 ..< sonsLen(procA): + if len(procA) != len(procB): return false + for i in 0 ..< len(procA): if procA.sons[i].kind != nkSym: return false if procB.sons[i].kind != nkSym: @@ -95,9 +95,9 @@ proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = when false: proc paramsFitBorrow(child, parent: PNode): bool = - var length = sonsLen(child) + var length = len(child) result = false - if length == sonsLen(parent): + if length == len(parent): for i in 1 ..< length: var m = child.sons[i].sym var n = parent.sons[i].sym diff --git a/compiler/renderer.nim b/compiler/renderer.nim index dfe66de03..cdd0357ee 100644 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -395,7 +395,7 @@ proc atom(g: TSrcGen; n: PNode): string = proc lcomma(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int = assert(theEnd < 0) result = 0 - for i in start .. sonsLen(n) + theEnd: + for i in start .. len(n) + theEnd: let param = n.sons[i] if nfDefaultParam notin param.flags: inc(result, lsub(g, param)) @@ -406,7 +406,7 @@ proc lcomma(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int = proc lsons(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): int = assert(theEnd < 0) result = 0 - for i in start .. sonsLen(n) + theEnd: inc(result, lsub(g, n.sons[i])) + for i in start .. len(n) + theEnd: inc(result, lsub(g, n.sons[i])) proc lsub(g: TSrcGen; n: PNode): int = # computes the length of a tree @@ -436,7 +436,7 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkTableConstr: result = if n.len > 0: lcomma(g, n) + 2 else: len("{:}") of nkClosedSymChoice, nkOpenSymChoice: - result = lsons(g, n) + len("()") + sonsLen(n) - 1 + result = lsons(g, n) + len("()") + len(n) - 1 of nkTupleTy: result = lcomma(g, n) + len("tuple[]") of nkTupleClassTy: result = len("tuple") of nkDotExpr: result = lsons(g, n) + 1 @@ -448,7 +448,7 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkDo: result = lsons(g, n) + len("do__:_") of nkConstDef, nkIdentDefs: result = lcomma(g, n, 0, - 3) - var L = sonsLen(n) + var L = len(n) if n.sons[L - 2].kind != nkEmpty: result = result + lsub(g, n.sons[L - 2]) + 2 if n.sons[L - 1].kind != nkEmpty: result = result + lsub(g, n.sons[L - 1]) + 3 of nkVarTuple: result = lcomma(g, n, 0, - 3) + len("() = ") + lsub(g, lastSon(n)) @@ -457,7 +457,7 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkChckRange: result = len("chckRange") + 2 + lcomma(g, n) of nkObjDownConv, nkObjUpConv: result = 2 - if sonsLen(n) >= 1: result = result + lsub(g, n.sons[0]) + if len(n) >= 1: result = result + lsub(g, n.sons[0]) result = result + lcomma(g, n, 1) of nkExprColonExpr: result = lsons(g, n) + 2 of nkInfix: result = lsons(g, n) + 2 @@ -491,16 +491,16 @@ proc lsub(g: TSrcGen; n: PNode): int = of nkIteratorTy: result = lsons(g, n) + len("iterator_") of nkSharedTy: result = lsons(g, n) + len("shared_") of nkEnumTy: - if sonsLen(n) > 0: + if len(n) > 0: result = lsub(g, n.sons[0]) + lcomma(g, n, 1) + len("enum_") else: result = len("enum") of nkEnumFieldDef: result = lsons(g, n) + 3 of nkVarSection, nkLetSection: - if sonsLen(n) > 1: result = MaxLineLen + 1 + if len(n) > 1: result = MaxLineLen + 1 else: result = lsons(g, n) + len("var_") of nkUsingStmt: - if sonsLen(n) > 1: result = MaxLineLen + 1 + if len(n) > 1: result = MaxLineLen + 1 else: result = lsons(g, n) + len("using_") of nkReturnStmt: if n.len > 0 and n[0].kind == nkAsgn: @@ -556,7 +556,7 @@ proc hasCom(n: PNode): bool = case n.kind of nkEmpty..nkNilLit: discard else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if hasCom(n.sons[i]): return true proc putWithSpace(g: var TSrcGen, kind: TTokType, s: string) = @@ -565,8 +565,8 @@ proc putWithSpace(g: var TSrcGen, kind: TTokType, s: string) = proc gcommaAux(g: var TSrcGen, n: PNode, ind: int, start: int = 0, theEnd: int = - 1, separator = tkComma) = - for i in start .. sonsLen(n) + theEnd: - var c = i < sonsLen(n) + theEnd + for i in start .. len(n) + theEnd: + var c = i < len(n) + theEnd var sublen = lsub(g, n.sons[i]) + ord(c) if not fits(g, sublen) and (ind + sublen < MaxLineLen): optNL(g, ind) let oldLen = g.tokens.len @@ -600,15 +600,15 @@ proc gsemicolon(g: var TSrcGen, n: PNode, start: int = 0, theEnd: int = - 1) = proc gsons(g: var TSrcGen, n: PNode, c: TContext, start: int = 0, theEnd: int = - 1) = - for i in start .. sonsLen(n) + theEnd: gsub(g, n.sons[i], c) + for i in start .. len(n) + theEnd: gsub(g, n.sons[i], c) proc gsection(g: var TSrcGen, n: PNode, c: TContext, kind: TTokType, k: string) = - if sonsLen(n) == 0: return # empty var sections are possible + if len(n) == 0: return # empty var sections are possible putWithSpace(g, kind, k) gcoms(g) indentNL(g) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): optNL(g) gsub(g, n.sons[i], c) gcoms(g) @@ -618,7 +618,7 @@ proc longMode(g: TSrcGen; n: PNode, start: int = 0, theEnd: int = - 1): bool = result = n.comment.len > 0 if not result: # check further - for i in start .. sonsLen(n) + theEnd: + for i in start .. len(n) + theEnd: if (lsub(g, n.sons[i]) > MaxLineLen): result = true break @@ -663,7 +663,7 @@ proc gif(g: var TSrcGen, n: PNode) = incl(c.flags, rfLongMode) gcoms(g) # a good place for comments gstmts(g, n.sons[0].sons[1], c) - var length = sonsLen(n) + var length = len(n) for i in 1 ..< length: optNL(g) gsub(g, n.sons[i], c) @@ -712,7 +712,7 @@ proc gtry(g: var TSrcGen, n: PNode) = proc gfor(g: var TSrcGen, n: PNode) = var c: TContext - var length = sonsLen(n) + var length = len(n) putWithSpace(g, tkFor, "for") initContext(c) if longMode(g, n) or @@ -730,7 +730,7 @@ proc gfor(g: var TSrcGen, n: PNode) = proc gcase(g: var TSrcGen, n: PNode) = var c: TContext initContext(c) - var length = sonsLen(n) + var length = len(n) if length == 0: return var last = if n.sons[length-1].kind == nkElse: -2 else: -1 if longMode(g, n, 0, last): incl(c.flags, rfLongMode) @@ -966,7 +966,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkColon, ":") gsub(g, n, n.len-1) else: - if sonsLen(n) >= 1: accentedName(g, n[0]) + if len(n) >= 1: accentedName(g, n[0]) put(g, tkParLe, "(") gcomma(g, n, 1) put(g, tkParRi, ")") @@ -1046,14 +1046,14 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gcomma(g, n) put(g, tkParRi, ")") of nkObjDownConv, nkObjUpConv: - if sonsLen(n) >= 1: gsub(g, n.sons[0]) + if len(n) >= 1: gsub(g, n.sons[0]) put(g, tkParLe, "(") gcomma(g, n, 1) put(g, tkParRi, ")") of nkClosedSymChoice, nkOpenSymChoice: if renderIds in g.flags: put(g, tkParLe, "(") - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if i > 0: put(g, tkOpr, "|") if n.sons[i].kind == nkSym: let s = n[i].sym @@ -1115,7 +1115,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gsub(g, n, bodyPos) of nkConstDef, nkIdentDefs: gcomma(g, n, 0, -3) - var L = sonsLen(n) + var L = len(n) if L >= 2 and n.sons[L - 2].kind != nkEmpty: putWithSpace(g, tkColon, ":") gsub(g, n, L - 2) @@ -1200,19 +1200,19 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = if n.len > 0: gsub(g, n.sons[0]) put(g, tkParRi, ")") of nkRefTy: - if sonsLen(n) > 0: + if len(n) > 0: putWithSpace(g, tkRef, "ref") gsub(g, n.sons[0]) else: put(g, tkRef, "ref") of nkPtrTy: - if sonsLen(n) > 0: + if len(n) > 0: putWithSpace(g, tkPtr, "ptr") gsub(g, n.sons[0]) else: put(g, tkPtr, "ptr") of nkVarTy: - if sonsLen(n) > 0: + if len(n) > 0: putWithSpace(g, tkVar, "var") gsub(g, n.sons[0]) else: @@ -1243,7 +1243,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = putWithSpace(g, tkEquals, "=") gsub(g, n.sons[2]) of nkObjectTy: - if sonsLen(n) > 0: + if len(n) > 0: putWithSpace(g, tkObject, "object") gsub(g, n.sons[0]) gsub(g, n.sons[1]) @@ -1253,7 +1253,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = put(g, tkObject, "object") of nkRecList: indentNL(g) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): optNL(g) gsub(g, n.sons[i], c) gcoms(g) @@ -1263,14 +1263,14 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = putWithSpace(g, tkOf, "of") gsub(g, n, 0) of nkProcTy: - if sonsLen(n) > 0: + if len(n) > 0: putWithSpace(g, tkProc, "proc") gsub(g, n, 0) gsub(g, n, 1) else: put(g, tkProc, "proc") of nkIteratorTy: - if sonsLen(n) > 0: + if len(n) > 0: putWithSpace(g, tkIterator, "iterator") gsub(g, n, 0) gsub(g, n, 1) @@ -1283,7 +1283,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gsub(g, n.sons[0]) put(g, tkBracketRi, "]") of nkEnumTy: - if sonsLen(n) > 0: + if len(n) > 0: putWithSpace(g, tkEnum, "enum") gsub(g, n.sons[0]) gcoms(g) @@ -1341,7 +1341,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = incl(a.flags, rfInConstExpr) gsection(g, n, a, tkConst, "const") of nkVarSection, nkLetSection, nkUsingStmt: - var L = sonsLen(n) + var L = len(n) if L == 0: return if n.kind == nkVarSection: putWithSpace(g, tkVar, "var") elif n.kind == nkLetSection: putWithSpace(g, tkLet, "let") @@ -1552,7 +1552,7 @@ proc renderModule*(n: PNode, infile, outfile: string, g: TSrcGen initSrcGen(g, renderFlags, conf) g.fid = fid - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): gsub(g, n.sons[i]) optNL(g) case n.sons[i].kind diff --git a/compiler/rodimpl.nim b/compiler/rodimpl.nim index b58f77ff6..94fd792bf 100644 --- a/compiler/rodimpl.nim +++ b/compiler/rodimpl.nim @@ -156,7 +156,7 @@ proc encodeNode(g: ModuleGraph; fInfo: TLineInfo, n: PNode, encodeVInt(n.sym.id, result) pushSym(w, n.sym) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): encodeNode(g, n.info, n.sons[i], result) add(result, ')') @@ -223,6 +223,9 @@ proc encodeType(g: ModuleGraph, t: PType, result: var string) = if t.lockLevel.ord != UnspecifiedLockLevel.ord: add(result, '\14') encodeVInt(t.lockLevel.int16, result) + if t.paddingAtEnd != 0: + add(result, '\15') + encodeVInt(t.paddingAtEnd, result) for a in t.attachedOps: add(result, '\16') if a == nil: @@ -241,7 +244,7 @@ proc encodeType(g: ModuleGraph, t: PType, result: var string) = add(result, '\21') encodeVInt(t.typeInst.uniqueId, result) pushType(w, t.typeInst) - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): if t.sons[i] == nil: add(result, "^()") else: @@ -631,6 +634,10 @@ proc loadType(g; id: int; info: TLineInfo): PType = else: result.lockLevel = UnspecifiedLockLevel + if b.s[b.pos] == '\15': + inc(b.pos) + result.paddingAtEnd = decodeVInt(b.s, b.pos).int16 + for a in low(result.attachedOps)..high(result.attachedOps): if b.s[b.pos] == '\16': inc(b.pos) diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index 9878cf597..2dcac5666 100644 --- a/compiler/scriptconfig.nim +++ b/compiler/scriptconfig.nim @@ -62,9 +62,15 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string; cbos listDirs: listDirs(a, {pcDir}) cbos removeDir: - os.removeDir getString(a, 0) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + os.removeDir getString(a, 0) cbos removeFile: - os.removeFile getString(a, 0) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + os.removeFile getString(a, 0) cbos createDir: os.createDir getString(a, 0) @@ -76,20 +82,35 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string; cbos getCurrentDir: setResult(a, os.getCurrentDir()) cbos moveFile: - os.moveFile(getString(a, 0), getString(a, 1)) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + os.moveFile(getString(a, 0), getString(a, 1)) cbos moveDir: - os.moveDir(getString(a, 0), getString(a, 1)) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + os.moveDir(getString(a, 0), getString(a, 1)) cbos copyFile: - os.copyFile(getString(a, 0), getString(a, 1)) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + os.copyFile(getString(a, 0), getString(a, 1)) cbos copyDir: - os.copyDir(getString(a, 0), getString(a, 1)) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + os.copyDir(getString(a, 0), getString(a, 1)) cbos getLastModificationTime: setResult(a, getLastModificationTime(getString(a, 0)).toUnix) cbos findExe: setResult(a, os.findExe(getString(a, 0))) cbos rawExec: - setResult(a, osproc.execCmd getString(a, 0)) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + setResult(a, osproc.execCmd getString(a, 0)) cbconf getEnv: setResult(a, os.getEnv(a.getString 0, a.getString 1)) @@ -164,11 +185,17 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string; cbconf cppDefine: options.cppDefine(conf, a.getString(0)) cbexc stdinReadLine, EOFError: - setResult(a, "") - setResult(a, stdin.readLine()) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + setResult(a, "") + setResult(a, stdin.readLine()) cbexc stdinReadAll, EOFError: - setResult(a, "") - setResult(a, stdin.readAll()) + if defined(nimsuggest) or graph.config.cmd == cmdCheck: + discard + else: + setResult(a, "") + setResult(a, stdin.readAll()) proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile; freshDefines=true; conf: ConfigRef) = @@ -187,6 +214,12 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile; conf.searchPaths.add(conf.libpath) + let oldGlobalOptions = conf.globalOptions + let oldSelectedGC = conf.selectedGC + undefSymbol(conf.symbols, "nimv2") + conf.globalOptions.excl optNimV2 + conf.selectedGC = gcUnselected + var m = graph.makeModule(scriptName) incl(m.flags, sfMainModule) graph.vm = setupVM(m, cache, scriptName.string, graph) @@ -194,6 +227,14 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile; graph.compileSystemModule() # TODO: see why this unsets hintConf in conf.notes discard graph.processModule(m, llStreamOpen(scriptName, fmRead)) + # watch out, "newruntime" can be set within NimScript itself and then we need + # to remember this: + if optNimV2 in oldGlobalOptions: + conf.globalOptions.incl optNimV2 + defineSymbol(conf.symbols, "nimv2") + if conf.selectedGC == gcUnselected: + conf.selectedGC = oldSelectedGC + # ensure we load 'system.nim' again for the real non-config stuff! resetSystemArtifacts(graph) # do not remove the defined symbols diff --git a/compiler/sem.nim b/compiler/sem.nim index ecf5e4f85..87f2444a3 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -575,7 +575,7 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode = if c.lastGenericIdx < c.generics.len: var a = newNodeI(nkStmtList, n.info) addCodeForGenerics(c, a) - if sonsLen(a) > 0: + if len(a) > 0: # a generic has been added to `a`: if result.kind != nkEmpty: addSon(a, result) result = a diff --git a/compiler/semcall.nim b/compiler/semcall.nim index cf83c599e..76f0e39af 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -405,7 +405,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode, elif c.config.errorCounter == 0: # don't cascade errors var args = "(" - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): if i > 1: add(args, ", ") add(args, typeToString(n.sons[i].typ)) add(args, ")") @@ -577,7 +577,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = # binding has to stay 'nil' for this to work! initCandidate(c, m, s, nil) - for i in 1..sonsLen(n)-1: + for i in 1..len(n)-1: let formal = s.ast.sons[genericParamsPos].sons[i-1].typ var arg = n[i].typ # try transforming the argument into a static one before feeding it into @@ -599,7 +599,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = assert n.kind == nkBracketExpr - for i in 1..sonsLen(n)-1: + for i in 1..len(n)-1: let e = semExpr(c, n.sons[i]) if e.typ == nil: n.sons[i].typ = errorType(c) diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 0d4d3ea48..97d17a3fa 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -410,10 +410,10 @@ proc illFormedAstLocal*(n: PNode; conf: ConfigRef) = localError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) proc checkSonsLen*(n: PNode, length: int; conf: ConfigRef) = - if sonsLen(n) != length: illFormedAst(n, conf) + if len(n) != length: illFormedAst(n, conf) proc checkMinSonsLen*(n: PNode, length: int; conf: ConfigRef) = - if sonsLen(n) < length: illFormedAst(n, conf) + if len(n) < length: illFormedAst(n, conf) proc isTopLevel*(c: PContext): bool {.inline.} = result = c.currentScope.depthLevel <= 2 diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 2d33c742b..eb5b8d2c1 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -225,7 +225,7 @@ proc isOwnedSym(c: PContext; n: PNode): bool = result = s != nil and sfSystemModule in s.owner.flags and s.name.s == "owned" proc semConv(c: PContext, n: PNode): PNode = - if sonsLen(n) != 2: + if len(n) != 2: localError(c.config, n.info, "a type conversion takes exactly one argument") return n @@ -301,7 +301,7 @@ proc semConv(c: PContext, n: PNode): PNode = localError(c.config, n.info, errGenerated, value & " can't be converted to " & result.typ.typeToString) else: - for i in 0 ..< sonsLen(op): + for i in 0 ..< len(op): let it = op.sons[i] let status = checkConvertible(c, result.typ, it) if status in {convOK, convNotNeedeed}: @@ -331,7 +331,7 @@ proc semCast(c: PContext, n: PNode): PNode = proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = const opToStr: array[mLow..mHigh, string] = ["low", "high"] - if sonsLen(n) != 2: + if len(n) != 2: localError(c.config, n.info, errXExpectsTypeOrValue % opToStr[m]) else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) @@ -369,7 +369,7 @@ proc fixupStaticType(c: PContext, n: PNode) = proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode = internalAssert c.config, - n.sonsLen == 3 and + n.len == 3 and n[1].typ != nil and n[2].kind in {nkStrLit..nkTripleStrLit, nkType} @@ -408,7 +408,7 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode = result.typ = n.typ proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode = - if sonsLen(n) != 3: + if len(n) != 3: localError(c.config, n.info, "'is' operator takes 2 arguments") let boolType = getSysType(c.graph, n.info, tyBool) @@ -452,9 +452,9 @@ proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode = proc semOpAux(c: PContext, n: PNode) = const flags = {efDetermineType} - for i in 1 ..< n.sonsLen: + for i in 1 ..< n.len: var a = n.sons[i] - if a.kind == nkExprEqExpr and sonsLen(a) == 2: + if a.kind == nkExprEqExpr and len(a) == 2: let info = a.sons[0].info a.sons[0] = newIdentNode(considerQuotedIdent(c, a.sons[0], a), info) a.sons[1] = semExprWithType(c, a.sons[1], flags) @@ -470,22 +470,22 @@ proc overloadedCallOpr(c: PContext, n: PNode): PNode = else: result = newNodeI(nkCall, n.info) addSon(result, newIdentNode(par, n.info)) - for i in 0 ..< sonsLen(n): addSon(result, n.sons[i]) + for i in 0 ..< len(n): addSon(result, n.sons[i]) result = semExpr(c, result) proc changeType(c: PContext; n: PNode, newType: PType, check: bool) = case n.kind of nkCurly, nkBracket: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): changeType(c, n.sons[i], elemType(newType), check) of nkPar, nkTupleConstr: let tup = newType.skipTypes({tyGenericInst, tyAlias, tySink, tyDistinct}) if tup.kind != tyTuple: if tup.kind == tyObject: return globalError(c.config, n.info, "no tuple type for constructor") - elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: + elif len(n) > 0 and n.sons[0].kind == nkExprColonExpr: # named tuple? - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var m = n.sons[i].sons[0] if m.kind != nkSym: globalError(c.config, m.info, "invalid tuple constructor") @@ -499,7 +499,7 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) = else: changeType(c, n.sons[i].sons[1], tup.sons[i], check) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): changeType(c, n.sons[i], tup.sons[i], check) when false: var m = n.sons[i] @@ -522,12 +522,12 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) = proc arrayConstrType(c: PContext, n: PNode): PType = var typ = newTypeS(tyArray, c) rawAddSon(typ, nil) # index type - if sonsLen(n) == 0: + if len(n) == 0: rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype! else: var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink}) addSonSkipIntLit(typ, t) - typ.sons[0] = makeRangeType(c, 0, sonsLen(n) - 1, n.info) + typ.sons[0] = makeRangeType(c, 0, len(n) - 1, n.info) result = typ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = @@ -538,12 +538,12 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = firstIndex, lastIndex: Int128 indexType = getSysType(c.graph, n.info, tyInt) lastValidIndex = lastOrd(c.config, indexType) - if sonsLen(n) == 0: + if len(n) == 0: rawAddSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype! lastIndex = toInt128(-1) else: var x = n.sons[0] - if x.kind == nkExprColonExpr and sonsLen(x) == 2: + if x.kind == nkExprColonExpr and len(x) == 2: var idx = semConstExpr(c, x.sons[0]) if not isOrdinalType(idx.typ): localError(c.config, idx.info, "expected ordinal value for array " & @@ -559,7 +559,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var typ = yy.typ addSon(result, yy) #var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal}) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): if lastIndex == lastValidIndex: let validIndex = makeRangeType(c, toInt64(firstIndex), toInt64(lastValidIndex), n.info, indexType) @@ -567,7 +567,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = "type '$1' by $2 elements" % [typeToString(validIndex), $(n.len-i)]) x = n.sons[i] - if x.kind == nkExprColonExpr and sonsLen(x) == 2: + if x.kind == nkExprColonExpr and len(x) == 2: var idx = semConstExpr(c, x.sons[0]) idx = fitNode(c, indexType, idx, x.info) if lastIndex+1 != getOrdValue(idx): @@ -683,8 +683,8 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = if n.sons[0].kind == nkSym and n.sons[0].sym.magic in FakeVarParams: # BUGFIX: check for L-Value still needs to be done for the arguments! # note sometimes this is eval'ed twice so we check for nkHiddenAddr here: - for i in 1 ..< sonsLen(n): - if i < sonsLen(t) and t.sons[i] != nil and + for i in 1 ..< len(n): + if i < len(t) and t.sons[i] != nil and skipTypes(t.sons[i], abstractInst-{tyTypeDesc}).kind == tyVar: let it = n[i] if isAssignable(c, it) notin {arLValue, arLocalLValue}: @@ -699,13 +699,13 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = localError(c.config, n.info, errXStackEscape % renderTree(n[1], {renderNoComments})) return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): let n = if n.kind == nkHiddenDeref: n[0] else: n if n.sons[i].kind == nkHiddenCallConv: # we need to recurse explicitly here as converters can create nested # calls and then they wouldn't be analysed otherwise analyseIfAddressTakenInCall(c, n.sons[i]) - if i < sonsLen(t) and + if i < len(t) and skipTypes(t.sons[i], abstractInst-{tyTypeDesc}).kind == tyVar: if n.sons[i].kind != nkHiddenAddr: n.sons[i] = analyseIfAddressTaken(c, n.sons[i]) @@ -887,7 +887,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = result = n0 result.kind = nkCall result.flags.incl nfExplicitCall - for i in 1 ..< sonsLen(n): addSon(result, n.sons[i]) + for i in 1 ..< len(n): addSon(result, n.sons[i]) return semExpr(c, result, flags) else: n.sons[0] = n0 @@ -918,7 +918,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = else: var hasErrorType = false var msg = "type mismatch: got <" - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): if i > 1: add(msg, ", ") let nt = n.sons[i].typ add(msg, typeToString(nt)) @@ -1006,7 +1006,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, result = nil case r.kind of nkRecList: - for i in 0 ..< sonsLen(r): + for i in 0 ..< len(r): result = lookupInRecordAndBuildCheck(c, n, r.sons[i], field, check) if result != nil: return of nkRecCase: @@ -1016,19 +1016,19 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, if result != nil: return let setType = createSetType(c, r.sons[0].typ) var s = newNodeIT(nkCurly, r.info, setType) - for i in 1 ..< sonsLen(r): + for i in 1 ..< len(r): var it = r.sons[i] case it.kind of nkOfBranch: result = lookupInRecordAndBuildCheck(c, n, lastSon(it), field, check) if result == nil: - for j in 0..sonsLen(it)-2: addSon(s, copyTree(it.sons[j])) + for j in 0..len(it)-2: addSon(s, copyTree(it.sons[j])) else: if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) addSon(check, c.graph.emptyNode) # make space for access node s = newNodeIT(nkCurly, n.info, setType) - for j in 0 .. sonsLen(it) - 2: addSon(s, copyTree(it.sons[j])) + for j in 0 .. len(it) - 2: addSon(s, copyTree(it.sons[j])) var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) addSon(inExpr, newSymNode(c.graph.opContains, n.info)) addSon(inExpr, s) @@ -1424,7 +1424,7 @@ proc semDeref(c: PContext, n: PNode): PNode = proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = ## returns nil if not a built-in subscript operator; also called for the ## checking of assignments - if sonsLen(n) == 1: + if len(n) == 1: let x = semDeref(c, n) if x == nil: return nil result = newNodeIT(nkDerefExpr, x.info, x.typ) @@ -1451,7 +1451,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = tyUncheckedArray: if n.len != 2: return nil n.sons[0] = makeDeref(n.sons[0]) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): n.sons[i] = semExprWithType(c, n.sons[i], flags*{efInTypeof, efDetermineType}) # Arrays index type is dictated by the range's type @@ -1786,7 +1786,7 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) = n.sons[0] = n.sons[0].sons[1] n.sons[0] = takeImplicitAddr(c, n.sons[0], t.kind == tyLent) of tyTuple: - for i in 0..<t.sonsLen: + for i in 0..<t.len: let e = skipTypes(t.sons[i], {tyGenericInst, tyAlias, tySink}) if e.kind in {tyVar, tyLent}: e.flags.incl tfVarIsPtr # bugfix for #4048, #4910, #6892 @@ -1896,7 +1896,6 @@ proc expectString(c: PContext, n: PNode): string = proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym = result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info) - result.flags = {sfGenSym} proc semExpandToAst(c: PContext, n: PNode): PNode = let macroCall = n[1] @@ -1947,7 +1946,7 @@ proc semExpandToAst(c: PContext, n: PNode): PNode = proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym, flags: TExprFlags = {}): PNode = - if sonsLen(n) == 2: + if len(n) == 2: n.sons[0] = newSymNode(magicSym, n.info) result = semExpandToAst(c, n) else: @@ -2077,14 +2076,14 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = # we replace this node by a 'true' or 'false' node: - if sonsLen(n) != 2: return semDirectOp(c, n, flags) + if len(n) != 2: return semDirectOp(c, n, flags) result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil)) result.info = n.info result.typ = getSysType(c.graph, n.info, tyBool) proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode = - if sonsLen(n) == 3: + if len(n) == 3: # XXX ugh this is really a hack: shallowCopy() can be overloaded only # with procs that take not 2 parameters: result = newNodeI(nkFastAsgn, n.info) @@ -2121,7 +2120,7 @@ proc setMs(n: PNode, s: PSym): PNode = n.sons[0].info = n.info proc semSizeof(c: PContext, n: PNode): PNode = - if sonsLen(n) != 2: + if len(n) != 2: localError(c.config, n.info, errXExpectsTypeOrValue % "sizeof") else: n.sons[1] = semExprWithType(c, n.sons[1], {efDetermineType}) @@ -2267,7 +2266,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = whenNimvm = exprNode.sym.magic == mNimvm if whenNimvm: n.flags.incl nfLL - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] case it.kind of nkElifBranch, nkElifExpr: @@ -2305,12 +2304,12 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode = proc semSetConstr(c: PContext, n: PNode): PNode = result = newNodeI(nkCurly, n.info) result.typ = newTypeS(tySet, c) - if sonsLen(n) == 0: + if len(n) == 0: rawAddSon(result.typ, newTypeS(tyEmpty, c)) else: # only semantic checking for all elements, later type checking: var typ: PType = nil - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if isRange(n.sons[i]): checkSonsLen(n.sons[i], 3, c.config) n.sons[i].sons[1] = semExprWithType(c, n.sons[i].sons[1]) @@ -2334,7 +2333,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = elif lengthOrd(c.config, typ) > MaxSetElements: typ = makeRangeType(c, 0, MaxSetElements-1, n.info) addSonSkipIntLit(result.typ, typ) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var m: PNode let info = n.sons[i].info if isRange(n.sons[i]): @@ -2353,7 +2352,7 @@ proc semTableConstr(c: PContext, n: PNode): PNode = var lastKey = 0 for i in 0..n.len-1: var x = n.sons[i] - if x.kind == nkExprColonExpr and sonsLen(x) == 2: + if x.kind == nkExprColonExpr and len(x) == 2: for j in lastKey ..< i: var pair = newNodeI(nkTupleConstr, x.info) pair.add(n.sons[j]) @@ -2375,7 +2374,7 @@ type paNone, paSingle, paTupleFields, paTuplePositions proc checkPar(c: PContext; n: PNode): TParKind = - var length = sonsLen(n) + var length = len(n) if length == 0: result = paTuplePositions # () elif length == 1: @@ -2401,7 +2400,7 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = var typ = newTypeS(tyTuple, c) typ.n = newNodeI(nkRecList, n.info) # nkIdentDefs var ids = initIntSet() - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if n[i].kind != nkExprColonExpr: illFormedAst(n.sons[i], c.config) let id = considerQuotedIdent(c, n[i][0]) @@ -2427,7 +2426,7 @@ proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = result = n # we don't modify n, but compute the type: result.kind = nkTupleConstr var typ = newTypeS(tyTuple, c) # leave typ.n nil! - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): n.sons[i] = semExprWithType(c, n.sons[i], flags*{efAllowDestructor}) addSonSkipIntLit(typ, n.sons[i].typ) result.typ = typ @@ -2749,7 +2748,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkUsingStmt: result = semUsing(c, n) of nkAsmStmt: result = semAsm(c, n) of nkYieldStmt: result = semYield(c, n) - of nkPragma: pragma(c, c.p.owner, n, stmtPragmas) + of nkPragma: pragma(c, c.p.owner, n, stmtPragmas, true) of nkIteratorDef: result = semIterator(c, n) of nkProcDef: result = semProc(c, n) of nkFuncDef: result = semFunc(c, n) diff --git a/compiler/semfields.nim b/compiler/semfields.nim index 88d57576a..1480374dd 100644 --- a/compiler/semfields.nim +++ b/compiler/semfields.nim @@ -27,7 +27,7 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode = of nkIdent, nkSym: result = n let ident = considerQuotedIdent(c.c, n) - var L = sonsLen(forLoop) + var L = len(forLoop) if c.replaceByFieldName: if ident.id == considerQuotedIdent(c.c, forLoop[0]).id: let fieldName = if c.tupleType.isNil: c.field.name.s @@ -54,8 +54,8 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode = localError(c.c.config, n.info, "'continue' not supported in a 'fields' loop") result = copyNode(n) - newSons(result, sonsLen(n)) - for i in 0 ..< sonsLen(n): + newSons(result, len(n)) + for i in 0 ..< len(n): result.sons[i] = instFieldLoopBody(c, n.sons[i], forLoop) type @@ -120,9 +120,9 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = var stmts = newNodeI(nkStmtList, n.info) result.sons[1] = stmts - var length = sonsLen(n) + var length = len(n) var call = n.sons[length-2] - if length-2 != sonsLen(call)-1 + ord(m==mFieldPairs): + if length-2 != len(call)-1 + ord(m==mFieldPairs): localError(c.config, n.info, errWrongNumberOfVariables) return result @@ -139,7 +139,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode = inc(c.p.nestedLoopCounter) if tupleTypeA.kind == tyTuple: var loopBody = n.sons[length-1] - for i in 0..sonsLen(tupleTypeA)-1: + for i in 0..len(tupleTypeA)-1: openScope(c) var fc: TFieldInstCtx fc.tupleType = tupleTypeA diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 81efc2436..5ba9c92ba 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -104,7 +104,7 @@ proc ordinalValToString*(a: PNode; g: ModuleGraph): string = result = $chr(toInt64(x) and 0xff) of tyEnum: var n = t.n - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if n.sons[i].kind != nkSym: internalError(g.config, a.info, "ordinalValToString") var field = n.sons[i].sym if field.position == x: @@ -194,7 +194,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = elif a.kind in {nkStrLit..nkTripleStrLit}: result = newIntNodeT(toInt128(a.strVal.len), n, g) else: - result = newIntNodeT(toInt128(sonsLen(a)), n, g) + result = newIntNodeT(toInt128(len(a)), n, g) of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away # XXX: Hides overflow/underflow of mAbsI: result = foldAbs(getInt(a), n, g) @@ -371,7 +371,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = proc getConstIfExpr(c: PSym, n: PNode; g: ModuleGraph): PNode = result = nil - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it.len == 2: var e = getConstExpr(c, it.sons[0], g) @@ -400,16 +400,16 @@ proc leValueConv*(a, b: PNode): bool = else: result = false # internalError(a.info, "leValueConv") proc magicCall(m: PSym, n: PNode; g: ModuleGraph): PNode = - if sonsLen(n) <= 1: return + if len(n) <= 1: return var s = n.sons[0].sym var a = getConstExpr(m, n.sons[1], g) var b, c: PNode if a == nil: return - if sonsLen(n) > 2: + if len(n) > 2: b = getConstExpr(m, n.sons[2], g) if b == nil: return - if sonsLen(n) > 3: + if len(n) > 3: c = getConstExpr(m, n.sons[3], g) if c == nil: return result = evalOp(s.magic, n, a, b, c, g) @@ -430,8 +430,8 @@ proc rangeCheck(n: PNode, value: Int128; g: ModuleGraph) = " to " & typeToString(n.typ)) proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode = - let dstTyp = skipTypes(n.typ, abstractRange) - let srcTyp = skipTypes(a.typ, abstractRange) + let dstTyp = skipTypes(n.typ, abstractRange - {tyTypeDesc}) + let srcTyp = skipTypes(a.typ, abstractRange - {tyTypeDesc}) # if srcTyp.kind == tyUInt64 and "FFFFFF" in $n: @@ -489,11 +489,11 @@ proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode = var idx = toInt64(getOrdValue(y)) case x.kind of nkPar, nkTupleConstr: - if idx >= 0 and idx < sonsLen(x): + if idx >= 0 and idx < len(x): result = x.sons[idx] if result.kind == nkExprColonExpr: result = result.sons[1] else: - localError(g.config, n.info, formatErrorIndexBound(idx, sonsLen(x)-1) & $n) + localError(g.config, n.info, formatErrorIndexBound(idx, len(x)-1) & $n) of nkBracket: idx = idx - toInt64(firstOrd(g.config, x.typ)) if idx >= 0 and idx < x.len: result = x.sons[int(idx)] @@ -514,7 +514,7 @@ proc foldFieldAccess(m: PSym, n: PNode; g: ModuleGraph): PNode = if x == nil or x.kind notin {nkObjConstr, nkPar, nkTupleConstr}: return var field = n.sons[1].sym - for i in ord(x.kind == nkObjConstr) ..< sonsLen(x): + for i in ord(x.kind == nkObjConstr) ..< len(x): var it = x.sons[i] if it.kind != nkExprColonExpr: # lookup per index: @@ -529,7 +529,7 @@ proc foldFieldAccess(m: PSym, n: PNode; g: ModuleGraph): PNode = proc foldConStrStr(m: PSym, n: PNode; g: ModuleGraph): PNode = result = newNodeIT(nkStrLit, n.info, n.typ) result.strVal = "" - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): let a = getConstExpr(m, n.sons[i], g) if a == nil: return nil result.strVal.add(getStrOrChar(a)) @@ -631,12 +631,12 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = var a = getArrayConstr(m, n.sons[1], g) if a.kind == nkBracket: # we can optimize it away: - result = newIntNodeT(sonsLen(a)-1, n, g) + result = newIntNodeT(len(a)-1, n, g) of mLengthOpenArray: var a = getArrayConstr(m, n.sons[1], g) if a.kind == nkBracket: # we can optimize it away! This fixes the bug ``len(134)``. - result = newIntNodeT(sonsLen(a), n, g) + result = newIntNodeT(len(a), n, g) else: result = magicCall(m, n, g) of mLengthArray: @@ -685,7 +685,7 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = addSon(result, b) #of nkObjConstr: # result = copyTree(n) - # for i in 1 ..< sonsLen(n): + # for i in 1 ..< len(n): # var a = getConstExpr(m, n.sons[i].sons[1]) # if a == nil: return nil # result.sons[i].sons[1] = a @@ -693,7 +693,7 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode = of nkPar, nkTupleConstr: # tuple constructor result = copyNode(n) - if (sonsLen(n) > 0) and (n.sons[0].kind == nkExprColonExpr): + if (len(n) > 0) and (n.sons[0].kind == nkExprColonExpr): for i, expr in n.pairs: let exprNew = copyNode(expr) # nkExprColonExpr exprNew.add expr[0] diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index 4116df357..89051ec4c 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -316,13 +316,13 @@ proc semGenericStmt(c: PContext, n: PNode, withBracketExpr ctx, a.sons[0]: result = semGenericStmt(c, result, flags, ctx) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx) of nkIfStmt: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, ctx) of nkWhenStmt: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): # bug #8603: conditions of 'when' statements are not # in a 'mixin' context: let it = n[i] @@ -333,22 +333,22 @@ proc semGenericStmt(c: PContext, n: PNode, n.sons[i] = semGenericStmt(c, it, flags+{withinMixin}, ctx) of nkWhileStmt: openScope(c) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): n.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx) closeScope(c) of nkCaseStmt: openScope(c) n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var a = n.sons[i] checkMinSonsLen(a, 1, c.config) - var L = sonsLen(a) + var L = len(a) for j in 0 .. L-2: a.sons[j] = semGenericStmt(c, a.sons[j], flags, ctx) a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, ctx) closeScope(c) of nkForStmt, nkParForStmt: - var L = sonsLen(n) + var L = len(n) openScope(c) n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, ctx) for i in 0 .. L - 3: @@ -372,10 +372,10 @@ proc semGenericStmt(c: PContext, n: PNode, of nkTryStmt, nkHiddenTryStmt: checkMinSonsLen(n, 2, c.config) n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var a = n.sons[i] checkMinSonsLen(a, 1, c.config) - var L = sonsLen(a) + var L = len(a) openScope(c) for j in 0 .. L-2: if a.sons[j].isInfixAs(): @@ -387,28 +387,28 @@ proc semGenericStmt(c: PContext, n: PNode, closeScope(c) of nkVarSection, nkLetSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a, c.config) checkMinSonsLen(a, 3, c.config) - var L = sonsLen(a) + var L = len(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) for j in 0 .. L-3: addTempDecl(c, getIdentNode(c, a.sons[j]), skVar) of nkGenericParams: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if (a.kind != nkIdentDefs): illFormedAst(a, c.config) checkMinSonsLen(a, 3, c.config) - var L = sonsLen(a) + var L = len(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) # do not perform symbol lookup for default expressions for j in 0 .. L-3: addTempDecl(c, getIdentNode(c, a.sons[j]), skType) of nkConstSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkConstDef): illFormedAst(a, c.config) @@ -417,13 +417,13 @@ proc semGenericStmt(c: PContext, n: PNode, a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, ctx) a.sons[2] = semGenericStmt(c, a.sons[2], flags, ctx) of nkTypeSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkTypeDef): illFormedAst(a, c.config) checkSonsLen(a, 3, c.config) addTempDecl(c, getIdentNode(c, a.sons[0]), skType) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkTypeDef): illFormedAst(a, c.config) @@ -436,10 +436,10 @@ proc semGenericStmt(c: PContext, n: PNode, else: a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx) of nkEnumTy: - if n.sonsLen > 0: + if n.len > 0: if n.sons[0].kind != nkEmpty: n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var a: PNode case n.sons[i].kind of nkEnumFieldDef: a = n.sons[i].sons[0] @@ -452,11 +452,11 @@ proc semGenericStmt(c: PContext, n: PNode, checkMinSonsLen(n, 1, c.config) if n.sons[0].kind != nkEmpty: n.sons[0] = semGenericStmt(c, n.sons[0], flags+{withinTypeDesc}, ctx) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var a = n.sons[i] if (a.kind != nkIdentDefs): illFormedAst(a, c.config) checkMinSonsLen(a, 3, c.config) - var L = sonsLen(a) + var L = len(a) a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx) a.sons[L-1] = semGenericStmt(c, a.sons[L-1], flags, ctx) for j in 0 .. L-3: @@ -489,7 +489,7 @@ proc semGenericStmt(c: PContext, n: PNode, checkMinSonsLen(n, 2, c.config) result.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx) when defined(nimsuggest): diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 43aa08818..0a8a3c3af 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -387,7 +387,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, if c.inGenericContext == 0: instantiateBody(c, n, fn.typ.n, result, fn) sideEffectsCheck(c, result) - if result.magic != mSlice: + if result.magic notin {mSlice, mTypeOf}: # 'toOpenArray' is special and it is allowed to return 'openArray': paramsTypeCheck(c, result.typ) else: diff --git a/compiler/semmacrosanity.nim b/compiler/semmacrosanity.nim index af740e518..890a521f5 100644 --- a/compiler/semmacrosanity.nim +++ b/compiler/semmacrosanity.nim @@ -16,14 +16,14 @@ proc ithField(n: PNode, field: var int): PSym = result = nil case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = ithField(n.sons[i], field) if result != nil: return of nkRecCase: if n.sons[0].kind != nkSym: return result = ithField(n.sons[0], field) if result != nil: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: result = ithField(lastSon(n.sons[i]), field) diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index ed0c12a95..29f51d578 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -180,7 +180,7 @@ proc semTypeTraits(c: PContext, n: PNode): PNode = checkMinSonsLen(n, 2, c.config) let t = n.sons[1].typ internalAssert c.config, t != nil and t.kind == tyTypeDesc - if t.sonsLen > 0: + if t.len > 0: # This is either a type known to sem or a typedesc # param to a regular proc (again, known at instantiation) result = evalTypeTrait(c, n, t, getCurrOwner(c)) @@ -293,7 +293,7 @@ proc semDynamicBindSym(c: PContext, n: PNode): PNode = proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode proc semOf(c: PContext, n: PNode): PNode = - if sonsLen(n) == 3: + if len(n) == 3: n.sons[1] = semExprWithType(c, n.sons[1]) n.sons[2] = semExprWithType(c, n.sons[2], {efDetermineType}) #restoreOldStyleType(n.sons[1]) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index c31f86f98..9957e772e 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -380,7 +380,7 @@ proc trackTryStmt(tracked: PEffects, n: PNode) = # Collect the exceptions caught by the except branches for i in 1 ..< n.len: let b = n.sons[i] - let blen = sonsLen(b) + let blen = len(b) if b.kind == nkExceptBranch: inc branches if blen == 1: @@ -398,7 +398,7 @@ proc trackTryStmt(tracked: PEffects, n: PNode) = # Add any other exception raised in the except bodies for i in 1 ..< n.len: let b = n.sons[i] - let blen = sonsLen(b) + let blen = len(b) if b.kind == nkExceptBranch: setLen(tracked.init, oldState) track(tracked, b.sons[blen-1]) @@ -430,7 +430,7 @@ proc isForwardedProc(n: PNode): bool = result = n.kind == nkSym and sfForward in n.sym.flags proc trackPragmaStmt(tracked: PEffects, n: PNode) = - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if whichPragma(it) == wEffects: # list the computed effects up to here: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 1b7d61376..512dbca68 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -157,7 +157,7 @@ proc semIf(c: PContext, n: PNode; flags: TExprFlags): PNode = result = n var typ = commonTypeBegin var hasElse = false - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it.len == 2: openScope(c) @@ -208,7 +208,7 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode = n[0] = semExprBranchScope(c, n[0]) typ = commonType(typ, n[0].typ) - var last = sonsLen(n) - 1 + var last = len(n) - 1 var catchAllExcepts = 0 for i in 1 .. last: @@ -363,13 +363,13 @@ 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 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[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 = sonsLen(a) + 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: @@ -416,7 +416,7 @@ 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 = sonsLen(obj.n) + field.position = len(obj.n) addSon(obj.n, newSymNode(field)) n.sons[0] = makeDeref x n.sons[1] = newSymNode(field) @@ -437,13 +437,13 @@ 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 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[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 = sonsLen(a) + var length = len(a) var typ: PType = nil if a.sons[length-2].kind != nkEmpty: @@ -502,7 +502,7 @@ 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 != sonsLen(tup): + elif length-2 != len(tup): localError(c.config, a.info, errWrongNumberOfVariables) b = newNodeI(nkVarTuple, a.info) newSons(b, length) @@ -583,13 +583,13 @@ 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 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[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 = sonsLen(a) + var length = len(a) var typ: PType = nil if a.sons[length-2].kind != nkEmpty: @@ -632,7 +632,7 @@ 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 != sonsLen(typ): + elif length-2 != len(typ): localError(c.config, a.info, errWrongNumberOfVariables) b = newNodeI(nkVarTuple, a.info) newSons(b, length) @@ -675,7 +675,7 @@ proc symForVar(c: PContext, n: PNode): PSym = proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = result = n - var length = sonsLen(n) + var length = len(n) let iterBase = n.sons[length-2].typ var iter = skipTypes(iterBase, {tyGenericInst, tyAlias, tySink}) var iterAfterVarLent = iter.skipTypes({tyLent, tyVar}) @@ -684,9 +684,9 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = if iterAfterVarLent.kind != tyTuple or length == 3: if length == 3: if n.sons[0].kind == nkVarTuple: - if sonsLen(n[0])-1 != sonsLen(iterAfterVarLent): + if len(n[0])-1 != len(iterAfterVarLent): localError(c.config, n[0].info, errWrongNumberOfVariables) - for i in 0 ..< sonsLen(n[0])-1: + for i in 0 ..< len(n[0])-1: var v = symForVar(c, n[0][i]) if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal) case iter.kind @@ -717,7 +717,7 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = elif v.owner == nil: v.owner = getCurrOwner(c) else: localError(c.config, n.info, errWrongNumberOfVariables) - elif length-2 != sonsLen(iterAfterVarLent): + elif length-2 != len(iterAfterVarLent): localError(c.config, n.info, errWrongNumberOfVariables) else: for i in 0 .. length - 3: @@ -733,9 +733,9 @@ proc semForVars(c: PContext, n: PNode; flags: TExprFlags): PNode = iter[i].skipTypes({tyLent}) else: iter[i] - if sonsLen(n[i])-1 != sonsLen(iter[i]): + if len(n[i])-1 != len(iter[i]): localError(c.config, n[i].info, errWrongNumberOfVariables) - for j in 0 ..< sonsLen(n[i])-1: + for j in 0 ..< len(n[i])-1: var v = symForVar(c, n[i][j]) if getCurrOwner(c).kind == skModule: incl(v.flags, sfGlobal) if mutable: @@ -859,7 +859,7 @@ proc handleCaseStmtMacro(c: PContext; n: PNode): PNode = proc semFor(c: PContext, n: PNode; flags: TExprFlags): PNode = checkMinSonsLen(n, 3, c.config) - var length = sonsLen(n) + var length = len(n) if forLoopMacros in c.features: result = handleForLoopMacro(c, n) if result != nil: return result @@ -929,7 +929,7 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = return result localError(c.config, n.sons[0].info, errSelectorMustBeOfCertainTypes) return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): setCaseContextIdx(c, i) var x = n.sons[i] when defined(nimsuggest): @@ -939,7 +939,7 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode = of nkOfBranch: checkMinSonsLen(x, 2, c.config) semCaseBranch(c, n, x, i, covered) - var last = sonsLen(x)-1 + var last = len(x)-1 x.sons[last] = semExprBranchScope(c, x.sons[last]) typ = commonType(typ, x.sons[last]) of nkElifBranch: @@ -1000,7 +1000,7 @@ 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 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkSym: addDecl(c, a.sym) else: illFormedAst(a, c.config) @@ -1017,7 +1017,7 @@ 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 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] when defined(nimsuggest): if c.config.cmd == cmdIdeTools: @@ -1149,7 +1149,7 @@ proc checkCovariantParamsUsages(c: PContext; genericType: PType) = discard traverseSubTypes(c, body) proc typeSectionRightSidePass(c: PContext, n: PNode) = - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue if a.kind != nkTypeDef: illFormedAst(a, c.config) @@ -1186,7 +1186,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = if body != nil: body.sym = s body.size = -1 # could not be computed properly - s.typ.sons[sonsLen(s.typ) - 1] = body + s.typ.sons[len(s.typ) - 1] = body if tfCovariant in s.typ.flags: checkCovariantParamsUsages(c, s.typ) # XXX: This is a temporary limitation: @@ -1276,7 +1276,7 @@ proc checkForMetaFields(c: PContext; n: PNode) = internalAssert c.config, false proc typeSectionFinalPass(c: PContext, n: PNode) = - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue let name = typeSectionTypeName(c, a.sons[0]) @@ -1374,7 +1374,7 @@ 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 ..< sonsLen(n): + for i in 1 ..< len(n): if n.sons[i].kind == nkSym: addParamOrResult(c, n.sons[i].sym, kind) else: illFormedAst(n, c.config) @@ -1498,7 +1498,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[paramsPos], gp, s) # paramsTypeCheck(c, s.typ) - if sonsLen(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty: + if len(gp) > 0 and n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: n.sons[genericParamsPos] = gp else: @@ -1724,7 +1724,7 @@ type proc hasObjParam(s: PSym): bool = var t = s.typ - for col in 1 ..< sonsLen(t): + for col in 1 ..< len(t): if skipTypes(t.sons[col], skipPtrs).kind == tyObject: return true @@ -1738,7 +1738,7 @@ 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 ..< sonsLen(tt): + for col in 1 ..< len(tt): let t = tt.sons[col] if t != nil and t.kind == tyGenericInvocation: var x = skipTypes(t.sons[0], {tyVar, tyLent, tyPtr, tyRef, tyGenericInst, @@ -1811,7 +1811,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # process parameters: if n.sons[paramsPos].kind != nkEmpty: semParamList(c, n.sons[paramsPos], gp, s) - if sonsLen(gp) > 0: + if len(gp) > 0: if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: n.sons[genericParamsPos] = gp @@ -2035,7 +2035,7 @@ proc semConverterDef(c: PContext, n: PNode): PNode = var s = result.sons[namePos].sym var t = s.typ if t.sons[0] == nil: localError(c.config, n.info, errXNeedsReturnType % "converter") - if sonsLen(t) != 2: localError(c.config, n.info, "a converter takes exactly one argument") + if len(t) != 2: localError(c.config, n.info, "a converter takes exactly one argument") addConverter(c, s) proc semMacroDef(c: PContext, n: PNode): PNode = @@ -2069,7 +2069,7 @@ proc incMod(c: PContext, n: PNode, it: PNode, includeStmtResult: PNode) = proc evalInclude(c: PContext, n: PNode): PNode = result = newNodeI(nkStmtList, n.info) addSon(result, n) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var imp: PNode let it = n.sons[i] if it.kind == nkInfix and it.len == 3 and it[0].ident.s != "/": @@ -2150,7 +2150,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode = LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} result = n result.kind = nkStmtList - var length = sonsLen(n) + var length = len(n) var voidContext = false var last = length-1 # by not allowing for nkCommentStmt etc. we ensure nkStmtListExpr actually diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index acf32d1b3..8c39a7676 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -34,7 +34,7 @@ type spNone, spGenSym, spInject proc symBinding(n: PNode): TSymBinding = - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] var key = if it.kind == nkExprColonExpr: it.sons[0] else: it if key.kind == nkIdent: @@ -125,6 +125,7 @@ type cursorInBody: bool # only for nimsuggest scopeN: int noGenSym: int + inTemplateHeader: int template withBracketExpr(ctx, x, body: untyped) = body @@ -144,9 +145,12 @@ proc getIdentNode(c: var TemplCtx, n: PNode): PNode = illFormedAst(n, c.c.config) result = n +template oldCheck(cx: TemplCtx; cond: bool): bool = + (optNimV019 notin cx.c.config.globalOptions or cond) + proc isTemplParam(c: TemplCtx, n: PNode): bool {.inline.} = result = n.kind == nkSym and n.sym.kind == skParam and - n.sym.owner == c.owner and sfGenSym notin n.sym.flags + n.sym.owner == c.owner and sfTemplateParam in n.sym.flags proc semTemplBody(c: var TemplCtx, n: PNode): PNode @@ -203,7 +207,7 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = else: replaceIdentBySym(c.c, n, ident) else: - if (n.kind == nkPragmaExpr and sonsLen(n) >= 2 and n.sons[1].kind == nkPragma): + 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: openScope(c) @@ -231,6 +235,8 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) = styleCheckDef(c.c.config, n.info, local) onDef(n.info, local) replaceIdentBySym(c.c, n, newSymNode(local, n.info)) + if k == skParam and c.inTemplateHeader > 0: + local.flags.incl sfTemplateParam else: replaceIdentBySym(c.c, n, ident) @@ -245,15 +251,15 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym; isField: bool): PNode = of OverloadableSyms: result = symChoice(c, n, s, scOpen, isField) of skGenericParam: - if isField: result = n + if isField and sfGenSym in s.flags: result = n else: result = newSymNodeTypeDesc(s, n.info) of skParam: result = n of skType: - if isField: result = n + if isField and sfGenSym in s.flags: result = n else: result = newSymNodeTypeDesc(s, n.info) else: - if isField: result = n + if isField and sfGenSym in s.flags: result = n else: result = newSymNode(s, n.info) proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode = @@ -288,7 +294,14 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode = n.sons[namePos] = semRoutineInTemplName(c, n.sons[namePos]) # open scope for parameters openScope(c) - for i in patternPos..miscPos: + for i in patternPos..paramsPos-1: + n.sons[i] = semTemplBody(c, n.sons[i]) + + if k == skTemplate: inc(c.inTemplateHeader) + n.sons[paramsPos] = semTemplBody(c, n.sons[paramsPos]) + if k == skTemplate: dec(c.inTemplateHeader) + + for i in paramsPos+1..miscPos: n.sons[i] = semTemplBody(c, n.sons[i]) # open scope for locals inc c.scopeN @@ -301,12 +314,12 @@ 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 ..< sonsLen(n): + for i in start ..< len(n): var a = n.sons[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 = sonsLen(a) + var L = len(a) when defined(nimsuggest): inc c.c.inTypeContext a.sons[L-2] = semTemplBody(c, a.sons[L-2]) @@ -331,8 +344,8 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = if n.ident.id in c.toInject: return n let s = qualifiedLookUp(c.c, n, {}) if s != nil: - if s.owner == c.owner and s.kind == skParam and - (sfGenSym notin s.flags or c.noGenSym == 0): + if s.owner == c.owner and s.kind == skParam and sfTemplateParam in s.flags: + # oldCheck(c, sfGenSym notin s.flags or c.noGenSym == 0): incl(s.flags, sfUsed) result = newSymNode(s, n.info) onUse(n.info, s) @@ -358,7 +371,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = of nkEmpty, nkSym..nkNilLit, nkComesFrom: discard of nkIfStmt: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it.len == 2: openScope(c) @@ -369,27 +382,27 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = n.sons[i] = semTemplBodyScope(c, it) of nkWhileStmt: openScope(c) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): n.sons[i] = semTemplBody(c, n.sons[i]) closeScope(c) of nkCaseStmt: openScope(c) n.sons[0] = semTemplBody(c, n.sons[0]) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var a = n.sons[i] checkMinSonsLen(a, 1, c.c.config) - var L = sonsLen(a) + 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]) closeScope(c) of nkForStmt, nkParForStmt: - var L = sonsLen(n) + var L = len(n) openScope(c) n.sons[L-2] = semTemplBody(c, n.sons[L-2]) for i in 0 .. L - 3: if n[i].kind == nkVarTuple: - for j in 0 ..< sonsLen(n[i])-1: + for j in 0 ..< len(n[i])-1: addLocalDecl(c, n[i][j], skForVar) else: addLocalDecl(c, n.sons[i], skForVar) @@ -414,10 +427,10 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = of nkTryStmt, nkHiddenTryStmt: checkMinSonsLen(n, 2, c.c.config) n.sons[0] = semTemplBodyScope(c, n.sons[0]) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var a = n.sons[i] checkMinSonsLen(a, 1, c.c.config) - var L = sonsLen(a) + var L = len(a) openScope(c) for j in 0 .. L-2: if a.sons[j].isInfixAs(): @@ -434,7 +447,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = n.sons[0] = semTemplBody(c, n.sons[0]) semTemplSomeDecl(c, n, skParam, 1) of nkConstSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkConstDef): illFormedAst(a, c.c.config) @@ -443,13 +456,13 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = a.sons[1] = semTemplBody(c, a.sons[1]) a.sons[2] = semTemplBody(c, a.sons[2]) of nkTypeSection: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[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 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind == nkCommentStmt: continue if (a.kind != nkTypeDef): illFormedAst(a, c.c.config) @@ -542,16 +555,16 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = if n.kind == nkDotExpr: result = n result.sons[0] = semTemplBody(c, n.sons[0]) - inc c.noGenSym + if optNimV019 notin c.c.config.globalOptions: inc c.noGenSym result.sons[1] = semTemplBody(c, n.sons[1]) - dec c.noGenSym + if optNimV019 notin c.c.config.globalOptions: dec c.noGenSym else: result = semTemplBodySons(c, n) of nkExprColonExpr, nkExprEqExpr: if n.len == 2: - inc c.noGenSym + if optNimV019 notin c.c.config.globalOptions: inc c.noGenSym result.sons[0] = semTemplBody(c, n.sons[0]) - dec c.noGenSym + if optNimV019 notin c.c.config.globalOptions: dec c.noGenSym result.sons[1] = semTemplBody(c, n.sons[1]) else: result = semTemplBodySons(c, n) @@ -583,7 +596,7 @@ 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 ..< sonsLen(n): + for i in 0 ..< len(n): result.sons[i] = semTemplBodyDirty(c, n.sons[i]) proc semTemplateDef(c: PContext, n: PNode): PNode = @@ -625,9 +638,11 @@ proc semTemplateDef(c: PContext, n: PNode): PNode = # 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 - param.flags.excl sfGenSym + param.flags.incl sfTemplateParam + if optNimV019 in c.config.globalOptions: + param.flags.excl sfGenSym if param.typ.kind != tyUntyped: allUntyped = false - if sonsLen(gp) > 0: + if len(gp) > 0: if n.sons[genericParamsPos].kind == nkEmpty: # we have a list of implicit type parameters: n.sons[genericParamsPos] = gp @@ -740,7 +755,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = if stupidStmtListExpr(n): result = semPatternBody(c, n.lastSon) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result.sons[i] = semPatternBody(c, n.sons[i]) of nkCallKinds: let s = qualifiedLookUp(c.c, n.sons[0], {}) @@ -773,7 +788,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = result.sons[1] = semPatternBody(c, n.sons[1]) return - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result.sons[i] = semPatternBody(c, n.sons[i]) else: # dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam', @@ -789,7 +804,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = of nkPar: if n.len == 1: return semPatternBody(c, n.sons[0]) else: discard - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result.sons[i] = semPatternBody(c, n.sons[i]) proc semPattern(c: PContext, n: PNode): PNode = diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 151318670..896db5c3c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -54,8 +54,8 @@ proc newConstraint(c: PContext, k: TTypeKind): PType = result.addSonSkipIntLit(newTypeS(k, c)) proc semEnum(c: PContext, n: PNode, prev: PType): PType = - if n.sonsLen == 0: return newConstraint(c, tyEnum) - elif n.sonsLen == 1: + if n.len == 0: return newConstraint(c, tyEnum) + elif n.len == 1: # don't create an empty tyEnum; fixes #3052 return errorType(c) var @@ -77,7 +77,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = var symbols: TStrTable if isPure: initStrTable(symbols) var hasNull = false - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): if n.sons[i].kind == nkEmpty: continue case n.sons[i].kind of nkEnumFieldDef: @@ -90,7 +90,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = var strVal: PNode = nil case skipTypes(v.typ, abstractInst-{tyTypeDesc}).kind of tyTuple: - if sonsLen(v) == 2: + if len(v) == 2: strVal = v.sons[1] # second tuple part is the string value if skipTypes(strVal.typ, abstractInst).kind in {tyString, tyCString}: if not isOrdinalType(v.sons[0].typ, allowEnumWithHoles=true): @@ -143,7 +143,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType = proc semSet(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tySet, prev, c) - if sonsLen(n) == 2 and n.sons[1].kind != nkEmpty: + if len(n) == 2 and n.sons[1].kind != nkEmpty: var base = semTypeNode(c, n.sons[1], nil) addSonSkipIntLit(result, base) if base.kind in {tyGenericInst, tyAlias, tySink}: base = lastSon(base) @@ -157,7 +157,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType = addSonSkipIntLit(result, errorType(c)) proc semContainerArg(c: PContext; n: PNode, kindStr: string; result: PType) = - if sonsLen(n) == 2: + if len(n) == 2: var base = semTypeNode(c, n.sons[1], nil) if base.kind == tyVoid: localError(c.config, n.info, errTIsNotAConcreteType % typeToString(base)) @@ -173,17 +173,17 @@ proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string, proc semVarargs(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyVarargs, prev, c) - if sonsLen(n) == 2 or sonsLen(n) == 3: + if len(n) == 2 or len(n) == 3: var base = semTypeNode(c, n.sons[1], nil) addSonSkipIntLit(result, base) - if sonsLen(n) == 3: + if len(n) == 3: result.n = newIdentNode(considerQuotedIdent(c, n.sons[2]), n.sons[2].info) else: localError(c.config, n.info, errXExpectsOneTypeParam % "varargs") addSonSkipIntLit(result, errorType(c)) proc semVarType(c: PContext, n: PNode, prev: PType): PType = - if sonsLen(n) == 1: + if len(n) == 1: result = newOrPrevType(tyVar, prev, c) var base = semTypeNode(c, n.sons[0], nil).skipTypes({tyTypeDesc}) if base.kind == tyVar: @@ -249,7 +249,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType = proc semRange(c: PContext, n: PNode, prev: PType): PType = result = nil - if sonsLen(n) == 2: + if len(n) == 2: if isRange(n[1]): result = semRangeAux(c, n[1], prev) let n = result.n @@ -315,7 +315,7 @@ proc semArrayIndex(c: PContext, n: PNode): PType = proc semArray(c: PContext, n: PNode, prev: PType): PType = var base: PType - if sonsLen(n) == 3: + if len(n) == 3: # 3 = length(array indx base) let indx = semArrayIndex(c, n[1]) var indxB = indx @@ -341,7 +341,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType = proc semOrdinal(c: PContext, n: PNode, prev: PType): PType = result = newOrPrevType(tyOrdinal, prev, c) - if sonsLen(n) == 2: + if len(n) == 2: var base = semTypeNode(c, n.sons[1], nil) if base.kind != tyGenericParam: if not isOrdinalType(base): @@ -414,7 +414,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym = result = errorSym(c, n) proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType = - if sonsLen(n) == 0: + if len(n) == 0: localError(c.config, n.info, errTypeExpected) result = newOrPrevType(tyTuple, prev, c) for it in n: @@ -426,11 +426,11 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType = result.n = newNodeI(nkRecList, n.info) var check = initIntSet() var counter = 0 - for i in ord(n.kind == nkBracketExpr) ..< sonsLen(n): + for i in ord(n.kind == nkBracketExpr) ..< len(n): var a = n.sons[i] if (a.kind != nkIdentDefs): illFormedAst(a, c.config) checkMinSonsLen(a, 3, c.config) - var length = sonsLen(a) + var length = len(a) if a.sons[length - 2].kind != nkEmpty: typ = semTypeNode(c, a.sons[length - 2], nil) else: @@ -460,7 +460,7 @@ proc semIdentVis(c: PContext, kind: TSymKind, n: PNode, allowed: TSymFlags): PSym = # identifier with visibility if n.kind == nkPostfix: - if sonsLen(n) == 2: + if len(n) == 2: # for gensym'ed identifiers the identifier may already have been # transformed to a symbol and we need to use that here: result = newSymG(kind, n.sons[1], c) @@ -497,7 +497,7 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode, proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) = let ex = t[branchIndex][currentEx].skipConv for i in 1 .. branchIndex: - for j in 0 .. sonsLen(t.sons[i]) - 2: + for j in 0 .. len(t.sons[i]) - 2: if i == branchIndex and j == currentEx: break if overlap(t.sons[i].sons[j].skipConv, ex): localError(c.config, ex.info, errDuplicateCaseLabel) @@ -534,7 +534,7 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode, proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, covered: var Int128) = - let lastIndex = sonsLen(branch) - 2 + let lastIndex = len(branch) - 2 for i in 0..lastIndex: var b = branch.sons[i] if b.kind == nkRange: @@ -544,7 +544,7 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, else: # constant sets and arrays are allowed: var r = semConstExpr(c, b) - if r.kind in {nkCurly, nkBracket} and len(r) == 0 and sonsLen(branch)==2: + if r.kind in {nkCurly, nkBracket} and len(r) == 0 and len(branch)==2: # discarding ``{}`` and ``[]`` branches silently delSon(branch, 0) return @@ -570,13 +570,13 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, checkForOverlap(c, t, i, branchIndex) # Elements added above needs to be checked for overlaps. - for i in lastIndex.succ..(sonsLen(branch) - 2): + for i in lastIndex.succ..(len(branch) - 2): checkForOverlap(c, t, i, branchIndex) proc toCover(c: PContext, t: PType): Int128 = let t2 = skipTypes(t, abstractVarRange-{tyTypeDesc}) if t2.kind == tyEnum and enumHasHoles(t2): - result = toInt128(sonsLen(t2.n)) + result = toInt128(len(t2.n)) else: # <---- let t = skipTypes(t, abstractVar-{tyTypeDesc}) @@ -635,7 +635,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, errorUndeclaredIdentifier(c, n.sons[0].info, typ.sym.name.s) elif not isOrdinalType(typ): localError(c.config, n.sons[0].info, "selector must be of an ordinal type, float or string") - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var b = copyTree(n.sons[i]) addSon(a, b) case n.sons[i].kind @@ -648,7 +648,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var IntSet, pos: var int, localError(c.config, b.info, "invalid else, all cases are already covered") chckCovered = false else: illFormedAst(n, c.config) - delSon(b, sonsLen(b) - 1) + delSon(b, len(b) - 1) semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype, hasCaseFields = true) if chckCovered and covered != toCover(c, a.sons[0].typ): if a.sons[0].typ.kind == tyEnum: @@ -664,7 +664,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, case n.kind of nkRecWhen: var branch: PNode = nil # the branch to take - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it == nil: illFormedAst(n, c.config) var idx = 1 @@ -701,12 +701,12 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, of nkRecList: # attempt to keep the nesting at a sane level: var a = if father.kind == nkRecList: father else: copyNode(n) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): semRecordNodeAux(c, n.sons[i], check, pos, a, rectype) if a != father: addSon(father, a) of nkIdentDefs: checkMinSonsLen(n, 3, c.config) - var length = sonsLen(n) + var length = len(n) var a: PNode if father.kind != nkRecList and length>=4: a = newNodeI(nkRecList, n.info) else: a = newNodeI(nkEmpty, n.info) @@ -721,7 +721,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, propagateToOwner(rectype, typ) var fieldOwner = if c.inGenericContext > 0: c.getCurrOwner else: rectype.sym - for i in 0 .. sonsLen(n)-3: + for i in 0 .. len(n)-3: var f = semIdentWithPragma(c, skField, n.sons[i], {sfExported}) suggestSym(c.config, n.sons[i].info, f, c.graph.usageSym) f.typ = typ @@ -756,13 +756,13 @@ proc addInheritedFieldsAux(c: PContext, check: var IntSet, pos: var int, of nkRecCase: if (n.sons[0].kind != nkSym): internalError(c.config, n.info, "addInheritedFieldsAux") addInheritedFieldsAux(c, check, pos, n.sons[0]) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: addInheritedFieldsAux(c, check, pos, lastSon(n.sons[i])) else: internalError(c.config, n.info, "addInheritedFieldsAux(record case branch)") of nkRecList, nkRecWhen, nkElifBranch, nkElse: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): addInheritedFieldsAux(c, check, pos, n.sons[i]) of nkSym: incl(check, n.sym.name.id) @@ -779,12 +779,12 @@ proc skipGenericInvocation(t: PType): PType {.inline.} = proc addInheritedFields(c: PContext, check: var IntSet, pos: var int, obj: PType) = assert obj.kind == tyObject - if (sonsLen(obj) > 0) and (obj.sons[0] != nil): + if (len(obj) > 0) and (obj.sons[0] != nil): addInheritedFields(c, check, pos, obj.sons[0].skipGenericInvocation) addInheritedFieldsAux(c, check, pos, obj.n) proc semObjectNode(c: PContext, n: PNode, prev: PType; isInheritable: bool): PType = - if n.sonsLen == 0: + if n.len == 0: return newConstraint(c, tyObject) var check = initIntSet() var pos = 0 @@ -850,6 +850,7 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = localError(c.config, n.info, "type '$1 void' is not allowed" % kindToStr[kind]) result = newOrPrevType(kind, prev, c) var isNilable = false + var isOwned = false # check every except the last is an object: for i in isCall .. n.len-2: let ni = n[i] @@ -857,16 +858,24 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType = isNilable = true else: let region = semTypeNode(c, ni, nil) - if region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin { + if region.kind == tyOwned: + isOwned = true + elif region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin { tyError, tyObject}: message c.config, n[i].info, errGenerated, "region needs to be an object type" + addSonSkipIntLit(result, region) else: message(c.config, n.info, warnDeprecated, "region for pointer types is deprecated") - addSonSkipIntLit(result, region) + addSonSkipIntLit(result, region) addSonSkipIntLit(result, t) if tfPartial in result.flags: if result.lastSon.kind == tyObject: incl(result.lastSon.flags, tfPartial) #if not isNilable: result.flags.incl tfNotNil + if isOwned and optNimV2 in c.config.globalOptions: + let t = newTypeS(tyOwned, c) + t.flags.incl tfHasOwned + t.rawAddSonNoPropagationOfTypeFlags result + result = t proc findEnforcedStaticType(t: PType): PType = # This handles types such as `static[T] and Foo`, @@ -973,7 +982,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result = addImplicitGeneric(c, t, paramTypId, info, genericParams, paramName) of tyDistinct: - if paramType.sonsLen == 1: + if paramType.len == 1: # disable the bindOnce behavior for the type class result = recurse(paramType.base, true) @@ -1005,7 +1014,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result = newTypeS(tyGenericInvocation, c) result.rawAddSon(paramType) - for i in 0 .. paramType.sonsLen - 2: + for i in 0 .. paramType.len - 2: if paramType.sons[i].kind == tyStatic: var staticCopy = paramType.sons[i].exactReplica staticCopy.flags.incl tfInferrableStatic @@ -1122,7 +1131,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, typ: PType = nil def: PNode = nil constraint: PNode = nil - length = sonsLen(a) + length = len(a) hasType = a.sons[length-2].kind != nkEmpty hasDefault = a.sons[length-1].kind != nkEmpty @@ -1272,7 +1281,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, proc semStmtListType(c: PContext, n: PNode, prev: PType): PType = checkMinSonsLen(n, 1, c.config) - var length = sonsLen(n) + var length = len(n) for i in 0 .. length - 2: n.sons[i] = semStmt(c, n.sons[i], {}) if length > 0: @@ -1337,7 +1346,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = else: addSonSkipIntLit(result, typ) if t.kind == tyForward: - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var elem = semGenericParamInInvocation(c, n.sons[i]) addToResult(elem) return @@ -1449,7 +1458,7 @@ template modifierTypeKindOfNode(n: PNode): TTypeKind = else: tyNone proc semTypeClass(c: PContext, n: PNode, prev: PType): PType = - # if n.sonsLen == 0: return newConstraint(c, tyTypeClass) + # if n.len == 0: return newConstraint(c, tyTypeClass) let pragmas = n[1] inherited = n[2] @@ -1560,7 +1569,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = semTypeof(c, n.sons[0], prev) if result.kind == tyTypeDesc: result.flags.incl tfExplicit of nkPar: - if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev) + if len(n) == 1: result = semTypeNode(c, n.sons[0], prev) else: result = semAnonTuple(c, n, prev) of nkTupleConstr: result = semAnonTuple(c, n, prev) @@ -1777,7 +1786,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = of nkDistinctTy: result = semDistinct(c, n, prev) of nkStaticTy: result = semStaticType(c, n[0], prev) of nkIteratorTy: - if n.sonsLen == 0: + if n.len == 0: result = newTypeS(tyBuiltInTypeClass, c) let child = newTypeS(tyProc, c) child.flags.incl tfIterator @@ -1790,7 +1799,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = else: result.callConv = ccClosure of nkProcTy: - if n.sonsLen == 0: + if n.len == 0: result = newConstraint(c, tyProc) else: result = semProcTypeWithScope(c, n, prev, skProc) @@ -1919,7 +1928,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = if n.kind != nkGenericParams: illFormedAst(n, c.config) return - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var a = n.sons[i] if a.kind != nkIdentDefs: illFormedAst(n, c.config) let L = a.len diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 7e4587658..ccabce155 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -169,7 +169,7 @@ proc replaceObjBranches(cl: TReplTypeVars, n: PNode): PNode = discard of nkRecWhen: var branch: PNode = nil # the branch to take - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it == nil: illFormedAst(n, cl.c.config) case it.kind @@ -189,7 +189,7 @@ proc replaceObjBranches(cl: TReplTypeVars, n: PNode): PNode = else: result = newNodeI(nkRecList, n.info) else: - for i in 0..<n.sonsLen: + for i in 0..<n.len: n.sons[i] = replaceObjBranches(cl, n.sons[i]) proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode = @@ -209,7 +209,7 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode = result = newNode(nkRecList, n.info) of nkRecWhen: var branch: PNode = nil # the branch to take - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it == nil: illFormedAst(n, cl.c.config) case it.kind @@ -234,7 +234,7 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode = result = if cl.allowMetaTypes: n else: cl.c.semExpr(cl.c, n) else: - var length = sonsLen(n) + var length = len(n) if length > 0: newSons(result, length) if start > 0: @@ -331,7 +331,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = when defined(reportCacheHits): echo "Generic instantiation cached ", typeToString(result), " for ", typeToString(t) return - for i in 1 ..< sonsLen(t): + for i in 1 ..< len(t): var x = t.sons[i] if x.kind in {tyGenericParam}: x = lookupTypeVar(cl, x) @@ -371,14 +371,14 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType = var typeMapLayer = newTypeMapLayer(cl) cl.typeMap = addr(typeMapLayer) - for i in 1 ..< sonsLen(t): + for i in 1 ..< len(t): var x = replaceTypeVarsT(cl, t.sons[i]) assert x.kind != tyGenericInvocation header.sons[i] = x propagateToOwner(header, x) cl.typeMap.put(body.sons[i-1], x) - for i in 1 ..< sonsLen(t): + for i in 1 ..< len(t): # if one of the params is not concrete, we cannot do anything # but we already raised an error! rawAddSon(result, header.sons[i]) @@ -446,11 +446,11 @@ proc eraseVoidParams*(t: PType) = if t.sons[0] != nil and t.sons[0].kind == tyVoid: t.sons[0] = nil - for i in 1 ..< t.sonsLen: + for i in 1 ..< t.len: # don't touch any memory unless necessary if t.sons[i].kind == tyVoid: var pos = i - for j in i+1 ..< t.sonsLen: + for j in i+1 ..< t.len: if t.sons[j].kind != tyVoid: t.sons[pos] = t.sons[j] t.n.sons[pos] = t.n.sons[j] @@ -460,7 +460,7 @@ proc eraseVoidParams*(t: PType) = break proc skipIntLiteralParams*(t: PType) = - for i in 0 ..< t.sonsLen: + for i in 0 ..< t.len: let p = t.sons[i] if p == nil: continue let skipped = p.skipIntLit @@ -573,7 +573,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = bailout() result = instCopyType(cl, t) idTablePut(cl.localCache, t, result) - for i in 1 ..< result.sonsLen: + for i in 1 ..< result.len: result.sons[i] = replaceTypeVarsT(cl, result.sons[i]) propagateToOwner(result, result.lastSon) @@ -586,7 +586,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType = #if not cl.allowMetaTypes: idTablePut(cl.localCache, t, result) - for i in 0 ..< sonsLen(result): + for i in 0 ..< len(result): if result.sons[i] != nil: if result.sons[i].kind == tyGenericBody: localError(cl.c.config, t.sym.info, @@ -693,10 +693,10 @@ proc recomputeFieldPositions*(t: PType; obj: PNode; currPosition: var int) = recomputeFieldPositions(b, b.n, currPosition) case obj.kind of nkRecList: - for i in 0 ..< sonsLen(obj): recomputeFieldPositions(nil, obj.sons[i], currPosition) + for i in 0 ..< len(obj): recomputeFieldPositions(nil, obj.sons[i], currPosition) of nkRecCase: recomputeFieldPositions(nil, obj.sons[0], currPosition) - for i in 1 ..< sonsLen(obj): + for i in 1 ..< len(obj): recomputeFieldPositions(nil, lastSon(obj.sons[i]), currPosition) of nkSym: obj.sym.position = currPosition diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index a9d911e27..90b7001a5 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -93,7 +93,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = case t.kind of tyGenericInvocation: - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): c.hashType t.sons[i], flags of tyDistinct: if CoDistinct in flags: @@ -180,15 +180,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) = of tyTuple: c &= char(t.kind) if t.n != nil and CoType notin flags: - assert(sonsLen(t.n) == sonsLen(t)) - for i in 0 ..< sonsLen(t.n): + assert(len(t.n) == len(t)) + for i in 0 ..< len(t.n): assert(t.n.sons[i].kind == nkSym) c &= t.n.sons[i].sym.name.s c &= ':' c.hashType(t.sons[i], flags+{CoIgnoreRange}) c &= ',' else: - for i in 0 ..< sonsLen(t): c.hashType t.sons[i], flags+{CoIgnoreRange} + for i in 0 ..< len(t): c.hashType t.sons[i], flags+{CoIgnoreRange} of tyRange: if CoIgnoreRange notin flags: c &= char(t.kind) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 2c22620da..10141e645 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -167,7 +167,7 @@ proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym, initIdTable(c.bindings) if binding != nil and callee.kind in routineKinds: var typeParams = callee.ast[genericParamsPos] - for i in 1..min(sonsLen(typeParams), sonsLen(binding)-1): + for i in 1..min(len(typeParams), len(binding)-1): var formalTypeParam = typeParams.sons[i-1].typ var bound = binding[i].typ if bound != nil: @@ -334,7 +334,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1; n.sons[i] = arg if arg.typ != nil and arg.typ.kind == tyError: return add(result, argTypeToString(arg, prefer)) - if i != sonsLen(n) - 1: add(result, ", ") + if i != len(n) - 1: add(result, ", ") proc typeRel*(c: var TCandidate, f, aOrig: PType, flags: TTypeRelFlags = {}): TTypeRelation @@ -440,7 +440,7 @@ proc handleFloatRange(f, a: PType): TTypeRelation = proc genericParamPut(c: var TCandidate; last, fGenericOrigin: PType) = if fGenericOrigin != nil and last.kind == tyGenericInst and last.len-1 == fGenericOrigin.len: - for i in 1 ..< sonsLen(fGenericOrigin): + for i in 1 ..< len(fGenericOrigin): let x = PType(idTableGet(c.bindings, fGenericOrigin.sons[i])) if x == nil: put(c, fGenericOrigin.sons[i], last.sons[i]) @@ -518,16 +518,16 @@ proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation = result = isNone if sameType(f, a): result = isEqual - elif sonsLen(a) == sonsLen(f): + elif len(a) == len(f): result = isEqual let firstField = if f.kind == tyTuple: 0 else: 1 - for i in firstField ..< sonsLen(f): + for i in firstField ..< len(f): var m = typeRel(c, f.sons[i], a.sons[i]) if m < isSubtype: return isNone result = minRel(result, m) if f.n != nil and a.n != nil: - for i in 0 ..< sonsLen(f.n): + for i in 0 ..< len(f.n): # check field names: if f.n.sons[i].kind != nkSym: return isNone elif a.n.sons[i].kind != nkSym: return isNone @@ -607,7 +607,7 @@ proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = case a.kind of tyProc: - if sonsLen(f) != sonsLen(a): return + if len(f) != len(a): return result = isEqual # start with maximum; also correct for no # params at all @@ -617,7 +617,7 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation = # Note: We have to do unification for the parameters before the # return type! - for i in 1 ..< f.sonsLen: + for i in 1 ..< f.len: checkParam(f.sons[i], a.sons[i]) if f.sons[0] != nil: @@ -943,7 +943,7 @@ proc isCovariantPtr(c: var TCandidate, f, a: PType): bool = of tyGenericInst: let body = f.base return body == a.base and - a.sonsLen == 3 and + a.len == 3 and tfWeakCovariant notin body.sons[0].flags and baseTypesCheck(f.sons[1], a.sons[1]) else: @@ -1416,7 +1416,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # YYYY result = isEqual - for i in 1 .. rootf.sonsLen-2: + for i in 1 .. rootf.len-2: let ff = rootf.sons[i] let aa = roota.sons[i] let res = typeRel(c, ff, aa, nextFlags) @@ -1497,8 +1497,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # simply no match for now: discard elif x.kind == tyGenericInst and f.sons[0] == x.sons[0] and - sonsLen(x) - 1 == sonsLen(f): - for i in 1 ..< sonsLen(f): + len(x) - 1 == len(f): + for i in 1 ..< len(f): if x.sons[i].kind == tyGenericParam: internalError(c.c.graph.config, "wrong instantiated type!") elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype: @@ -1506,7 +1506,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if f.sons[i].kind != tyTypeDesc: return result = isGeneric elif x.kind == tyGenericInst and isGenericSubtype(c, x, f, depth, f) and - (sonsLen(x) - 1 == sonsLen(f)): + (len(x) - 1 == len(f)): # do not recurse here in order to not K bind twice for this code: # # type @@ -1538,7 +1538,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # var it1 = internalFind(root, 312) # cannot instantiate: 'D' # # we steal the generic parameters from the tyGenericBody: - for i in 1 ..< sonsLen(f): + for i in 1 ..< len(f): let x = PType(idTableGet(c.bindings, genericBody.sons[i-1])) if x == nil: discard "maybe fine (for eg. a==tyNil)" @@ -1643,7 +1643,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, let roota = a.skipGenericAlias let rootf = f.lastSon.skipGenericAlias if a.kind == tyGenericInst and roota.base == rootf.base: - for i in 1 .. rootf.sonsLen-2: + for i in 1 .. rootf.len-2: let ff = rootf.sons[i] let aa = roota.sons[i] result = typeRel(c, ff, aa) @@ -1667,7 +1667,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, if tfWildcard in a.flags: result = isGeneric elif a.kind == tyTypeDesc: - if f.sonsLen == 0: + if f.len == 0: result = isGeneric else: internalAssert c.c.graph.config, a.len > 0 @@ -1689,7 +1689,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, result = isNone else: # check if 'T' has a constraint as in 'proc p[T: Constraint](x: T)' - if f.sonsLen > 0 and f.sons[0].kind != tyNone: + if f.len > 0 and f.sons[0].kind != tyNone: let oldInheritancePenalty = c.inheritancePenalty result = typeRel(c, f.sons[0], a, flags + {trDontBind}) if doBind and result notin {isNone, isGeneric}: @@ -2523,7 +2523,7 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = if m.state == csNoMatch: return # check that every formal parameter got a value: var f = 1 - while f < sonsLen(m.callee.n): + while f < len(m.callee.n): var formal = m.callee.n.sons[f].sym if not containsOrIncl(marker, formal.position): if formal.ast == nil: @@ -2562,7 +2562,7 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = # forget all inferred types if the overload matching failed if m.state == csNoMatch: for t in m.inferredTypes: - if t.sonsLen > 1: t.sons.setLen 1 + if t.len > 1: t.sons.setLen 1 proc argtypeMatches*(c: PContext, f, a: PType, fromHlo = false): bool = var m: TCandidate diff --git a/compiler/sizealignoffsetimpl.nim b/compiler/sizealignoffsetimpl.nim index 66b8ba1c9..fdca01136 100644 --- a/compiler/sizealignoffsetimpl.nim +++ b/compiler/sizealignoffsetimpl.nim @@ -80,7 +80,7 @@ proc computeSubObjectAlign(conf: ConfigRef; n: PNode): BiggestInt = of nkRecCase: assert(n.sons[0].kind == nkSym) result = computeSubObjectAlign(conf, n.sons[0]) - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): let child = n.sons[i] case child.kind of nkOfBranch, nkElse: @@ -123,7 +123,7 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, a computeObjectOffsetsFoldFunction(conf, n.sons[0], packed, accum) var maxChildAlign: int = if accum.offset == szUnknownSize: szUnknownSize else: 1 if not packed: - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): let child = n.sons[i] case child.kind of nkOfBranch, nkElse: @@ -140,7 +140,7 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, a # the union neds to be aligned first, before the offsets can be assigned accum.align(maxChildAlign) let accumRoot = accum # copy, because each branch should start af the same offset - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): var branchAccum = accumRoot computeObjectOffsetsFoldFunction(conf, n.sons[i].lastSon, packed, branchAccum) accum.mergeBranch(branchAccum) @@ -316,7 +316,7 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) = of tyTuple: try: var accum = OffsetAccum(maxAlign: 1) - for i in 0 ..< sonsLen(typ): + for i in 0 ..< len(typ): let child = typ.sons[i] computeSizeAlign(conf, child) accum.align(child.align) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 5cb365a4a..a254c1f13 100644 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -275,7 +275,7 @@ template wholeSymTab(cond, section: untyped) {.dirty.} = pm, c.inTypeContext > 0, scopeN)) proc suggestSymList(c: PContext, list, f: PNode; info: TLineInfo, outputs: var Suggestions) = - for i in 0 ..< sonsLen(list): + for i in 0 ..< len(list): if list.sons[i].kind == nkSym: suggestField(c, list.sons[i].sym, f, info, outputs) #else: InternalError(list.info, "getSymFromList") @@ -283,9 +283,9 @@ proc suggestSymList(c: PContext, list, f: PNode; info: TLineInfo, outputs: var S proc suggestObject(c: PContext, n, f: PNode; info: TLineInfo, outputs: var Suggestions) = case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): suggestObject(c, n.sons[i], f, info, outputs) + for i in 0 ..< len(n): suggestObject(c, n.sons[i], f, info, outputs) of nkRecCase: - var L = sonsLen(n) + var L = len(n) if L > 0: suggestObject(c, n.sons[0], f, info, outputs) for i in 1 ..< L: suggestObject(c, lastSon(n.sons[i]), f, info, outputs) @@ -318,7 +318,7 @@ proc suggestCall(c: PContext, n, nOrig: PNode, outputs: var Suggestions) = ideCon) proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} = - if s.typ != nil and sonsLen(s.typ) > 1 and s.typ.sons[1] != nil: + if s.typ != nil and len(s.typ) > 1 and s.typ.sons[1] != nil: # special rule: if system and some weird generic match via 'tyUntyped' # or 'tyGenericParam' we won't list it either to reduce the noise (nobody # wants 'system.`-|` as suggestion @@ -595,7 +595,7 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) = var x = safeSemExpr(c, n.sons[0]) if x.kind == nkEmpty or x.typ == nil: x = n.sons[0] addSon(a, x) - for i in 1..sonsLen(n)-1: + for i in 1..len(n)-1: # use as many typed arguments as possible: var x = safeSemExpr(c, n.sons[i]) if x.kind == nkEmpty or x.typ == nil: break diff --git a/compiler/transf.nim b/compiler/transf.nim index dc700278f..f1c89939f 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -71,7 +71,7 @@ proc newTransNode(kind: TNodeKind, n: PNode, result = x.PTransNode proc add(a, b: PTransNode) {.inline.} = addSon(PNode(a), PNode(b)) -proc len(a: PTransNode): int {.inline.} = sonsLen(a.PNode) +proc len(a: PTransNode): int {.inline.} = len(a.PNode) proc `[]=`(a: PTransNode, i: int, x: PTransNode) {.inline.} = var n = PNode(a) @@ -119,7 +119,7 @@ proc transform(c: PTransf, n: PNode): PTransNode proc transformSons(c: PTransf, n: PNode): PTransNode = result = newTransNode(n) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result[i] = transform(c, n.sons[i]) proc newAsgnStmt(c: PTransf, kind: TNodeKind, le: PNode, ri: PTransNode): PTransNode = @@ -176,7 +176,7 @@ proc freshVar(c: PTransf; v: PSym): PNode = proc transformVarSection(c: PTransf, v: PNode): PTransNode = result = newTransNode(v) - for i in 0 ..< sonsLen(v): + for i in 0 ..< len(v): var it = v.sons[i] if it.kind == nkCommentStmt: result[i] = PTransNode(it) @@ -201,7 +201,7 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode = else: if it.kind != nkVarTuple: internalError(c.graph.config, it.info, "transformVarSection: not nkVarTuple") - var L = sonsLen(it) + var L = len(it) var defs = newTransNode(it.kind, it.info, L) for j in 0 .. L-3: if it[j].kind == nkSym: @@ -219,7 +219,7 @@ proc transformConstSection(c: PTransf, v: PNode): PTransNode = result = PTransNode(v) when false: result = newTransNode(v) - for i in 0 ..< sonsLen(v): + for i in 0 ..< len(v): var it = v.sons[i] if it.kind == nkCommentStmt: result[i] = PTransNode(it) @@ -236,7 +236,7 @@ proc hasContinue(n: PNode): bool = of nkEmpty..nkNilLit, nkForStmt, nkParForStmt, nkWhileStmt: discard of nkContinueStmt: result = true else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): if hasContinue(n.sons[i]): return true proc newLabel(c: PTransf, n: PNode): PSym = @@ -318,7 +318,7 @@ proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode = return PTransNode(n) else: result = newTransNode(n) - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result[i] = introduceNewLocalVars(c, n.sons[i]) proc transformAsgn(c: PTransf, n: PNode): PTransNode = @@ -374,11 +374,11 @@ proc transformYield(c: PTransf, n: PNode): PTransNode = if c.transCon.forStmt.len != 3: e = skipConv(e) if e.kind in {nkPar, nkTupleConstr}: - for i in 0 ..< sonsLen(e): + for i in 0 ..< len(e): var v = e.sons[i] if v.kind == nkExprColonExpr: v = v.sons[1] if c.transCon.forStmt[i].kind == nkVarTuple: - for j in 0 ..< sonsLen(c.transCon.forStmt[i])-1: + for j in 0 ..< len(c.transCon.forStmt[i])-1: let lhs = c.transCon.forStmt[i][j] let rhs = transform(c, newTupleAccess(c.graph, v, j)) add(result, asgnTo(lhs, rhs)) @@ -389,13 +389,13 @@ proc transformYield(c: PTransf, n: PNode): PTransNode = else: # Unpack the tuple into the loop variables # XXX: BUG: what if `n` is an expression with side-effects? - for i in 0 .. sonsLen(c.transCon.forStmt) - 3: + for i in 0 .. len(c.transCon.forStmt) - 3: let lhs = c.transCon.forStmt.sons[i] let rhs = transform(c, newTupleAccess(c.graph, e, i)) add(result, asgnTo(lhs, rhs)) else: if c.transCon.forStmt.sons[0].kind == nkVarTuple: - for i in 0 ..< sonsLen(c.transCon.forStmt[0])-1: + for i in 0 ..< len(c.transCon.forStmt[0])-1: let lhs = c.transCon.forStmt[0][i] let rhs = transform(c, newTupleAccess(c.graph, e, i)) add(result, asgnTo(lhs, rhs)) @@ -575,7 +575,7 @@ proc putArgInto(arg: PNode, formal: PType): TPutArgInto = result = paDirectMapping of nkPar, nkTupleConstr, nkCurly, nkBracket: result = paFastAsgn - for i in 0 ..< sonsLen(arg): + for i in 0 ..< len(arg): if putArgInto(arg.sons[i], formal) != paDirectMapping: return result = paDirectMapping else: @@ -596,7 +596,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = # put mapping from formal parameters to actual parameters if n.kind != nkForStmt: internalError(c.graph.config, n.info, "transformFor") - var length = sonsLen(n) + var length = len(n) var call = n.sons[length - 2] let labl = newLabel(c, n) @@ -627,7 +627,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = var v = newNodeI(nkVarSection, n.info) for i in 0 .. length - 3: if n[i].kind == nkVarTuple: - for j in 0 ..< sonsLen(n[i])-1: + for j in 0 ..< len(n[i])-1: addVar(v, copyTree(n[i][j])) # declare new vars else: addVar(v, copyTree(n.sons[i])) # declare new vars @@ -643,7 +643,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode = if iter.kind != skIterator: return result # generate access statements for the parameters (unless they are constant) pushTransCon(c, newC) - for i in 1 ..< sonsLen(call): + for i in 1 ..< len(call): var arg = transform(c, call.sons[i]).PNode let ff = skipTypes(iter.typ, abstractInst) # can happen for 'nim check': @@ -694,7 +694,7 @@ proc transformCase(c: PTransf, n: PNode): PTransNode = # adds ``else: nil`` if needed for the code generator result = newTransNode(nkCaseStmt, n, 0) var ifs = PTransNode(nil) - for i in 0 .. sonsLen(n)-1: + for i in 0 .. len(n)-1: var it = n.sons[i] var e = transform(c, it) case it.kind @@ -744,7 +744,7 @@ proc flattenTreeAux(d, a: PNode, op: PSym) = let op2 = getMergeOp(a) if op2 != nil and (op2.id == op.id or op.magic != mNone and op2.magic == op.magic): - for i in 1 ..< sonsLen(a): flattenTreeAux(d, a.sons[i], op) + for i in 1 ..< len(a): flattenTreeAux(d, a.sons[i], op) else: addSon(d, copyTree(a)) @@ -765,11 +765,11 @@ proc transformCall(c: PTransf, n: PNode): PTransNode = result = newTransNode(nkCall, n, 0) add(result, transform(c, n.sons[0])) var j = 1 - while j < sonsLen(n): + while j < len(n): var a = transform(c, n.sons[j]).PNode inc(j) if isConstExpr(a): - while (j < sonsLen(n)): + while (j < len(n)): let b = transform(c, n.sons[j]).PNode if not isConstExpr(b): break a = evalOp(op.magic, n, a, b, nil, c.graph) @@ -844,17 +844,17 @@ proc commonOptimizations*(g: ModuleGraph; c: PSym, n: PNode): PNode = for i in 0 ..< n.safeLen: result.sons[i] = commonOptimizations(g, c, n.sons[i]) var op = getMergeOp(n) - if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3): + if (op != nil) and (op.magic != mNone) and (len(n) >= 3): result = newNodeIT(nkCall, n.info, n.typ) add(result, n.sons[0]) var args = newNode(nkArgList) flattenTreeAux(args, n, op) var j = 0 - while j < sonsLen(args): + while j < len(args): var a = args.sons[j] inc(j) if isConstExpr(a): - while j < sonsLen(args): + while j < len(args): let b = args.sons[j] if not isConstExpr(b): break a = evalOp(op.magic, result, a, b, nil, g) diff --git a/compiler/trees.nim b/compiler/trees.nim index 87ab7c00e..fd06425cb 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -44,8 +44,8 @@ proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool = of nkCommentStmt: result = a.comment == b.comment of nkEmpty, nkNilLit, nkType: result = true else: - if sonsLen(a) == sonsLen(b): - for i in 0 ..< sonsLen(a): + if len(a) == len(b): + for i in 0 ..< len(a): if not exprStructuralEquivalent(a.sons[i], b.sons[i], strictSymEquality): return result = true @@ -68,8 +68,8 @@ proc sameTree*(a, b: PNode): bool = of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal of nkEmpty, nkNilLit, nkType: result = true else: - if sonsLen(a) == sonsLen(b): - for i in 0 ..< sonsLen(a): + if len(a) == len(b): + for i in 0 ..< len(a): if not sameTree(a.sons[i], b.sons[i]): return result = true @@ -127,7 +127,7 @@ proc findPragma*(n: PNode, which: TSpecialWord): PNode = return son proc effectSpec*(n: PNode, effectType: TSpecialWord): PNode = - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): var it = n.sons[i] if it.kind == nkExprColonExpr and whichPragma(it) == effectType: result = it.sons[1] diff --git a/compiler/treetab.nim b/compiler/treetab.nim index 7d654509c..f346d8d97 100644 --- a/compiler/treetab.nim +++ b/compiler/treetab.nim @@ -31,7 +31,7 @@ proc hashTree(n: PNode): Hash = of nkStrLit..nkTripleStrLit: result = result !& hash(n.strVal) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = result !& hashTree(n.sons[i]) proc treesEquivalent(a, b: PNode): bool = @@ -46,8 +46,8 @@ proc treesEquivalent(a, b: PNode): bool = of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal else: - if sonsLen(a) == sonsLen(b): - for i in 0 ..< sonsLen(a): + if len(a) == len(b): + for i in 0 ..< len(a): if not treesEquivalent(a.sons[i], b.sons[i]): return result = true if result: result = sameTypeOrNil(a.typ, b.typ) diff --git a/compiler/types.nim b/compiler/types.nim index a05625327..1ed882cb8 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -132,13 +132,13 @@ proc getProcHeader*(conf: ConfigRef; sym: PSym; prefer: TPreferedDesc = preferNa if sym.kind in routineKinds: result.add '(' var n = sym.typ.n - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): let p = n.sons[i] if p.kind == nkSym: add(result, p.sym.name.s) add(result, ": ") add(result, typeToString(p.sym.typ, prefer)) - if i != sonsLen(n)-1: add(result, ", ") + if i != len(n)-1: add(result, ", ") else: result.add renderTree(p) add(result, ')') @@ -180,7 +180,7 @@ proc iterOverNode(marker: var IntSet, n: PNode, iter: TTypeIter, # a leaf result = iterOverTypeAux(marker, n.typ, iter, closure) else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = iterOverNode(marker, n.sons[i], iter, closure) if result: return @@ -195,7 +195,7 @@ proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter, of tyGenericInst, tyGenericBody, tyAlias, tySink, tyInferred: result = iterOverTypeAux(marker, lastSon(t), iter, closure) else: - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): result = iterOverTypeAux(marker, t.sons[i], iter, closure) if result: return if t.n != nil and t.kind != tyProc: result = iterOverNode(marker, t.n, iter, closure) @@ -212,14 +212,14 @@ proc searchTypeNodeForAux(n: PNode, p: TTypePredicate, result = false case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = searchTypeNodeForAux(n.sons[i], p, marker) if result: return of nkRecCase: assert(n.sons[0].kind == nkSym) result = searchTypeNodeForAux(n.sons[0], p, marker) if result: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: result = searchTypeNodeForAux(lastSon(n.sons[i]), p, marker) @@ -245,7 +245,7 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, of tyGenericInst, tyDistinct, tyAlias, tySink: result = searchTypeForAux(lastSon(t), predicate, marker) of tyArray, tySet, tyTuple: - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): result = searchTypeForAux(t.sons[i], predicate, marker) if result: return else: @@ -282,7 +282,7 @@ proc analyseObjectWithTypeFieldAux(t: PType, if t.n != nil: if searchTypeNodeForAux(t.n, isObjectWithTypeFieldPredicate, marker): return frEmbedded - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): var x = t.sons[i] if x != nil: x = x.skipTypes(skipPtrs) res = analyseObjectWithTypeFieldAux(x, marker) @@ -294,7 +294,7 @@ proc analyseObjectWithTypeFieldAux(t: PType, of tyGenericInst, tyDistinct, tyAlias, tySink: result = analyseObjectWithTypeFieldAux(lastSon(t), marker) of tyArray, tyTuple: - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): res = analyseObjectWithTypeFieldAux(t.sons[i], marker) if res != frNone: return frEmbedded @@ -344,7 +344,7 @@ proc canFormAcycleNode(marker: var IntSet, n: PNode, startId: int): bool = of nkNone..nkNilLit: discard else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = canFormAcycleNode(marker, n.sons[i], startId) if result: return @@ -355,7 +355,7 @@ proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool = case t.kind of tyTuple, tyObject, tyRef, tySequence, tyArray, tyOpenArray, tyVarargs: if not containsOrIncl(marker, t.id): - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): result = canFormAcycleAux(marker, t.sons[i], startId) if result: return if t.n != nil: result = canFormAcycleNode(marker, t.n, startId) @@ -391,7 +391,7 @@ proc mutateNode(marker: var IntSet, n: PNode, iter: TTypeMutator, # a leaf discard else: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): addSon(result, mutateNode(marker, n.sons[i], iter, closure)) proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator, @@ -400,7 +400,7 @@ proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator, if t == nil: return result = iter(t, closure) if not containsOrIncl(marker, t.id): - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): result.sons[i] = mutateTypeAux(marker, result.sons[i], iter, closure) if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure) assert(result != nil) @@ -491,7 +491,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil: # note: should probably be: {preferName, preferTypeName, preferGenericArg} result = t.sym.name.s - if t.kind == tyGenericParam and t.sonsLen > 0: + if t.kind == tyGenericParam and t.len > 0: result.add ": " var first = true for son in t.sons: @@ -513,13 +513,13 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = result = "int literal(" & $t.n.intVal & ")" of tyGenericInst, tyGenericInvocation: result = typeToString(t.sons[0]) & '[' - for i in 1 ..< sonsLen(t)-ord(t.kind != tyGenericInvocation): + for i in 1 ..< len(t)-ord(t.kind != tyGenericInvocation): if i > 1: add(result, ", ") add(result, typeToString(t.sons[i], preferGenericArg)) add(result, ']') of tyGenericBody: result = typeToString(t.lastSon) & '[' - for i in 0 .. sonsLen(t)-2: + for i in 0 .. len(t)-2: if i > 0: add(result, ", ") add(result, typeToString(t.sons[i], preferTypeName)) add(result, ']') @@ -560,7 +560,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = of tyUserTypeClassInst: let body = t.base result = body.sym.name.s & "[" - for i in 1 .. sonsLen(t) - 2: + for i in 1 .. len(t) - 2: if i > 1: add(result, ", ") add(result, typeToString(t.sons[i])) result.add "]" @@ -610,29 +610,29 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = # we iterate over t.sons here, because t.n may be nil if t.n != nil: result = "tuple[" - assert(sonsLen(t.n) == sonsLen(t)) - for i in 0 ..< sonsLen(t.n): + assert(len(t.n) == len(t)) + for i in 0 ..< len(t.n): assert(t.n.sons[i].kind == nkSym) add(result, t.n.sons[i].sym.name.s & ": " & typeToString(t.sons[i])) - if i < sonsLen(t.n) - 1: add(result, ", ") + if i < len(t.n) - 1: add(result, ", ") add(result, ']') - elif sonsLen(t) == 0: + elif len(t) == 0: result = "tuple[]" else: if prefer == preferTypeName: result = "(" else: result = "tuple of (" - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): add(result, typeToString(t.sons[i])) - if i < sonsLen(t) - 1: add(result, ", ") + if i < len(t) - 1: add(result, ", ") add(result, ')') of tyPtr, tyRef, tyVar, tyLent: result = typeToStr[t.kind] if t.len >= 2: setLen(result, result.len-1) result.add '[' - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): add(result, typeToString(t.sons[i])) - if i < sonsLen(t) - 1: add(result, ", ") + if i < len(t) - 1: add(result, ", ") result.add ']' else: result.add typeToString(t.sons[0]) @@ -654,12 +654,12 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = "proc " if tfUnresolved in t.flags: result.add "[*missing parameters*]" result.add "(" - for i in 1 ..< sonsLen(t): + for i in 1 ..< len(t): if t.n != nil and i < t.n.len and t.n[i].kind == nkSym: add(result, t.n[i].sym.name.s) add(result, ": ") add(result, typeToString(t.sons[i])) - if i < sonsLen(t) - 1: add(result, ", ") + if i < len(t) - 1: add(result, ", ") add(result, ')') if t.len > 0 and t.sons[0] != nil: add(result, ": " & typeToString(t.sons[0])) var prag = if t.callConv == ccDefault: "" else: CallingConvToStr[t.callConv] @@ -706,7 +706,7 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 = of tyUInt..tyUInt64: result = Zero of tyEnum: # if basetype <> nil then return firstOrd of basetype - if sonsLen(t) > 0 and t.sons[0] != nil: + if len(t) > 0 and t.sons[0] != nil: result = firstOrd(conf, t.sons[0]) else: assert(t.n.sons[0].kind == nkSym) @@ -766,8 +766,8 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 = of tyUInt64: result = toInt128(0xFFFFFFFFFFFFFFFF'u64) of tyEnum: - assert(t.n.sons[sonsLen(t.n) - 1].kind == nkSym) - result = toInt128(t.n.sons[sonsLen(t.n) - 1].sym.position) + assert(t.n.sons[len(t.n) - 1].kind == nkSym) + result = toInt128(t.n.sons[len(t.n) - 1].sym.position) of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink, tyStatic, tyInferred, tyUserTypeClasses: result = lastOrd(conf, lastSon(t)) @@ -908,8 +908,8 @@ proc sameConstraints(a, b: PNode): bool = proc equalParams(a, b: PNode): TParamsEquality = result = paramsEqual - var length = sonsLen(a) - if length != sonsLen(b): + var length = len(a) + if length != len(b): result = paramsNotEqual else: for i in 1 ..< length: @@ -939,9 +939,9 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = # two tuples are equivalent iff the names, types and positions are the same; # however, both types may not have any field names (t.n may be nil) which # complicates the matter a bit. - if sonsLen(a) == sonsLen(b): + if len(a) == len(b): result = true - for i in 0 ..< sonsLen(a): + for i in 0 ..< len(a): var x = a.sons[i] var y = b.sons[i] if IgnoreTupleFields in c.flags: @@ -951,7 +951,7 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool = result = sameTypeAux(x, y, c) if not result: return if a.n != nil and b.n != nil and IgnoreTupleFields notin c.flags: - for i in 0 ..< sonsLen(a.n): + for i in 0 ..< len(a.n): # check field names: if a.n.sons[i].kind == nkSym and b.n.sons[i].kind == nkSym: var x = a.n.sons[i].sym @@ -1014,23 +1014,23 @@ proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool = of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal of nkEmpty, nkNilLit, nkType: result = true else: - if sonsLen(a) == sonsLen(b): - for i in 0 ..< sonsLen(a): + if len(a) == len(b): + for i in 0 ..< len(a): if not sameObjectTree(a.sons[i], b.sons[i], c): return result = true proc sameObjectStructures(a, b: PType, c: var TSameTypeClosure): bool = # check base types: - if sonsLen(a) != sonsLen(b): return - for i in 0 ..< sonsLen(a): + if len(a) != len(b): return + for i in 0 ..< len(a): if not sameTypeOrNilAux(a.sons[i], b.sons[i], c): return if not sameObjectTree(a.n, b.n, c): return result = true proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool = - if sonsLen(a) != sonsLen(b): return false + if len(a) != len(b): return false result = true - for i in 0 ..< sonsLen(a): + for i in 0 ..< len(a): result = sameTypeOrNilAux(a.sons[i], b.sons[i], c) if not result: return @@ -1239,7 +1239,7 @@ proc typeAllowedNode(marker: var IntSet, n: PNode, kind: TSymKind, else: #if n.kind == nkRecCase and kind in {skProc, skFunc, skConst}: # return n[0].typ - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): let it = n.sons[i] result = typeAllowedNode(marker, it, kind, flags) if result != nil: break @@ -1249,7 +1249,7 @@ proc matchType*(a: PType, pattern: openArray[tuple[k:TTypeKind, i:int]], var a = a for k, i in pattern.items: if a.kind != k: return false - if i >= a.sonsLen or a.sons[i] == nil: return false + if i >= a.len or a.sons[i] == nil: return false a = a.sons[i] result = a.kind == last @@ -1284,7 +1284,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, else: result = typeAllowedAux(marker, t2, kind, flags) of tyProc: let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags - for i in 1 ..< sonsLen(t): + for i in 1 ..< len(t): result = typeAllowedAux(marker, t.sons[i], skParam, f-{taIsOpenArray}) if result != nil: break if result.isNil and t.sons[0] != nil: @@ -1346,7 +1346,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, of tyPtr: result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap}) of tySet: - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): result = typeAllowedAux(marker, t.sons[i], kind, flags) if result != nil: break of tyObject, tyTuple: @@ -1355,7 +1355,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, result = t else: let flags = flags+{taField} - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): result = typeAllowedAux(marker, t.sons[i], kind, flags) if result != nil: break if result.isNil and t.n != nil: @@ -1490,7 +1490,7 @@ proc isCompileTimeOnly*(t: PType): bool {.inline.} = proc containsCompileTimeOnly*(t: PType): bool = if isCompileTimeOnly(t): return true - for i in 0 ..< t.sonsLen: + for i in 0 ..< t.len: if t.sons[i] != nil and isCompileTimeOnly(t.sons[i]): return true return false diff --git a/compiler/vm.nim b/compiler/vm.nim index 072a1826b..a7980ae1d 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -200,8 +200,8 @@ proc copyValue(src: PNode): PNode = of nkIdent: result.ident = src.ident of nkStrLit..nkTripleStrLit: result.strVal = src.strVal else: - newSeq(result.sons, sonsLen(src)) - for i in 0 ..< sonsLen(src): + newSeq(result.sons, len(src)) + for i in 0 ..< len(src): result.sons[i] = copyValue(src.sons[i]) proc asgnComplex(x: var TFullReg, y: TFullReg) = @@ -782,7 +782,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = addSon(b, regs[rb].regToNode) var r = diffSets(c.config, regs[ra].node, b) discardSons(regs[ra].node) - for i in 0 ..< sonsLen(r): addSon(regs[ra].node, r.sons[i]) + for i in 0 ..< len(r): addSon(regs[ra].node, r.sons[i]) of opcCard: decodeB(rkInt) regs[ra].intVal = nimsets.cardSet(c.config, regs[rb].node) @@ -1164,7 +1164,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = # we know the next instruction is a 'fjmp': let branch = c.constants[instr.regBx-wordExcess] var cond = false - for j in 0 .. sonsLen(branch) - 2: + for j in 0 .. len(branch) - 2: if overlap(regs[ra].regToNode, branch.sons[j]): cond = true break @@ -1384,17 +1384,21 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = decodeBC(rkNode) let idx = regs[rc].intVal.int let src = regs[rb].node - if src.kind notin {nkEmpty..nkNilLit} and idx <% src.len: - regs[ra].node = src.sons[idx] - else: + if src.kind in {nkEmpty..nkNilLit}: + stackTrace(c, tos, pc, "cannot get child of node kind: n" & $src.kind) + elif idx >=% src.len: stackTrace(c, tos, pc, formatErrorIndexBound(idx, src.len-1)) + else: + regs[ra].node = src.sons[idx] of opcNSetChild: decodeBC(rkNode) let idx = regs[rb].intVal.int var dest = regs[ra].node if nfSem in dest.flags and allowSemcheckedAstModification notin c.config.legacyFeatures: stackTrace(c, tos, pc, "typechecked nodes may not be modified") - elif dest.kind in {nkEmpty..nkNilLit} or idx >=% dest.len: + elif dest.kind in {nkEmpty..nkNilLit}: + stackTrace(c, tos, pc, "cannot set child of node kind: n" & $dest.kind) + elif idx >=% dest.len: stackTrace(c, tos, pc, formatErrorIndexBound(idx, dest.len-1)) else: dest.sons[idx] = regs[rc].node @@ -1404,7 +1408,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = if nfSem in u.flags and allowSemcheckedAstModification notin c.config.legacyFeatures: stackTrace(c, tos, pc, "typechecked nodes may not be modified") elif u.kind in {nkEmpty..nkNilLit}: - stackTrace(c, tos, pc, "cannot add to node kind: " & $u.kind) + stackTrace(c, tos, pc, "cannot add to node kind: n" & $u.kind) else: u.add(regs[rc].node) regs[ra].node = u @@ -1415,7 +1419,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = if nfSem in u.flags and allowSemcheckedAstModification notin c.config.legacyFeatures: stackTrace(c, tos, pc, "typechecked nodes may not be modified") elif u.kind in {nkEmpty..nkNilLit}: - stackTrace(c, tos, pc, "cannot add to node kind: " & $u.kind) + stackTrace(c, tos, pc, "cannot add to node kind: n" & $u.kind) else: for i in 0 ..< x.len: u.add(x.sons[i]) regs[ra].node = u @@ -1549,17 +1553,20 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc], c.module, c.config) of opcGorge: - when defined(nimcore): - decodeBC(rkNode) - inc pc - let rd = c.code[pc].regA - - createStr regs[ra] - regs[ra].node.strVal = opGorge(regs[rb].node.strVal, - regs[rc].node.strVal, regs[rd].node.strVal, - c.debug[pc], c.config)[0] - else: - globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support") + if defined(nimsuggest) or c.config.cmd == cmdCheck: + discard "don't run staticExec for 'nim suggest'" + else: + when defined(nimcore): + decodeBC(rkNode) + inc pc + let rd = c.code[pc].regA + + createStr regs[ra] + regs[ra].node.strVal = opGorge(regs[rb].node.strVal, + regs[rc].node.strVal, regs[rd].node.strVal, + c.debug[pc], c.config)[0] + else: + globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support") of opcNError, opcNWarning, opcNHint: decodeB(rkNode) let a = regs[ra].node @@ -1582,7 +1589,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = error = formatMsg(conf, info, msg, arg)) if error.len > 0: c.errorFlag = error - elif sonsLen(ast) != 1: + elif len(ast) != 1: c.errorFlag = formatMsg(c.config, c.debug[pc], errGenerated, "expected expression, but got multiple statements") else: diff --git a/compiler/vmdeps.nim b/compiler/vmdeps.nim index 1b2538c79..e3d9533aa 100644 --- a/compiler/vmdeps.nim +++ b/compiler/vmdeps.nim @@ -242,7 +242,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; of tyRange: result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t) result.add atomicType("range", mRange) - if inst: + if inst and t.n.len == 2: let rng = newNodeX(nkInfix) rng.add newIdentNode(getIdent(cache, ".."), info) rng.add t.n.sons[0].copyTree @@ -250,7 +250,8 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; result.add rng else: result.add t.n.sons[0].copyTree - result.add t.n.sons[1].copyTree + if t.n.len > 1: + result.add t.n.sons[1].copyTree of tyPointer: result = atomicType("pointer", mPointer) of tyString: result = atomicType("string", mString) of tyCString: result = atomicType("cstring", mCstring) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 8863b2dc9..648ab926c 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -377,7 +377,7 @@ proc genIf(c: PCtx, n: PNode; dest: var TDest) = elsePos = c.xjmp(it.sons[0], opcFJmp, tmp) # if false c.clearDest(n, dest) c.gen(it.sons[1], dest) # then part - if i < sonsLen(n)-1: + if i < len(n)-1: endings.add(c.xjmp(it.sons[1], opcJmp, 0)) c.patch(elsePos) else: @@ -433,8 +433,8 @@ proc sameConstant*(a, b: PNode): bool = of nkType, nkNilLit: result = a.typ == b.typ of nkEmpty: result = true else: - if sonsLen(a) == sonsLen(b): - for i in 0 ..< sonsLen(a): + if len(a) == len(b): + for i in 0 ..< len(a): if not sameConstant(a.sons[i], b.sons[i]): return result = true @@ -479,7 +479,7 @@ proc genCase(c: PCtx; n: PNode; dest: var TDest) = c.gABx(it, opcBranch, tmp, b) let elsePos = c.xjmp(it.lastSon, opcFJmp, tmp) c.gen(it.lastSon, dest) - if i < sonsLen(n)-1: + if i < len(n)-1: endings.add(c.xjmp(it.lastSon, opcJmp, 0)) c.patch(elsePos) c.clearDest(n, dest) @@ -517,7 +517,7 @@ proc genTry(c: PCtx; n: PNode; dest: var TDest) = c.gABx(it, opcExcept, 0, 0) c.gen(it.lastSon, dest) c.clearDest(n, dest) - if i < sonsLen(n): + if i < len(n): endings.add(c.xjmp(it, opcJmp, 0)) c.patch(endExcept) let fin = lastSon(n) @@ -564,7 +564,7 @@ proc genCall(c: PCtx; n: PNode; dest: var TDest) = # varargs need 'opcSetType' for the FFI support: let fntyp = skipTypes(n.sons[0].typ, abstractInst) for i in 0..<n.len: - #if i > 0 and i < sonsLen(fntyp): + #if i > 0 and i < len(fntyp): # let paramType = fntyp.n.sons[i] # if paramType.typ.isCompileTimeOnly: continue var r: TRegister = x+i @@ -1716,10 +1716,10 @@ proc getNullValueAux(t: PType; obj: PNode, result: PNode; conf: ConfigRef; currP getNullValueAux(b, b.n, result, conf, currPosition) case obj.kind of nkRecList: - for i in 0 ..< sonsLen(obj): getNullValueAux(nil, obj.sons[i], result, conf, currPosition) + for i in 0 ..< len(obj): getNullValueAux(nil, obj.sons[i], result, conf, currPosition) of nkRecCase: getNullValueAux(nil, obj.sons[0], result, conf, currPosition) - for i in 1 ..< sonsLen(obj): + for i in 1 ..< len(obj): getNullValueAux(nil, lastSon(obj.sons[i]), result, conf, currPosition) of nkSym: let field = newNodeI(nkExprColonExpr, result.info) @@ -1764,7 +1764,7 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = addSon(result, getNullValue(elemType(t), info, conf)) of tyTuple: result = newNodeIT(nkTupleConstr, info, t) - for i in 0 ..< sonsLen(t): + for i in 0 ..< len(t): addSon(result, getNullValue(t.sons[i], info, conf)) of tySet: result = newNodeIT(nkCurly, info, t) diff --git a/compiler/vmmarshal.nim b/compiler/vmmarshal.nim index 2a81cb14d..8443890e5 100644 --- a/compiler/vmmarshal.nim +++ b/compiler/vmmarshal.nim @@ -18,13 +18,13 @@ proc ptrToInt(x: PNode): int {.inline.} = proc getField(n: PNode; position: int): PSym = case n.kind of nkRecList: - for i in 0 ..< sonsLen(n): + for i in 0 ..< len(n): result = getField(n.sons[i], position) if result != nil: return of nkRecCase: result = getField(n.sons[0], position) if result != nil: return - for i in 1 ..< sonsLen(n): + for i in 1 ..< len(n): case n.sons[i].kind of nkOfBranch, nkElse: result = getField(lastSon(n.sons[i]), position) @@ -39,7 +39,7 @@ proc storeAny(s: var string; t: PType; a: PNode; stored: var IntSet; conf: Confi proc storeObj(s: var string; typ: PType; x: PNode; stored: var IntSet; conf: ConfigRef) = assert x.kind == nkObjConstr let start = 1 - for i in start ..< sonsLen(x): + for i in start ..< len(x): if i > start: s.add(", ") var it = x.sons[i] if it.kind == nkExprColonExpr: diff --git a/compiler/vmops.nim b/compiler/vmops.nim index b0325b5b0..fe3c2516b 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -77,6 +77,14 @@ template wrap2svoid(op, modop) {.dirty.} = op(getString(a, 0), getString(a, 1)) modop op +template wrapDangerous(op, modop) {.dirty.} = + proc `op Wrapper`(a: VmArgs) {.nimcall.} = + if defined(nimsuggest) or c.config.cmd == cmdCheck: + discard + else: + op(getString(a, 0), getString(a, 1)) + modop op + proc getCurrentExceptionMsgWrapper(a: VmArgs) {.nimcall.} = setResult(a, if a.currentException.isNil: "" else: a.currentException.sons[3].skipColon.strVal) @@ -133,7 +141,7 @@ proc registerAdditionalOps*(c: PCtx) = wrap2svoid(putEnv, osop) wrap1s(dirExists, osop) wrap1s(fileExists, osop) - wrap2svoid(writeFile, ioop) + wrapDangerous(writeFile, ioop) wrap1s(readFile, ioop) wrap2si(readLines, ioop) systemop getCurrentExceptionMsg diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index 62b26adf3..23c87ac39 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -42,7 +42,7 @@ type wImmediate, wConstructor, wDestructor, wDelegator, wOverride, wImportCpp, wImportObjC, wImportCompilerProc, - wImportc, wExportc, wExportNims, wIncompleteStruct, wRequiresInit, + wImportc, wExportc, wExportCpp, wExportNims, wIncompleteStruct, wRequiresInit, wAlign, wNodecl, wPure, wSideEffect, wHeader, wNoSideEffect, wGcSafe, wNoreturn, wMerge, wLib, wDynlib, wCompilerProc, wCore, wProcVar, wBase, wUsed, @@ -129,7 +129,7 @@ const "immediate", "constructor", "destructor", "delegator", "override", "importcpp", "importobjc", - "importcompilerproc", "importc", "exportc", "exportnims", + "importcompilerproc", "importc", "exportc", "exportcpp", "exportnims", "incompletestruct", "requiresinit", "align", "nodecl", "pure", "sideeffect", "header", "nosideeffect", "gcsafe", "noreturn", "merge", "lib", "dynlib", diff --git a/compiler/writetracking.nim b/compiler/writetracking.nim index b310701ca..635224723 100644 --- a/compiler/writetracking.nim +++ b/compiler/writetracking.nim @@ -77,11 +77,11 @@ proc allRoots(n: PNode; result: var seq[ptr TSym]; info: var set[RootInfo]) = if typ != nil: typ = skipTypes(typ, abstractInst) if typ.kind != tyProc: typ = nil - else: assert(sonsLen(typ) == sonsLen(typ.n)) + else: assert(len(typ) == len(typ.n)) for i in 1 ..< n.len: let it = n.sons[i] - if typ != nil and i < sonsLen(typ): + if typ != nil and i < len(typ): assert(typ.n.sons[i].kind == nkSym) let paramType = typ.n.sons[i] if paramType.typ.isCompileTimeOnly: continue @@ -157,10 +157,10 @@ proc depsArgs(w: var W; n: PNode) = var typ = skipTypes(n.sons[0].typ, abstractInst) if typ.kind != tyProc: return # echo n.info, " ", n, " ", w.owner.name.s, " ", typeToString(typ) - assert(sonsLen(typ) == sonsLen(typ.n)) + assert(len(typ) == len(typ.n)) for i in 1 ..< n.len: let it = n.sons[i] - if i < sonsLen(typ): + if i < len(typ): assert(typ.n.sons[i].kind == nkSym) let paramType = typ.n.sons[i] if paramType.typ.isCompileTimeOnly: continue diff --git a/doc/manual.rst b/doc/manual.rst index a8326d94d..3c194b1d2 100644 --- a/doc/manual.rst +++ b/doc/manual.rst @@ -5928,6 +5928,31 @@ Is the same as: proc astHelper(n: NimNode): NimNode {.compileTime.} = result = n +``compileTime`` variables are available at runtime too. This simplifies certain +idioms where variables are filled at compile-time (for example, lookup tables) +but accessed at runtime: + +.. code-block:: nim + :test: "nim c -r $1" + + import macros + + var nameToProc {.compileTime.}: seq[(string, proc (): string {.nimcall.})] + + macro registerProc(p: untyped): untyped = + result = newTree(nnkStmtList, p) + + let procName = p[0] + let procNameAsStr = $p[0] + result.add quote do: + nameToProc.add((`procNameAsStr`, `procName`)) + + proc foo: string {.registerProc.} = "foo" + proc bar: string {.registerProc.} = "bar" + proc baz: string {.registerProc.} = "baz" + + doAssert nameToProc[2][1]() == "baz" + noReturn pragma --------------- diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 4e44b9b4f..2e1eeb042 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1191,17 +1191,23 @@ proc `params=`* (someProc: NimNode; params: NimNode) {.compileTime.}= proc pragma*(someProc: NimNode): NimNode {.compileTime.} = ## Get the pragma of a proc type ## These will be expanded - someProc.expectRoutine - result = someProc[4] -proc `pragma=`*(someProc: NimNode; val: NimNode){.compileTime.}= + if someProc.kind == nnkProcTy: + result = someProc[1] + else: + someProc.expectRoutine + result = someProc[4] +proc `pragma=`*(someProc: NimNode; val: NimNode) {.compileTime.}= ## Set the pragma of a proc type - someProc.expectRoutine expectKind(val, {nnkEmpty, nnkPragma}) - someProc[4] = val + if someProc.kind == nnkProcTy: + someProc[1] = val + else: + someProc.expectRoutine + someProc[4] = val proc addPragma*(someProc, pragma: NimNode) {.compileTime.} = ## Adds pragma to routine definition - someProc.expectRoutine + someProc.expectKind(RoutineNodes + {nnkProcTy}) var pragmaNode = someProc.pragma if pragmaNode.isNil or pragmaNode.kind == nnkEmpty: pragmaNode = newNimNode(nnkPragma) diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim index dea247246..a285928c2 100644 --- a/lib/posix/posix.nim +++ b/lib/posix/posix.nim @@ -95,9 +95,9 @@ const StatHasNanoseconds* = defined(linux) or defined(freebsd) or # Platform specific stuff -when defined(linux) and defined(amd64): +when (defined(linux) and not defined(android)) and defined(amd64): include posix_linux_amd64 -elif (defined(macosx) or defined(bsd)) and defined(cpu64): +elif (defined(macos) or defined(macosx) or defined(bsd)) and defined(cpu64): include posix_macos_amd64 elif defined(nintendoswitch): include posix_nintendoswitch diff --git a/lib/posix/posix_linux_amd64.nim b/lib/posix/posix_linux_amd64.nim index b4331fdad..be7934f2f 100644 --- a/lib/posix/posix_linux_amd64.nim +++ b/lib/posix/posix_linux_amd64.nim @@ -147,7 +147,7 @@ type Id* {.importc: "id_t", header: "<sys/types.h>".} = cuint Ino* {.importc: "ino_t", header: "<sys/types.h>".} = culong Key* {.importc: "key_t", header: "<sys/types.h>".} = cint - Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint # cuint really! + Mode* {.importc: "mode_t", header: "<sys/types.h>".} = uint32 Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = culong Off* {.importc: "off_t", header: "<sys/types.h>".} = clong Pid* {.importc: "pid_t", header: "<sys/types.h>".} = cint diff --git a/lib/posix/posix_macos_amd64.nim b/lib/posix/posix_macos_amd64.nim index 5000c1160..41522fd17 100644 --- a/lib/posix/posix_macos_amd64.nim +++ b/lib/posix/posix_macos_amd64.nim @@ -140,7 +140,12 @@ type Id* {.importc: "id_t", header: "<sys/types.h>".} = int Ino* {.importc: "ino_t", header: "<sys/types.h>".} = int Key* {.importc: "key_t", header: "<sys/types.h>".} = int - Mode* {.importc: "mode_t", header: "<sys/types.h>".} = int16 + Mode* {.importc: "mode_t", header: "<sys/types.h>".} = ( + when defined(openbsd) or defined(netbsd): + uint32 + else: + uint16 + ) Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int16 Off* {.importc: "off_t", header: "<sys/types.h>".} = int64 Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int32 diff --git a/lib/posix/posix_nintendoswitch.nim b/lib/posix/posix_nintendoswitch.nim index 887d16586..d1cc042ea 100644 --- a/lib/posix/posix_nintendoswitch.nim +++ b/lib/posix/posix_nintendoswitch.nim @@ -123,7 +123,7 @@ type Id* {.importc: "id_t", header: "<sys/types.h>".} = cuint Ino* {.importc: "ino_t", header: "<sys/types.h>".} = culong Key* {.importc: "key_t", header: "<sys/types.h>".} = cint - Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint # cuint really! + Mode* {.importc: "mode_t", header: "<sys/types.h>".} = uint16 Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = culong Off* {.importc: "off_t", header: "<sys/types.h>".} = clong Pid* {.importc: "pid_t", header: "<sys/types.h>".} = cint diff --git a/lib/posix/posix_other.nim b/lib/posix/posix_other.nim index b9a6c2517..c582240d1 100644 --- a/lib/posix/posix_other.nim +++ b/lib/posix/posix_other.nim @@ -149,7 +149,13 @@ type Id* {.importc: "id_t", header: "<sys/types.h>".} = int Ino* {.importc: "ino_t", header: "<sys/types.h>".} = int Key* {.importc: "key_t", header: "<sys/types.h>".} = int - Mode* {.importc: "mode_t", header: "<sys/types.h>".} = cint + Mode* {.importc: "mode_t", header: "<sys/types.h>".} = ( + when defined(android) or defined(macos) or defined(macosx) or + (defined(bsd) and not defined(openbsd) and not defined(netbsd)): + uint16 + else: + uint32 + ) Nlink* {.importc: "nlink_t", header: "<sys/types.h>".} = int Off* {.importc: "off_t", header: "<sys/types.h>".} = int64 Pid* {.importc: "pid_t", header: "<sys/types.h>".} = int32 diff --git a/lib/pure/collections/tables.nim b/lib/pure/collections/tables.nim index 1352bdf68..967a6726f 100644 --- a/lib/pure/collections/tables.nim +++ b/lib/pure/collections/tables.nim @@ -307,6 +307,22 @@ proc initTable*[A, B](initialSize = defaultInitialSize): Table[A, B] = b = initTable[char, seq[int]]() initImpl(result, initialSize) +proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) = + ## Inserts a ``(key, value)`` pair into ``t``. + ## + ## See also: + ## * `[] proc<#[],Table[A,B],A>`_ for retrieving a value of a key + ## * `hasKeyOrPut proc<#hasKeyOrPut,Table[A,B],A,B>`_ + ## * `mgetOrPut proc<#mgetOrPut,Table[A,B],A,B>`_ + ## * `del proc<#del,Table[A,B],A>`_ for removing a key from the table + runnableExamples: + var a = initTable[char, int]() + a['x'] = 7 + a['y'] = 33 + doAssert a == {'x': 7, 'y': 33}.toTable + + putImpl(enlarge) + proc toTable*[A, B](pairs: openArray[(A, B)]): Table[A, B] = ## Creates a new hash table that contains the given ``pairs``. ## @@ -362,22 +378,6 @@ proc `[]`*[A, B](t: var Table[A, B], key: A): var B = ## the table get(t, key) -proc `[]=`*[A, B](t: var Table[A, B], key: A, val: B) = - ## Inserts a ``(key, value)`` pair into ``t``. - ## - ## See also: - ## * `[] proc<#[],Table[A,B],A>`_ for retrieving a value of a key - ## * `hasKeyOrPut proc<#hasKeyOrPut,Table[A,B],A,B>`_ - ## * `mgetOrPut proc<#mgetOrPut,Table[A,B],A,B>`_ - ## * `del proc<#del,Table[A,B],A>`_ for removing a key from the table - runnableExamples: - var a = initTable[char, int]() - a['x'] = 7 - a['y'] = 33 - doAssert a == {'x': 7, 'y': 33}.toTable - - putImpl(enlarge) - proc hasKey*[A, B](t: Table[A, B], key: A): bool = ## Returns true if ``key`` is in the table ``t``. ## @@ -1285,6 +1285,22 @@ proc initOrderedTable*[A, B](initialSize = defaultInitialSize): OrderedTable[A, b = initOrderedTable[char, seq[int]]() initImpl(result, initialSize) +proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) = + ## Inserts a ``(key, value)`` pair into ``t``. + ## + ## See also: + ## * `[] proc<#[],OrderedTable[A,B],A>`_ for retrieving a value of a key + ## * `hasKeyOrPut proc<#hasKeyOrPut,OrderedTable[A,B],A,B>`_ + ## * `mgetOrPut proc<#mgetOrPut,OrderedTable[A,B],A,B>`_ + ## * `del proc<#del,OrderedTable[A,B],A>`_ for removing a key from the table + runnableExamples: + var a = initOrderedTable[char, int]() + a['x'] = 7 + a['y'] = 33 + doAssert a == {'x': 7, 'y': 33}.toOrderedTable + + putImpl(enlarge) + proc toOrderedTable*[A, B](pairs: openArray[(A, B)]): OrderedTable[A, B] = ## Creates a new ordered hash table that contains the given ``pairs``. ## @@ -1342,22 +1358,6 @@ proc `[]`*[A, B](t: var OrderedTable[A, B], key: A): var B = ## key is in the table get(t, key) -proc `[]=`*[A, B](t: var OrderedTable[A, B], key: A, val: B) = - ## Inserts a ``(key, value)`` pair into ``t``. - ## - ## See also: - ## * `[] proc<#[],OrderedTable[A,B],A>`_ for retrieving a value of a key - ## * `hasKeyOrPut proc<#hasKeyOrPut,OrderedTable[A,B],A,B>`_ - ## * `mgetOrPut proc<#mgetOrPut,OrderedTable[A,B],A,B>`_ - ## * `del proc<#del,OrderedTable[A,B],A>`_ for removing a key from the table - runnableExamples: - var a = initOrderedTable[char, int]() - a['x'] = 7 - a['y'] = 33 - doAssert a == {'x': 7, 'y': 33}.toOrderedTable - - putImpl(enlarge) - proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool = ## Returns true if ``key`` is in the table ``t``. ## diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 23b23b4a4..597c0891f 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -841,10 +841,27 @@ proc parseJson(p: var JsonParser): JsonNode = raiseParseErr(p, "{") when not defined(js): + iterator parseJsonFragments*(s: Stream, filename: string = ""): JsonNode = + ## Parses from a stream `s` into `JsonNodes`. `filename` is only needed + ## for nice error messages. + ## The JSON fragments are separated by whitespace. This can be substantially + ## faster than the comparable loop + ## ``for x in splitWhitespace(s): yield parseJson(x)``. + ## This closes the stream `s` after it's done. + var p: JsonParser + p.open(s, filename) + try: + discard getTok(p) # read first token + while p.tok != tkEof: + yield p.parseJson() + finally: + p.close() + proc parseJson*(s: Stream, filename: string = ""): JsonNode = ## Parses from a stream `s` into a `JsonNode`. `filename` is only needed ## for nice error messages. ## If `s` contains extra data, it will raise `JsonParsingError`. + ## This closes the stream `s` after it's done. var p: JsonParser p.open(s, filename) try: @@ -1778,3 +1795,11 @@ when isMainModule: ) doAssert(obj == to(%obj, type(obj))) + + when not defined(js): + const fragments = """[1,2,3] {"hi":3} 12 [] """ + var res = "" + for x in parseJsonFragments(newStringStream(fragments)): + res.add($x) + res.add " " + doAssert res == fragments diff --git a/lib/pure/os.nim b/lib/pure/os.nim index b0c3d3441..65b98d7a1 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -1435,17 +1435,17 @@ proc getFilePermissions*(filename: string): set[FilePermission] {. var a: Stat if stat(filename, a) < 0'i32: raiseOSError(osLastError()) result = {} - if (a.st_mode and S_IRUSR) != 0'i32: result.incl(fpUserRead) - if (a.st_mode and S_IWUSR) != 0'i32: result.incl(fpUserWrite) - if (a.st_mode and S_IXUSR) != 0'i32: result.incl(fpUserExec) + if (a.st_mode and S_IRUSR.Mode) != 0.Mode: result.incl(fpUserRead) + if (a.st_mode and S_IWUSR.Mode) != 0.Mode: result.incl(fpUserWrite) + if (a.st_mode and S_IXUSR.Mode) != 0.Mode: result.incl(fpUserExec) - if (a.st_mode and S_IRGRP) != 0'i32: result.incl(fpGroupRead) - if (a.st_mode and S_IWGRP) != 0'i32: result.incl(fpGroupWrite) - if (a.st_mode and S_IXGRP) != 0'i32: result.incl(fpGroupExec) + if (a.st_mode and S_IRGRP.Mode) != 0.Mode: result.incl(fpGroupRead) + if (a.st_mode and S_IWGRP.Mode) != 0.Mode: result.incl(fpGroupWrite) + if (a.st_mode and S_IXGRP.Mode) != 0.Mode: result.incl(fpGroupExec) - if (a.st_mode and S_IROTH) != 0'i32: result.incl(fpOthersRead) - if (a.st_mode and S_IWOTH) != 0'i32: result.incl(fpOthersWrite) - if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec) + if (a.st_mode and S_IROTH.Mode) != 0.Mode: result.incl(fpOthersRead) + if (a.st_mode and S_IWOTH.Mode) != 0.Mode: result.incl(fpOthersWrite) + if (a.st_mode and S_IXOTH.Mode) != 0.Mode: result.incl(fpOthersExec) else: when useWinUnicode: wrapUnary(res, getFileAttributesW, filename) @@ -1470,18 +1470,18 @@ proc setFilePermissions*(filename: string, permissions: set[FilePermission]) {. ## * `getFilePermissions <#getFilePermissions,string>`_ ## * `FilePermission enum <#FilePermission>`_ when defined(posix): - var p = 0'i32 - if fpUserRead in permissions: p = p or S_IRUSR - if fpUserWrite in permissions: p = p or S_IWUSR - if fpUserExec in permissions: p = p or S_IXUSR + var p = 0.Mode + if fpUserRead in permissions: p = p or S_IRUSR.Mode + if fpUserWrite in permissions: p = p or S_IWUSR.Mode + if fpUserExec in permissions: p = p or S_IXUSR.Mode - if fpGroupRead in permissions: p = p or S_IRGRP - if fpGroupWrite in permissions: p = p or S_IWGRP - if fpGroupExec in permissions: p = p or S_IXGRP + if fpGroupRead in permissions: p = p or S_IRGRP.Mode + if fpGroupWrite in permissions: p = p or S_IWGRP.Mode + if fpGroupExec in permissions: p = p or S_IXGRP.Mode - if fpOthersRead in permissions: p = p or S_IROTH - if fpOthersWrite in permissions: p = p or S_IWOTH - if fpOthersExec in permissions: p = p or S_IXOTH + if fpOthersRead in permissions: p = p or S_IROTH.Mode + if fpOthersWrite in permissions: p = p or S_IWOTH.Mode + if fpOthersExec in permissions: p = p or S_IXOTH.Mode if chmod(filename, cast[Mode](p)) != 0: raiseOSError(osLastError()) else: @@ -2854,7 +2854,7 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped = else: template checkAndIncludeMode(rawMode, formalMode: untyped) = - if (rawInfo.st_mode and rawMode) != 0'i32: + if (rawInfo.st_mode and rawMode.Mode) != 0.Mode: formalInfo.permissions.incl(formalMode) formalInfo.id = (rawInfo.st_dev, rawInfo.st_ino) formalInfo.size = rawInfo.st_size diff --git a/lib/pure/parsejson.nim b/lib/pure/parsejson.nim index f86f3dfae..9893e434e 100644 --- a/lib/pure/parsejson.nim +++ b/lib/pure/parsejson.nim @@ -105,7 +105,7 @@ proc open*(my: var JsonParser, input: Stream, filename: string; rawStringLiterals = false) = ## initializes the parser with an input stream. `Filename` is only used ## for nice error messages. If `rawStringLiterals` is true, string literals - ## are kepts with their surrounding quotes and escape sequences in them are + ## are kept with their surrounding quotes and escape sequences in them are ## left untouched too. lexbase.open(my, input) my.filename = filename diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index 844fbd13c..7ce65b438 100644 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -890,12 +890,13 @@ macro mkHandlerTplts(handlers: untyped): untyped = # <handler code block> # ... proc mkEnter(hdName, body: NimNode): NimNode = - quote do: - template `hdName`(s, p, start) = + template helper(hdName, body) {.dirty.} = + template hdName(s, p, start) = let s {.inject.} = s let p {.inject.} = p let start {.inject.} = start - `body` + body + result = getAst(helper(hdName, body)) template mkLeave(hdPostf, body) {.dirty.} = # this has to be dirty to be able to capture *result* as *length* in diff --git a/lib/pure/streams.nim b/lib/pure/streams.nim index 28d9d7612..448c6121a 100644 --- a/lib/pure/streams.nim +++ b/lib/pure/streams.nim @@ -127,7 +127,7 @@ type peekDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.} writeDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int) - {.nimcall, raises: [Defect, IOError, OSError], tags: [WriteIOEffect], gcsafe.} + {.nimcall, raises: [Defect, IOError, OSError], tags: [WriteIOEffect], gcsafe.} flushImpl*: proc (s: Stream) {.nimcall, raises: [Defect, IOError, OSError], tags: [WriteIOEffect], gcsafe.} diff --git a/lib/pure/strformat.nim b/lib/pure/strformat.nim index ba75ce95f..af9568d92 100644 --- a/lib/pure/strformat.nim +++ b/lib/pure/strformat.nim @@ -234,7 +234,7 @@ quoted string literal. It is not an identifier yet. Then the strformat macro creates the ``arg`` identifier from the string literal. An identifier that cannot be resolved anymore. -The workaround for this is to bind template argument to a new local variable. +The workaround for this is to bind the template argument to a new local variable. .. code-block:: nim diff --git a/lib/system.nim b/lib/system.nim index d3fd9ddc8..ebea457dd 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -1989,6 +1989,8 @@ when defined(boehmgc): const boehmLib = "boehmgc.dll" elif defined(macosx): const boehmLib = "libgc.dylib" + elif defined(openbsd): + const boehmLib = "libgc.so.4.0" else: const boehmLib = "libgc.so.1" {.pragma: boehmGC, noconv, dynlib: boehmLib.} diff --git a/lib/system/mmdisp.nim b/lib/system/mmdisp.nim index 47bb400a7..0d1bb1767 100644 --- a/lib/system/mmdisp.nim +++ b/lib/system/mmdisp.nim @@ -112,8 +112,8 @@ when defined(boehmgc): if result == nil: raiseOutOfMem() proc alloc0(size: Natural): pointer = result = alloc(size) - proc realloc(p: pointer, newsize: Natural): pointer = - result = boehmRealloc(p, newsize) + proc realloc(p: pointer, newSize: Natural): pointer = + result = boehmRealloc(p, newSize) if result == nil: raiseOutOfMem() proc dealloc(p: pointer) = boehmDealloc(p) @@ -122,8 +122,8 @@ when defined(boehmgc): if result == nil: raiseOutOfMem() proc allocShared0(size: Natural): pointer = result = allocShared(size) - proc reallocShared(p: pointer, newsize: Natural): pointer = - result = boehmRealloc(p, newsize) + proc reallocShared(p: pointer, newSize: Natural): pointer = + result = boehmRealloc(p, newSize) if result == nil: raiseOutOfMem() proc deallocShared(p: pointer) = boehmDealloc(p) diff --git a/nimsuggest/tests/ttemplate_highlight.nim b/nimsuggest/tests/disabled_ttemplate_highlight.nim index 2cbac3be5..2cbac3be5 100644 --- a/nimsuggest/tests/ttemplate_highlight.nim +++ b/nimsuggest/tests/disabled_ttemplate_highlight.nim diff --git a/testament/categories.nim b/testament/categories.nim index 6e885966e..1b785776f 100644 --- a/testament/categories.nim +++ b/testament/categories.nim @@ -506,6 +506,7 @@ proc testNimblePackages(r: var TResults, cat: Category) = else: inc r.passed r.addResult(test, targetC, "", "", reSuccess) + errors = r.total - r.passed if errors == 0: r.addResult(packageFileTest, targetC, "", "", reSuccess) diff --git a/testament/important_packages.nim b/testament/important_packages.nim index 0b21547c3..5455b5fa4 100644 --- a/testament/important_packages.nim +++ b/testament/important_packages.nim @@ -82,3 +82,4 @@ pkg "with" pkg "ws" pkg "yaml" pkg "zero_functional", "nim c -r test.nim" +pkg "tensordsl", "nim c -r tests/tests.nim", false, "https://krux02@bitbucket.org/krux02/tensordslnim.git" diff --git a/testament/testament.nim b/testament/testament.nim index 5d0213ce5..f70a2afef 100644 --- a/testament/testament.nim +++ b/testament/testament.nim @@ -332,8 +332,7 @@ proc generatedFile(test: TTest, target: TTarget): string = else: let (_, name, _) = test.name.splitFile let ext = targetToExt[target] - result = nimcacheDir(test.name, test.options, target) / - name.replace("_", "__").changeFileExt(ext) + result = nimcacheDir(test.name, test.options, target) / "@" & name.changeFileExt(ext) proc needsCodegenCheck(spec: TSpec): bool = result = spec.maxCodeSize > 0 or spec.ccodeCheck.len > 0 diff --git a/tests/cpp/mexportc.nim b/tests/cpp/mexportc.nim new file mode 100644 index 000000000..dee51f157 --- /dev/null +++ b/tests/cpp/mexportc.nim @@ -0,0 +1,9 @@ +{.used.} # ideally, would not be needed + +var fun0 {.exportc.} = 10 +proc fun1() {.exportc.} = discard +proc fun2() {.exportc: "$1".} = discard +proc fun3() {.exportc: "fun3Bis".} = discard + +when defined cpp: + proc funx1() {.exportcpp.} = discard diff --git a/tests/cpp/tempty_generic_obj.nim b/tests/cpp/tempty_generic_obj.nim index b61c699f6..d05a82f9a 100644 --- a/tests/cpp/tempty_generic_obj.nim +++ b/tests/cpp/tempty_generic_obj.nim @@ -8,7 +8,7 @@ import typetraits # bug #4625 type - Vector {.importcpp: "std::vector<'0 >", header: "vector".} [T] = object + Vector[T] {.importcpp: "std::vector<'0 >", header: "vector".} = object proc initVector[T](): Vector[T] {.importcpp: "'0(@)", header: "vector", constructor.} @@ -24,7 +24,7 @@ vf.doSomething() # Nim uses doSomething[int] here in C++ # Alternative definition: # https://github.com/nim-lang/Nim/issues/7653 -type VectorAlt* {.importcpp: "std::vector", header: "<vector>", nodecl.} [T] = object +type VectorAlt*[T] {.importcpp: "std::vector", header: "<vector>", nodecl.} = object proc mkVector*[T]: VectorAlt[T] {.importcpp: "std::vector<'*0>()", header: "<vector>", constructor, nodecl.} proc foo(): VectorAlt[cint] = @@ -36,3 +36,10 @@ proc bar(): VectorAlt[cstring] = var x = foo() var y = bar() +proc init[T; Self: Vector[T]](_: typedesc[Self], n: csize): Vector[T] + {.importcpp: "std::vector<'*0>(@)", header: "<vector>", constructor, nodecl.} +proc size[T](x: Vector[T]): csize + {.importcpp: "#.size()", header: "<vector>", nodecl.} + +var z = Vector[int16].init(32) +assert z.size == 32 diff --git a/tests/cpp/texportc.nim b/tests/cpp/texportc.nim new file mode 100644 index 000000000..3a2fa8748 --- /dev/null +++ b/tests/cpp/texportc.nim @@ -0,0 +1,22 @@ +discard """ + targets: "c cpp" +""" + +var fun0 {.importc.}: int +proc fun1() {.importc.} +proc fun2() {.importc: "$1".} +proc fun3() {.importc: "fun3Bis".} + +when defined cpp: + # proc funx1() {.importcpp.} # this does not work yet + proc funx1() {.importc: "_Z5funx1v".} + +doAssert fun0 == 10 +fun1() +fun2() +fun3() + +when defined cpp: + funx1() + +import ./mexportc diff --git a/tests/destructor/tnewruntime_misc.nim b/tests/destructor/tnewruntime_misc.nim index 8abf0d30b..e6be5824d 100644 --- a/tests/destructor/tnewruntime_misc.nim +++ b/tests/destructor/tnewruntime_misc.nim @@ -4,7 +4,10 @@ discard """ Indeed axc (v: 10) -0 new: 0''' +0 new: 0 +... +destroying GenericObj[T] GenericObj[system.int] +''' """ import core / allocators @@ -92,9 +95,25 @@ type x: seq[(A, B)] -proc toTable[A,B](p: sink openArray[(A, B)]): Table[A, B] = +proc toTable[A,B](p: sink openArray[(A, B)]): Table[A, B] = for zz in mitems(p): result.x.add move(zz) let table = {"a": new(int)}.toTable() + +# bug # #12051 + +type + GenericObj[T] = object + val: T + Generic[T] = owned ref GenericObj[T] + +proc `=destroy`[T](x: var GenericObj[T]) = + echo "destroying GenericObj[T] ", x.typeof # to know when its being destroyed + +proc main12() = + let gnrc = Generic[int](val: 42) + echo "..." + +main12() diff --git a/tests/errmsgs/tnnodeadd.nim b/tests/errmsgs/tnnodeadd.nim new file mode 100644 index 000000000..61921883e --- /dev/null +++ b/tests/errmsgs/tnnodeadd.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "cannot add to node kind: nnkInt8Lit" + line: 7 +""" +import macros +macro t(x: untyped): untyped = + x.add(newEmptyNode()) +t(38'i8) diff --git a/tests/errmsgs/tnnodeindex.nim b/tests/errmsgs/tnnodeindex.nim new file mode 100644 index 000000000..5e37e7977 --- /dev/null +++ b/tests/errmsgs/tnnodeindex.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "index 5 not in 0 .. 2" + line: 7 +""" +import macros +macro t(x: untyped): untyped = + result = x[5] +t([1, 2, 3]) diff --git a/tests/errmsgs/tnnodeindexkind.nim b/tests/errmsgs/tnnodeindexkind.nim new file mode 100644 index 000000000..9ea045e66 --- /dev/null +++ b/tests/errmsgs/tnnodeindexkind.nim @@ -0,0 +1,8 @@ +discard """ + errormsg: "cannot set child of node kind: nnkStrLit" + line: 7 +""" +import macros +macro t(x: untyped): untyped = + x[0] = newEmptyNode() +t("abc") diff --git a/tests/gensym/tgensymgeneric.nim b/tests/gensym/tgensymgeneric.nim index 9963ba808..c17a0715f 100644 --- a/tests/gensym/tgensymgeneric.nim +++ b/tests/gensym/tgensymgeneric.nim @@ -40,15 +40,15 @@ doAssert y.x == "abc" import macros static: - let sym1 = genSym() - let sym2 = genSym() - let sym3 = sym1 + let sym1 = genSym() + let sym2 = genSym() + let sym3 = sym1 let nimsym = sym1.symbol - doAssert sym1 == sym1 - doAssert sym2 != sym3 + doAssert sym1 == sym1 + doAssert sym2 != sym3 doAssert sym2.symbol != sym3.symbol - doAssert sym3 == sym1 + doAssert sym3 == sym1 doAssert sym1.symbol == sym1.symbol - doAssert nimsym == nimsym + doAssert nimsym == nimsym echo "true" diff --git a/tests/iter/tyieldintry.nim b/tests/iter/tyieldintry.nim index 32eef494e..62c16c741 100644 --- a/tests/iter/tyieldintry.nim +++ b/tests/iter/tyieldintry.nim @@ -467,5 +467,19 @@ block: #9716 doAssert(b == "hello") test(it, 1, 1, 1) +block: # nnkChckRange + type Foo = distinct uint64 + template yieldDistinct: Foo = + yield 2 + Foo(0) + + iterator it(): int {.closure.} = + yield 1 + var a: int + a = int(yieldDistinct()) + yield 3 + + test(it, 1, 2, 3) + echo "ok" diff --git a/tests/macros/tmacrotypes.nim b/tests/macros/tmacrotypes.nim index ab8bcfa95..8cf93a593 100644 --- a/tests/macros/tmacrotypes.nim +++ b/tests/macros/tmacrotypes.nim @@ -3,12 +3,14 @@ discard """ void; ntyVoid; void; void int; ntyInt; int; int proc (); ntyProc; proc[void]; proc () -voidProc; ntyProc; proc[void]; proc ()''' +voidProc; ntyProc; proc[void]; proc () +typeDesc[range[1 .. 5]]; ntyTypeDesc; typeDesc[range[1, 5]]; typeDesc[range[1 .. 5]] +typeDesc[range]; ntyTypeDesc; typeDesc[range[T]]; typeDesc[range]''' """ import macros -macro checkType(ex: typed; expected: string): untyped = +macro checkType(ex: typed): untyped = echo ex.getTypeInst.repr, "; ", ex.typeKind, "; ", ex.getType.repr, "; ", ex.getTypeImpl.repr macro checkProcType(fn: typed): untyped = @@ -19,9 +21,9 @@ macro checkProcType(fn: typed): untyped = proc voidProc = echo "hello" proc intProc(a: int, b: float): int {.checkProcType.} = 10 -checkType(voidProc(), "void") -checkType(intProc(10, 20.0), "int") -checkType(voidProc, "procTy") +checkType(voidProc()) +checkType(intProc(10, 20.0)) +checkType(voidProc) checkProcType(voidProc) # bug #10548 @@ -68,3 +70,6 @@ macro foobar(arg: typed): untyped = var x: Vec2f foobar(x) + +checkType(range[1..5]) +checkType(range) diff --git a/tests/niminaction/Chapter8/sdl/sdl.nim b/tests/niminaction/Chapter8/sdl/sdl.nim index a1b30281b..14fa59c85 100644 --- a/tests/niminaction/Chapter8/sdl/sdl.nim +++ b/tests/niminaction/Chapter8/sdl/sdl.nim @@ -1,9 +1,13 @@ when defined(Windows): const libName* = "SDL2.dll" -elif defined(Linux): +elif defined(Linux) or defined(freebsd): const libName* = "libSDL2.so" elif defined(MacOsX): const libName* = "libSDL2.dylib" +elif defined(openbsd): + const libName* = "libSDL2.so.0.6" +else: + {.error: "SDL library name not set for this platform".} type SdlWindow = object diff --git a/tests/pragmas/t8741.nim b/tests/pragmas/t8741.nim index c132c3543..61a449c01 100644 --- a/tests/pragmas/t8741.nim +++ b/tests/pragmas/t8741.nim @@ -1,6 +1,10 @@ discard """ - errormsg: "cannot attach a custom pragma to 'a'" - line: 9 + cmd: "nim check --hint[processing]:off $file" + errormsg: "3 is not two" + nimout: '''t8741.nim(13, 9) Error: cannot attach a custom pragma to 'a' +t8741.nim(29, 15) template/generic instantiation of `onlyTwo` from here +t8741.nim(25, 12) Error: 3 is not two +''' """ for a {.gensym, inject.} in @[1,2,3]: @@ -8,3 +12,18 @@ for a {.gensym, inject.} in @[1,2,3]: for a {.foobar.} in @[1,2,3]: discard + +type Foo[N: static[int]] = distinct int + +proc isTwo(n: int): bool = + n == 2 + +proc onlyTwo[N: static[int]](a: Foo[N]): int = + when isTwo(N): + int(a) + else: + {.error: $(N) & " is not two".} + +when isMainModule: + let foo: Foo[3] = Foo[3](5) + echo onlyTwo(foo) diff --git a/tests/template/mtempl5.nim b/tests/template/mtempl5.nim index 3c2881764..2cc6f91bc 100644 --- a/tests/template/mtempl5.nim +++ b/tests/template/mtempl5.nim @@ -7,4 +7,18 @@ template templ*(): int = bind gx, gy gx + gy +import json + +const + codeField = "foobar" + messageField = "more" + +template trap*(path: string, body: untyped): untyped = + #bind codeField, messageField + try: + body + except: + let msg = getCurrentExceptionMsg() + #debug "Error occurred within RPC ", path = path, errorMessage = msg + result = %*{codeField: "SERVER_ERROR", messageField: msg} diff --git a/tests/template/template_issues.nim b/tests/template/template_issues.nim index b7dd2a1a7..e56d44480 100644 --- a/tests/template/template_issues.nim +++ b/tests/template/template_issues.nim @@ -7,6 +7,7 @@ a hi Hello, World! (e: 42) +hey ''' """ @@ -235,3 +236,12 @@ var x = X.fails(42) echo x + +import mtempl5 + + +proc foo(): auto = + trap "foo": + echo "hey" + +discard foo() diff --git a/tests/template/tparams_gensymed.nim b/tests/template/tparams_gensymed.nim index fe5608add..a35d878d5 100644 --- a/tests/template/tparams_gensymed.nim +++ b/tests/template/tparams_gensymed.nim @@ -14,6 +14,7 @@ wth 1 0 (total: 6) +S1 ''' """ # bug #1915 @@ -164,3 +165,33 @@ template baz(): untyped = echo (total: bar2(3)) baz() + +# bug #12121 +macro state_machine_enum(states: varargs[untyped]) = + result = nnkTypeSection.newTree( + nnkTypeDef.newTree( + nnkPragmaExpr.newTree(ident("State"), nnkPragma.newTree(ident("pure"))), + newEmptyNode(), + nnkEnumTy.newTree(newEmptyNode()) + ) + ) + + for s in states: + expectKind(s, nnkIdent) + result[0][2].add s + +template mystate_machine(body: untyped) = + state_machine_enum(S1, S2, S3) + var state_stack: seq[State] + template state_current(): State {.inject, used.} = + state_stack[^1] + template state_push(state_name) {.inject, used.} = + state_stack.add State.state_name + template state_pop(n = 1) {.inject, used.} = + state_stack.setLen(state_stack.len - n) + body + +mystate_machine: + state_push(S1) + echo state_current() + state_pop() diff --git a/tests/vm/tcompiletimetable.nim b/tests/vm/tcompiletimetable.nim index e78c06536..ece2ddfe9 100644 --- a/tests/vm/tcompiletimetable.nim +++ b/tests/vm/tcompiletimetable.nim @@ -3,7 +3,10 @@ discard """ 3 4:2 Got Hi -Got Hey''' +Got Hey +a +b +c''' """ # bug #404 @@ -47,3 +50,9 @@ addStuff("Hey"): echo "Hey" addStuff("Hi"): echo "Hi" dump() +# ensure .compileTime vars can be used at runtime: +import macros + +var xzzzz {.compileTime.}: array[3, string] = ["a", "b", "c"] + +for i in 0..high(xzzzz): echo xzzzz[i] |