Cosmetic compiler cleanup (#12718)

* Cleanup compiler code base

* Unify add calls

* Unify len invocations

* Unify range operators

* Fix oversight

* Remove {.procvar.} pragma

* initCandidate -> newCandidate where reasonable

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

View file

@ -22,17 +22,17 @@ proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult =
result = arNo
case n.kind
of nkRecList:
for i in 0 ..< len(n):
result = isPartOfAux(n.sons[i], b, marker)
for i in 0..<n.len:
result = isPartOfAux(n[i], b, marker)
if result == arYes: return
of nkRecCase:
assert(n.sons[0].kind == nkSym)
result = isPartOfAux(n.sons[0], b, marker)
assert(n[0].kind == nkSym)
result = isPartOfAux(n[0], b, marker)
if result == arYes: return
for i in 1 ..< len(n):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = isPartOfAux(lastSon(n.sons[i]), b, marker)
result = isPartOfAux(lastSon(n[i]), b, marker)
if result == arYes: return
else: discard "isPartOfAux(record case branch)"
of nkSym:
@ -46,14 +46,14 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
if compareTypes(a, b, dcEqIgnoreDistinct): return arYes
case a.kind
of tyObject:
if a.sons[0] != nil:
result = isPartOfAux(a.sons[0].skipTypes(skipPtrs), b, marker)
if a[0] != nil:
result = isPartOfAux(a[0].skipTypes(skipPtrs), b, marker)
if result == arNo: result = isPartOfAux(a.n, b, marker)
of tyGenericInst, tyDistinct, tyAlias, tySink:
result = isPartOfAux(lastSon(a), b, marker)
of tyArray, tySet, tyTuple:
for i in 0 ..< len(a):
result = isPartOfAux(a.sons[i], b, marker)
for i in 0..<a.len:
result = isPartOfAux(a[i], b, marker)
if result == arYes: return
else: discard
@ -108,7 +108,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
result = arMaybe
of nkBracketExpr:
result = isPartOf(a[0], b[0])
if len(a) >= 2 and len(b) >= 2:
if a.len >= 2 and b.len >= 2:
# array accesses:
if result == arYes and isDeepConstExpr(a[1]) and isDeepConstExpr(b[1]):
# we know it's the same array and we have 2 constant indexes;
@ -181,14 +181,14 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
else: discard
of nkObjConstr:
result = arNo
for i in 1 ..< b.len:
for i in 1..<b.len:
let res = isPartOf(a, b[i][1])
if res != arNo:
result = res
if res == arYes: break
of nkCallKinds:
result = arNo
for i in 1 ..< b.len:
for i in 1..<b.len:
let res = isPartOf(a, b[i])
if res != arNo:
result = res

View file

@ -1025,27 +1025,27 @@ type Indexable = PNode | PType
proc len*(n: Indexable): int {.inline.} =
when defined(nimNoNilSeqs):
result = len(n.sons)
result = n.sons.len
else:
if isNil(n.sons): result = 0
else: result = len(n.sons)
else: result = n.sons.len
proc safeLen*(n: PNode): int {.inline.} =
## works even for leaves.
if n.kind in {nkNone..nkNilLit}: result = 0
else: result = len(n)
else: result = n.len
proc safeArrLen*(n: PNode): int {.inline.} =
## works for array-like objects (strings passed as openArray in VM).
if n.kind in {nkStrLit..nkTripleStrLit}:result = len(n.strVal)
if n.kind in {nkStrLit..nkTripleStrLit}:result = n.strVal.len
elif n.kind in {nkNone..nkFloat128Lit}: result = 0
else: result = len(n)
else: result = n.len
proc add*(father, son: PNode) =
proc add*(father, son: Indexable) =
assert son != nil
when not defined(nimNoNilSeqs):
if isNil(father.sons): father.sons = @[]
add(father.sons, son)
father.sons.add(son)
template `[]`*(n: Indexable, i: int): Indexable = n.sons[i]
template `[]=`*(n: Indexable, i: int; x: Indexable) = n.sons[i] = x
@ -1144,18 +1144,18 @@ const # for all kind of hash tables:
proc copyStrTable*(dest: var TStrTable, src: TStrTable) =
dest.counter = src.counter
setLen(dest.data, len(src.data))
for i in 0 .. high(src.data): dest.data[i] = src.data[i]
setLen(dest.data, src.data.len)
for i in 0..high(src.data): dest.data[i] = src.data[i]
proc copyIdTable*(dest: var TIdTable, src: TIdTable) =
dest.counter = src.counter
newSeq(dest.data, len(src.data))
for i in 0 .. high(src.data): dest.data[i] = src.data[i]
newSeq(dest.data, src.data.len)
for i in 0..high(src.data): dest.data[i] = src.data[i]
proc copyObjectSet*(dest: var TObjectSet, src: TObjectSet) =
dest.counter = src.counter
setLen(dest.data, len(src.data))
for i in 0 .. high(src.data): dest.data[i] = src.data[i]
setLen(dest.data, src.data.len)
for i in 0..high(src.data): dest.data[i] = src.data[i]
proc discardSons*(father: PNode) =
when defined(nimNoNilSeqs):
@ -1286,12 +1286,6 @@ proc newStrNode*(strVal: string; info: TLineInfo): PNode =
result = newNodeI(nkStrLit, info)
result.strVal = strVal
proc addSon*(father, son: PNode) =
assert son != nil
when not defined(nimNoNilSeqs):
if isNil(father.sons): father.sons = @[]
add(father.sons, son)
proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode,
params,
name, pattern, genericParams,
@ -1366,8 +1360,8 @@ proc assignType*(dest, src: PType) =
mergeLoc(dest.sym.loc, src.sym.loc)
else:
dest.sym = src.sym
newSons(dest, len(src))
for i in 0 ..< len(src): dest.sons[i] = src.sons[i]
newSons(dest, src.len)
for i in 0..<src.len: dest[i] = src[i]
proc copyType*(t: PType, owner: PSym, keepId: bool): PType =
result = newType(t.kind, owner)
@ -1503,27 +1497,26 @@ proc propagateToOwner*(owner, elem: PType) =
proc rawAddSon*(father, son: PType) =
when not defined(nimNoNilSeqs):
if isNil(father.sons): father.sons = @[]
add(father.sons, son)
father.sons.add(son)
if not son.isNil: propagateToOwner(father, son)
proc rawAddSonNoPropagationOfTypeFlags*(father, son: PType) =
when not defined(nimNoNilSeqs):
if isNil(father.sons): father.sons = @[]
add(father.sons, son)
father.sons.add(son)
proc addSonNilAllowed*(father, son: PNode) =
when not defined(nimNoNilSeqs):
if isNil(father.sons): father.sons = @[]
add(father.sons, son)
father.sons.add(son)
proc delSon*(father: PNode, idx: int) =
when defined(nimNoNilSeqs):
if father.len == 0: return
else:
if isNil(father.sons): return
var length = len(father)
for i in idx .. length - 2: father.sons[i] = father.sons[i + 1]
setLen(father.sons, length - 1)
for i in idx..<father.len - 1: father[i] = father[i + 1]
father.sons.setLen(father.len - 1)
proc copyNode*(src: PNode): PNode =
# does not copy its sons!
@ -1562,7 +1555,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, len(src))
else: newSeq(result.sons, src.len)
proc copyTree*(src: PNode): PNode =
# copy a whole syntax tree; performs deep copying
@ -1583,21 +1576,21 @@ proc copyTree*(src: PNode): PNode =
of nkIdent: result.ident = src.ident
of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
else:
newSeq(result.sons, len(src))
for i in 0 ..< len(src):
result.sons[i] = copyTree(src.sons[i])
newSeq(result.sons, src.len)
for i in 0..<src.len:
result[i] = copyTree(src[i])
proc hasSonWith*(n: PNode, kind: TNodeKind): bool =
for i in 0 ..< len(n):
if n.sons[i].kind == kind:
for i in 0..<n.len:
if n[i].kind == kind:
return true
result = false
proc hasNilSon*(n: PNode): bool =
for i in 0 ..< safeLen(n):
if n.sons[i] == nil:
for i in 0..<n.safeLen:
if n[i] == nil:
return true
elif hasNilSon(n.sons[i]):
elif hasNilSon(n[i]):
return true
result = false
@ -1606,15 +1599,15 @@ proc containsNode*(n: PNode, kinds: TNodeKinds): bool =
case n.kind
of nkEmpty..nkNilLit: result = n.kind in kinds
else:
for i in 0 ..< len(n):
if n.kind in kinds or containsNode(n.sons[i], kinds): return true
for i in 0..<n.len:
if n.kind in kinds or containsNode(n[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 ..< len(n):
if (n.sons[i].kind == kind) or hasSubnodeWith(n.sons[i], kind):
for i in 0..<n.len:
if (n[i].kind == kind) or hasSubnodeWith(n[i], kind):
return true
result = false
@ -1710,19 +1703,19 @@ proc requiredParams*(s: PSym): int =
# Returns the number of required params (without default values)
# XXX: Perhaps we can store this in the `offset` field of the
# symbol instead?
for i in 1 ..< s.typ.len:
for i in 1..<s.typ.len:
if s.typ.n[i].sym.ast != nil:
return i - 1
return s.typ.len - 1
proc hasPattern*(s: PSym): bool {.inline.} =
result = isRoutine(s) and s.ast.sons[patternPos].kind != nkEmpty
result = isRoutine(s) and s.ast[patternPos].kind != nkEmpty
iterator items*(n: PNode): PNode =
for i in 0..<n.safeLen: yield n.sons[i]
for i in 0..<n.safeLen: yield n[i]
iterator pairs*(n: PNode): tuple[i: int, n: PNode] =
for i in 0..<n.safeLen: yield (i, n.sons[i])
for i in 0..<n.safeLen: yield (i, n[i])
proc isAtom*(n: PNode): bool {.inline.} =
result = n.kind >= nkNone and n.kind <= nkNilLit
@ -1740,7 +1733,7 @@ proc makeStmtList*(n: PNode): PNode =
proc skipStmtList*(n: PNode): PNode =
if n.kind in {nkStmtList, nkStmtListExpr}:
for i in 0 .. n.len-2:
for i in 0..<n.len-1:
if n[i].kind notin {nkEmpty, nkCommentStmt}: return n
result = n.lastSon
else:
@ -1797,7 +1790,7 @@ when false:
proc containsNil*(n: PNode): bool =
# only for debugging
if n.isNil: return true
for i in 0 ..< n.safeLen:
for i in 0..<n.safeLen:
if n[i].containsNil: return true
template hasDestructor*(t: PType): bool = {tfHasAsgn, tfHasOwned} * t.flags != {}
@ -1831,11 +1824,11 @@ proc newProcType*(info: TLineInfo; owner: PSym): PType =
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
# the effects are now stored in there too ... this is a bit hacky, but as
# usual we desperately try to save memory:
addSon(result.n, newNodeI(nkEffectList, info))
result.n.add newNodeI(nkEffectList, info)
proc addParam*(procType: PType; param: PSym) =
param.position = procType.len-1
addSon(procType.n, newSymNode(param))
procType.n.add newSymNode(param)
rawAddSon(procType, param.typ)
template destructor*(t: PType): PSym = t.attachedOps[attachedDestructor]

View file

@ -116,9 +116,9 @@ proc skipConvAndClosure*(n: PNode): PNode =
case result.kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64,
nkClosure:
result = result.sons[0]
result = result[0]
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = result.sons[1]
result = result[1]
else: break
proc sameValue*(a, b: PNode): bool =
@ -160,17 +160,17 @@ proc lookupInRecord(n: PNode, field: PIdent): PSym =
result = nil
case n.kind
of nkRecList:
for i in 0 ..< len(n):
result = lookupInRecord(n.sons[i], field)
for i in 0..<n.len:
result = lookupInRecord(n[i], field)
if result != nil: return
of nkRecCase:
if (n.sons[0].kind != nkSym): return nil
result = lookupInRecord(n.sons[0], field)
if (n[0].kind != nkSym): return nil
result = lookupInRecord(n[0], field)
if result != nil: return
for i in 1 ..< len(n):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = lookupInRecord(lastSon(n.sons[i]), field)
result = lookupInRecord(lastSon(n[i]), field)
if result != nil: return
else: return nil
of nkSym:
@ -183,9 +183,9 @@ 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 ..< len(list):
if list.sons[i].kind == nkSym:
result = list.sons[i].sym
for i in start..<list.len:
if list[i].kind == nkSym:
result = list[i].sym
if result.name.id == ident.id: return
else: return nil
result = nil
@ -221,11 +221,11 @@ proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym =
## gensym'ed and then they have '`<number>' suffix that we need to
## ignore, see compiler / evaltempl.nim, snippet:
##
## .. code-block:: nim
##..code-block:: nim
##
## result.add newIdentNode(getIdent(c.ic, x.name.s & "`gensym" & $x.id),
## if c.instLines: actual.info else: templ.info)
for i in 1 ..< len(list):
for i in 1..<list.len:
let it = list[i].sym
if it.name.id == ident.id or
sameIgnoreBacktickGensymInfo(it.name.s, ident.s): return it
@ -254,15 +254,15 @@ proc makeYamlString*(s: string): Rope =
const MaxLineLength = 64
result = nil
var res = "\""
for i in 0 ..< s.len:
for i in 0..<s.len:
if (i + 1) mod MaxLineLength == 0:
add(res, '\"')
add(res, "\n")
add(result, rope(res))
res.add('\"')
res.add("\n")
result.add(rope(res))
res = "\"" # reset
add(res, toYamlChar(s[i]))
add(res, '\"')
add(result, rope(res))
res.add(toYamlChar(s[i]))
res.add('\"')
result.add(rope(res))
proc flagsToStr[T](flags: set[T]): Rope =
if flags == {}:
@ -270,8 +270,8 @@ proc flagsToStr[T](flags: set[T]): Rope =
else:
result = nil
for x in items(flags):
if result != nil: add(result, ", ")
add(result, makeYamlString($x))
if result != nil: result.add(", ")
result.add(makeYamlString($x))
result = "[" & result & "]"
proc lineInfoToStr(conf: ConfigRef; info: TLineInfo): Rope =
@ -298,25 +298,25 @@ proc symToYamlAux(conf: ConfigRef; n: PSym, marker: var IntSet, indent: int,
# indent + 2, maxRecDepth - 1),
let istr = rspaces(indent + 2)
result = rope("{")
addf(result, "$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
addf(result, "$N$1\"name\": $2", [istr, makeYamlString(n.name.s)])
addf(result, "$N$1\"typ\": $2", [istr, typeToYamlAux(conf, n.typ, marker, indent + 2, maxRecDepth - 1)])
result.addf("$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
result.addf("$N$1\"name\": $2", [istr, makeYamlString(n.name.s)])
result.addf("$N$1\"typ\": $2", [istr, typeToYamlAux(conf, n.typ, marker, indent + 2, maxRecDepth - 1)])
if conf != nil:
# if we don't pass the config, we probably don't care about the line info
addf(result, "$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
result.addf("$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
if card(n.flags) > 0:
addf(result, "$N$1\"flags\": $2", [istr, flagsToStr(n.flags)])
addf(result, "$N$1\"magic\": $2", [istr, makeYamlString($n.magic)])
addf(result, "$N$1\"ast\": $2", [istr, ast])
addf(result, "$N$1\"options\": $2", [istr, flagsToStr(n.options)])
addf(result, "$N$1\"position\": $2", [istr, rope(n.position)])
addf(result, "$N$1\"k\": $2", [istr, makeYamlString($n.loc.k)])
addf(result, "$N$1\"storage\": $2", [istr, makeYamlString($n.loc.storage)])
result.addf("$N$1\"flags\": $2", [istr, flagsToStr(n.flags)])
result.addf("$N$1\"magic\": $2", [istr, makeYamlString($n.magic)])
result.addf("$N$1\"ast\": $2", [istr, ast])
result.addf("$N$1\"options\": $2", [istr, flagsToStr(n.options)])
result.addf("$N$1\"position\": $2", [istr, rope(n.position)])
result.addf("$N$1\"k\": $2", [istr, makeYamlString($n.loc.k)])
result.addf("$N$1\"storage\": $2", [istr, makeYamlString($n.loc.storage)])
if card(n.loc.flags) > 0:
addf(result, "$N$1\"flags\": $2", [istr, makeYamlString($n.loc.flags)])
addf(result, "$N$1\"r\": $2", [istr, n.loc.r])
addf(result, "$N$1\"lode\": $2", [istr, treeToYamlAux(conf, n.loc.lode, marker, indent + 2, maxRecDepth - 1)])
addf(result, "$N$1}", [rspaces(indent)])
result.addf("$N$1\"flags\": $2", [istr, makeYamlString($n.loc.flags)])
result.addf("$N$1\"r\": $2", [istr, n.loc.r])
result.addf("$N$1\"lode\": $2", [istr, treeToYamlAux(conf, n.loc.lode, marker, indent + 2, maxRecDepth - 1)])
result.addf("$N$1}", [rspaces(indent)])
proc typeToYamlAux(conf: ConfigRef; n: PType, marker: var IntSet, indent: int,
maxRecDepth: int): Rope =
@ -327,27 +327,27 @@ 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 len(n) > 0:
if n.len > 0:
sonsRope = rope("[")
for i in 0 ..< len(n):
if i > 0: add(sonsRope, ",")
addf(sonsRope, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, n.sons[i],
for i in 0..<n.len:
if i > 0: sonsRope.add(",")
sonsRope.addf("$N$1$2", [rspaces(indent + 4), typeToYamlAux(conf, n[i],
marker, indent + 4, maxRecDepth - 1)])
addf(sonsRope, "$N$1]", [rspaces(indent + 2)])
sonsRope.addf("$N$1]", [rspaces(indent + 2)])
else:
sonsRope = rope("null")
let istr = rspaces(indent + 2)
result = rope("{")
addf(result, "$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
addf(result, "$N$1\"sym\": $2", [istr, symToYamlAux(conf, n.sym, marker, indent + 2, maxRecDepth - 1)])
addf(result, "$N$1\"n\": $2", [istr, treeToYamlAux(conf, n.n, marker, indent + 2, maxRecDepth - 1)])
result.addf("$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
result.addf("$N$1\"sym\": $2", [istr, symToYamlAux(conf, n.sym, marker, indent + 2, maxRecDepth - 1)])
result.addf("$N$1\"n\": $2", [istr, treeToYamlAux(conf, n.n, marker, indent + 2, maxRecDepth - 1)])
if card(n.flags) > 0:
addf(result, "$N$1\"flags\": $2", [istr, flagsToStr(n.flags)])
addf(result, "$N$1\"callconv\": $2", [istr, makeYamlString(CallingConvToStr[n.callConv])])
addf(result, "$N$1\"size\": $2", [istr, rope(n.size)])
addf(result, "$N$1\"align\": $2", [istr, rope(n.align)])
addf(result, "$N$1\"sons\": $2", [istr, sonsRope])
result.addf("$N$1\"flags\": $2", [istr, flagsToStr(n.flags)])
result.addf("$N$1\"callconv\": $2", [istr, makeYamlString(CallingConvToStr[n.callConv])])
result.addf("$N$1\"size\": $2", [istr, rope(n.size)])
result.addf("$N$1\"align\": $2", [istr, rope(n.align)])
result.addf("$N$1\"sons\": $2", [istr, sonsRope])
proc treeToYamlAux(conf: ConfigRef; n: PNode, marker: var IntSet, indent: int,
maxRecDepth: int): Rope =
@ -358,34 +358,34 @@ proc treeToYamlAux(conf: ConfigRef; n: PNode, marker: var IntSet, indent: int,
result = "{$N$1\"kind\": $2" % [istr, makeYamlString($n.kind)]
if maxRecDepth != 0:
if conf != nil:
addf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
result.addf(",$N$1\"info\": $2", [istr, lineInfoToStr(conf, n.info)])
case n.kind
of nkCharLit..nkInt64Lit:
addf(result, ",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
result.addf(",$N$1\"intVal\": $2", [istr, rope(n.intVal)])
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
addf(result, ",$N$1\"floatVal\": $2",
result.addf(",$N$1\"floatVal\": $2",
[istr, rope(n.floatVal.toStrMaxPrecision)])
of nkStrLit..nkTripleStrLit:
addf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
result.addf(",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
of nkSym:
addf(result, ",$N$1\"sym\": $2",
result.addf(",$N$1\"sym\": $2",
[istr, symToYamlAux(conf, n.sym, marker, indent + 2, maxRecDepth)])
of nkIdent:
if n.ident != nil:
addf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
result.addf(",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
else:
addf(result, ",$N$1\"ident\": null", [istr])
result.addf(",$N$1\"ident\": null", [istr])
else:
if len(n) > 0:
addf(result, ",$N$1\"sons\": [", [istr])
for i in 0 ..< len(n):
if i > 0: add(result, ",")
addf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(conf, n.sons[i],
if n.len > 0:
result.addf(",$N$1\"sons\": [", [istr])
for i in 0..<n.len:
if i > 0: result.add(",")
result.addf("$N$1$2", [rspaces(indent + 4), treeToYamlAux(conf, n[i],
marker, indent + 4, maxRecDepth - 1)])
addf(result, "$N$1]", [istr])
addf(result, ",$N$1\"typ\": $2",
result.addf("$N$1]", [istr])
result.addf(",$N$1\"typ\": $2",
[istr, typeToYamlAux(conf, n.typ, marker, indent + 2, maxRecDepth)])
addf(result, "$N$1}", [rspaces(indent)])
result.addf("$N$1}", [rspaces(indent)])
proc treeToYaml(conf: ConfigRef; n: PNode, indent: int = 0, maxRecDepth: int = - 1): Rope =
var marker = initIntSet()
@ -427,7 +427,7 @@ proc indentLess(this: var DebugPrinter) =
proc newlineAndIndent(this: var DebugPrinter) =
this.res.add "\n"
this.currentLine += 1
for i in 0 ..< this.indent:
for i in 0..<this.indent:
this.res.add ' '
proc openCurly(this: var DebugPrinter) =
@ -563,12 +563,12 @@ proc value(this: var DebugPrinter; value: PType) =
this.key "n"
this.value value.n
if len(value) > 0:
if value.len > 0:
this.key "sons"
this.openBracket
for i in 0 ..< len(value):
this.value value.sons[i]
if i != len(value) - 1:
for i in 0..<value.len:
this.value value[i]
if i != value.len - 1:
this.comma
this.closeBracket
@ -616,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 len(value) > 0:
if value.len > 0:
this.key "sons"
this.openBracket
for i in 0 ..< len(value):
this.value value.sons[i]
if i != len(value) - 1:
for i in 0..<value.len:
this.value value[i]
if i != value.len - 1:
this.comma
this.closeBracket
@ -677,13 +677,13 @@ proc objectSetRawInsert(data: var TObjectSeq, obj: RootRef) =
proc objectSetEnlarge(t: var TObjectSet) =
var n: TObjectSeq
newSeq(n, len(t.data) * GrowthFactor)
for i in 0 .. high(t.data):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i] != nil: objectSetRawInsert(n, t.data[i])
swap(t.data, n)
proc objectSetIncl*(t: var TObjectSet, obj: RootRef) =
if mustRehash(len(t.data), t.counter): objectSetEnlarge(t)
if mustRehash(t.data.len, t.counter): objectSetEnlarge(t)
objectSetRawInsert(t.data, obj)
inc(t.counter)
@ -696,7 +696,7 @@ proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool =
if it == obj:
return true # found it
h = nextTry(h, high(t.data))
if mustRehash(len(t.data), t.counter):
if mustRehash(t.data.len, t.counter):
objectSetEnlarge(t)
objectSetRawInsert(t.data, obj)
else:
@ -739,13 +739,13 @@ proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) =
proc strTableEnlarge(t: var TStrTable) =
var n: seq[PSym]
newSeq(n, len(t.data) * GrowthFactor)
for i in 0 .. high(t.data):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i] != nil: strTableRawInsert(n, t.data[i])
swap(t.data, n)
proc strTableAdd*(t: var TStrTable, n: PSym) =
if mustRehash(len(t.data), t.counter): strTableEnlarge(t)
if mustRehash(t.data.len, t.counter): strTableEnlarge(t)
strTableRawInsert(t.data, n)
inc(t.counter)
@ -772,7 +772,7 @@ proc strTableInclReportConflict*(t: var TStrTable, n: PSym;
if not onConflictKeepOld:
t.data[replaceSlot] = n # overwrite it with newer definition!
return t.data[replaceSlot] # found it
elif mustRehash(len(t.data), t.counter):
elif mustRehash(t.data.len, t.counter):
strTableEnlarge(t)
strTableRawInsert(t.data, n)
else:
@ -876,7 +876,7 @@ iterator items*(tab: TStrTable): PSym =
s = nextIter(it, tab)
proc hasEmptySlot(data: TIdPairSeq): bool =
for h in 0 .. high(data):
for h in 0..high(data):
if data[h].key == nil:
return true
result = false
@ -929,9 +929,9 @@ proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
assert(t.data[index].key != nil)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
newSeq(n, len(t.data) * GrowthFactor)
for i in 0 .. high(t.data):
if mustRehash(t.data.len, t.counter):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i].key != nil:
idTableRawInsert(n, t.data[i].key, t.data[i].val)
assert(hasEmptySlot(n))
@ -940,7 +940,7 @@ proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
inc(t.counter)
iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: RootRef] =
for i in 0 .. high(t.data):
for i in 0..high(t.data):
if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
@ -974,10 +974,10 @@ proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
assert(t.data[index].key != nil)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
if mustRehash(t.data.len, t.counter):
var n: TIdNodePairSeq
newSeq(n, len(t.data) * GrowthFactor)
for i in 0 .. high(t.data):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i].key != nil:
idNodeTableRawInsert(n, t.data[i].key, t.data[i].val)
swap(t.data, n)
@ -985,13 +985,13 @@ proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
inc(t.counter)
iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] =
for i in 0 .. high(t.data):
for i in 0..high(t.data):
if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
proc initIITable(x: var TIITable) =
x.counter = 0
newSeq(x.data, StartSize)
for i in 0 ..< StartSize: x.data[i].key = InvalidKey
for i in 0..<StartSize: x.data[i].key = InvalidKey
proc iiTableRawGet(t: TIITable, key: int): int =
var h: Hash
@ -1022,11 +1022,11 @@ proc iiTablePut(t: var TIITable, key, val: int) =
assert(t.data[index].key != InvalidKey)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
if mustRehash(t.data.len, t.counter):
var n: TIIPairSeq
newSeq(n, len(t.data) * GrowthFactor)
for i in 0 .. high(n): n[i].key = InvalidKey
for i in 0 .. high(t.data):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(n): n[i].key = InvalidKey
for i in 0..high(t.data):
if t.data[i].key != InvalidKey:
iiTableRawInsert(n, t.data[i].key, t.data[i].val)
swap(t.data, n)

View file

@ -52,25 +52,25 @@ proc bitSetInit(b: var TBitSet, length: int) =
newSeq(b, length)
proc bitSetUnion(x: var TBitSet, y: TBitSet) =
for i in 0 .. high(x): x[i] = x[i] or y[i]
for i in 0..high(x): x[i] = x[i] or y[i]
proc bitSetDiff(x: var TBitSet, y: TBitSet) =
for i in 0 .. high(x): x[i] = x[i] and not y[i]
for i in 0..high(x): x[i] = x[i] and not y[i]
proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
for i in 0 .. high(x): x[i] = x[i] xor y[i]
for i in 0..high(x): x[i] = x[i] xor y[i]
proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
for i in 0 .. high(x): x[i] = x[i] and y[i]
for i in 0..high(x): x[i] = x[i] and y[i]
proc bitSetEquals(x, y: TBitSet): bool =
for i in 0 .. high(x):
for i in 0..high(x):
if x[i] != y[i]:
return false
result = true
proc bitSetContains(x, y: TBitSet): bool =
for i in 0 .. high(x):
for i in 0..high(x):
if (x[i] and not y[i]) != Zero:
return false
result = true

View file

@ -37,34 +37,34 @@ template eq(a, b): bool = cmp(a, b) == 0
proc getOrDefault*[Key, Val](b: BTree[Key, Val], key: Key): Val =
var x = b.root
while x.isInternal:
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if j+1 == x.entries or less(key, x.keys[j+1]):
x = x.links[j]
break
assert(not x.isInternal)
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if eq(key, x.keys[j]): return x.vals[j]
proc contains*[Key, Val](b: BTree[Key, Val], key: Key): bool =
var x = b.root
while x.isInternal:
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if j+1 == x.entries or less(key, x.keys[j+1]):
x = x.links[j]
break
assert(not x.isInternal)
for j in 0 ..< x.entries:
for j in 0..<x.entries:
if eq(key, x.keys[j]): return true
return false
proc copyHalf[Key, Val](h, result: Node[Key, Val]) =
for j in 0 ..< Mhalf:
for j in 0..<Mhalf:
result.keys[j] = h.keys[Mhalf + j]
if h.isInternal:
for j in 0 ..< Mhalf:
for j in 0..<Mhalf:
result.links[j] = h.links[Mhalf + j]
else:
for j in 0 ..< Mhalf:
for j in 0..<Mhalf:
shallowCopy(result.vals[j], h.vals[Mhalf + j])
proc split[Key, Val](h: Node[Key, Val]): Node[Key, Val] =

View file

@ -102,7 +102,7 @@ proc hashTree(c: var MD5Context, n: PNode) =
of nkStrLit..nkTripleStrLit:
c &= n.strVal
else:
for i in 0..<n.len: hashTree(c, n.sons[i])
for i in 0..<n.len: hashTree(c, n[i])
proc hashType(c: var MD5Context, t: PType) =
# modelled after 'typeToString'
@ -120,44 +120,44 @@ proc hashType(c: var MD5Context, t: PType) =
case t.kind
of tyGenericBody, tyGenericInst, tyGenericInvocation:
for i in 0 ..< len(t)-ord(t.kind != tyGenericInvocation):
c.hashType t.sons[i]
for i in 0..<t.len-ord(t.kind != tyGenericInvocation):
c.hashType t[i]
of tyUserTypeClass:
internalAssert t.sym != nil and t.sym.owner != nil
c &= t.sym.owner.name.s
of tyUserTypeClassInst:
let body = t.base
c.hashSym body.sym
for i in 1 .. len(t) - 2:
c.hashType t.sons[i]
for i in 1..<t.len-1:
c.hashType t[i]
of tyFromExpr:
c.hashTree(t.n)
of tyArray:
c.hashTree(t.sons[0].n)
c.hashType(t.sons[1])
c.hashTree(t[0].n)
c.hashType(t[1])
of tyTuple:
if t.n != nil:
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
assert(t.n.len == t.len)
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)
c &= t.n[i].sym.name.s
c &= ":"
c.hashType(t.sons[i])
c.hashType(t[i])
c &= ","
else:
for i in 0 ..< len(t): c.hashType t.sons[i]
for i in 0..<t.len: c.hashType t[i]
of tyRange:
c.hashTree(t.n)
c.hashType(t.sons[0])
c.hashType(t[0])
of tyProc:
c &= (if tfIterator in t.flags: "iterator " else: "proc ")
for i in 0..<t.len: c.hashType(t.sons[i])
for i in 0..<t.len: c.hashType(t[i])
md5Update(c, cast[cstring](addr(t.callConv)), 1)
if tfNoSideEffect in t.flags: c &= ".noSideEffect"
if tfThread in t.flags: c &= ".thread"
else:
for i in 0..<t.len: c.hashType(t.sons[i])
for i in 0..<t.len: c.hashType(t[i])
if tfNotNil in t.flags: c &= "not nil"
proc canonConst(n: PNode): TUid =
@ -238,35 +238,35 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
encodeVInt(n.sym.id, result)
pushSym(w, n.sym)
else:
for i in 0 ..< len(n):
encodeNode(w, n.info, n.sons[i], result)
add(result, ')')
for i in 0..<n.len:
encodeNode(w, n.info, n[i], result)
result.add(')')
proc encodeLoc(w: PRodWriter, loc: TLoc, result: var string) =
var oldLen = result.len
result.add('<')
if loc.k != low(loc.k): encodeVInt(ord(loc.k), result)
if loc.s != low(loc.s):
add(result, '*')
result.add('*')
encodeVInt(ord(loc.s), result)
if loc.flags != {}:
add(result, '$')
result.add('$')
encodeVInt(cast[int32](loc.flags), result)
if loc.t != nil:
add(result, '^')
result.add('^')
encodeVInt(cast[int32](loc.t.id), result)
pushType(w, loc.t)
if loc.r != nil:
add(result, '!')
result.add('!')
encodeStr($loc.r, result)
if loc.a != 0:
add(result, '?')
result.add('?')
encodeVInt(loc.a, result)
if oldLen + 1 == result.len:
# no data was necessary, so remove the '<' again:
setLen(result, oldLen)
else:
add(result, '>')
result.add('>')
proc encodeType(w: PRodWriter, t: PType, result: var string) =
if t == nil:
@ -277,47 +277,47 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) =
if t.kind == tyForward: internalError("encodeType: tyForward")
# for the new rodfile viewer we use a preceding [ so that the data section
# can easily be disambiguated:
add(result, '[')
result.add('[')
encodeVInt(ord(t.kind), result)
add(result, '+')
result.add('+')
encodeVInt(t.id, result)
if t.n != nil:
encodeNode(w, unknownLineInfo(), t.n, result)
if t.flags != {}:
add(result, '$')
result.add('$')
encodeVInt(cast[int32](t.flags), result)
if t.callConv != low(t.callConv):
add(result, '?')
result.add('?')
encodeVInt(ord(t.callConv), result)
if t.owner != nil:
add(result, '*')
result.add('*')
encodeVInt(t.owner.id, result)
pushSym(w, t.owner)
if t.sym != nil:
add(result, '&')
result.add('&')
encodeVInt(t.sym.id, result)
pushSym(w, t.sym)
if t.size != - 1:
add(result, '/')
result.add('/')
encodeVBiggestInt(t.size, result)
if t.align != - 1:
add(result, '=')
result.add('=')
encodeVInt(t.align, result)
encodeLoc(w, t.loc, result)
for i in 0 ..< len(t):
if t.sons[i] == nil:
add(result, "^()")
for i in 0..<t.len:
if t[i] == nil:
result.add("^()")
else:
add(result, '^')
encodeVInt(t.sons[i].id, result)
pushType(w, t.sons[i])
result.add('^')
encodeVInt(t[i].id, result)
pushType(w, t[i])
proc encodeLib(w: PRodWriter, lib: PLib, info: TLineInfo, result: var string) =
add(result, '|')
result.add('|')
encodeVInt(ord(lib.kind), result)
add(result, '|')
result.add('|')
encodeStr($lib.name, result)
add(result, '|')
result.add('|')
encodeNode(w, info, lib.path, result)
proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
@ -363,7 +363,7 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
encodeLoc(w, s.loc, result)
if s.annex != nil: encodeLib(w, s.annex, s.info, result)
if s.constraint != nil:
add(result, '#')
result.add('#')
encodeNode(w, unknownLineInfo(), s.constraint, result)
# lazy loading will soon reload the ast lazily, so the ast needs to be
# the last entry of a symbol:

View file

@ -11,41 +11,41 @@
proc leftAppearsOnRightSide(le, ri: PNode): bool =
if le != nil:
for i in 1 ..< ri.len:
for i in 1..<ri.len:
let r = ri[i]
if isPartOf(le, r) != arNo: return true
proc hasNoInit(call: PNode): bool {.inline.} =
result = call.sons[0].kind == nkSym and sfNoInit in call.sons[0].sym.flags
result = call[0].kind == nkSym and sfNoInit in call[0].sym.flags
proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
callee, params: Rope) =
genLineDir(p, ri)
var pl = callee & ~"(" & params
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
if typ.sons[0] != nil:
if isInvalidReturnType(p.config, typ.sons[0]):
var typ = skipTypes(ri[0].typ, abstractInst)
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if params != nil: pl.add(~", ")
# 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':
if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true)
if d.k == locNone: getTemp(p, typ[0], d, needsInit=true)
elif d.k notin {locTemp} and not hasNoInit(ri):
# reset before pass as 'result' var:
discard "resetLoc(p, d)"
add(pl, addrLoc(p.config, d))
add(pl, ~");$n")
pl.add(addrLoc(p.config, d))
pl.add(~");$n")
line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
add(pl, addrLoc(p.config, tmp))
add(pl, ~");$n")
getTemp(p, typ[0], tmp, needsInit=true)
pl.add(addrLoc(p.config, tmp))
pl.add(~");$n")
line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
add(pl, ~")")
pl.add(~")")
if p.module.compileToCpp:
if lfSingleUse in d.flags:
# do not generate spurious temporaries for C++! For C we're better off
@ -56,22 +56,22 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
excl d.flags, lfSingleUse
else:
if d.k == locNone and p.splitDecls == 0:
getTempCpp(p, typ.sons[0], d, pl)
getTempCpp(p, typ[0], d, pl)
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
if d.k == locNone: getTemp(p, typ[0], d)
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
add(pl, ~");$n")
pl.add(~");$n")
line(p, cpsStmts, pl)
proc genBoundsCheck(p: BProc; arr, a, b: TLoc)
@ -89,7 +89,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
if skipped:
q = skipConv(n)
while q.kind == nkStmtListExpr and q.len > 0:
for i in 0..q.len-2:
for i in 0..<q.len-1:
genStmts(p, q[i])
q = q.lastSon
var b, c: TLoc
@ -100,7 +100,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
if optBoundsCheck in p.options:
genBoundsCheck(p, a, b, c)
let ty = skipTypes(a.t, abstractVar+{tyPtr})
let dest = getTypeDesc(p.module, n.typ.sons[0])
let dest = getTypeDesc(p.module, n.typ[0])
case ty.kind
of tyArray:
let first = toInt64(firstOrd(p.config, ty))
@ -148,7 +148,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
proc genArgStringToCString(p: BProc, n: PNode): Rope {.inline.} =
var a: TLoc
initLocExpr(p, n.sons[0], a)
initLocExpr(p, n[0], a)
result = ropecg(p.module, "#nimToCStringConv($1)", [a.rdLoc])
proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): Rope =
@ -156,17 +156,17 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode): Rope =
if n.kind == nkStringToCString:
result = genArgStringToCString(p, n)
elif skipTypes(param.typ, abstractVar).kind in {tyOpenArray, tyVarargs}:
var n = if n.kind != nkHiddenAddr: n else: n.sons[0]
var n = if n.kind != nkHiddenAddr: n else: n[0]
result = openArrayLoc(p, n)
elif ccgIntroducedPtr(p.config, param, call[0].typ[0]):
initLocExpr(p, n, a)
result = addrLoc(p.config, a)
elif p.module.compileToCpp and param.typ.kind == tyVar and
n.kind == nkHiddenAddr:
initLocExprSingleUse(p, n.sons[0], a)
initLocExprSingleUse(p, n[0], a)
# if the proc is 'importc'ed but not 'importcpp'ed then 'var T' still
# means '*T'. See posix.nim for lots of examples that do that in the wild.
let callee = call.sons[0]
let callee = call[0]
if callee.kind == nkSym and
{sfImportc, sfInfixCall, sfCompilerProc} * callee.sym.flags == {sfImportc} and
{lfHeader, lfNoDecl} * callee.sym.loc.flags != {}:
@ -186,15 +186,15 @@ proc genArgNoParam(p: BProc, n: PNode): Rope =
result = rdLoc(a)
template genParamLoop(params) {.dirty.} =
if i < len(typ):
assert(typ.n.sons[i].kind == nkSym)
let paramType = typ.n.sons[i]
if i < typ.len:
assert(typ.n[i].kind == nkSym)
let paramType = typ.n[i]
if not paramType.typ.isCompileTimeOnly:
if params != nil: add(params, ~", ")
add(params, genArg(p, ri.sons[i], paramType.sym, ri))
if params != nil: params.add(~", ")
params.add(genArg(p, ri[i], paramType.sym, ri))
else:
if params != nil: add(params, ~", ")
add(params, genArgNoParam(p, ri.sons[i]))
if params != nil: params.add(~", ")
params.add(genArgNoParam(p, ri[i]))
proc addActualSuffixForHCR(res: var Rope, module: PSym, sym: PSym) =
if sym.flags * {sfImportc, sfNonReloadable} == {} and sym.loc.k == locProc and
@ -204,18 +204,17 @@ proc addActualSuffixForHCR(res: var Rope, module: PSym, sym: PSym) =
proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc
# this is a hotspot in the compiler
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
var params: Rope
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInstOwned)
var typ = skipTypes(ri[0].typ, abstractInstOwned)
assert(typ.kind == tyProc)
assert(len(typ) == len(typ.n))
var length = len(ri)
for i in 1 ..< length:
assert(typ.len == typ.n.len)
for i in 1..<ri.len:
genParamLoop(params)
var callee = rdLoc(op)
if p.hcrOn and ri.sons[0].kind == nkSym:
callee.addActualSuffixForHCR(p.module.module, ri.sons[0].sym)
if p.hcrOn and ri[0].kind == nkSym:
callee.addActualSuffixForHCR(p.module.module, ri[0].sym)
fixupCall(p, le, ri, d, callee, params)
proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
@ -229,14 +228,13 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
const PatProc = "$1.ClE_0? $1.ClP_0($3$1.ClE_0):(($4)($1.ClP_0))($2)"
const PatIter = "$1.ClP_0($3$1.ClE_0)" # we know the env exists
var op: TLoc
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
var pl: Rope
var typ = skipTypes(ri.sons[0].typ, abstractInst)
var typ = skipTypes(ri[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = len(ri)
for i in 1 ..< length:
assert(len(typ) == len(typ.n))
for i in 1..<ri.len:
assert(typ.len == typ.n.len)
genParamLoop(pl)
template genCallPattern {.dirty.} =
@ -246,27 +244,27 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
lineF(p, cpsStmts, PatProc & ";$n", [rdLoc(op), pl, pl.addComma, rawProc])
let rawProc = getRawProcType(p, typ)
if typ.sons[0] != nil:
if isInvalidReturnType(p.config, typ.sons[0]):
if len(ri) > 1: add(pl, ~", ")
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if ri.len > 1: pl.add(~", ")
# 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':
if d.k == locNone:
getTemp(p, typ.sons[0], d, needsInit=true)
getTemp(p, typ[0], d, needsInit=true)
elif d.k notin {locTemp} and not hasNoInit(ri):
# reset before pass as 'result' var:
discard "resetLoc(p, d)"
add(pl, addrLoc(p.config, d))
pl.add(addrLoc(p.config, d))
genCallPattern()
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
add(pl, addrLoc(p.config, tmp))
getTemp(p, typ[0], tmp, needsInit=true)
pl.add(addrLoc(p.config, tmp))
genCallPattern()
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
@ -280,23 +278,23 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
genCallPattern()
proc genOtherArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
if i < len(typ):
if i < typ.len:
# '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]
let paramType = typ.n[i]
assert(paramType.kind == nkSym)
if paramType.typ.isCompileTimeOnly:
result = nil
elif typ.sons[i].kind == tyVar and ri.sons[i].kind == nkHiddenAddr:
result = genArgNoParam(p, ri.sons[i][0])
elif typ[i].kind == tyVar and ri[i].kind == nkHiddenAddr:
result = genArgNoParam(p, ri[i][0])
else:
result = genArgNoParam(p, ri.sons[i]) #, typ.n.sons[i].sym)
result = genArgNoParam(p, ri[i]) #, typ.n[i].sym)
else:
if tfVarargs notin typ.flags:
localError(p.config, ri.info, "wrong argument count")
result = nil
else:
result = genArgNoParam(p, ri.sons[i])
result = genArgNoParam(p, ri[i])
discard """
Dot call syntax in C++
@ -340,16 +338,16 @@ proc skipAddrDeref(node: PNode): PNode =
var isAddr = false
case n.kind
of nkAddr, nkHiddenAddr:
n = n.sons[0]
n = n[0]
isAddr = true
of nkDerefExpr, nkHiddenDeref:
n = n.sons[0]
n = n[0]
else: return n
if n.kind == nkObjDownConv: n = n.sons[0]
if n.kind == nkObjDownConv: n = n[0]
if isAddr and n.kind in {nkDerefExpr, nkHiddenDeref}:
result = n.sons[0]
result = n[0]
elif n.kind in {nkAddr, nkHiddenAddr}:
result = n.sons[0]
result = n[0]
else:
result = node
@ -357,13 +355,13 @@ 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 < len(typ)
assert(typ.n.sons[i].kind == nkSym)
internalAssert p.config, i < typ.len
assert(typ.n[i].kind == nkSym)
# if the parameter is lying (tyVar) and thus we required an additional deref,
# skip the deref:
var ri = ri[i]
while ri.kind == nkObjDownConv: ri = ri[0]
let t = typ.sons[i].skipTypes({tyGenericInst, tyAlias, tySink})
let t = typ[i].skipTypes({tyGenericInst, tyAlias, tySink})
if t.kind == tyVar:
let x = if ri.kind == nkHiddenAddr: ri[0] else: ri
if x.typ.kind == tyPtr:
@ -385,7 +383,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): Rope =
else:
ri = skipAddrDeref(ri)
if ri.kind in {nkAddr, nkHiddenAddr}: ri = ri[0]
result = genArgNoParam(p, ri) #, typ.n.sons[i].sym)
result = genArgNoParam(p, ri) #, typ.n[i].sym)
result.add(".")
proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
@ -395,7 +393,7 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
case pat[i]
of '@':
var first = true
for k in j ..< ri.len:
for k in j..<ri.len:
let arg = genOtherArg(p, ri, k, typ)
if arg.len > 0:
if not first:
@ -407,12 +405,12 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
if i+1 < pat.len and pat[i+1] in {'+', '@'}:
let ri = ri[j]
if ri.kind in nkCallKinds:
let typ = skipTypes(ri.sons[0].typ, abstractInst)
if pat[i+1] == '+': result.add genArgNoParam(p, ri.sons[0])
let typ = skipTypes(ri[0].typ, abstractInst)
if pat[i+1] == '+': result.add genArgNoParam(p, ri[0])
result.add(~"(")
if 1 < ri.len:
result.add genOtherArg(p, ri, 1, typ)
for k in j+1 ..< ri.len:
for k in j+1..<ri.len:
result.add(~", ")
result.add genOtherArg(p, ri, k, typ)
result.add(~")")
@ -423,7 +421,7 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
result.add genThisArg(p, ri, j, typ)
inc i
elif i+1 < pat.len and pat[i+1] == '[':
var arg = ri.sons[j].skipAddrDeref
var arg = ri[j].skipAddrDeref
while arg.kind in {nkAddr, nkHiddenAddr, nkObjDownConv}: arg = arg[0]
result.add genArgNoParam(p, arg)
#result.add debugTree(arg, 0, 10)
@ -443,24 +441,23 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): Rope =
if pat[i] notin {'@', '#', '\''}: inc(i)
else: break
if i - 1 >= start:
add(result, substr(pat, start, i - 1))
result.add(substr(pat, start, i - 1))
proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
var typ = skipTypes(ri[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = len(ri)
assert(len(typ) == len(typ.n))
assert(typ.len == typ.n.len)
# don't call '$' here for efficiency:
let pat = ri.sons[0].sym.loc.r.data
let pat = ri[0].sym.loc.r.data
internalAssert p.config, pat.len > 0
if pat.contains({'#', '(', '@', '\''}):
var pl = genPatternCall(p, ri, pat, typ)
# simpler version of 'fixupCall' that works with the pl+params combination:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
if typ.sons[0] != nil:
var typ = skipTypes(ri[0].typ, abstractInst)
if typ[0] != nil:
if p.module.compileToCpp and lfSingleUse in d.flags:
# do not generate spurious temporaries for C++! For C we're better off
# with them to prevent undefined behaviour and because the codegen
@ -469,115 +466,114 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
d.r = pl
excl d.flags, lfSingleUse
else:
if d.k == locNone: getTemp(p, typ.sons[0], d)
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
add(pl, ~";$n")
pl.add(~";$n")
line(p, cpsStmts, pl)
else:
var pl: Rope = nil
#var param = typ.n.sons[1].sym
#var param = typ.n[1].sym
if 1 < ri.len:
add(pl, genThisArg(p, ri, 1, typ))
add(pl, op.r)
pl.add(genThisArg(p, ri, 1, typ))
pl.add(op.r)
var params: Rope
for i in 2 ..< length:
for i in 2..<ri.len:
if params != nil: params.add(~", ")
assert(len(typ) == len(typ.n))
add(params, genOtherArg(p, ri, i, typ))
assert(typ.len == typ.n.len)
params.add(genOtherArg(p, ri, i, typ))
fixupCall(p, le, ri, d, pl, params)
proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
# generates a crappy ObjC call
var op: TLoc
initLocExpr(p, ri.sons[0], op)
initLocExpr(p, ri[0], op)
var pl = ~"["
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
var typ = skipTypes(ri[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = len(ri)
assert(len(typ) == len(typ.n))
assert(typ.len == typ.n.len)
# don't call '$' here for efficiency:
let pat = ri.sons[0].sym.loc.r.data
let pat = ri[0].sym.loc.r.data
internalAssert p.config, pat.len > 0
var start = 3
if ' ' in pat:
start = 1
add(pl, op.r)
if length > 1:
add(pl, ~": ")
add(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
pl.add(op.r)
if ri.len > 1:
pl.add(~": ")
pl.add(genArg(p, ri[1], typ.n[1].sym, ri))
start = 2
else:
if length > 1:
add(pl, genArg(p, ri.sons[1], typ.n.sons[1].sym, ri))
add(pl, ~" ")
add(pl, op.r)
if length > 2:
add(pl, ~": ")
add(pl, genArg(p, ri.sons[2], typ.n.sons[2].sym, ri))
for i in start ..< length:
assert(len(typ) == len(typ.n))
if i >= len(typ):
if ri.len > 1:
pl.add(genArg(p, ri[1], typ.n[1].sym, ri))
pl.add(~" ")
pl.add(op.r)
if ri.len > 2:
pl.add(~": ")
pl.add(genArg(p, ri[2], typ.n[2].sym, ri))
for i in start..<ri.len:
assert(typ.len == typ.n.len)
if i >= typ.len:
internalError(p.config, ri.info, "varargs for objective C method?")
assert(typ.n.sons[i].kind == nkSym)
var param = typ.n.sons[i].sym
add(pl, ~" ")
add(pl, param.name.s)
add(pl, ~": ")
add(pl, genArg(p, ri.sons[i], param, ri))
if typ.sons[0] != nil:
if isInvalidReturnType(p.config, typ.sons[0]):
if len(ri) > 1: add(pl, ~" ")
assert(typ.n[i].kind == nkSym)
var param = typ.n[i].sym
pl.add(~" ")
pl.add(param.name.s)
pl.add(~": ")
pl.add(genArg(p, ri[i], param, ri))
if typ[0] != nil:
if isInvalidReturnType(p.config, typ[0]):
if ri.len > 1: pl.add(~" ")
# 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:
if d.k == locNone: getTemp(p, typ.sons[0], d, needsInit=true)
add(pl, ~"Result: ")
add(pl, addrLoc(p.config, d))
add(pl, ~"];$n")
if d.k == locNone: getTemp(p, typ[0], d, needsInit=true)
pl.add(~"Result: ")
pl.add(addrLoc(p.config, d))
pl.add(~"];$n")
line(p, cpsStmts, pl)
else:
var tmp: TLoc
getTemp(p, typ.sons[0], tmp, needsInit=true)
add(pl, addrLoc(p.config, tmp))
add(pl, ~"];$n")
getTemp(p, typ[0], tmp, needsInit=true)
pl.add(addrLoc(p.config, tmp))
pl.add(~"];$n")
line(p, cpsStmts, pl)
genAssignment(p, d, tmp, {}) # no need for deep copying
else:
add(pl, ~"]")
if d.k == locNone: getTemp(p, typ.sons[0], d)
pl.add(~"]")
if d.k == locNone: getTemp(p, typ[0], d)
assert(d.t != nil) # generate an assignment to d:
var list: TLoc
initLoc(list, locCall, ri, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
else:
add(pl, ~"];$n")
pl.add(~"];$n")
line(p, cpsStmts, pl)
proc genCall(p: BProc, e: PNode, d: var TLoc) =
if e.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).callConv == ccClosure:
if e[0].typ.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).callConv == ccClosure:
genClosureCall(p, nil, e, d)
elif e.sons[0].kind == nkSym and sfInfixCall in e.sons[0].sym.flags:
elif e[0].kind == nkSym and sfInfixCall in e[0].sym.flags:
genInfixCall(p, nil, e, d)
elif e.sons[0].kind == nkSym and sfNamedParamCall in e.sons[0].sym.flags:
elif e[0].kind == nkSym and sfNamedParamCall in e[0].sym.flags:
genNamedParamCall(p, e, d)
else:
genPrefixCall(p, nil, e, d)
postStmtActions(p)
proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) =
if ri.sons[0].typ.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).callConv == ccClosure:
if ri[0].typ.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).callConv == ccClosure:
genClosureCall(p, le, ri, d)
elif ri.sons[0].kind == nkSym and sfInfixCall in ri.sons[0].sym.flags:
elif ri[0].kind == nkSym and sfInfixCall in ri[0].sym.flags:
genInfixCall(p, le, ri, d)
elif ri.sons[0].kind == nkSym and sfNamedParamCall in ri.sons[0].sym.flags:
elif ri[0].kind == nkSym and sfNamedParamCall in ri[0].sym.flags:
genNamedParamCall(p, ri, d)
else:
genPrefixCall(p, le, ri, d)

File diff suppressed because it is too large Load diff

View file

@ -35,8 +35,8 @@ proc detectSeqVersion(m: BModule): int =
proc genStringLiteralDataOnlyV1(m: BModule, s: string): Rope =
discard cgsym(m, "TGenericSeq")
result = getTempName(m)
addf(m.s[cfsData], "STRING_LITERAL($1, $2, $3);$n",
[result, makeCString(s), rope(len(s))])
m.s[cfsData].addf("STRING_LITERAL($1, $2, $3);$n",
[result, makeCString(s), rope(s.len)])
proc genStringLiteralV1(m: BModule; n: PNode): Rope =
if s.isNil:
@ -54,10 +54,10 @@ proc genStringLiteralV1(m: BModule; n: PNode): Rope =
# ------ Version 2: destructor based strings and seqs -----------------------
proc genStringLiteralDataOnlyV2(m: BModule, s: string; result: Rope) =
addf(m.s[cfsData], "static const struct {$n" &
m.s[cfsData].addf("static const struct {$n" &
" NI cap; void* allocator; NIM_CHAR data[$2+1];$n" &
"} $1 = { $2, NIM_NIL, $3 };$n",
[result, rope(len(s)), makeCString(s)])
[result, rope(s.len), makeCString(s)])
proc genStringLiteralV2(m: BModule; n: PNode): Rope =
let id = nodeTableTestOrSet(m.dataCache, n, m.labels)
@ -68,12 +68,12 @@ proc genStringLiteralV2(m: BModule; n: PNode): Rope =
discard cgsym(m, "NimStrPayload")
discard cgsym(m, "NimStringV2")
# string literal not found in the cache:
addf(m.s[cfsData], "static const NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[result, rope(len(n.strVal)), pureLit])
m.s[cfsData].addf("static const NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[result, rope(n.strVal.len), pureLit])
else:
result = getTempName(m)
addf(m.s[cfsData], "static const NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[result, rope(len(n.strVal)), m.tmpBase & rope(id)])
m.s[cfsData].addf("static const NimStringV2 $1 = {$2, (NimStrPayload*)&$3};$n",
[result, rope(n.strVal.len), m.tmpBase & rope(id)])
proc genStringLiteralV2Const(m: BModule; n: PNode): Rope =
let id = nodeTableTestOrSet(m.dataCache, n, m.labels)
@ -86,7 +86,7 @@ proc genStringLiteralV2Const(m: BModule; n: PNode): Rope =
genStringLiteralDataOnlyV2(m, n.strVal, pureLit)
else:
pureLit = m.tmpBase & rope(id)
result = "{$1, (NimStrPayload*)&$2}" % [rope(len(n.strVal)), pureLit]
result = "{$1, (NimStrPayload*)&$2}" % [rope(n.strVal.len), pureLit]
# ------ Version selector ---------------------------------------------------

View file

@ -50,9 +50,9 @@ const
proc genSectionStart*(fs: TCFileSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):
result = nil
add(result, "\n/*\t")
add(result, CFileSectionNames[fs])
add(result, ":*/\n")
result.add("\n/*\t")
result.add(CFileSectionNames[fs])
result.add(":*/\n")
proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):
@ -61,9 +61,9 @@ proc genSectionEnd*(fs: TCFileSection; conf: ConfigRef): Rope =
proc genSectionStart*(ps: TCProcSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):
result = rope("")
add(result, "\n/*\t")
add(result, CProcSectionNames[ps])
add(result, ":*/\n")
result.add("\n/*\t")
result.add(CProcSectionNames[ps])
result.add(":*/\n")
proc genSectionEnd*(ps: TCProcSection; conf: ConfigRef): Rope =
if compilationCachePresent(conf):

View file

@ -46,7 +46,7 @@ proc inExceptBlockLen(p: BProc): int =
proc startBlockInternal(p: BProc): int {.discardable.} =
inc(p.labels)
result = len(p.blocks)
result = p.blocks.len
setLen(p.blocks, result + 1)
p.blocks[result].id = p.labels
p.blocks[result].nestedTryStmts = p.nestedTryStmts.len.int16
@ -62,16 +62,15 @@ 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 = len(n)
# if we have a something that's been captured, use the lowering instead:
for i in 0 .. L-3:
for i in 0..<n.len-2:
if n[i].kind != nkSym:
genStmts(p, lowerTupleUnpacking(p.module.g.graph, n, p.prc))
return
# check only the first son
var forHcr = treatGlobalDifferentlyForHCR(p.module, n.sons[0].sym)
var forHcr = treatGlobalDifferentlyForHCR(p.module, n[0].sym)
let hcrCond = if forHcr: getTempName(p.module) else: nil
var hcrGlobals: seq[tuple[loc: TLoc, tp: Rope]]
# determine if the tuple is constructed at top-level scope or inside of a block (if/while/block)
@ -85,10 +84,10 @@ proc genVarTuple(p: BProc, n: PNode) =
startBlock(p)
genLineDir(p, n)
initLocExpr(p, n.sons[L-1], tup)
initLocExpr(p, n[^1], tup)
var t = tup.t.skipTypes(abstractInst)
for i in 0 .. L-3:
let vn = n.sons[i]
for i in 0..<n.len-2:
let vn = n[i]
let v = vn.sym
if sfCompileTime in v.flags: continue
var traverseProc: Rope
@ -100,13 +99,13 @@ proc genVarTuple(p: BProc, n: PNode) =
registerTraverseProc(p, v, traverseProc)
else:
assignLocalVar(p, vn)
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(p.config, n[L-1]))
initLocalVar(p, v, immediateAsgn=isAssignedImmediately(p.config, n[^1]))
initLoc(field, locExpr, vn, tup.storage)
if t.kind == tyTuple:
field.r = "$1.Field$2" % [rdLoc(tup), rope(i)]
else:
if t.n.sons[i].kind != nkSym: internalError(p.config, n.info, "genVarTuple")
field.r = "$1.$2" % [rdLoc(tup), mangleRecFieldName(p.module, t.n.sons[i].sym)]
if t.n[i].kind != nkSym: internalError(p.config, n.info, "genVarTuple")
field.r = "$1.$2" % [rdLoc(tup), mangleRecFieldName(p.module, t.n[i].sym)]
putLocIntoDest(p, v.loc, field)
if forHcr or isGlobalInBlock:
hcrGlobals.add((loc: v.loc, tp: if traverseProc == nil: ~"NULL" else: traverseProc))
@ -121,12 +120,12 @@ proc genVarTuple(p: BProc, n: PNode) =
lineCg(p, cpsLocals, "NIM_BOOL $1 = NIM_FALSE;$n", [hcrCond])
for curr in hcrGlobals:
lineCg(p, cpsLocals, "$1 |= hcrRegisterGlobal($4, \"$2\", sizeof($3), $5, (void**)&$2);$N",
[hcrCond, curr.loc.r, rdLoc(curr.loc), getModuleDllPath(p.module, n.sons[0].sym), curr.tp])
[hcrCond, curr.loc.r, rdLoc(curr.loc), getModuleDllPath(p.module, n[0].sym), curr.tp])
proc loadInto(p: BProc, le, ri: PNode, a: var TLoc) {.inline.} =
if ri.kind in nkCallKinds and (ri.sons[0].kind != nkSym or
ri.sons[0].sym.magic == mNone):
if ri.kind in nkCallKinds and (ri[0].kind != nkSym or
ri[0].sym.magic == mNone):
genAsgnCall(p, le, ri, a)
else:
# this is a hacky way to fix #1181 (tmissingderef)::
@ -153,7 +152,7 @@ proc blockBody(b: var TBlock): Rope =
proc endBlock(p: BProc, blockEnd: Rope) =
let topBlock = p.blocks.len-1
# the block is merged into the parent block
add(p.blocks[topBlock-1].sections[cpsStmts], p.blocks[topBlock].blockBody)
p.blocks[topBlock-1].sections[cpsStmts].add(p.blocks[topBlock].blockBody)
setLen(p.blocks, topBlock)
# this is done after the block is popped so $n is
# properly indented when pretty printing is enabled
@ -190,7 +189,7 @@ proc genState(p: BProc, n: PNode) =
internalAssert p.config, n.len == 1
let n0 = n[0]
if n0.kind == nkIntLit:
let idx = n.sons[0].intVal
let idx = n[0].intVal
linefmt(p, cpsStmts, "STATE$1: ;$n", [idx])
elif n0.kind == nkStrLit:
linefmt(p, cpsStmts, "$1: ;$n", [n0.strVal])
@ -201,7 +200,7 @@ proc blockLeaveActions(p: BProc, howManyTrys, howManyExcepts: int) =
var stack = newSeq[tuple[fin: PNode, inExcept: bool]](0)
for i in 1 .. howManyTrys:
for i in 1..howManyTrys:
let tryStmt = p.nestedTryStmts.pop
if not p.module.compileToCpp or optNoCppExceptions in p.config.globalOptions:
# Pop safe points generated by try
@ -236,7 +235,7 @@ proc genGotoState(p: BProc, n: PNode) =
# case 0: goto STATE0;
# ...
var a: TLoc
initLocExpr(p, n.sons[0], a)
initLocExpr(p, n[0], a)
lineF(p, cpsStmts, "switch ($1) {$n", [rdLoc(a)])
p.beforeRetNeeded = true
lineF(p, cpsStmts, "case -1:$n", [])
@ -244,12 +243,12 @@ proc genGotoState(p: BProc, n: PNode) =
howManyTrys = p.nestedTryStmts.len,
howManyExcepts = p.inExceptBlockLen)
lineF(p, cpsStmts, " goto BeforeRet_;$n", [])
var statesCounter = lastOrd(p.config, n.sons[0].typ)
var statesCounter = lastOrd(p.config, n[0].typ)
if n.len >= 2 and n[1].kind == nkIntLit:
statesCounter = getInt(n[1])
let prefix = if n.len == 3 and n[2].kind == nkStrLit: n[2].strVal.rope
else: rope"STATE"
for i in 0i64 .. toInt64(statesCounter):
for i in 0i64..toInt64(statesCounter):
lineF(p, cpsStmts, "case $2: goto $1$2;$n", [prefix, rope(i)])
lineF(p, cpsStmts, "}$n", [])
@ -257,11 +256,11 @@ proc genBreakState(p: BProc, n: PNode, d: var TLoc) =
var a: TLoc
initLoc(d, locExpr, n, OnUnknown)
if n.sons[0].kind == nkClosure:
initLocExpr(p, n.sons[0].sons[1], a)
if n[0].kind == nkClosure:
initLocExpr(p, n[0][1], a)
d.r = "(((NI*) $1)[1] < 0)" % [rdLoc(a)]
else:
initLocExpr(p, n.sons[0], a)
initLocExpr(p, n[0], a)
# the environment is guaranteed to contain the 'state' field at offset 1:
d.r = "((((NI*) $1.ClE_0)[1]) < 0)" % [rdLoc(a)]
@ -322,12 +321,12 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
if value.kind in nkCallKinds and value[0].kind == nkSym and
sfConstructor in value[0].sym.flags:
var params: Rope
let typ = skipTypes(value.sons[0].typ, abstractInst)
let typ = skipTypes(value[0].typ, abstractInst)
assert(typ.kind == tyProc)
for i in 1..<value.len:
if params != nil: params.add(~", ")
assert(len(typ) == len(typ.n))
add(params, genOtherArg(p, value, i, typ))
assert(typ.len == typ.n.len)
params.add(genOtherArg(p, value, i, typ))
if params == nil:
lineF(p, cpsStmts, "$#;$n", [decl])
else:
@ -368,15 +367,15 @@ proc genSingleVar(p: BProc, v: PSym; vn, value: PNode) =
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])
genSingleVar(p, v, a[0], a[2])
proc genClosureVar(p: BProc, a: PNode) =
var immediateAsgn = a.sons[2].kind != nkEmpty
var immediateAsgn = a[2].kind != nkEmpty
var v: TLoc
initLocExpr(p, a.sons[0], v)
initLocExpr(p, a[0], v)
genLineDir(p, a)
if immediateAsgn:
loadInto(p, a.sons[0], a.sons[2], v)
loadInto(p, a[0], a[2], v)
else:
constructLoc(p, v)
@ -385,7 +384,7 @@ proc genVarStmt(p: BProc, n: PNode) =
if it.kind == nkCommentStmt: continue
if it.kind == nkIdentDefs:
# can be a lifted var nowadays ...
if it.sons[0].kind == nkSym:
if it[0].kind == nkSym:
genSingleVar(p, it)
else:
genClosureVar(p, it)
@ -416,53 +415,53 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
if d.k == locTemp and isEmptyType(n.typ): d.k = locNone
if it.len == 2:
startBlock(p)
initLocExprSingleUse(p, it.sons[0], a)
initLocExprSingleUse(p, it[0], a)
lelse = getLabel(p)
inc(p.labels)
lineF(p, cpsStmts, "if (!$1) goto $2;$n",
[rdLoc(a), lelse])
if p.module.compileToCpp:
# avoid "jump to label crosses initialization" error:
add(p.s(cpsStmts), "{")
expr(p, it.sons[1], d)
add(p.s(cpsStmts), "}")
p.s(cpsStmts).add "{"
expr(p, it[1], d)
p.s(cpsStmts).add "}"
else:
expr(p, it.sons[1], d)
expr(p, it[1], d)
endBlock(p)
if len(n) > 1:
if n.len > 1:
lineF(p, cpsStmts, "goto $1;$n", [lend])
fixLabel(p, lelse)
elif it.len == 1:
startBlock(p)
expr(p, it.sons[0], d)
expr(p, it[0], d)
endBlock(p)
else: internalError(p.config, n.info, "genIf()")
if len(n) > 1: fixLabel(p, lend)
if n.len > 1: fixLabel(p, lend)
proc genReturnStmt(p: BProc, t: PNode) =
if nfPreventCg in t.flags: return
p.beforeRetNeeded = true
genLineDir(p, t)
if (t.sons[0].kind != nkEmpty): genStmts(p, t.sons[0])
if (t[0].kind != nkEmpty): genStmts(p, t[0])
blockLeaveActions(p,
howManyTrys = p.nestedTryStmts.len,
howManyExcepts = p.inExceptBlockLen)
if (p.finallySafePoints.len > 0) and not p.noSafePoints:
# If we're in a finally block, and we came here by exception
# consume it before we return.
var safePoint = p.finallySafePoints[p.finallySafePoints.len-1]
var safePoint = p.finallySafePoints[^1]
linefmt(p, cpsStmts, "if ($1.status != 0) #popCurrentException();$n", [safePoint])
lineF(p, cpsStmts, "goto BeforeRet_;$n", [])
proc genGotoForCase(p: BProc; caseStmt: PNode) =
for i in 1 ..< caseStmt.len:
for i in 1..<caseStmt.len:
startBlock(p)
let it = caseStmt.sons[i]
for j in 0 .. it.len-2:
if it.sons[j].kind == nkRange:
let it = caseStmt[i]
for j in 0..<it.len-1:
if it[j].kind == nkRange:
localError(p.config, it.info, "range notation not available for computed goto")
return
let val = getOrdValue(it.sons[j])
let val = getOrdValue(it[j])
lineF(p, cpsStmts, "NIMSTATE_$#:$n", [val.rope])
genStmts(p, it.lastSon)
endBlock(p)
@ -473,7 +472,7 @@ iterator fieldValuePairs(n: PNode): tuple[memberSym, valueSym: PNode] =
for identDefs in n:
if identDefs.kind == nkIdentDefs:
let valueSym = identDefs[^1]
for i in 0 ..< identDefs.len-2:
for i in 0..<identDefs.len-2:
let memberSym = identDefs[i]
yield((memberSym: memberSym, valueSym: valueSym))
@ -481,22 +480,22 @@ proc genComputedGoto(p: BProc; n: PNode) =
# first pass: Generate array of computed labels:
var casePos = -1
var arraySize: int
for i in 0 ..< n.len:
let it = n.sons[i]
for i in 0..<n.len:
let it = n[i]
if it.kind == nkCaseStmt:
if lastSon(it).kind != nkOfBranch:
localError(p.config, it.info,
"case statement must be exhaustive for computed goto"); return
casePos = i
if enumHasHoles(it.sons[0].typ):
if enumHasHoles(it[0].typ):
localError(p.config, it.info,
"case statement cannot work on enums with holes for computed goto"); return
let aSize = lengthOrd(p.config, it.sons[0].typ)
let aSize = lengthOrd(p.config, it[0].typ)
if aSize > 10_000:
localError(p.config, it.info,
"case statement has too many cases for computed goto"); return
arraySize = toInt(aSize)
if firstOrd(p.config, it.sons[0].typ) != 0:
if firstOrd(p.config, it[0].typ) != 0:
localError(p.config, it.info,
"case statement has to start at 0 for computed goto"); return
if casePos < 0:
@ -510,54 +509,54 @@ proc genComputedGoto(p: BProc; n: PNode) =
gotoArray.addf("&&TMP$#_};$n", [rope(id+arraySize)])
line(p, cpsLocals, gotoArray)
for j in 0 ..< casePos:
genStmts(p, n.sons[j])
for j in 0..<casePos:
genStmts(p, n[j])
let caseStmt = n.sons[casePos]
let caseStmt = n[casePos]
var a: TLoc
initLocExpr(p, caseStmt.sons[0], a)
initLocExpr(p, caseStmt[0], a)
# first goto:
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
for i in 1 ..< caseStmt.len:
for i in 1..<caseStmt.len:
startBlock(p)
let it = caseStmt.sons[i]
for j in 0 .. it.len-2:
if it.sons[j].kind == nkRange:
let it = caseStmt[i]
for j in 0..<it.len-1:
if it[j].kind == nkRange:
localError(p.config, it.info, "range notation not available for computed goto")
return
let val = getOrdValue(it.sons[j])
let val = getOrdValue(it[j])
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(toInt64(val)+id+1)])
genStmts(p, it.lastSon)
for j in casePos+1 ..< n.sons.len:
genStmts(p, n.sons[j])
for j in casePos+1..<n.len:
genStmts(p, n[j])
for j in 0 ..< casePos:
for j in 0..<casePos:
# prevent new local declarations
# compile declarations as assignments
let it = n.sons[j]
let it = n[j]
if it.kind in {nkLetSection, nkVarSection}:
let asgn = copyNode(it)
asgn.kind = nkAsgn
asgn.sons.setLen 2
for sym, value in it.fieldValuePairs:
if value.kind != nkEmpty:
asgn.sons[0] = sym
asgn.sons[1] = value
asgn[0] = sym
asgn[1] = value
genStmts(p, asgn)
else:
genStmts(p, it)
var a: TLoc
initLocExpr(p, caseStmt.sons[0], a)
initLocExpr(p, caseStmt[0], a)
lineF(p, cpsStmts, "goto *$#[$#];$n", [tmp, a.rdLoc])
endBlock(p)
for j in casePos+1 ..< n.sons.len:
genStmts(p, n.sons[j])
for j in casePos+1..<n.len:
genStmts(p, n[j])
proc genWhileStmt(p: BProc, t: PNode) =
@ -565,23 +564,23 @@ proc genWhileStmt(p: BProc, t: PNode) =
# significantly worse code
var
a: TLoc
assert(len(t) == 2)
assert(t.len == 2)
inc(p.withinLoop)
genLineDir(p, t)
preserveBreakIdx:
var loopBody = t.sons[1]
var loopBody = t[1]
if loopBody.stmtsContainPragma(wComputedGoto) and
hasComputedGoto in CC[p.config.cCompiler].props:
# for closure support weird loop bodies are generated:
if loopBody.len == 2 and loopBody.sons[0].kind == nkEmpty:
loopBody = loopBody.sons[1]
if loopBody.len == 2 and loopBody[0].kind == nkEmpty:
loopBody = loopBody[1]
genComputedGoto(p, loopBody)
else:
p.breakIdx = startBlock(p, "while (1) {$n")
p.blocks[p.breakIdx].isLoop = true
initLocExpr(p, t.sons[0], a)
if (t.sons[0].kind != nkIntLit) or (t.sons[0].intVal == 0):
initLocExpr(p, t[0], a)
if (t[0].kind != nkIntLit) or (t[0].intVal == 0):
let label = assignLabel(p.blocks[p.breakIdx])
lineF(p, cpsStmts, "if (!$1) goto $2;$n", [rdLoc(a), label])
genStmts(p, loopBody)
@ -602,30 +601,30 @@ proc genBlock(p: BProc, n: PNode, d: var TLoc) =
d.flags.incl(lfEnforceDeref)
preserveBreakIdx:
p.breakIdx = startBlock(p)
if n.sons[0].kind != nkEmpty:
if n[0].kind != nkEmpty:
# named block?
assert(n.sons[0].kind == nkSym)
var sym = n.sons[0].sym
assert(n[0].kind == nkSym)
var sym = n[0].sym
sym.loc.k = locOther
sym.position = p.breakIdx+1
expr(p, n.sons[1], d)
expr(p, n[1], d)
endBlock(p)
proc genParForStmt(p: BProc, t: PNode) =
assert(len(t) == 3)
assert(t.len == 3)
inc(p.withinLoop)
genLineDir(p, t)
preserveBreakIdx:
let forLoopVar = t.sons[0].sym
let forLoopVar = t[0].sym
var rangeA, rangeB: TLoc
assignLocalVar(p, t.sons[0])
assignLocalVar(p, t[0])
#initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack)
#discard mangleName(forLoopVar)
let call = t.sons[1]
assert(len(call) in {4, 5})
initLocExpr(p, call.sons[1], rangeA)
initLocExpr(p, call.sons[2], rangeB)
let call = t[1]
assert(call.len in {4, 5})
initLocExpr(p, call[1], rangeA)
initLocExpr(p, call[2], rangeB)
# $n at the beginning because of #9710
if call.len == 4: # `||`(a, b, annotation)
@ -633,29 +632,29 @@ proc genParForStmt(p: BProc, t: PNode) =
"for ($1 = $2; $1 <= $3; ++$1)",
[forLoopVar.loc.rdLoc,
rangeA.rdLoc, rangeB.rdLoc,
call.sons[3].getStr.rope])
call[3].getStr.rope])
else: # `||`(a, b, step, annotation)
var step: TLoc
initLocExpr(p, call.sons[3], step)
initLocExpr(p, call[3], step)
lineF(p, cpsStmts, "$n#pragma omp $5$n" &
"for ($1 = $2; $1 <= $3; $1 += $4)",
[forLoopVar.loc.rdLoc,
rangeA.rdLoc, rangeB.rdLoc, step.rdLoc,
call.sons[4].getStr.rope])
call[4].getStr.rope])
p.breakIdx = startBlock(p)
p.blocks[p.breakIdx].isLoop = true
genStmts(p, t.sons[2])
genStmts(p, t[2])
endBlock(p)
dec(p.withinLoop)
proc genBreakStmt(p: BProc, t: PNode) =
var idx = p.breakIdx
if t.sons[0].kind != nkEmpty:
if t[0].kind != nkEmpty:
# named break?
assert(t.sons[0].kind == nkSym)
var sym = t.sons[0].sym
assert(t[0].kind == nkSym)
var sym = t[0].sym
doAssert(sym.loc.k == locOther)
idx = sym.position-1
else:
@ -704,17 +703,15 @@ proc genRaiseStmt(p: BProc, t: PNode) =
template genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
rangeFormat, eqFormat: FormatStr, labl: TLabel) =
var
x, y: TLoc
var length = len(b)
for i in 0 .. length - 2:
if b.sons[i].kind == nkRange:
initLocExpr(p, b.sons[i].sons[0], x)
initLocExpr(p, b.sons[i].sons[1], y)
var x, y: TLoc
for i in 0..<b.len - 1:
if b[i].kind == nkRange:
initLocExpr(p, b[i][0], x)
initLocExpr(p, b[i][1], y)
lineCg(p, cpsStmts, rangeFormat,
[rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
else:
initLocExpr(p, b.sons[i], x)
initLocExpr(p, b[i], x)
lineCg(p, cpsStmts, eqFormat, [rdCharLoc(e), rdCharLoc(x), labl])
proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
@ -724,12 +721,11 @@ proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
# bug #4230: avoid false sharing between branches:
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 = len(t.sons[i])
exprBlock(p, t.sons[i].sons[length - 1], d)
if t[i].kind == nkOfBranch:
exprBlock(p, t[i][^1], d)
lineF(p, cpsStmts, "goto $1;$n", [lend])
else:
exprBlock(p, t.sons[i].sons[0], d)
exprBlock(p, t[i][0], d)
result = lend
template genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
@ -740,8 +736,8 @@ template genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
var labId = p.labels
for i in 1..until:
inc(p.labels)
if t.sons[i].kind == nkOfBranch: # else statement
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
if t[i].kind == nkOfBranch: # else statement
genCaseGenericBranch(p, t[i], a, rangeFormat, eqFormat,
"LA" & rope(p.labels) & "_")
else:
lineF(p, cpsStmts, "goto LA$1_;$n", [rope(p.labels)])
@ -758,38 +754,37 @@ template genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
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, len(t)-1, a)
initLocExpr(p, t[0], a)
var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, t.len-1, a)
fixLabel(p, lend)
proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel,
branches: var openArray[Rope]) =
var x: TLoc
var length = len(b)
for i in 0 .. length - 2:
assert(b.sons[i].kind != nkRange)
initLocExpr(p, b.sons[i], x)
assert(b.sons[i].kind in {nkStrLit..nkTripleStrLit})
var j = int(hashString(p.config, b.sons[i].strVal) and high(branches))
for i in 0..<b.len - 1:
assert(b[i].kind != nkRange)
initLocExpr(p, b[i], x)
assert(b[i].kind in {nkStrLit..nkTripleStrLit})
var j = int(hashString(p.config, b[i].strVal) and high(branches))
appcg(p.module, branches[j], "if (#eqStrings($1, $2)) goto $3;$n",
[rdLoc(e), rdLoc(x), labl])
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 ..< len(t):
if t.sons[i].kind == nkOfBranch: inc(strings, len(t.sons[i]) - 1)
for i in 1..<t.len:
if t[i].kind == nkOfBranch: inc(strings, t[i].len - 1)
if strings > stringCaseThreshold:
var bitMask = math.nextPowerOfTwo(strings) - 1
var branches: seq[Rope]
newSeq(branches, bitMask + 1)
var a: TLoc
initLocExpr(p, t.sons[0], a) # fist pass: generate ifs+goto:
initLocExpr(p, t[0], a) # fist pass: generate ifs+goto:
var labId = p.labels
for i in 1 ..< len(t):
for i in 1..<t.len:
inc(p.labels)
if t.sons[i].kind == nkOfBranch:
genCaseStringBranch(p, t.sons[i], a, "LA" & rope(p.labels) & "_",
if t[i].kind == nkOfBranch:
genCaseStringBranch(p, t[i], a, "LA" & rope(p.labels) & "_",
branches)
else:
# else statement: nothing to do yet
@ -797,28 +792,28 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
discard
linefmt(p, cpsStmts, "switch (#hashString($1) & $2) {$n",
[rdLoc(a), bitMask])
for j in 0 .. high(branches):
for j in 0..high(branches):
if branches[j] != nil:
lineF(p, cpsStmts, "case $1: $n$2break;$n",
[intLiteral(j), branches[j]])
lineF(p, cpsStmts, "}$n", []) # else statement:
if t.sons[len(t)-1].kind != nkOfBranch:
if 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, len(t)-1)
var lend = genCaseSecondPass(p, t, d, labId, t.len-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 .. len(b)-2:
for i in 0..<b.len-1:
# last son is block
if (b.sons[i].kind == nkRange) and
b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit:
if (b[i].kind == nkRange) and
b[i][1].intVal - b[i][0].intVal > RangeExpandLimit:
return true
proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
for i in 1..n.len-1:
for i in 1..<n.len:
var branch = n[i]
var stmtBlock = lastSon(branch)
if stmtBlock.stmtsContainPragma(wLinearScanEnd):
@ -828,8 +823,7 @@ proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
result = i
proc genCaseRange(p: BProc, branch: PNode) =
var length = branch.len
for j in 0 .. length-2:
for j in 0..<branch.len-1:
if branch[j].kind == nkRange:
if hasSwitchRange in CC[p.config.cCompiler].props:
lineF(p, cpsStmts, "case $1 ... $2:$n", [
@ -849,7 +843,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
# generate if part (might be empty):
var a: TLoc
initLocExpr(p, n.sons[0], a)
initLocExpr(p, n[0], a)
var lend = if splitPoint > 0: genIfForCaseUntil(p, n, d,
rangeFormat = "if ($1 >= $2 && $1 <= $3) goto $4;$n",
eqFormat = "if ($1 == $2) goto $3;$n",
@ -859,7 +853,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
if splitPoint+1 < n.len:
lineF(p, cpsStmts, "switch ($1) {$n", [rdCharLoc(a)])
var hasDefault = false
for i in splitPoint+1 ..< n.len:
for i in splitPoint+1..<n.len:
# bug #4230: avoid false sharing between branches:
if d.k == locTemp and isEmptyType(n.typ): d.k = locNone
var branch = n[i]
@ -880,14 +874,14 @@ proc genCase(p: BProc, t: PNode, d: var TLoc) =
genLineDir(p, t)
if not isEmptyType(t.typ) and d.k == locNone:
getTemp(p, t.typ, d)
case skipTypes(t.sons[0].typ, abstractVarRange).kind
case skipTypes(t[0].typ, abstractVarRange).kind
of tyString:
genStringCase(p, t, d)
of tyFloat..tyFloat128:
genCaseGeneric(p, t, d, "if ($1 >= $2 && $1 <= $3) goto $4;$n",
"if ($1 == $2) goto $3;$n")
else:
if t.sons[0].kind == nkSym and sfGoto in t.sons[0].sym.flags:
if t[0].kind == nkSym and sfGoto in t[0].sym.flags:
genGotoForCase(p, t)
else:
genOrdinalCase(p, t, d)
@ -926,7 +920,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
genLineDir(p, t)
discard cgsym(p.module, "popCurrentExceptionEx")
let fin = if t[^1].kind == nkFinally: t[^1] else: nil
add(p.nestedTryStmts, (fin, false))
p.nestedTryStmts.add((fin, false))
startBlock(p, "try {$n")
expr(p, t[0], d)
endBlock(p)
@ -947,7 +941,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
genExceptBranchBody(t[i][0])
endBlock(p)
else:
for j in 0..t[i].len-2:
for j in 0..<t[i].len-1:
if t[i][j].isInfixAs():
let exvar = t[i][j][2] # ex1 in `except ExceptType as ex1:`
fillLoc(exvar.sym.loc, locTemp, exvar, mangleLocalName(p, exvar.sym), OnUnknown)
@ -1023,40 +1017,38 @@ 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 = len(t)
let fin = if t[^1].kind == nkFinally: t[^1] else: nil
add(p.nestedTryStmts, (fin, quirkyExceptions))
expr(p, t.sons[0], d)
p.nestedTryStmts.add((fin, quirkyExceptions))
expr(p, t[0], d)
if not quirkyExceptions:
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
endBlock(p)
startBlock(p, "else {$n")
linefmt(p, cpsStmts, "#popSafePoint();$n", [])
genRestoreFrameAfterException(p)
elif 1 < length and t.sons[1].kind == nkExceptBranch:
elif 1 < t.len and t[1].kind == nkExceptBranch:
startBlock(p, "if (#getCurrentException()) {$n")
else:
startBlock(p)
p.nestedTryStmts[^1].inExcept = true
var i = 1
while (i < length) and (t.sons[i].kind == nkExceptBranch):
while (i < t.len) and (t[i].kind == nkExceptBranch):
# bug #4230: avoid false sharing between branches:
if d.k == locTemp and isEmptyType(t.typ): d.k = locNone
var blen = len(t.sons[i])
if blen == 1:
if t[i].len == 1:
# general except section:
if i > 1: lineF(p, cpsStmts, "else", [])
startBlock(p)
if not quirkyExceptions:
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
expr(p, t.sons[i].sons[0], d)
expr(p, t[i][0], d)
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
endBlock(p)
else:
var orExpr: Rope = nil
for j in 0 .. blen - 2:
assert(t.sons[i].sons[j].kind == nkType)
if orExpr != nil: add(orExpr, "||")
for j in 0..<t[i].len - 1:
assert(t[i][j].kind == nkType)
if orExpr != nil: orExpr.add("||")
let checkFor = if optTinyRtti in p.config.globalOptions:
genTypeInfo2Name(p.module, t[i][j].typ)
else:
@ -1068,15 +1060,15 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) =
startBlock(p, "if ($1) {$n", [orExpr])
if not quirkyExceptions:
linefmt(p, cpsStmts, "$1.status = 0;$n", [safePoint])
expr(p, t.sons[i].sons[blen-1], d)
expr(p, t[i][^1], d)
linefmt(p, cpsStmts, "#popCurrentException();$n", [])
endBlock(p)
inc(i)
discard pop(p.nestedTryStmts)
endBlock(p) # end of else block
if i < length and t.sons[i].kind == nkFinally:
if i < t.len and t[i].kind == nkFinally:
p.finallySafePoints.add(safePoint)
genSimpleBlock(p, t.sons[i].sons[0])
genSimpleBlock(p, t[i][0])
discard pop(p.finallySafePoints)
if not quirkyExceptions:
linefmt(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
@ -1120,12 +1112,12 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): Rope =
if x[j] in {'"', ':'}:
# don't modify the line if already in quotes or
# some clobber register list:
add(result, x); add(result, "\L")
result.add(x); result.add("\L")
else:
# ignore empty lines
add(result, "\"")
add(result, x)
add(result, "\\n\"\n")
result.add("\"")
result.add(x)
result.add("\\n\"\n")
else:
res.add("\L")
result = res.rope
@ -1139,25 +1131,25 @@ proc genAsmStmt(p: BProc, t: PNode) =
# work:
if p.prc == nil:
# top level asm statement?
add(p.module.s[cfsProcHeaders], runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s]))
p.module.s[cfsProcHeaders].add runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s])
else:
add(p.s(cpsStmts), indentLine(p, runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s])))
p.s(cpsStmts).add indentLine(p, runtimeFormat(CC[p.config.cCompiler].asmStmtFrmt, [s]))
proc determineSection(n: PNode): TCFileSection =
result = cfsProcHeaders
if n.len >= 1 and n.sons[0].kind in {nkStrLit..nkTripleStrLit}:
let sec = n.sons[0].strVal
if n.len >= 1 and n[0].kind in {nkStrLit..nkTripleStrLit}:
let sec = n[0].strVal
if sec.startsWith("/*TYPESECTION*/"): result = cfsTypes
elif sec.startsWith("/*VARSECTION*/"): result = cfsVars
elif sec.startsWith("/*INCLUDESECTION*/"): result = cfsHeaders
proc genEmit(p: BProc, t: PNode) =
var s = genAsmOrEmitStmt(p, t.sons[1])
var s = genAsmOrEmitStmt(p, t[1])
if p.prc == nil:
# top level emit pragma?
let section = determineSection(t[1])
genCLineDir(p.module.s[section], t.info, p.config)
add(p.module.s[section], s)
p.module.s[section].add(s)
else:
genLineDir(p, t)
line(p, cpsStmts, s)
@ -1169,18 +1161,18 @@ proc genPragma(p: BProc, n: PNode) =
of wInjectStmt:
var p = newProc(nil, p.module)
p.options = p.options - {optLineTrace, optStackTrace}
genStmts(p, it.sons[1])
genStmts(p, it[1])
p.module.injectStmt = p.s(cpsStmts)
else: discard
proc fieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
if optFieldCheck in p.options:
var le = asgn.sons[0]
var le = asgn[0]
if le.kind == nkCheckedFieldExpr:
var field = le.sons[0].sons[1].sym
var field = le[0][1].sym
result = sfDiscriminant in field.flags
elif le.kind == nkDotExpr:
var field = le.sons[1].sym
var field = le[1].sym
result = sfDiscriminant in field.flags
proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
@ -1188,14 +1180,13 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
var t = skipTypes(objtype, abstractVar)
assert t.kind == tyObject
discard genTypeInfo(p.module, t, a.lode.info)
var L = toInt64(lengthOrd(p.config, field.typ))
if not containsOrIncl(p.module.declaredThings, field.id):
appcg(p.module, cfsVars, "extern $1",
[discriminatorTableDecl(p.module, t, field)])
lineCg(p, cpsStmts,
"#FieldDiscriminantCheck((NI)(NU)($1), (NI)(NU)($2), $3, $4);$n",
[rdLoc(a), rdLoc(tmp), discriminatorTableName(p.module, t, field),
intLiteral(L+1)])
intLiteral(toInt64(lengthOrd(p.config, field.typ))+1)])
proc genCaseObjDiscMapping(p: BProc, e: PNode, t: PType, field: PSym; d: var TLoc) =
const ObjDiscMappingProcSlot = -5
@ -1214,12 +1205,12 @@ proc genCaseObjDiscMapping(p: BProc, e: PNode, t: PType, field: PSym; d: var TLo
proc asgnFieldDiscriminant(p: BProc, e: PNode) =
var a, tmp: TLoc
var dotExpr = e.sons[0]
if dotExpr.kind == nkCheckedFieldExpr: dotExpr = dotExpr.sons[0]
initLocExpr(p, e.sons[0], a)
var dotExpr = e[0]
if dotExpr.kind == nkCheckedFieldExpr: dotExpr = dotExpr[0]
initLocExpr(p, e[0], a)
getTemp(p, a.t, tmp)
expr(p, e.sons[1], tmp)
let field = dotExpr.sons[1].sym
expr(p, e[1], tmp)
let field = dotExpr[1].sym
if optTinyRtti in p.config.globalOptions:
let t = dotExpr[0].typ.skipTypes(abstractInst)
var oldVal, newVal: TLoc
@ -1229,13 +1220,13 @@ proc asgnFieldDiscriminant(p: BProc, e: PNode) =
"#nimFieldDiscriminantCheckV2($1, $2);$n",
[rdLoc(oldVal), rdLoc(newVal)])
else:
genDiscriminantCheck(p, a, tmp, dotExpr.sons[0].typ, field)
genDiscriminantCheck(p, a, tmp, dotExpr[0].typ, field)
genAssignment(p, a, tmp, {})
proc genAsgn(p: BProc, e: PNode, fastAsgn: bool) =
if e.sons[0].kind == nkSym and sfGoto in e.sons[0].sym.flags:
if e[0].kind == nkSym and sfGoto in e[0].sym.flags:
genLineDir(p, e)
genGotoVar(p, e.sons[1])
genGotoVar(p, e[1])
elif not fieldDiscriminantCheckNeeded(p, e):
let le = e[0]
let ri = e[1]

View file

@ -19,8 +19,8 @@ proc accessThreadLocalVar(p: BProc, s: PSym) =
if emulatedThreadVars(p.config) and not p.threadVarAccessed:
p.threadVarAccessed = true
incl p.module.flags, usesThreadVars
addf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV_;$n", [])
add(p.procSec(cpsInit),
p.procSec(cpsLocals).addf("\tNimThreadVars* NimTV_;$n", [])
p.procSec(cpsInit).add(
ropecg(p.module, "\tNimTV_ = (NimThreadVars*) #GetThreadLocalVars();$n", []))
proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
@ -30,23 +30,23 @@ proc declareThreadVar(m: BModule, s: PSym, isExtern: bool) =
# allocator for it :-(
if not containsOrIncl(m.g.nimtvDeclared, s.id):
m.g.nimtvDeps.add(s.loc.t)
addf(m.g.nimtv, "$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r])
m.g.nimtv.addf("$1 $2;$n", [getTypeDesc(m, s.loc.t), s.loc.r])
else:
if isExtern: add(m.s[cfsVars], "extern ")
if optThreads in m.config.globalOptions: add(m.s[cfsVars], "NIM_THREADVAR ")
add(m.s[cfsVars], getTypeDesc(m, s.loc.t))
addf(m.s[cfsVars], " $1;$n", [s.loc.r])
if isExtern: m.s[cfsVars].add("extern ")
if optThreads in m.config.globalOptions: m.s[cfsVars].add("NIM_THREADVAR ")
m.s[cfsVars].add(getTypeDesc(m, s.loc.t))
m.s[cfsVars].addf(" $1;$n", [s.loc.r])
proc generateThreadLocalStorage(m: BModule) =
if m.g.nimtv != nil and (usesThreadVars in m.flags or sfMainModule in m.module.flags):
for t in items(m.g.nimtvDeps): discard getTypeDesc(m, t)
addf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [m.g.nimtv])
m.s[cfsSeqTypes].addf("typedef struct {$1} NimThreadVars;$n", [m.g.nimtv])
proc generateThreadVarsSize(m: BModule) =
if m.g.nimtv != nil:
let externc = if m.config.cmd == cmdCompileToCpp or
sfCompileToCpp in m.module.flags: "extern \"C\" "
else: ""
addf(m.s[cfsProcs],
m.s[cfsProcs].addf(
"$#NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}$n",
[externc.rope])

View file

@ -28,18 +28,18 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, n: PNode;
if n == nil: return
case n.kind
of nkRecList:
for i in 0 ..< len(n):
genTraverseProc(c, accessor, n.sons[i], typ)
for i in 0..<n.len:
genTraverseProc(c, accessor, n[i], typ)
of nkRecCase:
if (n.sons[0].kind != nkSym): internalError(c.p.config, n.info, "genTraverseProc")
if (n[0].kind != nkSym): internalError(c.p.config, n.info, "genTraverseProc")
var p = c.p
let disc = n.sons[0].sym
let disc = n[0].sym
if disc.loc.r == nil: fillObjectFields(c.p.module, typ)
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 ..< len(n):
let branch = n.sons[i]
for i in 1..<n.len:
let branch = n[i]
assert branch.kind in {nkOfBranch, nkElse}
if branch.kind == nkOfBranch:
genCaseRange(c.p, branch)
@ -73,29 +73,29 @@ proc genTraverseProc(c: TTraversalClosure, accessor: Rope, typ: PType) =
tySink, tyOwned:
genTraverseProc(c, accessor, lastSon(typ))
of tyArray:
let arraySize = lengthOrd(c.p.config, typ.sons[0])
let arraySize = lengthOrd(c.p.config, typ[0])
var i: TLoc
getTemp(p, getSysType(c.p.module.g.graph, unknownLineInfo(), tyInt), i)
let oldCode = p.s(cpsStmts)
linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
[i.r, arraySize])
let oldLen = p.s(cpsStmts).len
genTraverseProc(c, ropecg(c.p.module, "$1[$2]", [accessor, i.r]), typ.sons[1])
genTraverseProc(c, ropecg(c.p.module, "$1[$2]", [accessor, i.r]), typ[1])
if p.s(cpsStmts).len == oldLen:
# do not emit dummy long loops for faster debug builds:
p.s(cpsStmts) = oldCode
else:
lineF(p, cpsStmts, "}$n", [])
of tyObject:
for i in 0 ..< len(typ):
var x = typ.sons[i]
for i in 0..<typ.len:
var x = typ[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 ..< len(typ):
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", [accessor, i]), typ.sons[i])
for i in 0..<typ.len:
genTraverseProc(c, ropecg(c.p.module, "$1.Field$2", [accessor, i]), typ[i])
of tyRef:
lineCg(p, cpsStmts, visitorFrmt, [accessor, c.visitorFrmt])
of tySequence:
@ -127,7 +127,7 @@ proc genTraverseProcSeq(c: TTraversalClosure, accessor: Rope, typ: PType) =
lineF(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n",
[i.r, lenExpr(c.p, a)])
let oldLen = p.s(cpsStmts).len
genTraverseProc(c, "$1$3[$2]" % [accessor, i.r, dataField(c.p)], typ.sons[0])
genTraverseProc(c, "$1$3[$2]" % [accessor, i.r, dataField(c.p)], typ[0])
if p.s(cpsStmts).len == oldLen:
# do not emit dummy long loops for faster debug builds:
p.s(cpsStmts) = oldCode
@ -155,11 +155,11 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
if typ.kind == tySequence:
genTraverseProcSeq(c, "a".rope, typ)
else:
if skipTypes(typ.sons[0], typedescInst+{tyOwned}).kind == tyArray:
if skipTypes(typ[0], typedescInst+{tyOwned}).kind == tyArray:
# C's arrays are broken beyond repair:
genTraverseProc(c, "a".rope, typ.sons[0])
genTraverseProc(c, "a".rope, typ[0])
else:
genTraverseProc(c, "(*a)".rope, typ.sons[0])
genTraverseProc(c, "(*a)".rope, typ[0])
let generatedProc = "$1 {$n$2$3$4}\n" %
[header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)]
@ -168,8 +168,8 @@ proc genTraverseProc(m: BModule, origTyp: PType; sig: SigHash): Rope =
m.s[cfsProcs].add(generatedProc)
if hcrOn:
addf(m.s[cfsProcHeaders], "N_NIMCALL_PTR(void, $1)(void*, NI);\n", [result])
addf(m.s[cfsDynLibInit], "\t$1 = (N_NIMCALL_PTR(void, )(void*, NI)) hcrRegisterProc($3, \"$1\", (void*)$2);\n",
m.s[cfsProcHeaders].addf("N_NIMCALL_PTR(void, $1)(void*, NI);\n", [result])
m.s[cfsDynLibInit].addf("\t$1 = (N_NIMCALL_PTR(void, )(void*, NI)) hcrRegisterProc($3, \"$1\", (void*)$2);\n",
[result, markerName, getModuleDllPath(m)])
proc genTraverseProcForGlobal(m: BModule, s: PSym; info: TLineInfo): Rope =

View file

@ -48,7 +48,7 @@ proc mangleName(m: BModule; s: PSym): Rope =
result = s.loc.r
if result == nil:
result = s.name.s.mangle.rope
add(result, idOrSig(s, m.module.name.s.mangle, m.sigConflicts))
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts))
s.loc.r = result
writeMangledName(m.ndi, s, m.config)
@ -175,7 +175,7 @@ proc mapType(conf: ConfigRef; typ: PType): TCTypeKind =
of 4: result = ctInt32
of 8: result = ctInt64
else: result = ctInt32
of tyRange: result = mapType(conf, typ.sons[0])
of tyRange: result = mapType(conf, typ[0])
of tyPtr, tyVar, tyLent, tyRef:
var base = skipTypes(typ.lastSon, typedescInst)
case base.kind
@ -213,7 +213,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope
proc isObjLackingTypeField(typ: PType): bool {.inline.} =
result = (typ.kind == tyObject) and ((tfFinal in typ.flags) and
(typ.sons[0] == nil) or isPureObject(typ))
(typ[0] == nil) or isPureObject(typ))
proc isInvalidReturnType(conf: ConfigRef; rettype: PType): bool =
# Arrays and sets cannot be returned by a C procedure, because C is
@ -248,7 +248,7 @@ proc cacheGetType(tab: TypeCache; sig: SigHash): Rope =
proc addAbiCheck(m: BModule, t: PType, name: Rope) =
if isDefined(m.config, "checkabi") and (let size = getSize(m.config, t); size != szUnknownSize):
addf(m.s[cfsTypeInfo], "NIM_CHECK_SIZE($1, $2);$n", [name, rope(size)])
m.s[cfsTypeInfo].addf("NIM_CHECK_SIZE($1, $2);$n", [name, rope(size)])
proc ccgIntroducedPtr(conf: ConfigRef; s: PSym, retType: PType): bool =
var pt = skipTypes(s.typ, typedescInst)
@ -265,7 +265,7 @@ proc ccgIntroducedPtr(conf: ConfigRef; s: PSym, retType: PType): bool =
result = true # requested anyway
elif retType != nil and retType.kind == tyLent:
result = true
elif (tfFinal in pt.flags) and (pt.sons[0] == nil):
elif (tfFinal in pt.flags) and (pt[0] == nil):
result = false # no need, because no subtyping possible
else:
result = true # ordinary objects are always passed by reference,
@ -316,7 +316,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
of tyNil: result = typeNameOrLiteral(m, typ, "void*")
of tyInt..tyUInt64:
result = typeNameOrLiteral(m, typ, NumericalTypeToStr[typ.kind])
of tyDistinct, tyRange, tyOrdinal: result = getSimpleTypeDesc(m, typ.sons[0])
of tyDistinct, tyRange, tyOrdinal: result = getSimpleTypeDesc(m, typ[0])
of tyStatic:
if typ.n != nil: result = getSimpleTypeDesc(m, lastSon typ)
else: internalError(m.config, "tyStatic for getSimpleTypeDesc")
@ -331,10 +331,10 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
addAbiCheck(m, typ, result)
proc pushType(m: BModule, typ: PType) =
for i in 0 .. high(m.typeStack):
for i in 0..high(m.typeStack):
# pointer equality is good enough here:
if m.typeStack[i] == typ: return
add(m.typeStack, typ)
m.typeStack.add(typ)
proc getTypePre(m: BModule, typ: PType; sig: SigHash): Rope =
if typ == nil: result = rope("void")
@ -391,7 +391,7 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet): Rope =
of tySequence:
let sig = hashType(t)
if optSeqDestructors in m.config.globalOptions:
if skipTypes(etB.sons[0], typedescInst).kind == tyEmpty:
if skipTypes(etB[0], typedescInst).kind == tyEmpty:
internalError(m.config, "cannot map the empty seq type to a C type")
result = cacheGetType(m.forwTypeCache, sig)
@ -434,7 +434,7 @@ $3ifndef $2_Content_PP
$3define $2_Content_PP
struct $2_Content { NI cap;#AllocatorObj* allocator;$1 data[SEQ_DECL_SIZE];};
$3endif$N
""", [getTypeDescAux(m, t.skipTypes(abstractInst).sons[0], check), result, rope"#"])
""", [getTypeDescAux(m, t.skipTypes(abstractInst)[0], check), result, rope"#"])
proc paramStorageLoc(param: PSym): TStorageLoc =
if param.typ.skipTypes({tyVar, tyLent, tyTypeDesc}).kind notin {
@ -447,28 +447,28 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
check: var IntSet, declareEnvironment=true;
weakDep=false) =
params = nil
if t.sons[0] == nil or isInvalidReturnType(m.config, t.sons[0]):
if t[0] == nil or isInvalidReturnType(m.config, t[0]):
rettype = ~"void"
else:
rettype = getTypeDescAux(m, t.sons[0], check)
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
rettype = getTypeDescAux(m, t[0], check)
for i in 1..<t.n.len:
if t.n[i].kind != nkSym: internalError(m.config, t.n.info, "genProcParams")
var param = t.n[i].sym
if isCompileTimeOnly(param.typ): continue
if params != nil: add(params, ~", ")
fillLoc(param.loc, locParam, t.n.sons[i], mangleParamName(m, param),
if params != nil: params.add(~", ")
fillLoc(param.loc, locParam, t.n[i], mangleParamName(m, param),
param.paramStorageLoc)
if ccgIntroducedPtr(m.config, param, t.sons[0]):
add(params, getTypeDescWeak(m, param.typ, check))
add(params, ~"*")
if ccgIntroducedPtr(m.config, param, t[0]):
params.add(getTypeDescWeak(m, param.typ, check))
params.add(~"*")
incl(param.loc.flags, lfIndirect)
param.loc.storage = OnUnknown
elif weakDep:
add(params, getTypeDescWeak(m, param.typ, check))
params.add(getTypeDescWeak(m, param.typ, check))
else:
add(params, getTypeDescAux(m, param.typ, check))
add(params, ~" ")
add(params, param.loc.r)
params.add(getTypeDescAux(m, param.typ, check))
params.add(~" ")
params.add(param.loc.r)
# declare the len field for open arrays:
var arr = param.typ
if arr.kind in {tyVar, tyLent, tySink}: arr = arr.lastSon
@ -477,26 +477,26 @@ proc genProcParams(m: BModule, t: PType, rettype, params: var Rope,
# this fixes the 'sort' bug:
if param.typ.kind in {tyVar, tyLent}: param.loc.storage = OnUnknown
# need to pass hidden parameter:
addf(params, ", NI $1Len_$2", [param.loc.r, j.rope])
params.addf(", NI $1Len_$2", [param.loc.r, j.rope])
inc(j)
arr = arr.sons[0].skipTypes({tySink})
if t.sons[0] != nil and isInvalidReturnType(m.config, t.sons[0]):
var arr = t.sons[0]
if params != nil: add(params, ", ")
if mapReturnType(m.config, t.sons[0]) != ctArray:
add(params, getTypeDescWeak(m, arr, check))
add(params, "*")
arr = arr[0].skipTypes({tySink})
if t[0] != nil and isInvalidReturnType(m.config, t[0]):
var arr = t[0]
if params != nil: params.add(", ")
if mapReturnType(m.config, t[0]) != ctArray:
params.add(getTypeDescWeak(m, arr, check))
params.add("*")
else:
add(params, getTypeDescAux(m, arr, check))
addf(params, " Result", [])
params.add(getTypeDescAux(m, arr, check))
params.addf(" Result", [])
if t.callConv == ccClosure and declareEnvironment:
if params != nil: add(params, ", ")
add(params, "void* ClE_0")
if params != nil: params.add(", ")
params.add("void* ClE_0")
if tfVarargs in t.flags:
if params != nil: add(params, ", ")
add(params, "...")
if params == nil: add(params, "void)")
else: add(params, ")")
if params != nil: params.add(", ")
params.add("...")
if params == nil: params.add("void)")
else: params.add(")")
params = "(" & params
proc mangleRecFieldName(m: BModule; field: PSym): Rope =
@ -512,37 +512,37 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
result = nil
case n.kind
of nkRecList:
for i in 0 ..< len(n):
add(result, genRecordFieldsAux(m, n.sons[i], rectype, check))
for i in 0..<n.len:
result.add(genRecordFieldsAux(m, n[i], rectype, check))
of nkRecCase:
if n.sons[0].kind != nkSym: internalError(m.config, n.info, "genRecordFieldsAux")
add(result, genRecordFieldsAux(m, n.sons[0], rectype, check))
if n[0].kind != nkSym: internalError(m.config, n.info, "genRecordFieldsAux")
result.add(genRecordFieldsAux(m, n[0], rectype, check))
# 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 ..< len(n):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
let k = lastSon(n.sons[i])
let k = lastSon(n[i])
if k.kind != nkSym:
let a = genRecordFieldsAux(m, k, rectype, check)
if a != nil:
if tfPacked notin rectype.flags:
add(unionBody, "struct {")
unionBody.add("struct {")
else:
if hasAttribute in CC[m.config.cCompiler].props:
add(unionBody, "struct __attribute__((__packed__)){" )
unionBody.add("struct __attribute__((__packed__)){" )
else:
addf(unionBody, "#pragma pack(push, 1)$nstruct{", [])
add(unionBody, a)
addf(unionBody, "};$n", [])
unionBody.addf("#pragma pack(push, 1)$nstruct{", [])
unionBody.add(a)
unionBody.addf("};$n", [])
if tfPacked in rectype.flags and hasAttribute notin CC[m.config.cCompiler].props:
addf(unionBody, "#pragma pack(pop)$n", [])
unionBody.addf("#pragma pack(pop)$n", [])
else:
add(unionBody, genRecordFieldsAux(m, k, rectype, check))
unionBody.add(genRecordFieldsAux(m, k, rectype, check))
else: internalError(m.config, "genRecordFieldsAux(record case branch)")
if unionBody != nil:
addf(result, "union{$n$1};$n", [unionBody])
result.addf("union{$n$1};$n", [unionBody])
of nkSym:
let field = n.sym
if field.typ.kind == tyVoid: return
@ -557,17 +557,17 @@ proc genRecordFieldsAux(m: BModule, n: PNode,
if not isImportedCppType(rectype):
let fieldType = field.loc.lode.typ.skipTypes(abstractInst)
if fieldType.kind == tyUncheckedArray:
addf(result, "$1 $2[SEQ_DECL_SIZE];$n",
result.addf("$1 $2[SEQ_DECL_SIZE];$n",
[getTypeDescAux(m, fieldType.elemType, check), sname])
elif fieldType.kind == tySequence:
# we need to use a weak dependency here for trecursive_table.
addf(result, "$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname])
result.addf("$1 $2;$n", [getTypeDescWeak(m, field.loc.t, check), sname])
elif field.bitsize != 0:
addf(result, "$1 $2:$3;$n", [getTypeDescAux(m, field.loc.t, check), sname, rope($field.bitsize)])
result.addf("$1 $2:$3;$n", [getTypeDescAux(m, field.loc.t, check), sname, rope($field.bitsize)])
else:
# don't use fieldType here because we need the
# tyGenericInst for C++ template support
addf(result, "$1 $2;$n", [getTypeDescAux(m, field.loc.t, check), sname])
result.addf("$1 $2;$n", [getTypeDescAux(m, field.loc.t, check), sname])
else: internalError(m.config, n.info, "genRecordFieldsAux()")
proc getRecordFields(m: BModule, typ: PType, check: var IntSet): Rope =
@ -599,7 +599,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
if typ.kind == tyObject:
if typ.sons[0] == nil:
if typ[0] == nil:
if (typ.sym != nil and sfPure in typ.sym.flags) or tfFinal in typ.flags:
appcg(m, result, " {$n", [])
else:
@ -607,7 +607,7 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
hasField = true
elif m.compileToCpp:
appcg(m, result, " : public $1 {$n",
[getTypeDescAux(m, typ.sons[0].skipTypes(skipPtrs), check)])
[getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check)])
if typ.isException:
appcg(m, result, "virtual void raise() { throw *this; }$n", []) # required for polymorphic exceptions
if typ.sym.magic == mException:
@ -619,17 +619,17 @@ proc getRecordDesc(m: BModule, typ: PType, name: Rope,
hasField = true
else:
appcg(m, result, " {$n $1 Sup;$n",
[getTypeDescAux(m, typ.sons[0].skipTypes(skipPtrs), check)])
[getTypeDescAux(m, typ[0].skipTypes(skipPtrs), check)])
hasField = true
else:
addf(result, " {$n", [name])
result.addf(" {$n", [name])
let desc = getRecordFields(m, typ, check)
if desc == nil and not hasField:
addf(result, "char dummy;$n", [])
result.addf("char dummy;$n", [])
else:
add(result, desc)
add(result, "};\L")
result.add(desc)
result.add("};\L")
if tfPacked in typ.flags and hasAttribute notin CC[m.config.cCompiler].props:
result.add "#pragma pack(pop)\L"
@ -637,12 +637,12 @@ 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 ..< len(typ):
addf(desc, "$1 Field$2;$n",
[getTypeDescAux(m, typ.sons[i], check), rope(i)])
if desc == nil: add(result, "char dummy;\L")
else: add(result, desc)
add(result, "};\L")
for i in 0..<typ.len:
desc.addf("$1 Field$2;$n",
[getTypeDescAux(m, typ[i], check), rope(i)])
if desc == nil: result.add("char dummy;\L")
else: result.add(desc)
result.add("};\L")
proc scanCppGenericSlot(pat: string, cursor, outIdx, outStars: var int): bool =
# A helper proc for handling cppimport patterns, involving numeric
@ -667,10 +667,10 @@ proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
if idx >= typ.len:
doAssert false, "invalid apostrophe type parameter index"
result = typ.sons[idx]
result = typ[idx]
for i in 1..stars:
if result != nil and result.len > 0:
result = if result.kind == tyGenericInst: result.sons[1]
result = if result.kind == tyGenericInst: result[1]
else: result.elemType
proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
@ -726,7 +726,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
result = getTypeDescAux(m, et, check) & star
m.typeCache[sig] = result
of tyOpenArray, tyVarargs:
result = getTypeDescWeak(m, t.sons[0], check) & "*"
result = getTypeDescWeak(m, t[0], check) & "*"
m.typeCache[sig] = result
of tyEnum:
result = cacheGetType(m.typeCache, sig)
@ -737,23 +737,23 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
m.typeCache[sig] = result
var size: int
if firstOrd(m.config, t) < 0:
addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result])
m.s[cfsTypes].addf("typedef NI32 $1;$n", [result])
size = 4
else:
size = int(getSize(m.config, t))
case size
of 1: addf(m.s[cfsTypes], "typedef NU8 $1;$n", [result])
of 2: addf(m.s[cfsTypes], "typedef NU16 $1;$n", [result])
of 4: addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result])
of 8: addf(m.s[cfsTypes], "typedef NI64 $1;$n", [result])
of 1: m.s[cfsTypes].addf("typedef NU8 $1;$n", [result])
of 2: m.s[cfsTypes].addf("typedef NU16 $1;$n", [result])
of 4: m.s[cfsTypes].addf("typedef NI32 $1;$n", [result])
of 8: m.s[cfsTypes].addf("typedef NI64 $1;$n", [result])
else: internalError(m.config, t.sym.info, "getTypeDescAux: enum")
when false:
let owner = hashOwner(t.sym)
if not gDebugInfo.hasEnum(t.sym.name.s, t.sym.info.line, owner):
var vals: seq[(string, int)] = @[]
for i in 0 ..< t.n.len:
assert(t.n.sons[i].kind == nkSym)
let field = t.n.sons[i].sym
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)
let field = t.n[i].sym
vals.add((field.name.s, field.position.int))
gDebugInfo.registerEnum(EnumDesc(size: size, owner: owner, id: t.sym.id,
name: t.sym.name.s, values: vals))
@ -764,10 +764,10 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
genProcParams(m, t, rettype, desc, check, true, true)
if not isImportedType(t):
if t.callConv != ccClosure: # procedure vars may need a closure!
addf(m.s[cfsTypes], "typedef $1_PTR($2, $3) $4;$n",
m.s[cfsTypes].addf("typedef $1_PTR($2, $3) $4;$n",
[rope(CallingConvToStr[t.callConv]), rettype, result, desc])
else:
addf(m.s[cfsTypes], "typedef struct {$n" &
m.s[cfsTypes].addf("typedef struct {$n" &
"N_NIMCALL_PTR($2, ClP_0) $3;$n" &
"void* ClE_0;$n} $1;$n",
[result, rettype, desc])
@ -786,7 +786,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
assert(cacheGetType(m.typeCache, sig) == nil)
m.typeCache[sig] = result & seqStar(m)
if not isImportedType(t):
if skipTypes(t.sons[0], typedescInst).kind != tyEmpty:
if skipTypes(t[0], typedescInst).kind != tyEmpty:
const
cppSeq = "struct $2 : #TGenericSeq {$n"
cSeq = "struct $2 {$n" &
@ -794,28 +794,28 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
if m.compileToCpp:
appcg(m, m.s[cfsSeqTypes],
cppSeq & " $1 data[SEQ_DECL_SIZE];$n" &
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
"};$n", [getTypeDescAux(m, t[0], check), result])
else:
appcg(m, m.s[cfsSeqTypes],
cSeq & " $1 data[SEQ_DECL_SIZE];$n" &
"};$n", [getTypeDescAux(m, t.sons[0], check), result])
"};$n", [getTypeDescAux(m, t[0], check), result])
else:
result = rope("TGenericSeq")
add(result, seqStar(m))
result.add(seqStar(m))
of tyUncheckedArray:
result = getTypeName(m, origTyp, sig)
m.typeCache[sig] = result
if not isImportedType(t):
let foo = getTypeDescAux(m, t.sons[0], check)
addf(m.s[cfsTypes], "typedef $1 $2[1];$n", [foo, result])
let foo = getTypeDescAux(m, t[0], check)
m.s[cfsTypes].addf("typedef $1 $2[1];$n", [foo, result])
of tyArray:
var n: BiggestInt = toInt64(lengthOrd(m.config, t))
if n <= 0: n = 1 # make an array of at least one element
result = getTypeName(m, origTyp, sig)
m.typeCache[sig] = result
if not isImportedType(t):
let foo = getTypeDescAux(m, t.sons[1], check)
addf(m.s[cfsTypes], "typedef $1 $2[$3];$n",
let foo = getTypeDescAux(m, t[1], check)
m.s[cfsTypes].addf("typedef $1 $2[$3];$n",
[foo, result, rope(n)])
else: addAbiCheck(m, t, result)
of tyObject, tyTuple:
@ -850,9 +850,9 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
result.add cppName.data.substr(chunkStart)
else:
result = cppName & "<"
for i in 1 .. origTyp.len-2:
for i in 1..<origTyp.len-1:
if i > 1: result.add(" COMMA ")
addResultType(origTyp.sons[i])
addResultType(origTyp[i])
result.add("> ")
# always call for sideeffects:
assert t.kind != tyTuple
@ -861,7 +861,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
# with the C macros for defining procs such as N_NIMCALL. We must
# create a typedef for the type and use it in the proc signature:
let typedefName = ~"TY" & $sig
addf(m.s[cfsTypes], "typedef $1 $2;$n", [result, typedefName])
m.s[cfsTypes].addf("typedef $1 $2;$n", [result, typedefName])
m.typeCache[sig] = typedefName
result = typedefName
else:
@ -877,7 +877,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
let recdesc = if t.kind != tyTuple: getRecordDesc(m, t, result, check)
else: getTupleDesc(m, t, result, check)
if not isImportedType(t):
add(m.s[cfsTypes], recdesc)
m.s[cfsTypes].add(recdesc)
elif tfIncompleteStruct notin t.flags: addAbiCheck(m, t, result)
of tySet:
result = $t.kind & '_' & getTypeName(m, t.lastSon, hashType t.lastSon)
@ -885,8 +885,8 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
if not isImportedType(t):
let s = int(getSize(m.config, t))
case s
of 1, 2, 4, 8: addf(m.s[cfsTypes], "typedef NU$2 $1;$n", [result, rope(s*8)])
else: addf(m.s[cfsTypes], "typedef NU8 $1[$2];$n",
of 1, 2, 4, 8: m.s[cfsTypes].addf("typedef NU$2 $1;$n", [result, rope(s*8)])
else: m.s[cfsTypes].addf("typedef NU8 $1[$2];$n",
[result, rope(getSize(m.config, t))])
of tyGenericInst, tyDistinct, tyOrdinal, tyTypeDesc, tyAlias, tySink, tyOwned,
tyUserTypeClass, tyUserTypeClassInst, tyInferred:
@ -915,10 +915,10 @@ proc getClosureType(m: BModule, t: PType, kind: TClosureTypeKind): Rope =
genProcParams(m, t, rettype, desc, check, declareEnvironment=kind != clHalf)
if not isImportedType(t):
if t.callConv != ccClosure or kind != clFull:
addf(m.s[cfsTypes], "typedef $1_PTR($2, $3) $4;$n",
m.s[cfsTypes].addf("typedef $1_PTR($2, $3) $4;$n",
[rope(CallingConvToStr[t.callConv]), rettype, result, desc])
else:
addf(m.s[cfsTypes], "typedef struct {$n" &
m.s[cfsTypes].addf("typedef struct {$n" &
"N_NIMCALL_PTR($2, ClP_0) $3;$n" &
"void* ClE_0;$n} $1;$n",
[result, rettype, desc])
@ -926,7 +926,7 @@ proc getClosureType(m: BModule, t: PType, kind: TClosureTypeKind): Rope =
proc finishTypeDescriptions(m: BModule) =
var i = 0
var check = initIntSet()
while i < len(m.typeStack):
while i < m.typeStack.len:
let t = m.typeStack[i]
if optSeqDestructors in m.config.globalOptions and t.skipTypes(abstractInst).kind == tySequence:
seqV2ContentType(m, t, check)
@ -964,11 +964,11 @@ proc genProcHeader(m: BModule, prc: PSym, asPtr: bool = false): Rope =
let asPtrStr = rope(if asPtr: "_PTR" else: "")
var name = prc.loc.r
if isReloadable(m, prc) and not asPtr:
add(name, "_actual")
name.add("_actual")
# careful here! don't access ``prc.ast`` as that could reload large parts of
# the object graph!
if prc.constraint.isNil:
addf(result, "$1$2($3, $4)$5",
result.addf("$1$2($3, $4)$5",
[rope(CallingConvToStr[prc.typ.callConv]), asPtrStr, rettype, name,
params])
else:
@ -999,7 +999,7 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType;
var size: Rope
if tfIncompleteStruct in typ.flags: size = rope"void*"
else: size = getTypeDesc(m, origType)
addf(m.s[cfsTypeInit3],
m.s[cfsTypeInit3].addf(
"$1.size = sizeof($2);$n" & "$1.kind = $3;$n" & "$1.base = $4;$n",
[nameHcr, size, rope(nimtypeKind), base])
# compute type flags for GC optimization
@ -1008,30 +1008,30 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType;
if not canFormAcycle(typ): flags = flags or 2
#else MessageOut("can contain a cycle: " & typeToString(typ))
if flags != 0:
addf(m.s[cfsTypeInit3], "$1.flags = $2;$n", [nameHcr, rope(flags)])
m.s[cfsTypeInit3].addf("$1.flags = $2;$n", [nameHcr, rope(flags)])
discard cgsym(m, "TNimType")
if isDefined(m.config, "nimTypeNames"):
var typename = typeToString(if origType.typeInst != nil: origType.typeInst
else: origType, preferName)
if typename == "ref object" and origType.skipTypes(skipPtrs).sym != nil:
typename = "anon ref object from " & m.config$origType.skipTypes(skipPtrs).sym.info
addf(m.s[cfsTypeInit3], "$1.name = $2;$n",
m.s[cfsTypeInit3].addf("$1.name = $2;$n",
[nameHcr, makeCString typename])
discard cgsym(m, "nimTypeRoot")
addf(m.s[cfsTypeInit3], "$1.nextType = nimTypeRoot; nimTypeRoot=&$1;$n",
m.s[cfsTypeInit3].addf("$1.nextType = nimTypeRoot; nimTypeRoot=&$1;$n",
[nameHcr])
if m.hcrOn:
addf(m.s[cfsVars], "static TNimType* $1;$n", [name])
addf(m.hcrCreateTypeInfosProc, "\thcrRegisterGlobal($2, \"$1\", sizeof(TNimType), NULL, (void**)&$1);$n",
m.s[cfsVars].addf("static TNimType* $1;$n", [name])
m.hcrCreateTypeInfosProc.addf("\thcrRegisterGlobal($2, \"$1\", sizeof(TNimType), NULL, (void**)&$1);$n",
[name, getModuleDllPath(m, m.module)])
else:
addf(m.s[cfsVars], "TNimType $1;$n", [name])
m.s[cfsVars].addf("TNimType $1;$n", [name])
proc genTypeInfoAux(m: BModule, typ, origType: PType, name: Rope;
info: TLineInfo) =
var base: Rope
if len(typ) > 0 and typ.lastSon != nil:
if typ.len > 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):
@ -1046,7 +1046,7 @@ proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope =
# bugfix: we need to search the type that contains the discriminator:
var objtype = objtype.skipTypes(abstractPtrs)
while lookupInRecord(objtype.n, d.name) == nil:
objtype = objtype.sons[0].skipTypes(abstractPtrs)
objtype = objtype[0].skipTypes(abstractPtrs)
if objtype.sym == nil:
internalError(m.config, d.info, "anonymous obj with discriminator")
result = "NimDT_$1_$2" % [rope($hashType(objtype)), rope(d.name.s.mangle)]
@ -1060,67 +1060,66 @@ proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): Rope =
proc genTNimNodeArray(m: BModule, name: Rope, size: Rope) =
if m.hcrOn:
addf(m.s[cfsVars], "static TNimNode** $1;$n", [name])
addf(m.hcrCreateTypeInfosProc, "\thcrRegisterGlobal($3, \"$1\", sizeof(TNimNode*) * $2, NULL, (void**)&$1);$n",
m.s[cfsVars].addf("static TNimNode** $1;$n", [name])
m.hcrCreateTypeInfosProc.addf("\thcrRegisterGlobal($3, \"$1\", sizeof(TNimNode*) * $2, NULL, (void**)&$1);$n",
[name, size, getModuleDllPath(m, m.module)])
else:
addf(m.s[cfsTypeInit1], "static TNimNode* $1[$2];$n", [name, size])
m.s[cfsTypeInit1].addf("static TNimNode* $1[$2];$n", [name, size])
proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope;
info: TLineInfo) =
case n.kind
of nkRecList:
var L = len(n)
if L == 1:
genObjectFields(m, typ, origType, n.sons[0], expr, info)
elif L > 0:
var tmp = getTempName(m) & "_" & $L
genTNimNodeArray(m, tmp, rope(L))
for i in 0 ..< L:
if n.len == 1:
genObjectFields(m, typ, origType, n[0], expr, info)
elif n.len > 0:
var tmp = getTempName(m) & "_" & $n.len
genTNimNodeArray(m, tmp, rope(n.len))
for i in 0..<n.len:
var tmp2 = getNimNode(m)
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
genObjectFields(m, typ, origType, n.sons[i], tmp2, info)
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, rope(L), tmp])
m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
genObjectFields(m, typ, origType, n[i], tmp2, info)
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, rope(n.len), tmp])
else:
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n", [expr, rope(L)])
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2;$n", [expr, rope(n.len)])
of nkRecCase:
assert(n.sons[0].kind == nkSym)
var field = n.sons[0].sym
assert(n[0].kind == nkSym)
var field = n[0].sym
var tmp = discriminatorTableName(m, typ, field)
var L = lengthOrd(m.config, field.typ)
assert L > 0
if field.loc.r == nil: fillObjectFields(m, typ)
if field.loc.t == nil:
internalError(m.config, n.info, "genObjectFields")
addf(m.s[cfsTypeInit3], "$1.kind = 3;$n" &
m.s[cfsTypeInit3].addf("$1.kind = 3;$n" &
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
"$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
"$1.len = $7;$n", [expr, getTypeDesc(m, origType), field.loc.r,
genTypeInfo(m, field.typ, info),
makeCString(field.name.s),
tmp, rope(L)])
addf(m.s[cfsData], "TNimNode* $1[$2];$n", [tmp, rope(L+1)])
for i in 1 ..< len(n):
var b = n.sons[i] # branch
m.s[cfsData].addf("TNimNode* $1[$2];$n", [tmp, rope(L+1)])
for i in 1..<n.len:
var b = n[i] # branch
var tmp2 = getNimNode(m)
genObjectFields(m, typ, origType, lastSon(b), tmp2, info)
case b.kind
of nkOfBranch:
if len(b) < 2:
if b.len < 2:
internalError(m.config, b.info, "genObjectFields; nkOfBranch broken")
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]))
for j in 0..<b.len - 1:
if b[j].kind == nkRange:
var x = toInt(getOrdValue(b[j][0]))
var y = toInt(getOrdValue(b[j][1]))
while x <= y:
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(x), tmp2])
m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n", [tmp, rope(x), tmp2])
inc(x)
else:
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n",
[tmp, rope(getOrdValue(b.sons[j])), tmp2])
m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n",
[tmp, rope(getOrdValue(b[j])), tmp2])
of nkElse:
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n",
m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n",
[tmp, rope(L), tmp2])
else: internalError(m.config, n.info, "genObjectFields(nkRecCase)")
of nkSym:
@ -1131,7 +1130,7 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope;
if field.loc.r == nil: fillObjectFields(m, typ)
if field.loc.t == nil:
internalError(m.config, n.info, "genObjectFields")
addf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
m.s[cfsTypeInit3].addf("$1.kind = 1;$n" &
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
"$1.name = $5;$n", [expr, getTypeDesc(m, origType),
field.loc.r, genTypeInfo(m, field.typ, info), makeCString(field.name.s)])
@ -1148,35 +1147,34 @@ proc genObjectInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo
var tmp = getNimNode(m)
if not isImportedType(typ):
genObjectFields(m, typ, origType, typ.n, tmp, info)
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [tiNameForHcr(m, name), tmp])
var t = typ.sons[0]
m.s[cfsTypeInit3].addf("$1.node = &$2;$n", [tiNameForHcr(m, name), tmp])
var t = typ[0]
while t != nil:
t = t.skipTypes(skipPtrs)
t.flags.incl tfObjHasKids
t = t.sons[0]
t = t[0]
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 = len(typ)
if length > 0:
var tmp = getTempName(m) & "_" & $length
genTNimNodeArray(m, tmp, rope(length))
for i in 0 ..< length:
var a = typ.sons[i]
if typ.len > 0:
var tmp = getTempName(m) & "_" & $typ.len
genTNimNodeArray(m, tmp, rope(typ.len))
for i in 0..<typ.len:
var a = typ[i]
var tmp2 = getNimNode(m)
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
addf(m.s[cfsTypeInit3], "$1.kind = 1;$n" &
m.s[cfsTypeInit3].addf("$1[$2] = &$3;$n", [tmp, rope(i), tmp2])
m.s[cfsTypeInit3].addf("$1.kind = 1;$n" &
"$1.offset = offsetof($2, Field$3);$n" &
"$1.typ = $4;$n" &
"$1.name = \"Field$3\";$n",
[tmp2, getTypeDesc(m, origType), rope(i), genTypeInfo(m, a, info)])
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, rope(length), tmp])
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
[expr, rope(typ.len), tmp])
else:
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 2;$n",
[expr, rope(length)])
addf(m.s[cfsTypeInit3], "$1.node = &$2;$n", [tiNameForHcr(m, name), expr])
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2;$n",
[expr, rope(typ.len)])
m.s[cfsTypeInit3].addf("$1.node = &$2;$n", [tiNameForHcr(m, name), expr])
proc genEnumInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) =
# Type information for enumerations is quite heavy, so we do some
@ -1184,51 +1182,50 @@ 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 = len(typ.n)
var nodePtrs = getTempName(m) & "_" & $length
genTNimNodeArray(m, nodePtrs, rope(length))
var nodePtrs = getTempName(m) & "_" & $typ.n.len
genTNimNodeArray(m, nodePtrs, rope(typ.n.len))
var enumNames, specialCases: Rope
var firstNimNode = m.typeNodes
var hasHoles = false
for i in 0 ..< length:
assert(typ.n.sons[i].kind == nkSym)
var field = typ.n.sons[i].sym
for i in 0..<typ.n.len:
assert(typ.n[i].kind == nkSym)
var field = typ.n[i].sym
var elemNode = getNimNode(m)
if field.ast == nil:
# no explicit string literal for the enum field, so use field.name:
add(enumNames, makeCString(field.name.s))
enumNames.add(makeCString(field.name.s))
else:
add(enumNames, makeCString(field.ast.strVal))
if i < length - 1: add(enumNames, ", \L")
enumNames.add(makeCString(field.ast.strVal))
if i < typ.n.len - 1: enumNames.add(", \L")
if field.position != i or tfEnumHasHoles in typ.flags:
addf(specialCases, "$1.offset = $2;$n", [elemNode, rope(field.position)])
specialCases.addf("$1.offset = $2;$n", [elemNode, rope(field.position)])
hasHoles = true
var enumArray = getTempName(m)
var counter = getTempName(m)
addf(m.s[cfsTypeInit1], "NI $1;$n", [counter])
addf(m.s[cfsTypeInit1], "static char* NIM_CONST $1[$2] = {$n$3};$n",
[enumArray, rope(length), enumNames])
addf(m.s[cfsTypeInit3], "for ($1 = 0; $1 < $2; $1++) {$n" &
m.s[cfsTypeInit1].addf("NI $1;$n", [counter])
m.s[cfsTypeInit1].addf("static char* NIM_CONST $1[$2] = {$n$3};$n",
[enumArray, rope(typ.n.len), enumNames])
m.s[cfsTypeInit3].addf("for ($1 = 0; $1 < $2; $1++) {$n" &
"$3[$1+$4].kind = 1;$n" & "$3[$1+$4].offset = $1;$n" &
"$3[$1+$4].name = $5[$1];$n" & "$6[$1] = &$3[$1+$4];$n" & "}$n", [counter,
rope(length), m.typeNodesName, rope(firstNimNode), enumArray, nodePtrs])
add(m.s[cfsTypeInit3], specialCases)
addf(m.s[cfsTypeInit3],
rope(typ.n.len), m.typeNodesName, rope(firstNimNode), enumArray, nodePtrs])
m.s[cfsTypeInit3].add(specialCases)
m.s[cfsTypeInit3].addf(
"$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n$4.node = &$1;$n",
[getNimNode(m), rope(length), nodePtrs, tiNameForHcr(m, name)])
[getNimNode(m), rope(typ.n.len), nodePtrs, tiNameForHcr(m, name)])
if hasHoles:
# 1 << 2 is {ntfEnumHole}
addf(m.s[cfsTypeInit3], "$1.flags = 1<<2;$n", [tiNameForHcr(m, name)])
m.s[cfsTypeInit3].addf("$1.flags = 1<<2;$n", [tiNameForHcr(m, name)])
proc genSetInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) =
assert(typ.sons[0] != nil)
assert(typ[0] != nil)
genTypeInfoAux(m, typ, typ, name, info)
var tmp = getNimNode(m)
addf(m.s[cfsTypeInit3], "$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n",
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 0;$n" & "$3.node = &$1;$n",
[tmp, rope(firstOrd(m.config, typ)), tiNameForHcr(m, name)])
proc genArrayInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) =
genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ.sons[1], info), info)
genTypeInfoAuxBase(m, typ, typ, name, genTypeInfo(m, typ[1], info), info)
proc fakeClosureType(m: BModule; owner: PSym): PType =
# we generate the same RTTI as for a tuple[pointer, ref tuple[]]
@ -1243,16 +1240,16 @@ include ccgtrav
proc genDeepCopyProc(m: BModule; s: PSym; result: Rope) =
genProc(m, s)
addf(m.s[cfsTypeInit3], "$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
m.s[cfsTypeInit3].addf("$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
[result, s.loc.r])
proc declareNimType(m: BModule, str: Rope, ownerModule: PSym) =
if m.hcrOn:
addf(m.s[cfsVars], "static TNimType* $1;$n", [str])
addf(m.s[cfsTypeInit1], "\t$1 = (TNimType*)hcrGetGlobal($2, \"$1\");$n",
m.s[cfsVars].addf("static TNimType* $1;$n", [str])
m.s[cfsTypeInit1].addf("\t$1 = (TNimType*)hcrGetGlobal($2, \"$1\");$n",
[str, getModuleDllPath(m, ownerModule)])
else:
addf(m.s[cfsVars], "extern TNimType $1;$n", [str])
m.s[cfsVars].addf("extern TNimType $1;$n", [str])
proc genTypeInfo2Name(m: BModule; t: PType): Rope =
var res = "|"
@ -1274,7 +1271,7 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope =
else:
res.add $hashType(it)
res.add "|"
it = it.sons[0]
it = it[0]
result = makeCString(res)
proc trivialDestructor(s: PSym): bool {.inline.} = s.ast[bodyPos].len == 0
@ -1298,8 +1295,8 @@ proc genObjectInfoV2(m: BModule, t, origType: PType, name: Rope; info: TLineInfo
d = t.destructor.loc.r
else:
d = rope("NIM_NIL")
addf(m.s[cfsVars], "TNimType $1;$n", [name])
addf(m.s[cfsTypeInit3], "$1.destructor = (void*)$2; $1.size = sizeof($3); $1.name = $4;$n", [
m.s[cfsVars].addf("TNimType $1;$n", [name])
m.s[cfsTypeInit3].addf("$1.destructor = (void*)$2; $1.size = sizeof($3); $1.name = $4;$n", [
name, d, getTypeDesc(m, t), genTypeInfo2Name(m, t)])
proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope =
@ -1358,12 +1355,12 @@ proc genTypeInfo(m: BModule, t: PType; info: TLineInfo): Rope =
if optSeqDestructors notin m.config.globalOptions:
if m.config.selectedGC >= gcMarkAndSweep:
let markerProc = genTraverseProc(m, origType, sig)
addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
of tyRef:
genTypeInfoAux(m, t, t, result, info)
if m.config.selectedGC >= gcMarkAndSweep:
let markerProc = genTraverseProc(m, origType, sig)
addf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
m.s[cfsTypeInit3].addf("$1.marker = $2;$n", [tiNameForHcr(m, result), markerProc])
of tyPtr, tyRange, tyUncheckedArray: genTypeInfoAux(m, t, t, result, info)
of tyArray: genArrayInfo(m, t, result, info)
of tySet: genSetInfo(m, t, result, info)

View file

@ -16,11 +16,11 @@ import
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
case n.kind
of nkStmtList:
for i in 0 ..< n.len:
for i in 0..<n.len:
result = getPragmaStmt(n[i], w)
if result != nil: break
of nkPragma:
for i in 0 ..< n.len:
for i in 0..<n.len:
if whichPragma(n[i]) == w: return n[i]
else: discard
@ -33,7 +33,7 @@ proc hashString*(conf: ConfigRef; s: string): BiggestInt =
# we have to use the same bitwidth
# as the target CPU
var b = 0'u64
for i in 0 ..< len(s):
for i in 0..<s.len:
b = b + uint(s[i])
b = b + (b shl 10)
b = b xor (b shr 6)
@ -43,7 +43,7 @@ proc hashString*(conf: ConfigRef; s: string): BiggestInt =
result = cast[Hash](b)
else:
var a = 0'u32
for i in 0 ..< len(s):
for i in 0..<s.len:
a = a + uint32(s[i])
a = a + (a shl 10)
a = a xor (a shr 6)
@ -70,18 +70,18 @@ proc mangle*(name: string): string =
template special(x) =
result.add x
requiresUnderscore = true
for i in start..(name.len-1):
for i in start..<name.len:
let c = name[i]
case c
of 'a'..'z', '0'..'9', 'A'..'Z':
add(result, c)
result.add(c)
of '_':
# we generate names like 'foo_9' for scope disambiguations and so
# disallow this here:
if i > 0 and i < name.len-1 and name[i+1] in Digits:
discard
else:
add(result, c)
result.add(c)
of '$': special "dollar"
of '%': special "percent"
of '&': special "amp"
@ -102,7 +102,7 @@ proc mangle*(name: string): string =
of '@': special "at"
of '|': special "bar"
else:
add(result, "X" & toHex(ord(c), 2))
result.add("X" & toHex(ord(c), 2))
requiresUnderscore = true
if requiresUnderscore:
result.add "_"

View file

@ -38,7 +38,7 @@ when not declared(dynlib.libCandidates):
for middle in split(substr(s, le + 1, ri - 1), '|'):
libCandidates(prefix & middle & suffix, dest)
else:
add(dest, s)
dest.add(s)
when options.hasTinyCBackend:
import tccgen
@ -122,7 +122,6 @@ macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
args.expectKind nnkBracket
# echo "ropecg ", newLit(frmt).repr, ", ", args.repr
var i = 0
var length = len(frmt)
result = nnkStmtListExpr.newTree()
result.add quote do:
@ -142,7 +141,7 @@ macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
result.add newCall(ident "add", resVar, newLit(strLit))
strLit.setLen 0
while i < length:
while i < frmt.len:
if frmt[i] == '$':
inc(i) # skip '$'
case frmt[i]
@ -159,9 +158,9 @@ macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
while true:
j = (j * 10) + ord(frmt[i]) - ord('0')
inc(i)
if i >= length or not (frmt[i] in {'0'..'9'}): break
if i >= frmt.len or not (frmt[i] in {'0'..'9'}): break
num = j
if j > len(args):
if j > args.len:
error("ropes: invalid format string " & newLit(frmt).repr & " args.len: " & $args.len)
flushStrLit()
@ -170,7 +169,7 @@ macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
flushStrLit()
result.add quote do:
if optLineDir notin `m`.config.options:
add(`resVar`, "\L")
`resVar`.add("\L")
inc(i)
of 'N':
strLit.add "\L"
@ -195,49 +194,49 @@ macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
flushStrLit()
result.add newCall(formatValue, resVar, newCall(ident"cgsym", m, ident))
var start = i
while i < length:
while i < frmt.len:
if frmt[i] != '$' and frmt[i] != '#': inc(i)
else: break
if i - 1 >= start:
add(strLit, substr(frmt, start, i - 1))
strLit.add(substr(frmt, start, i - 1))
flushStrLit()
result.add newCall(ident"rope", resVar)
proc indentLine(p: BProc, r: Rope): Rope =
result = r
for i in 0 ..< p.blocks.len:
for i in 0..<p.blocks.len:
prepend(result, "\t".rope)
template appcg(m: BModule, c: var Rope, frmt: FormatStr,
args: untyped) =
add(c, ropecg(m, frmt, args))
c.add(ropecg(m, frmt, args))
template appcg(m: BModule, sec: TCFileSection, frmt: FormatStr,
args: untyped) =
add(m.s[sec], ropecg(m, frmt, args))
m.s[sec].add(ropecg(m, frmt, args))
template appcg(p: BProc, sec: TCProcSection, frmt: FormatStr,
args: untyped) =
add(p.s(sec), ropecg(p.module, frmt, args))
p.s(sec).add(ropecg(p.module, frmt, args))
template line(p: BProc, sec: TCProcSection, r: Rope) =
add(p.s(sec), indentLine(p, r))
p.s(sec).add(indentLine(p, r))
template line(p: BProc, sec: TCProcSection, r: string) =
add(p.s(sec), indentLine(p, r.rope))
p.s(sec).add(indentLine(p, r.rope))
template lineF(p: BProc, sec: TCProcSection, frmt: FormatStr,
args: untyped) =
add(p.s(sec), indentLine(p, frmt % args))
p.s(sec).add(indentLine(p, frmt % args))
template lineCg(p: BProc, sec: TCProcSection, frmt: FormatStr,
args: untyped) =
add(p.s(sec), indentLine(p, ropecg(p.module, frmt, args)))
p.s(sec).add(indentLine(p, ropecg(p.module, frmt, args)))
template linefmt(p: BProc, sec: TCProcSection, frmt: FormatStr,
args: untyped) =
add(p.s(sec), indentLine(p, ropecg(p.module, frmt, args)))
p.s(sec).add(indentLine(p, ropecg(p.module, frmt, args)))
proc safeLineNm(info: TLineInfo): int =
result = toLinenumber(info)
@ -246,7 +245,7 @@ proc safeLineNm(info: TLineInfo): int =
proc genCLineDir(r: var Rope, filename: string, line: int; conf: ConfigRef) =
assert line >= 0
if optLineDir in conf.options:
addf(r, "$N#line $2 $1$N",
r.addf("$N#line $2 $1$N",
[rope(makeSingleLineCString(filename)), rope(line)])
proc genCLineDir(r: var Rope, info: TLineInfo; conf: ConfigRef) =
@ -263,7 +262,7 @@ proc genLineDir(p: BProc, t: PNode) =
let line = t.info.safeLineNm
if optEmbedOrigSrc in p.config.globalOptions:
add(p.s(cpsStmts), ~"//" & sourceLine(p.config, t.info) & "\L")
p.s(cpsStmts).add(~"//" & sourceLine(p.config, t.info) & "\L")
genCLineDir(p.s(cpsStmts), toFullPath(p.config, t.info), line, p.config)
if ({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and
(p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex != InvalidFileIdx:
@ -272,7 +271,7 @@ proc genLineDir(p: BProc, t: PNode) =
[line, quotedFilename(p.config, t.info)])
proc postStmtActions(p: BProc) {.inline.} =
add(p.s(cpsStmts), p.module.injectStmt)
p.s(cpsStmts).add(p.module.injectStmt)
proc accessThreadLocalVar(p: BProc, s: PSym)
proc emulatedThreadVars(conf: ConfigRef): bool {.inline.}
@ -343,9 +342,9 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
if not takeAddr: r = "(*$1)" % [r]
var s = skipTypes(t, abstractInst)
if not p.module.compileToCpp:
while s.kind == tyObject and s.sons[0] != nil:
add(r, ".Sup")
s = skipTypes(s.sons[0], skipPtrs)
while s.kind == tyObject and s[0] != nil:
r.add(".Sup")
s = skipTypes(s[0], skipPtrs)
linefmt(p, section, "$1.m_type = $2;$n", [r, genTypeInfo(p.module, t, a.lode.info)])
of frEmbedded:
if optTinyRtti in p.config.globalOptions:
@ -360,9 +359,9 @@ proc genObjectInit(p: BProc, section: TCProcSection, t: PType, a: TLoc,
if not takeAddr: r = "(*$1)" % [r]
var s = skipTypes(t, abstractInst)
if not p.module.compileToCpp:
while s.kind == tyObject and s.sons[0] != nil and s.sym.magic != mException:
add(r, ".Sup")
s = skipTypes(s.sons[0], skipPtrs)
while s.kind == tyObject and s[0] != nil and s.sym.magic != mException:
r.add(".Sup")
s = skipTypes(s[0], skipPtrs)
linefmt(p, section, "$1.name = $2;$n", [r, makeCString(t.skipTypes(abstractInst).sym.name.s)])
type
@ -483,12 +482,12 @@ proc localVarDecl(p: BProc; n: PNode): Rope =
result.addf("NIM_ALIGN($1) ", [rope(s.alignment)])
result.add getTypeDesc(p.module, s.typ)
if s.constraint.isNil:
if sfRegister in s.flags: add(result, " register")
if sfRegister in s.flags: result.add(" register")
#elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
# add(decl, " GC_GUARD")
if sfVolatile in s.flags: add(result, " volatile")
add(result, " ")
add(result, s.loc.r)
# decl.add(" GC_GUARD")
if sfVolatile in s.flags: result.add(" volatile")
result.add(" ")
result.add(s.loc.r)
else:
result = runtimeFormat(s.cgDeclFrmt, [result, s.loc.r])
@ -534,16 +533,16 @@ proc assignGlobalVar(p: BProc, n: PNode) =
if s.constraint.isNil:
if s.kind in {skLet, skVar, skField, skForVar} and s.alignment > 0:
decl.addf "NIM_ALIGN($1) ", [rope(s.alignment)]
if p.hcrOn: add(decl, "static ")
elif sfImportc in s.flags: add(decl, "extern ")
add(decl, td)
if p.hcrOn: add(decl, "*")
if sfRegister in s.flags: add(decl, " register")
if sfVolatile in s.flags: add(decl, " volatile")
addf(decl, " $1;$n", [s.loc.r])
if p.hcrOn: decl.add("static ")
elif sfImportc in s.flags: decl.add("extern ")
decl.add(td)
if p.hcrOn: decl.add("*")
if sfRegister in s.flags: decl.add(" register")
if sfVolatile in s.flags: decl.add(" volatile")
decl.addf(" $1;$n", [s.loc.r])
else:
decl = runtimeFormat(s.cgDeclFrmt & ";$n", [td, s.loc.r])
add(p.module.s[cfsVars], decl)
p.module.s[cfsVars].add(decl)
if p.withinLoop > 0:
# fixes tests/run/tzeroarray:
resetLoc(p, s.loc)
@ -621,7 +620,7 @@ proc initFrame(p: BProc, procname, filename: Rope): Rope =
proc initFrameNoDebug(p: BProc; frame, procname, filename: Rope; line: int): Rope =
discard cgsym(p.module, "nimFrame")
addf(p.blocks[0].sections[cpsLocals], "TFrame $1;$n", [frame])
p.blocks[0].sections[cpsLocals].addf("TFrame $1;$n", [frame])
result = ropecg(p.module, "\t$1.procname = $2; $1.filename = $3; " &
" $1.line = $4; $1.len = -1; nimFrame(&$1);$n",
[frame, procname, filename, line])
@ -649,15 +648,15 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
var tmp = getTempName(m)
assert(lib.name == nil)
lib.name = tmp # BUGFIX: cgsym has awful side-effects
addf(m.s[cfsVars], "static void* $1;$n", [tmp])
m.s[cfsVars].addf("static void* $1;$n", [tmp])
if lib.path.kind in {nkStrLit..nkTripleStrLit}:
var s: TStringSeq = @[]
libCandidates(lib.path.strVal, s)
rawMessage(m.config, hintDependency, lib.path.strVal)
var loadlib: Rope = nil
for i in 0 .. high(s):
for i in 0..high(s):
inc(m.labels)
if i > 0: add(loadlib, "||")
if i > 0: loadlib.add("||")
let n = newStrNode(nkStrLit, s[i])
n.info = lib.path.info
appcg(m, loadlib, "($1 = #nimLoadLibrary($2))$n",
@ -675,9 +674,9 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
[getTypeDesc(m, lib.path.typ), rdLoc(dest)])
expr(p, lib.path, dest)
add(m.s[cfsVars], p.s(cpsLocals))
add(m.s[cfsDynLibInit], p.s(cpsInit))
add(m.s[cfsDynLibInit], p.s(cpsStmts))
m.s[cfsVars].add(p.s(cpsLocals))
m.s[cfsDynLibInit].add(p.s(cpsInit))
m.s[cfsDynLibInit].add(p.s(cpsStmts))
appcg(m, m.s[cfsDynLibInit],
"if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n",
[tmp, rdLoc(dest)])
@ -707,27 +706,27 @@ proc symInDynamicLib(m: BModule, sym: PSym) =
var a: TLoc
initLocExpr(m.initProc, n[0], a)
var params = rdLoc(a) & "("
for i in 1 .. n.len-2:
for i in 1..<n.len-1:
initLocExpr(m.initProc, n[i], a)
params.add(rdLoc(a))
params.add(", ")
let load = "\t$1 = ($2) ($3$4));$n" %
[tmp, getTypeDesc(m, sym.typ), params, makeCString($extname)]
var last = lastSon(n)
if last.kind == nkHiddenStdConv: last = last.sons[1]
if last.kind == nkHiddenStdConv: last = last[1]
internalAssert(m.config, last.kind == nkStrLit)
let idx = last.strVal
if idx.len == 0:
add(m.initProc.s(cpsStmts), load)
m.initProc.s(cpsStmts).add(load)
elif idx.len == 1 and idx[0] in {'0'..'9'}:
add(m.extensionLoaders[idx[0]], load)
m.extensionLoaders[idx[0]].add(load)
else:
internalError(m.config, sym.info, "wrong index: " & idx)
else:
appcg(m, m.s[cfsDynLibInit],
"\t$1 = ($2) #nimGetProcAddr($3, $4);$n",
[tmp, getTypeDesc(m, sym.typ), lib.name, makeCString($extname)])
addf(m.s[cfsVars], "$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
m.s[cfsVars].addf("$2 $1;$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)])
proc varInDynamicLib(m: BModule, sym: PSym) =
var lib = sym.annex
@ -740,7 +739,7 @@ proc varInDynamicLib(m: BModule, sym: PSym) =
appcg(m, m.s[cfsDynLibInit],
"$1 = ($2*) #nimGetProcAddr($3, $4);$n",
[tmp, getTypeDesc(m, sym.typ), lib.name, makeCString($extname)])
addf(m.s[cfsVars], "$2* $1;$n",
m.s[cfsVars].addf("$2* $1;$n",
[sym.loc.r, getTypeDesc(m, sym.loc.t)])
proc symInDynamicLibPartial(m: BModule, sym: PSym) =
@ -765,16 +764,16 @@ proc cgsym(m: BModule, name: string): Rope =
result.addActualSuffixForHCR(m.module, sym)
proc generateHeaders(m: BModule) =
add(m.s[cfsHeaders], "\L#include \"nimbase.h\"\L")
m.s[cfsHeaders].add("\L#include \"nimbase.h\"\L")
for it in m.headerFiles:
if it[0] == '#':
add(m.s[cfsHeaders], rope(it.replace('`', '"') & "\L"))
m.s[cfsHeaders].add(rope(it.replace('`', '"') & "\L"))
elif it[0] notin {'"', '<'}:
addf(m.s[cfsHeaders], "#include \"$1\"$N", [rope(it)])
m.s[cfsHeaders].addf("#include \"$1\"$N", [rope(it)])
else:
addf(m.s[cfsHeaders], "#include $1$N", [rope(it)])
add(m.s[cfsHeaders], """#undef LANGUAGE_C
m.s[cfsHeaders].addf("#include $1$N", [rope(it)])
m.s[cfsHeaders].add("""#undef LANGUAGE_C
#undef MIPSEB
#undef MIPSEL
#undef PPC
@ -942,7 +941,7 @@ proc allPathsAsgnResult(n: PNode): InitResultEnum =
else:
allPathsInBranch(it.lastSon)
else:
for i in 0..<safeLen(n):
for i in 0..<n.safeLen:
allPathsInBranch(n[i])
proc getProcTypeCast(m: BModule, prc: PSym): Rope =
@ -963,12 +962,12 @@ proc genProcAux(m: BModule, prc: PSym) =
if sfInjectDestructors in prc.flags:
procBody = injectDestructorCalls(m.g.graph, prc, procBody)
if sfPure notin prc.flags and prc.typ.sons[0] != nil:
if sfPure notin prc.flags and prc.typ[0] != nil:
if resultPos >= prc.ast.len:
internalError(m.config, prc.info, "proc has no result symbol")
let resNode = prc.ast.sons[resultPos]
let resNode = prc.ast[resultPos]
let res = resNode.sym # get result symbol
if not isInvalidReturnType(m.config, prc.typ.sons[0]):
if not isInvalidReturnType(m.config, prc.typ[0]):
if sfNoInit in prc.flags: incl(res.flags, sfNoInit)
if sfNoInit in prc.flags and p.module.compileToCpp and (let val = easyResultAsgn(procBody); val != nil):
var decl = localVarDecl(p, resNode)
@ -998,8 +997,8 @@ proc genProcAux(m: BModule, prc: PSym) =
#incl(res.loc.flags, lfIndirect)
res.loc.storage = OnUnknown
for i in 1 ..< len(prc.typ.n):
let param = prc.typ.n.sons[i].sym
for i in 1..<prc.typ.n.len:
let param = prc.typ.n[i].sym
if param.typ.isCompileTimeOnly: continue
assignParam(p, param, prc.typ[0])
closureSetup(p, prc)
@ -1019,29 +1018,29 @@ proc genProcAux(m: BModule, prc: PSym) =
# Add forward declaration for "_actual"-suffixed functions defined in the same module (or inline).
# This fixes the use of methods and also the case when 2 functions within the same module
# call each other using directly the "_actual" versions (an optimization) - see issue #11608
addf(m.s[cfsProcHeaders], "$1;\n", [header])
m.s[cfsProcHeaders].addf("$1;\n", [header])
generatedProc.add ropecg(p.module, "$1 {", [header])
add(generatedProc, initGCFrame(p))
generatedProc.add(initGCFrame(p))
if optStackTrace in prc.options:
add(generatedProc, p.s(cpsLocals))
generatedProc.add(p.s(cpsLocals))
var procname = makeCString(prc.name.s)
add(generatedProc, initFrame(p, procname, quotedFilename(p.config, prc.info)))
generatedProc.add(initFrame(p, procname, quotedFilename(p.config, prc.info)))
else:
add(generatedProc, p.s(cpsLocals))
generatedProc.add(p.s(cpsLocals))
if optProfiler in prc.options:
# invoke at proc entry for recursion:
appcg(p, cpsInit, "\t#nimProfile();$n", [])
if p.beforeRetNeeded: add(generatedProc, "{")
add(generatedProc, p.s(cpsInit))
add(generatedProc, p.s(cpsStmts))
if p.beforeRetNeeded: add(generatedProc, ~"\t}BeforeRet_: ;$n")
add(generatedProc, deinitGCFrame(p))
if optStackTrace in prc.options: add(generatedProc, deinitFrame(p))
add(generatedProc, returnStmt)
add(generatedProc, ~"}$N")
add(m.s[cfsProcs], generatedProc)
if p.beforeRetNeeded: generatedProc.add("{")
generatedProc.add(p.s(cpsInit))
generatedProc.add(p.s(cpsStmts))
if p.beforeRetNeeded: generatedProc.add(~"\t}BeforeRet_: ;$n")
generatedProc.add(deinitGCFrame(p))
if optStackTrace in prc.options: generatedProc.add(deinitFrame(p))
generatedProc.add(returnStmt)
generatedProc.add(~"}$N")
m.s[cfsProcs].add(generatedProc)
if isReloadable(m, prc):
addf(m.s[cfsDynLibInit], "\t$1 = ($3) hcrRegisterProc($4, \"$1\", (void*)$2);$n",
m.s[cfsDynLibInit].addf("\t$1 = ($3) hcrRegisterProc($4, \"$1\", (void*)$2);$n",
[prc.loc.r, prc.loc.r & "_actual", getProcTypeCast(m, prc), getModuleDllPath(m, prc)])
proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} =
@ -1059,11 +1058,11 @@ proc genProcPrototype(m: BModule, sym: PSym) =
if lfDynamicLib in sym.loc.flags:
if getModule(sym).id != m.module.id and
not containsOrIncl(m.declaredThings, sym.id):
add(m.s[cfsVars], ropecg(m, "$1 $2 $3;$n",
m.s[cfsVars].add(ropecg(m, "$1 $2 $3;$n",
[(if isReloadable(m, sym): "static" else: "extern"),
getTypeDesc(m, sym.loc.t), mangleDynLibProc(sym)]))
if isReloadable(m, sym):
addf(m.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
m.s[cfsDynLibInit].addf("\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
[mangleDynLibProc(sym), getTypeDesc(m, sym.loc.t), getModuleDllPath(m, sym)])
elif not containsOrIncl(m.declaredProtos, sym.id):
let asPtr = isReloadable(m, sym)
@ -1077,7 +1076,7 @@ proc genProcPrototype(m: BModule, sym: PSym) =
header.add(" __attribute__((naked))")
if sfNoReturn in sym.flags and hasAttribute in CC[m.config.cCompiler].props:
header.add(" __attribute__((noreturn))")
add(m.s[cfsProcHeaders], ropecg(m, "$1;$N", [header]))
m.s[cfsProcHeaders].add(ropecg(m, "$1;$N", [header]))
# TODO: figure out how to rename this - it DOES generate a forward declaration
proc genProcNoForward(m: BModule, prc: PSym) =
@ -1116,7 +1115,7 @@ proc genProcNoForward(m: BModule, prc: PSym) =
# reloadable (and has no _actual suffix) - other modules will need to be able to get it through
# the hcr dynlib (also put it in the DynLibInit section - right after it gets loaded)
if isReloadable(q, prc):
addf(q.s[cfsDynLibInit], "\t$1 = ($2) hcrRegisterProc($3, \"$1\", (void*)$1);$n",
q.s[cfsDynLibInit].addf("\t$1 = ($2) hcrRegisterProc($3, \"$1\", (void*)$1);$n",
[prc.loc.r, getTypeDesc(q, prc.loc.t), getModuleDllPath(m, q.module)])
else:
symInDynamicLibPartial(m, prc)
@ -1128,7 +1127,7 @@ proc genProcNoForward(m: BModule, prc: PSym) =
# to do the declaredProtos check before the call to genProcPrototype
if isReloadable(m, prc) and prc.id notin m.declaredProtos and
q != nil and q.module.id != m.module.id:
addf(m.s[cfsDynLibInit], "\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
m.s[cfsDynLibInit].addf("\t$1 = ($2) hcrGetProc($3, \"$1\");$n",
[prc.loc.r, getProcTypeCast(m, prc), getModuleDllPath(m, prc)])
genProcPrototype(m, prc)
if q != nil and not containsOrIncl(q.declaredThings, prc.id):
@ -1152,16 +1151,16 @@ proc requestConstImpl(p: BProc, sym: PSym) =
var q = findPendingModule(m, sym)
if q != nil and not containsOrIncl(q.declaredThings, sym.id):
assert q.initProc.module == q
addf(q.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
q.s[cfsData].addf("NIM_CONST $1 $2 = $3;$n",
[getTypeDesc(q, sym.typ), sym.loc.r, genConstExpr(q.initProc, sym.ast)])
# declare header:
if q != m and not containsOrIncl(m.declaredThings, sym.id):
assert(sym.loc.r != nil)
let headerDecl = "extern NIM_CONST $1 $2;$n" %
[getTypeDesc(m, sym.loc.t), sym.loc.r]
add(m.s[cfsData], headerDecl)
m.s[cfsData].add(headerDecl)
if sfExportc in sym.flags and p.module.g.generatedHeader != nil:
add(p.module.g.generatedHeader.s[cfsData], headerDecl)
p.module.g.generatedHeader.s[cfsData].add(headerDecl)
proc isActivated(prc: PSym): bool = prc.typ != nil
@ -1197,19 +1196,19 @@ proc genVarPrototype(m: BModule, n: PNode) =
incl(m.declaredThings, sym.id)
if sym.kind in {skLet, skVar, skField, skForVar} and sym.alignment > 0:
m.s[cfsVars].addf "NIM_ALIGN($1) ", [rope(sym.alignment)]
add(m.s[cfsVars], if m.hcrOn: "static " else: "extern ")
add(m.s[cfsVars], getTypeDesc(m, sym.loc.t))
if m.hcrOn: add(m.s[cfsVars], "*")
if lfDynamicLib in sym.loc.flags: add(m.s[cfsVars], "*")
if sfRegister in sym.flags: add(m.s[cfsVars], " register")
if sfVolatile in sym.flags: add(m.s[cfsVars], " volatile")
addf(m.s[cfsVars], " $1;$n", [sym.loc.r])
if m.hcrOn: addf(m.initProc.procSec(cpsLocals),
m.s[cfsVars].add(if m.hcrOn: "static " else: "extern ")
m.s[cfsVars].add(getTypeDesc(m, sym.loc.t))
if m.hcrOn: m.s[cfsVars].add("*")
if lfDynamicLib in sym.loc.flags: m.s[cfsVars].add("*")
if sfRegister in sym.flags: m.s[cfsVars].add(" register")
if sfVolatile in sym.flags: m.s[cfsVars].add(" volatile")
m.s[cfsVars].addf(" $1;$n", [sym.loc.r])
if m.hcrOn: m.initProc.procSec(cpsLocals).addf(
"\t$1 = ($2*)hcrGetGlobal($3, \"$1\");$n", [sym.loc.r,
getTypeDesc(m, sym.loc.t), getModuleDllPath(m, sym)])
proc addIntTypes(result: var Rope; conf: ConfigRef) {.inline.} =
addf(result, "#define NIM_INTBITS $1\L", [
result.addf("#define NIM_INTBITS $1\L", [
platform.CPU[conf.target.targetCPU].intSize.rope])
if conf.cppCustomNamespace.len > 0:
result.add("#define USE_NIM_NAMESPACE ")
@ -1236,7 +1235,7 @@ proc getCopyright(conf: ConfigRef; cfile: Cfile): Rope =
proc getFileHeader(conf: ConfigRef; cfile: Cfile): Rope =
result = getCopyright(conf, cfile)
if conf.hcrOn: add(result, "#define NIM_HOT_CODE_RELOADING\L")
if conf.hcrOn: result.add("#define NIM_HOT_CODE_RELOADING\L")
addIntTypes(result, conf)
proc getSomeNameForModule(m: PSym): Rope =
@ -1280,15 +1279,15 @@ proc genMainProc(m: BModule) =
"\t\t#nimLoadLibraryError($2);$N",
[handle, genStringLiteral(m, n)])
add(preMainCode, loadLib("hcr_handle", "hcrGetProc"))
add(preMainCode, "\tvoid* rtl_handle;\L")
add(preMainCode, loadLib("rtl_handle", "nimGC_setStackBottom"))
add(preMainCode, hcrGetProcLoadCode(m, "nimGC_setStackBottom", "nimrtl_", "rtl_handle", "nimGetProcAddr"))
add(preMainCode, "\tinner = PreMain;\L")
add(preMainCode, "\tinitStackBottomWith_actual((void *)&inner);\L")
add(preMainCode, "\t(*inner)();\L")
preMainCode.add(loadLib("hcr_handle", "hcrGetProc"))
preMainCode.add("\tvoid* rtl_handle;\L")
preMainCode.add(loadLib("rtl_handle", "nimGC_setStackBottom"))
preMainCode.add(hcrGetProcLoadCode(m, "nimGC_setStackBottom", "nimrtl_", "rtl_handle", "nimGetProcAddr"))
preMainCode.add("\tinner = PreMain;\L")
preMainCode.add("\tinitStackBottomWith_actual((void *)&inner);\L")
preMainCode.add("\t(*inner)();\L")
else:
add(preMainCode, "\tPreMain();\L")
preMainCode.add("\tPreMain();\L")
const
# not a big deal if we always compile these 3 global vars... makes the HCR code easier
@ -1465,63 +1464,63 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
let systemModulePath = getModuleDllPath(m, g.modules[g.graph.config.m.systemFileIdx.int].module)
let mainModulePath = getModuleDllPath(m, m.module)
if sfMainModule in m.module.flags:
addf(hcrModuleMeta, "\t$1,$n", [systemModulePath])
hcrModuleMeta.addf("\t$1,$n", [systemModulePath])
g.graph.importDeps.withValue(FileIndex(m.module.position), deps):
for curr in deps[]:
addf(hcrModuleMeta, "\t$1,$n", [getModuleDllPath(m, g.modules[curr.int].module)])
addf(hcrModuleMeta, "\t\"\"};$n", [])
addf(hcrModuleMeta, "$nN_LIB_EXPORT N_NIMCALL(void**, HcrGetImportedModules)() { return (void**)hcr_module_list; }$n", [])
addf(hcrModuleMeta, "$nN_LIB_EXPORT N_NIMCALL(char*, HcrGetSigHash)() { return \"$1\"; }$n$n",
hcrModuleMeta.addf("\t$1,$n", [getModuleDllPath(m, g.modules[curr.int].module)])
hcrModuleMeta.addf("\t\"\"};$n", [])
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(void**, HcrGetImportedModules)() { return (void**)hcr_module_list; }$n", [])
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(char*, HcrGetSigHash)() { return \"$1\"; }$n$n",
[($sigHash(m.module)).rope])
if sfMainModule in m.module.flags:
add(g.mainModProcs, hcrModuleMeta)
addf(g.mainModProcs, "static void* hcr_handle;$N", [])
addf(g.mainModProcs, "N_LIB_EXPORT N_NIMCALL(void, $1)(void);$N", [init])
addf(g.mainModProcs, "N_LIB_EXPORT N_NIMCALL(void, $1)(void);$N", [datInit])
addf(g.mainModProcs, "N_LIB_EXPORT N_NIMCALL(void, $1)(void*, N_NIMCALL_PTR(void*, getProcAddr)(void*, char*));$N", [m.getHcrInitName])
addf(g.mainModProcs, "N_LIB_EXPORT N_NIMCALL(void, HcrCreateTypeInfos)(void);$N", [])
addf(g.mainModInit, "\t$1();$N", [init])
addf(g.otherModsInit, "\thcrInit((void**)hcr_module_list, $1, $2, $3, hcr_handle, nimGetProcAddr);$n",
g.mainModProcs.add(hcrModuleMeta)
g.mainModProcs.addf("static void* hcr_handle;$N", [])
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void);$N", [init])
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void);$N", [datInit])
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void*, N_NIMCALL_PTR(void*, getProcAddr)(void*, char*));$N", [m.getHcrInitName])
g.mainModProcs.addf("N_LIB_EXPORT N_NIMCALL(void, HcrCreateTypeInfos)(void);$N", [])
g.mainModInit.addf("\t$1();$N", [init])
g.otherModsInit.addf("\thcrInit((void**)hcr_module_list, $1, $2, $3, hcr_handle, nimGetProcAddr);$n",
[mainModulePath, systemModulePath, datInit])
addf(g.mainDatInit, "\t$1(hcr_handle, nimGetProcAddr);$N", [m.getHcrInitName])
addf(g.mainDatInit, "\thcrAddModule($1);\n", [mainModulePath])
addf(g.mainDatInit, "\tHcrCreateTypeInfos();$N", [])
g.mainDatInit.addf("\t$1(hcr_handle, nimGetProcAddr);$N", [m.getHcrInitName])
g.mainDatInit.addf("\thcrAddModule($1);\n", [mainModulePath])
g.mainDatInit.addf("\tHcrCreateTypeInfos();$N", [])
# nasty nasty hack to get the command line functionality working with HCR
# register the 2 variables on behalf of the os module which might not even
# be loaded (in which case it will get collected but that is not a problem)
let osModulePath = ($systemModulePath).replace("stdlib_system", "stdlib_os").rope
addf(g.mainDatInit, "\thcrAddModule($1);\n", [osModulePath])
add(g.mainDatInit, "\tint* cmd_count;\n")
add(g.mainDatInit, "\tchar*** cmd_line;\n")
addf(g.mainDatInit, "\thcrRegisterGlobal($1, \"cmdCount\", sizeof(cmd_count), NULL, (void**)&cmd_count);$N", [osModulePath])
addf(g.mainDatInit, "\thcrRegisterGlobal($1, \"cmdLine\", sizeof(cmd_line), NULL, (void**)&cmd_line);$N", [osModulePath])
add(g.mainDatInit, "\t*cmd_count = cmdCount;\n")
add(g.mainDatInit, "\t*cmd_line = cmdLine;\n")
g.mainDatInit.addf("\thcrAddModule($1);\n", [osModulePath])
g.mainDatInit.add("\tint* cmd_count;\n")
g.mainDatInit.add("\tchar*** cmd_line;\n")
g.mainDatInit.addf("\thcrRegisterGlobal($1, \"cmdCount\", sizeof(cmd_count), NULL, (void**)&cmd_count);$N", [osModulePath])
g.mainDatInit.addf("\thcrRegisterGlobal($1, \"cmdLine\", sizeof(cmd_line), NULL, (void**)&cmd_line);$N", [osModulePath])
g.mainDatInit.add("\t*cmd_count = cmdCount;\n")
g.mainDatInit.add("\t*cmd_line = cmdLine;\n")
else:
add(m.s[cfsInitProc], hcrModuleMeta)
m.s[cfsInitProc].add(hcrModuleMeta)
return
if m.s[cfsDatInitProc].len > 0:
addf(g.mainModProcs, "N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [datInit])
addf(g.mainDatInit, "\t$1();$N", [datInit])
g.mainModProcs.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [datInit])
g.mainDatInit.addf("\t$1();$N", [datInit])
# Initialization of TLS and GC should be done in between
# systemDatInit and systemInit calls if any
if sfSystemModule in m.module.flags:
if emulatedThreadVars(m.config) and m.config.target.targetOS != osStandalone:
add(g.mainDatInit, ropecg(m, "\t#initThreadVarsEmulation();$N", []))
g.mainDatInit.add(ropecg(m, "\t#initThreadVarsEmulation();$N", []))
if m.config.target.targetOS != osStandalone and m.config.selectedGC != gcNone:
add(g.mainDatInit, ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", []))
g.mainDatInit.add(ropecg(m, "\t#initStackBottomWith((void *)&inner);$N", []))
if m.s[cfsInitProc].len > 0:
addf(g.mainModProcs, "N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [init])
g.mainModProcs.addf("N_LIB_PRIVATE N_NIMCALL(void, $1)(void);$N", [init])
let initCall = "\t$1();$N" % [init]
if sfMainModule in m.module.flags:
add(g.mainModInit, initCall)
g.mainModInit.add(initCall)
elif sfSystemModule in m.module.flags:
add(g.mainDatInit, initCall) # systemInit must called right after systemDatInit if any
g.mainDatInit.add(initCall) # systemInit must called right after systemDatInit if any
else:
add(g.otherModsInit, initCall)
g.otherModsInit.add(initCall)
proc genDatInitCode(m: BModule) =
## this function is called in cgenWriteModules after all modules are closed,
@ -1540,14 +1539,14 @@ proc genDatInitCode(m: BModule) =
for i in cfsTypeInit1..cfsDynLibInit:
if m.s[i].len != 0:
moduleDatInitRequired = true
add(prc, genSectionStart(i, m.config))
add(prc, m.s[i])
add(prc, genSectionEnd(i, m.config))
prc.add(genSectionStart(i, m.config))
prc.add(m.s[i])
prc.add(genSectionEnd(i, m.config))
addf(prc, "}$N$N", [])
prc.addf("}$N$N", [])
if moduleDatInitRequired:
add(m.s[cfsDatInitProc], prc)
m.s[cfsDatInitProc].add(prc)
# Very similar to the contents of symInDynamicLib - basically only the
# things needed for the hot code reloading runtime procs to be loaded
@ -1562,7 +1561,7 @@ proc hcrGetProcLoadCode(m: BModule, sym, prefix, handle, getProcFunc: string): R
prc.typ.sym = nil
if not containsOrIncl(m.declaredThings, prc.id):
addf(m.s[cfsVars], "static $2 $1;$n", [prc.loc.r, getTypeDesc(m, prc.loc.t)])
m.s[cfsVars].addf("static $2 $1;$n", [prc.loc.r, getTypeDesc(m, prc.loc.t)])
result = "\t$1 = ($2) $3($4, $5);$n" %
[tmp, getTypeDesc(m, prc.typ), getProcFunc.rope, handle.rope, makeCString(prefix & sym)]
@ -1591,7 +1590,7 @@ proc genInitCode(m: BModule) =
[m.nimTypesName, m.nimTypes])
if m.hcrOn:
addf(prc, "\tint* nim_hcr_dummy_ = 0;$n" &
prc.addf("\tint* nim_hcr_dummy_ = 0;$n" &
"\tNIM_BOOL nim_hcr_do_init_ = " &
"hcrRegisterGlobal($1, \"module_initialized_\", 1, NULL, (void**)&nim_hcr_dummy_);$n",
[getModuleDllPath(m, m.module)])
@ -1599,29 +1598,29 @@ proc genInitCode(m: BModule) =
template writeSection(thing: untyped, section: TCProcSection, addHcrGuards = false) =
if m.thing.s(section).len > 0:
moduleInitRequired = true
if addHcrGuards: add(prc, "\tif (nim_hcr_do_init_) {\n\n")
add(prc, genSectionStart(section, m.config))
add(prc, m.thing.s(section))
add(prc, genSectionEnd(section, m.config))
if addHcrGuards: add(prc, "\n\t} // nim_hcr_do_init_\n")
if addHcrGuards: prc.add("\tif (nim_hcr_do_init_) {\n\n")
prc.add(genSectionStart(section, m.config))
prc.add(m.thing.s(section))
prc.add(genSectionEnd(section, m.config))
if addHcrGuards: prc.add("\n\t} // nim_hcr_do_init_\n")
if m.preInitProc.s(cpsInit).len > 0 or m.preInitProc.s(cpsStmts).len > 0:
# Give this small function its own scope
addf(prc, "{$N", [])
prc.addf("{$N", [])
# Keep a bogus frame in case the code needs one
add(prc, ~"\tTFrame FR_; FR_.len = 0;$N")
prc.add(~"\tTFrame FR_; FR_.len = 0;$N")
writeSection(preInitProc, cpsLocals)
writeSection(preInitProc, cpsInit, m.hcrOn)
writeSection(preInitProc, cpsStmts)
addf(prc, "}$N", [])
prc.addf("}$N", [])
# add new scope for following code, because old vcc compiler need variable
# be defined at the top of the block
addf(prc, "{$N", [])
prc.addf("{$N", [])
if m.initProc.gcFrameId > 0:
moduleInitRequired = true
add(prc, initGCFrame(m.initProc))
prc.add(initGCFrame(m.initProc))
writeSection(initProc, cpsLocals)
@ -1633,22 +1632,22 @@ proc genInitCode(m: BModule) =
incl m.flags, frameDeclared
if preventStackTrace notin m.flags:
var procname = makeCString(m.module.name.s)
add(prc, initFrame(m.initProc, procname, quotedFilename(m.config, m.module.info)))
prc.add(initFrame(m.initProc, procname, quotedFilename(m.config, m.module.info)))
else:
add(prc, ~"\tTFrame FR_; FR_.len = 0;$N")
prc.add(~"\tTFrame FR_; FR_.len = 0;$N")
writeSection(initProc, cpsInit, m.hcrOn)
writeSection(initProc, cpsStmts)
if optStackTrace in m.initProc.options and preventStackTrace notin m.flags:
add(prc, deinitFrame(m.initProc))
prc.add(deinitFrame(m.initProc))
if m.initProc.gcFrameId > 0:
moduleInitRequired = true
add(prc, deinitGCFrame(m.initProc))
addf(prc, "}$N", [])
prc.add(deinitGCFrame(m.initProc))
prc.addf("}$N", [])
addf(prc, "}$N$N", [])
prc.addf("}$N$N", [])
# we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because
# that would lead to a *nesting* of merge sections which the merger does
@ -1657,32 +1656,32 @@ proc genInitCode(m: BModule) =
if m.hcrOn:
var procsToLoad = @["hcrRegisterProc", "hcrGetProc", "hcrRegisterGlobal", "hcrGetGlobal"]
addf(m.s[cfsInitProc], "N_LIB_EXPORT N_NIMCALL(void, $1)(void* handle, N_NIMCALL_PTR(void*, getProcAddr)(void*, char*)) {$N", [getHcrInitName(m)])
m.s[cfsInitProc].addf("N_LIB_EXPORT N_NIMCALL(void, $1)(void* handle, N_NIMCALL_PTR(void*, getProcAddr)(void*, char*)) {$N", [getHcrInitName(m)])
if sfMainModule in m.module.flags:
# additional procs to load
procsToLoad.add("hcrInit")
procsToLoad.add("hcrAddModule")
# load procs
for curr in procsToLoad:
add(m.s[cfsInitProc], hcrGetProcLoadCode(m, curr, "", "handle", "getProcAddr"))
addf(m.s[cfsInitProc], "}$N$N", [])
m.s[cfsInitProc].add(hcrGetProcLoadCode(m, curr, "", "handle", "getProcAddr"))
m.s[cfsInitProc].addf("}$N$N", [])
for i, el in pairs(m.extensionLoaders):
if el != nil:
let ex = "NIM_EXTERNC N_NIMCALL(void, nimLoadProcs$1)(void) {$2}$N$N" %
[(i.ord - '0'.ord).rope, el]
moduleInitRequired = true
add(prc, ex)
prc.add(ex)
if moduleInitRequired or sfMainModule in m.module.flags:
add(m.s[cfsInitProc], prc)
m.s[cfsInitProc].add(prc)
genDatInitCode(m)
if m.hcrOn:
addf(m.s[cfsInitProc], "N_LIB_EXPORT N_NIMCALL(void, HcrCreateTypeInfos)(void) {$N", [])
add(m.s[cfsInitProc], m.hcrCreateTypeInfosProc)
addf(m.s[cfsInitProc], "}$N$N", [])
m.s[cfsInitProc].addf("N_LIB_EXPORT N_NIMCALL(void, HcrCreateTypeInfos)(void) {$N", [])
m.s[cfsInitProc].add(m.hcrCreateTypeInfosProc)
m.s[cfsInitProc].addf("}$N$N", [])
registerModuleToMain(m.g, m)
@ -1694,31 +1693,31 @@ proc genModule(m: BModule, cfile: Cfile): Rope =
generateThreadLocalStorage(m)
generateHeaders(m)
add(result, genSectionStart(cfsHeaders, m.config))
add(result, m.s[cfsHeaders])
result.add(genSectionStart(cfsHeaders, m.config))
result.add(m.s[cfsHeaders])
if m.config.cppCustomNamespace.len > 0:
result.add openNamespaceNim(m.config.cppCustomNamespace)
add(result, genSectionEnd(cfsHeaders, m.config))
add(result, genSectionStart(cfsFrameDefines, m.config))
result.add(genSectionEnd(cfsHeaders, m.config))
result.add(genSectionStart(cfsFrameDefines, m.config))
if m.s[cfsFrameDefines].len > 0:
add(result, m.s[cfsFrameDefines])
result.add(m.s[cfsFrameDefines])
else:
add(result, "#define nimfr_(x, y)\n#define nimln_(x, y)\n")
add(result, genSectionEnd(cfsFrameDefines, m.config))
result.add("#define nimfr_(x, y)\n#define nimln_(x, y)\n")
result.add(genSectionEnd(cfsFrameDefines, m.config))
for i in cfsForwardTypes .. cfsProcs:
for i in cfsForwardTypes..cfsProcs:
if m.s[i].len > 0:
moduleIsEmpty = false
add(result, genSectionStart(i, m.config))
add(result, m.s[i])
add(result, genSectionEnd(i, m.config))
result.add(genSectionStart(i, m.config))
result.add(m.s[i])
result.add(genSectionEnd(i, m.config))
if m.s[cfsInitProc].len > 0:
moduleIsEmpty = false
add(result, m.s[cfsInitProc])
result.add(m.s[cfsInitProc])
if m.s[cfsDatInitProc].len > 0 or m.hcrOn:
moduleIsEmpty = false
add(result, m.s[cfsDatInitProc])
result.add(m.s[cfsDatInitProc])
if m.config.cppCustomNamespace.len > 0:
result.add closeNamespaceNim()
@ -1803,12 +1802,12 @@ proc writeHeader(m: BModule) =
generateHeaders(m)
generateThreadLocalStorage(m)
for i in cfsHeaders .. cfsProcs:
add(result, genSectionStart(i, m.config))
add(result, m.s[i])
add(result, genSectionEnd(i, m.config))
for i in cfsHeaders..cfsProcs:
result.add(genSectionStart(i, m.config))
result.add(m.s[i])
result.add(genSectionEnd(i, m.config))
if m.config.cppCustomNamespace.len > 0 and i == cfsHeaders: result.add openNamespaceNim(m.config.cppCustomNamespace)
add(result, m.s[cfsInitProc])
result.add(m.s[cfsInitProc])
if optGenDynLib in m.config.globalOptions:
result.add("N_LIB_IMPORT ")
@ -1910,7 +1909,7 @@ proc writeModule(m: BModule, pending: bool) =
if sfMainModule in m.module.flags:
# generate main file:
genMainProc(m)
add(m.s[cfsProcHeaders], m.g.mainModProcs)
m.s[cfsProcHeaders].add(m.g.mainModProcs)
generateThreadVarsSize(m)
var cf = Cfile(nimname: m.module.name.s, cname: cfile,

View file

@ -172,7 +172,7 @@ proc includeHeader*(this: BModule; header: string) =
proc s*(p: BProc, s: TCProcSection): var Rope {.inline.} =
# section in the current block
result = p.blocks[p.blocks.len-1].sections[s]
result = p.blocks[^1].sections[s]
proc procSec*(p: BProc, s: TCProcSection): var Rope {.inline.} =
# top level proc sections

View file

@ -23,11 +23,11 @@ proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =
result = n
elif diff < 0:
result = newNodeIT(nkObjUpConv, n.info, d)
addSon(result, n)
result.add n
if downcast: internalError(conf, n.info, "cgmeth.genConv: no upcast allowed")
elif diff > 0:
result = newNodeIT(nkObjDownConv, n.info, d)
addSon(result, n)
result.add n
if not downcast:
internalError(conf, n.info, "cgmeth.genConv: no downcast allowed")
else:
@ -44,26 +44,26 @@ proc getDispatcher*(s: PSym): PSym =
proc methodCall*(n: PNode; conf: ConfigRef): PNode =
result = n
# replace ordinary method by dispatcher method:
let disp = getDispatcher(result.sons[0].sym)
let disp = getDispatcher(result[0].sym)
if disp != nil:
result.sons[0].sym = disp
result[0].sym = disp
# change the arguments to up/downcasts to fit the dispatcher's parameters:
for i in 1 ..< len(result):
result.sons[i] = genConv(result.sons[i], disp.typ.sons[i], true, conf)
for i in 1..<result.len:
result[i] = genConv(result[i], disp.typ[i], true, conf)
else:
localError(conf, n.info, "'" & $result.sons[0] & "' lacks a dispatcher")
localError(conf, n.info, "'" & $result[0] & "' lacks a dispatcher")
type
MethodResult = enum No, Invalid, Yes
proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
if a.name.id != b.name.id: return
if len(a.typ) != len(b.typ):
if a.typ.len != b.typ.len:
return
for i in 1 ..< len(a.typ):
var aa = a.typ.sons[i]
var bb = b.typ.sons[i]
for i in 1..<a.typ.len:
var aa = a.typ[i]
var bb = b.typ[i]
while true:
aa = skipTypes(aa, {tyGenericInst, tyAlias})
bb = skipTypes(bb, {tyGenericInst, tyAlias})
@ -72,7 +72,7 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
bb = bb.lastSon
else:
break
if sameType(a.typ.sons[i], b.typ.sons[i]):
if sameType(a.typ[i], b.typ[i]):
if aa.kind == tyObject and result != Invalid:
result = Yes
elif aa.kind == tyObject and bb.kind == tyObject and (i == 1 or multiMethods):
@ -90,22 +90,22 @@ proc sameMethodBucket(a, b: PSym; multiMethods: bool): MethodResult =
return No
if result == Yes:
# check for return type:
if not sameTypeOrNil(a.typ.sons[0], b.typ.sons[0]):
if b.typ.sons[0] != nil and b.typ.sons[0].kind == tyUntyped:
if not sameTypeOrNil(a.typ[0], b.typ[0]):
if b.typ[0] != nil and b.typ[0].kind == tyUntyped:
# infer 'auto' from the base to make it consistent:
b.typ.sons[0] = a.typ.sons[0]
b.typ[0] = a.typ[0]
else:
return No
proc attachDispatcher(s: PSym, dispatcher: PNode) =
if dispatcherPos < s.ast.len:
# we've added a dispatcher already, so overwrite it
s.ast.sons[dispatcherPos] = dispatcher
s.ast[dispatcherPos] = dispatcher
else:
setLen(s.ast.sons, dispatcherPos+1)
if s.ast[resultPos] == nil:
s.ast[resultPos] = newNodeI(nkEmpty, s.info)
s.ast.sons[dispatcherPos] = dispatcher
s.ast[dispatcherPos] = dispatcher
proc createDispatcher(s: PSym): PSym =
var disp = copySym(s)
@ -115,16 +115,16 @@ proc createDispatcher(s: PSym): PSym =
# we can't inline the dispatcher itself (for now):
if disp.typ.callConv == ccInline: disp.typ.callConv = ccDefault
disp.ast = copyTree(s.ast)
disp.ast.sons[bodyPos] = newNodeI(nkEmpty, s.info)
disp.ast[bodyPos] = newNodeI(nkEmpty, s.info)
disp.loc.r = nil
if s.typ.sons[0] != nil:
if s.typ[0] != nil:
if disp.ast.len > resultPos:
disp.ast.sons[resultPos].sym = copySym(s.ast.sons[resultPos].sym)
disp.ast[resultPos].sym = copySym(s.ast[resultPos].sym)
else:
# We've encountered a method prototype without a filled-in
# resultPos slot. We put a placeholder in there that will
# be updated in fixupDispatcher().
disp.ast.addSon(newNodeI(nkEmpty, s.info))
disp.ast.add newNodeI(nkEmpty, s.info)
attachDispatcher(s, newSymNode(disp))
# attach to itself to prevent bugs:
attachDispatcher(disp, newSymNode(disp))
@ -137,8 +137,8 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
# the lock level of the dispatcher needs to be updated/checked
# against that of the method.
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])
disp.ast[resultPos].kind == nkEmpty:
disp.ast[resultPos] = copyTree(meth.ast[resultPos])
# The following code works only with lock levels, so we disable
# it when they're not available.
@ -158,13 +158,12 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
disp.typ.lockLevel = meth.typ.lockLevel
proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
let L = len(g.methods)
var witness: PSym
for i in 0 ..< L:
for i in 0..<g.methods.len:
let disp = g.methods[i].dispatcher
case sameMethodBucket(disp, s, multimethods = optMultiMethods in g.config.globalOptions)
of Yes:
add(g.methods[i].methods, s)
g.methods[i].methods.add(s)
attachDispatcher(s, disp.ast[dispatcherPos])
fixupDispatcher(s, disp, g.config)
#echo "fixup ", disp.name.s, " ", disp.id
@ -178,7 +177,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
of Invalid:
if witness.isNil: witness = g.methods[i].methods[0]
# create a new dispatcher:
add(g.methods, (methods: @[s], dispatcher: createDispatcher(s)))
g.methods.add((methods: @[s], dispatcher: createDispatcher(s)))
#echo "adding ", s.info
#if fromCache:
# internalError(s.info, "no method dispatcher found")
@ -190,32 +189,32 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
proc relevantCol(methods: seq[PSym], col: int): bool =
# returns true iff the position is relevant
var t = methods[0].typ.sons[col].skipTypes(skipPtrs)
var t = methods[0].typ[col].skipTypes(skipPtrs)
if t.kind == tyObject:
for i in 1 .. high(methods):
let t2 = skipTypes(methods[i].typ.sons[col], skipPtrs)
for i in 1..high(methods):
let t2 = skipTypes(methods[i].typ[col], skipPtrs)
if not sameType(t2, t):
return true
proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int =
for col in 1 ..< len(a.typ):
for col in 1..<a.typ.len:
if contains(relevantCols, col):
var aa = skipTypes(a.typ.sons[col], skipPtrs)
var bb = skipTypes(b.typ.sons[col], skipPtrs)
var aa = skipTypes(a.typ[col], skipPtrs)
var bb = skipTypes(b.typ[col], skipPtrs)
var d = inheritanceDiff(aa, bb)
if (d != high(int)) and d != 0:
return d
proc sortBucket(a: var seq[PSym], relevantCols: IntSet) =
# we use shellsort here; fast and simple
var n = len(a)
var n = a.len
var h = 1
while true:
h = 3 * h + 1
if h > n: break
while true:
h = h div 3
for i in h ..< n:
for i in h..<n:
var v = a[i]
var j = i
while cmpSignatures(a[j - h], v, relevantCols) >= 0:
@ -228,71 +227,70 @@ 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 = len(base.typ)
var paramLen = base.typ.len
var nilchecks = newNodeI(nkStmtList, base.info)
var disp = newNodeI(nkIfStmt, base.info)
var ands = getSysMagic(g, unknownLineInfo(), "and", mAnd)
var iss = getSysMagic(g, unknownLineInfo(), "of", mOf)
let boolType = getSysType(g, unknownLineInfo(), tyBool)
for col in 1 ..< paramLen:
for col in 1..<paramLen:
if contains(relevantCols, col):
let param = base.typ.n.sons[col].sym
let param = base.typ.n[col].sym
if param.typ.skipTypes(abstractInst).kind in {tyRef, tyPtr}:
addSon(nilchecks, newTree(nkCall,
newSymNode(getCompilerProc(g, "chckNilDisp")), newSymNode(param)))
for meth in 0 .. high(methods):
nilchecks.add newTree(nkCall,
newSymNode(getCompilerProc(g, "chckNilDisp")), newSymNode(param))
for meth in 0..high(methods):
var curr = methods[meth] # generate condition:
var cond: PNode = nil
for col in 1 ..< paramLen:
for col in 1..<paramLen:
if contains(relevantCols, col):
var isn = newNodeIT(nkCall, base.info, boolType)
addSon(isn, newSymNode(iss))
let param = base.typ.n.sons[col].sym
addSon(isn, newSymNode(param))
addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col]))
isn.add newSymNode(iss)
let param = base.typ.n[col].sym
isn.add newSymNode(param)
isn.add newNodeIT(nkType, base.info, curr.typ[col])
if cond != nil:
var a = newNodeIT(nkCall, base.info, boolType)
addSon(a, newSymNode(ands))
addSon(a, cond)
addSon(a, isn)
a.add newSymNode(ands)
a.add cond
a.add isn
cond = a
else:
cond = isn
let retTyp = base.typ.sons[0]
let retTyp = base.typ[0]
let call = newNodeIT(nkCall, base.info, retTyp)
addSon(call, newSymNode(curr))
for col in 1 ..< paramLen:
addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym),
curr.typ.sons[col], false, g.config))
call.add newSymNode(curr)
for col in 1..<paramLen:
call.add genConv(newSymNode(base.typ.n[col].sym),
curr.typ[col], false, g.config)
var ret: PNode
if retTyp != nil:
var a = newNodeI(nkFastAsgn, base.info)
addSon(a, newSymNode(base.ast.sons[resultPos].sym))
addSon(a, call)
a.add newSymNode(base.ast[resultPos].sym)
a.add call
ret = newNodeI(nkReturnStmt, base.info)
addSon(ret, a)
ret.add a
else:
ret = call
if cond != nil:
var a = newNodeI(nkElifBranch, base.info)
addSon(a, cond)
addSon(a, ret)
addSon(disp, a)
a.add cond
a.add ret
disp.add a
else:
disp = ret
nilchecks.add disp
nilchecks.flags.incl nfTransf # should not be further transformed
result.ast.sons[bodyPos] = nilchecks
result.ast[bodyPos] = nilchecks
proc generateMethodDispatchers*(g: ModuleGraph): PNode =
result = newNode(nkStmtList)
for bucket in 0 ..< len(g.methods):
for bucket in 0..<g.methods.len:
var relevantCols = initIntSet()
for col in 1 ..< len(g.methods[bucket].methods[0].typ):
for col in 1..<g.methods[bucket].methods[0].typ.len:
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
break
sortBucket(g.methods[bucket].methods, relevantCols)
addSon(result,
newSymNode(genDispatcher(g, g.methods[bucket].methods, relevantCols)))
result.add newSymNode(genDispatcher(g, g.methods[bucket].methods, relevantCols))

View file

@ -237,7 +237,7 @@ proc toStmtList(n: PNode): PNode =
proc addGotoOut(n: PNode, gotoOut: PNode): PNode =
# Make sure `n` is a stmtlist, and ends with `gotoOut`
result = toStmtList(n)
if result.len == 0 or result.sons[^1].kind != nkGotoState:
if result.len == 0 or result[^1].kind != nkGotoState:
result.add(gotoOut)
proc newTempVar(ctx: var Ctx, typ: PType): PSym =
@ -273,7 +273,7 @@ proc transformBreaksAndContinuesInWhile(ctx: var Ctx, n: PNode, before, after: P
if ctx.blockLevel == 0:
result = after
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformBreaksAndContinuesInWhile(n[i], before, after)
proc transformBreaksInBlock(ctx: var Ctx, n: PNode, label, after: PNode): PNode =
@ -293,7 +293,7 @@ proc transformBreaksInBlock(ctx: var Ctx, n: PNode, label, after: PNode): PNode
if label.kind == nkSym and n[0].sym == label.sym:
result = after
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformBreaksInBlock(n[i], label, after)
proc newNullifyCurExc(ctx: var Ctx, info: TLineInfo): PNode =
@ -318,7 +318,7 @@ proc collectExceptState(ctx: var Ctx, n: PNode): PNode {.inline.} =
if c.len > 1:
var cond: PNode
for i in 0 .. c.len - 2:
for i in 0..<c.len - 1:
assert(c[i].kind == nkType)
let nextCond = newTree(nkCall,
newSymNode(g.getSysMagic(c.info, "of", mOf)),
@ -401,7 +401,7 @@ proc exprToStmtList(n: PNode): tuple[s, res: PNode] =
var n = n
while n.kind == nkStmtListExpr:
result.s.sons.add(n.sons)
result.s.sons.setLen(result.s.sons.len - 1) # delete last son
result.s.sons.setLen(result.s.len - 1) # delete last son
n = n[^1]
result.res = n
@ -435,7 +435,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkYieldStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -449,7 +449,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkPar, nkObjConstr, nkTupleConstr, nkBracket:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -459,7 +459,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
if n.typ.isNil: internalError(ctx.g.config, "lowerStmtListExprs: constr typ.isNil")
result.typ = n.typ
for i in 0 ..< n.len:
for i in 0..<n.len:
case n[i].kind
of nkExprColonExpr:
if n[i][1].kind == nkStmtListExpr:
@ -475,7 +475,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkIfStmt, nkIfExpr:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -541,7 +541,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkTryStmt, nkHiddenTryStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -554,7 +554,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
let tmp = ctx.newTempVar(n.typ)
n[0] = ctx.convertExprBodyToAsgn(n[0], tmp)
for i in 1 ..< n.len:
for i in 1..<n.len:
let branch = n[i]
case branch.kind
of nkExceptBranch:
@ -571,7 +571,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkCaseStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -589,7 +589,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
result.add(st)
n[0] = ex
for i in 1 ..< n.len:
for i in 1..<n.len:
let branch = n[i]
case branch.kind
of nkOfBranch:
@ -603,7 +603,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkCallKinds, nkChckRange, nkChckRangeF, nkChckRange64:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -643,7 +643,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
result.add(ifNode)
result.add(ctx.newEnvVarAccess(tmp))
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
if n[i].kind == nkStmtListExpr:
let (st, ex) = exprToStmtList(n[i])
result.add(st)
@ -672,7 +672,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkDiscardStmt, nkReturnStmt, nkRaiseStmt:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -686,7 +686,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv, nkObjDownConv,
nkDerefExpr, nkHiddenDeref:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -700,7 +700,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
of nkAsgn, nkFastAsgn:
var ns = false
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], ns)
if ns:
@ -785,7 +785,7 @@ proc lowerStmtListExprs(ctx: var Ctx, n: PNode, needsSplit: var bool): PNode =
result.add(ex)
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.lowerStmtListExprs(n[i], needsSplit)
proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
@ -849,7 +849,7 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode =
of nkSkip:
discard
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformReturnsInTry(n[i])
proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode =
@ -859,14 +859,14 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode
of nkStmtList, nkStmtListExpr:
result = addGotoOut(result, gotoOut)
for i in 0 ..< n.len:
for i in 0..<n.len:
if n[i].hasYields:
# Create a new split
let go = newNodeI(nkGotoState, n[i].info)
n[i] = ctx.transformClosureIteratorBody(n[i], go)
let s = newNodeI(nkStmtList, n[i + 1].info)
for j in i + 1 ..< n.len:
for j in i + 1..<n.len:
s.add(n[j])
n.sons.setLen(i + 1)
@ -889,7 +889,7 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode
result[^1] = ctx.transformClosureIteratorBody(result[^1], gotoOut)
of nkIfStmt, nkCaseStmt:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformClosureIteratorBody(n[i], gotoOut)
if n[^1].kind != nkElse:
# We don't have an else branch, but every possible branch has to end with
@ -1001,7 +1001,7 @@ proc transformClosureIteratorBody(ctx: var Ctx, n: PNode, gotoOut: PNode): PNode
internalError(ctx.g.config, "closure iter " & $n.kind)
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformClosureIteratorBody(n[i], gotoOut)
proc stateFromGotoState(n: PNode): int =
@ -1038,18 +1038,18 @@ proc transformStateAssignments(ctx: var Ctx, n: PNode): PNode =
result.add(ctx.newStateAssgn(stateFromGotoState(n[1])))
var retStmt = newNodeI(nkReturnStmt, n.info)
if n[0].sons[0].kind != nkEmpty:
var a = newNodeI(nkAsgn, n[0].sons[0].info)
var retVal = n[0].sons[0] #liftCapturedVars(n.sons[0], owner, d, c)
addSon(a, newSymNode(getClosureIterResult(ctx.g, ctx.fn)))
addSon(a, retVal)
if n[0][0].kind != nkEmpty:
var a = newNodeI(nkAsgn, n[0][0].info)
var retVal = n[0][0] #liftCapturedVars(n[0], owner, d, c)
a.add newSymNode(getClosureIterResult(ctx.g, ctx.fn))
a.add retVal
retStmt.add(a)
else:
retStmt.add(ctx.g.emptyNode)
result.add(retStmt)
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformStateAssignments(n[i])
of nkSkip:
@ -1069,7 +1069,7 @@ proc transformStateAssignments(ctx: var Ctx, n: PNode): PNode =
result.add(breakState)
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.transformStateAssignments(n[i])
proc skipStmtList(ctx: Ctx; n: PNode): PNode =
@ -1110,7 +1110,7 @@ proc skipThroughEmptyStates(ctx: var Ctx, n: PNode): PNode =
result = copyTree(n)
result[0].intVal = ctx.skipEmptyStates(result[0].intVal.int)
else:
for i in 0 ..< n.len:
for i in 0..<n.len:
n[i] = ctx.skipThroughEmptyStates(n[i])
proc newArrayType(g: ModuleGraph; n: int, t: PType, owner: PSym): PType =

View file

@ -110,7 +110,7 @@ proc writeCommandLineUsage*(conf: ConfigRef) =
msgWriteln(conf, getCommandLineDesc(conf), {msgStdout})
proc addPrefix(switch: string): string =
if len(switch) <= 1: result = "-" & switch
if switch.len <= 1: result = "-" & switch
else: result = "--" & switch
const
@ -127,14 +127,14 @@ proc splitSwitch(conf: ConfigRef; switch: string, cmd, arg: var string, pass: TC
info: TLineInfo) =
cmd = ""
var i = 0
if i < len(switch) and switch[i] == '-': inc(i)
if i < len(switch) and switch[i] == '-': inc(i)
while i < len(switch):
if i < switch.len and switch[i] == '-': inc(i)
if i < switch.len and switch[i] == '-': inc(i)
while i < switch.len:
case switch[i]
of 'a'..'z', 'A'..'Z', '0'..'9', '_', '.': add(cmd, switch[i])
of 'a'..'z', 'A'..'Z', '0'..'9', '_', '.': cmd.add(switch[i])
else: break
inc(i)
if i >= len(switch): arg = ""
if i >= switch.len: arg = ""
# cmd:arg => (cmd,arg)
elif switch[i] in {':', '='}: arg = substr(switch, i + 1)
# cmd[sub]:rest => (cmd,[sub]:rest)
@ -178,17 +178,17 @@ proc processSpecificNote*(arg: string, state: TSpecialWord, pass: TCmdLinePass,
var i = 0
var n = hintMin
var isBracket = false
if i < len(arg) and arg[i] == '[':
if i < arg.len and arg[i] == '[':
isBracket = true
inc(i)
while i < len(arg) and (arg[i] notin {':', '=', ']'}):
add(id, arg[i])
while i < arg.len and (arg[i] notin {':', '=', ']'}):
id.add(arg[i])
inc(i)
if isBracket:
if i < len(arg) and arg[i] == ']': inc(i)
if i < arg.len and arg[i] == ']': inc(i)
else: invalidCmdLineOption(conf, pass, orig, info)
if i < len(arg) and (arg[i] in {':', '='}): inc(i)
if i < arg.len and (arg[i] in {':', '='}): inc(i)
else: invalidCmdLineOption(conf, pass, orig, info)
if state == wHint:
let x = findStr(lineinfos.HintsToStr, id)

View file

@ -25,7 +25,7 @@ type
dotGraph: Rope
proc addDependencyAux(b: Backend; importing, imported: string) =
addf(b.dotGraph, "$1 -> \"$2\";$n", [rope(importing), rope(imported)])
b.dotGraph.addf("$1 -> \"$2\";$n", [rope(importing), rope(imported)])
# s1 -> s2_4[label="[0-9]"];
proc addDotDependency(c: PPassContext, n: PNode): PNode =
@ -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 ..< len(n):
var imported = getModuleName(g.config, n.sons[i])
for i in 0..<n.len:
var imported = getModuleName(g.config, n[i])
addDependencyAux(b, g.module.name.s, imported)
of nkFromStmt, nkImportExceptStmt:
var imported = getModuleName(g.config, n.sons[0])
var imported = getModuleName(g.config, n[0])
addDependencyAux(b, g.module.name.s, imported)
of nkStmtList, nkBlockStmt, nkStmtListExpr, nkBlockExpr:
for i in 0 ..< len(n): discard addDotDependency(c, n.sons[i])
for i in 0..<n.len: discard addDotDependency(c, n[i])
else:
discard

View file

@ -331,20 +331,20 @@ when true:
L4:
join F1
]#
if isTrue(n.sons[0]):
if isTrue(n[0]):
# 'while true' is an idiom in Nim and so we produce
# better code for it:
for i in 0..2:
withBlock(nil):
c.gen(n.sons[1])
c.gen(n[1])
else:
let oldForksLen = c.forks.len
var endings: array[3, TPosition]
for i in 0..2:
withBlock(nil):
c.gen(n.sons[0])
c.gen(n[0])
endings[i] = c.forkI(n)
c.gen(n.sons[1])
c.gen(n[1])
for i in countdown(endings.high, 0):
let endPos = endings[i]
c.patch(endPos)
@ -363,20 +363,20 @@ else:
let oldForksLen = c.forks.len
let lab1 = c.genLabel
withBlock(nil):
if isTrue(n.sons[0]):
c.gen(n.sons[1])
if isTrue(n[0]):
c.gen(n[1])
c.jmpBack(n, lab1)
else:
c.gen(n.sons[0])
c.gen(n[0])
let lab2 = c.forkI(n)
c.gen(n.sons[1])
c.gen(n[1])
c.jmpBack(n, lab1)
c.patch(lab2)
setLen(c.forks, oldForksLen)
proc genBlock(c: var Con; n: PNode) =
withBlock(n.sons[0].sym):
c.gen(n.sons[1])
withBlock(n[0].sym):
c.gen(n[1])
proc genJoins(c: var Con; n: PNode) =
for i in countdown(c.forks.high, 0): joinI(c, c.forks[i], n)
@ -384,10 +384,10 @@ proc genJoins(c: var Con; n: PNode) =
proc genBreak(c: var Con; n: PNode) =
genJoins(c, n)
let lab1 = c.gotoI(n)
if n.sons[0].kind == nkSym:
#echo cast[int](n.sons[0].sym)
if n[0].kind == nkSym:
#echo cast[int](n[0].sym)
for i in countdown(c.blocks.len-1, 0):
if c.blocks[i].label == n.sons[0].sym:
if c.blocks[i].label == n[0].sym:
c.blocks[i].fixups.add lab1
return
#globalError(n.info, "VM problem: cannot find 'break' target")
@ -441,13 +441,13 @@ proc genIf(c: var Con, n: PNode) =
]#
let oldLen = c.forks.len
var endings: seq[TPosition] = @[]
for i in 0 ..< len(n):
var it = n.sons[i]
c.gen(it.sons[0])
for i in 0..<n.len:
var it = n[i]
c.gen(it[0])
if it.len == 2:
let elsePos = forkI(c, it[1])
c.gen(it.sons[1])
endings.add(c.gotoI(it.sons[1]))
c.gen(it[1])
endings.add(c.gotoI(it[1]))
c.patch(elsePos)
for i in countdown(endings.high, 0):
let endPos = endings[i]
@ -461,9 +461,9 @@ proc genAndOr(c: var Con; n: PNode) =
# asgn dest, b
# lab1:
# join F1
c.gen(n.sons[1])
c.gen(n[1])
forkT(n):
c.gen(n.sons[2])
c.gen(n[2])
proc genCase(c: var Con; n: PNode) =
# if (!expr1) goto lab1;
@ -476,16 +476,16 @@ proc genCase(c: var Con; n: PNode) =
# lab2:
# elsePart
# Lend:
let isExhaustive = skipTypes(n.sons[0].typ,
let isExhaustive = skipTypes(n[0].typ,
abstractVarRange-{tyTypeDesc}).kind notin {tyFloat..tyFloat128, tyString}
var endings: seq[TPosition] = @[]
let oldLen = c.forks.len
c.gen(n.sons[0])
for i in 1 ..< n.len:
let it = n.sons[i]
c.gen(n[0])
for i in 1..<n.len:
let it = n[i]
if it.len == 1:
c.gen(it.sons[0])
c.gen(it[0])
elif i == n.len-1 and isExhaustive:
# treat the last branch as 'else' if this is an exhaustive case statement.
c.gen(it.lastSon)
@ -507,7 +507,7 @@ proc genTry(c: var Con; n: PNode) =
let oldFixups = c.tryStmtFixups.len
#let elsePos = c.forkI(n)
c.gen(n.sons[0])
c.gen(n[0])
dec c.inTryStmt
for i in oldFixups..c.tryStmtFixups.high:
let f = c.tryStmtFixups[i]
@ -520,10 +520,9 @@ proc genTry(c: var Con; n: PNode) =
setLen(c.tryStmtFixups, oldFixups)
#c.patch(elsePos)
for i in 1 ..< n.len:
let it = n.sons[i]
for i in 1..<n.len:
let it = n[i]
if it.kind != nkFinally:
var blen = len(it)
let endExcept = c.forkI(it)
c.gen(it.lastSon)
endings.add(c.gotoI(it))
@ -538,7 +537,7 @@ proc genTry(c: var Con; n: PNode) =
let fin = lastSon(n)
if fin.kind == nkFinally:
c.gen(fin.sons[0])
c.gen(fin[0])
doAssert(c.forks.len == oldLen)
template genNoReturn(c: var Con; n: PNode) =
@ -547,7 +546,7 @@ template genNoReturn(c: var Con; n: PNode) =
proc genRaise(c: var Con; n: PNode) =
genJoins(c, n)
gen(c, n.sons[0])
gen(c, n[0])
if c.inTryStmt > 0:
c.tryStmtFixups.add c.gotoI(n)
else:
@ -555,12 +554,12 @@ proc genRaise(c: var Con; n: PNode) =
proc genImplicitReturn(c: var Con) =
if c.owner.kind in {skProc, skFunc, skMethod, skIterator, skConverter} and resultPos < c.owner.ast.len:
gen(c, c.owner.ast.sons[resultPos])
gen(c, c.owner.ast[resultPos])
proc genReturn(c: var Con; n: PNode) =
genJoins(c, n)
if n.sons[0].kind != nkEmpty:
gen(c, n.sons[0])
if n[0].kind != nkEmpty:
gen(c, n[0])
else:
genImplicitReturn(c)
genNoReturn(c, n)
@ -695,7 +694,7 @@ proc genCall(c: var Con; n: PNode) =
for i in 1..<n.len:
gen(c, n[i])
when false:
if t != nil and i < t.len and t.sons[i].kind == tyVar:
if t != nil and i < t.len and t[i].kind == tyVar:
# This is wrong! Pass by var is a 'might def', not a 'must def'
# like the other defs we emit. This is not good enough for a move
# optimizer.
@ -728,23 +727,23 @@ proc genVarSection(c: var Con; n: PNode) =
discard
elif a.kind == nkVarTuple:
gen(c, a.lastSon)
for i in 0 .. a.len-3: genDef(c, a[i])
for i in 0..<a.len-2: genDef(c, a[i])
else:
gen(c, a.lastSon)
if a.lastSon.kind != nkEmpty:
genDef(c, a.sons[0])
genDef(c, a[0])
proc gen(c: var Con; n: PNode) =
case n.kind
of nkSym: genUse(c, n)
of nkCallKinds:
if n.sons[0].kind == nkSym:
let s = n.sons[0].sym
if n[0].kind == nkSym:
let s = n[0].sym
if s.magic != mNone:
genMagic(c, n, s.magic)
else:
genCall(c, n)
if sfNoReturn in n.sons[0].sym.flags:
if sfNoReturn in n[0].sym.flags:
genNoReturn(c, n)
else:
genCall(c, n)
@ -760,7 +759,7 @@ proc gen(c: var Con; n: PNode) =
of nkIfStmt, nkIfExpr: genIf(c, n)
of nkWhenStmt:
# This is "when nimvm" node. Chose the first branch.
gen(c, n.sons[0].sons[1])
gen(c, n[0][1])
of nkCaseStmt: genCase(c, n)
of nkWhileStmt: genWhile(c, n)
of nkBlockExpr, nkBlockStmt: genBlock(c, n)
@ -772,10 +771,10 @@ proc gen(c: var Con; n: PNode) =
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr, nkYieldStmt:
for x in n: gen(c, x)
of nkPragmaBlock: gen(c, n.lastSon)
of nkDiscardStmt, nkObjDownConv, nkObjUpConv: gen(c, n.sons[0])
of nkDiscardStmt, nkObjDownConv, nkObjUpConv: gen(c, n[0])
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast, nkHiddenSubConv, nkHiddenStdConv:
gen(c, n.sons[1])
of nkStringToCString, nkCStringToString: gen(c, n.sons[0])
gen(c, n[1])
of nkStringToCString, nkCStringToString: gen(c, n[0])
of nkVarSection, nkLetSection: genVarSection(c, n)
of nkDefer:
doAssert false, "dfa construction pass requires the elimination of 'defer'"

View file

@ -50,12 +50,12 @@ proc whichType(d: PDoc; n: PNode): PSym =
if d.types.strTableContains(n.sym):
result = n.sym
else:
for i in 0..<safeLen(n):
for i in 0..<n.safeLen:
let x = whichType(d, n[i])
if x != nil: return x
proc attachToType(d: PDoc; p: PSym): PSym =
let params = p.ast.sons[paramsPos]
let params = p.ast[paramsPos]
template check(i) =
result = whichType(d, params[i])
if result != nil: return result
@ -68,7 +68,7 @@ proc attachToType(d: PDoc; p: PSym): PSym =
template declareClosures =
proc compilerMsgHandler(filename: string, line, col: int,
msgKind: rst.MsgKind, arg: string) {.procvar, gcsafe.} =
msgKind: rst.MsgKind, arg: string) {.gcsafe.} =
# translate msg kind:
var k: TMsgKind
case msgKind
@ -85,7 +85,7 @@ template declareClosures =
{.gcsafe.}:
globalError(conf, newLineInfo(conf, AbsoluteFile filename, line, col), k, arg)
proc docgenFindFile(s: string): string {.procvar, gcsafe.} =
proc docgenFindFile(s: string): string {.gcsafe.} =
result = options.findFile(conf, s).string
if result.len == 0:
result = getCurrentDir() / s
@ -176,11 +176,11 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
result.thisDir = result.destFile.splitFile.dir
template dispA(conf: ConfigRef; dest: var Rope, xml, tex: string, args: openArray[Rope]) =
if conf.cmd != cmdRst2tex: addf(dest, xml, args)
else: addf(dest, tex, args)
if conf.cmd != cmdRst2tex: dest.addf(xml, args)
else: dest.addf(tex, args)
proc getVarIdx(varnames: openArray[string], id: string): int =
for i in 0 .. high(varnames):
for i in 0..high(varnames):
if cmpIgnoreStyle(varnames[i], id) == 0:
return i
result = -1
@ -189,44 +189,43 @@ proc ropeFormatNamedVars(conf: ConfigRef; frmt: FormatStr,
varnames: openArray[string],
varvalues: openArray[Rope]): Rope =
var i = 0
var L = len(frmt)
result = nil
var num = 0
while i < L:
while i < frmt.len:
if frmt[i] == '$':
inc(i) # skip '$'
case frmt[i]
of '#':
add(result, varvalues[num])
result.add(varvalues[num])
inc(num)
inc(i)
of '$':
add(result, "$")
result.add("$")
inc(i)
of '0'..'9':
var j = 0
while true:
j = (j * 10) + ord(frmt[i]) - ord('0')
inc(i)
if (i > L + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
if (i > frmt.len + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
if j > high(varvalues) + 1:
rawMessage(conf, errGenerated, "Invalid format string; too many $s: " & frmt)
num = j
add(result, varvalues[j - 1])
result.add(varvalues[j - 1])
of 'A'..'Z', 'a'..'z', '\x80'..'\xFF':
var id = ""
while true:
add(id, frmt[i])
id.add(frmt[i])
inc(i)
if not (frmt[i] in {'A'..'Z', '_', 'a'..'z', '\x80'..'\xFF'}): break
var idx = getVarIdx(varnames, id)
if idx >= 0: add(result, varvalues[idx])
if idx >= 0: result.add(varvalues[idx])
else: rawMessage(conf, errGenerated, "unknown substition variable: " & id)
of '{':
var id = ""
inc(i)
while i < frmt.len and frmt[i] != '}':
add(id, frmt[i])
id.add(frmt[i])
inc(i)
if i >= frmt.len:
rawMessage(conf, errGenerated, "expected closing '}'")
@ -234,15 +233,15 @@ proc ropeFormatNamedVars(conf: ConfigRef; frmt: FormatStr,
inc(i) # skip }
# search for the variable:
let idx = getVarIdx(varnames, id)
if idx >= 0: add(result, varvalues[idx])
if idx >= 0: result.add(varvalues[idx])
else: rawMessage(conf, errGenerated, "unknown substition variable: " & id)
else:
add(result, "$")
result.add("$")
var start = i
while i < L:
while i < frmt.len:
if frmt[i] != '$': inc(i)
else: break
if i - 1 >= start: add(result, substr(frmt, start, i - 1))
if i - 1 >= start: result.add(substr(frmt, start, i - 1))
proc genComment(d: PDoc, n: PNode): string =
result = ""
@ -259,8 +258,8 @@ proc genRecCommentAux(d: PDoc, n: PNode): Rope =
if n.kind in {nkStmtList, nkStmtListExpr, nkTypeDef, nkConstDef,
nkObjectTy, nkRefTy, nkPtrTy, nkAsgn, nkFastAsgn, nkHiddenStdConv}:
# notin {nkEmpty..nkNilLit, nkEnumTy, nkTupleTy}:
for i in 0 ..< len(n):
result = genRecCommentAux(d, n.sons[i])
for i in 0..<n.len:
result = genRecCommentAux(d, n[i])
if result != nil: return
else:
when defined(nimNoNilSeqs): n.comment = ""
@ -287,8 +286,8 @@ proc getPlainDocstring(n: PNode): string =
if startsWith(n.comment, "##"):
result = n.comment
if result.len < 1:
for i in 0 ..< safeLen(n):
result = getPlainDocstring(n.sons[i])
for i in 0..<n.safeLen:
result = getPlainDocstring(n[i])
if result.len > 0: return
proc belongsToPackage(conf: ConfigRef; module: PSym): bool =
@ -358,7 +357,7 @@ proc nodeToHighlightedHtml(d: PDoc; n: PNode; result: var Rope; renderFlags: TRe
dispA(d.conf, result, "<span class=\"Identifier\">$1</span>",
"\\spanIdentifier{$1}", [rope(esc(d.target, literal))])
of tkSpaces, tkInvalid:
add(result, literal)
result.add(literal)
of tkCurlyDotLe:
dispA(d.conf, result, "<span>" & # This span is required for the JS to work properly
"""<span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span>
@ -465,7 +464,7 @@ proc getAllRunnableExamplesRec(d: PDoc; n, orig: PNode; dest: var Rope) =
nodeToHighlightedHtml(d, b, dest, {}, nil)
dest.add(d.config.getOrDefault"doc.listing_end" % id)
else: discard
for i in 0 ..< n.safeLen:
for i in 0..<n.safeLen:
getAllRunnableExamplesRec(d, n[i], orig, dest)
proc getAllRunnableExamples(d: PDoc; n: PNode; dest: var Rope) =
@ -474,8 +473,8 @@ proc getAllRunnableExamples(d: PDoc; n: PNode; dest: var Rope) =
proc isVisible(d: PDoc; n: PNode): bool =
result = false
if n.kind == nkPostfix:
if n.len == 2 and n.sons[0].kind == nkIdent:
var v = n.sons[0].ident
if n.len == 2 and n[0].kind == nkIdent:
var v = n[0].ident
result = v.id == ord(wStar) or v.id == ord(wMinus)
elif n.kind == nkSym:
# we cannot generate code for forwarded symbols here as we have no
@ -488,12 +487,12 @@ proc isVisible(d: PDoc; n: PNode): bool =
if result and containsOrIncl(d.emitted, n.sym.id):
result = false
elif n.kind == nkPragmaExpr:
result = isVisible(d, n.sons[0])
result = isVisible(d, n[0])
proc getName(d: PDoc, n: PNode, splitAfter = -1): string =
case n.kind
of nkPostfix: result = getName(d, n.sons[1], splitAfter)
of nkPragmaExpr: result = getName(d, n.sons[0], splitAfter)
of nkPostfix: result = getName(d, n[1], splitAfter)
of nkPragmaExpr: result = getName(d, n[0], splitAfter)
of nkSym: result = esc(d.target, n.sym.renderDefinitionName, splitAfter)
of nkIdent: result = esc(d.target, n.ident.s, splitAfter)
of nkAccQuoted:
@ -507,8 +506,8 @@ proc getName(d: PDoc, n: PNode, splitAfter = -1): string =
proc getNameIdent(cache: IdentCache; n: PNode): PIdent =
case n.kind
of nkPostfix: result = getNameIdent(cache, n.sons[1])
of nkPragmaExpr: result = getNameIdent(cache, n.sons[0])
of nkPostfix: result = getNameIdent(cache, n[1])
of nkPragmaExpr: result = getNameIdent(cache, n[0])
of nkSym: result = n.sym.name
of nkIdent: result = n.ident
of nkAccQuoted:
@ -522,13 +521,13 @@ proc getNameIdent(cache: IdentCache; n: PNode): PIdent =
proc getRstName(n: PNode): PRstNode =
case n.kind
of nkPostfix: result = getRstName(n.sons[1])
of nkPragmaExpr: result = getRstName(n.sons[0])
of nkPostfix: result = getRstName(n[1])
of nkPragmaExpr: result = getRstName(n[0])
of nkSym: result = newRstNode(rnLeaf, n.sym.renderDefinitionName)
of nkIdent: result = newRstNode(rnLeaf, n.ident.s)
of nkAccQuoted:
result = getRstName(n.sons[0])
for i in 1 ..< n.len: result.text.add(getRstName(n[i]).text)
result = getRstName(n[0])
for i in 1..<n.len: result.text.add(getRstName(n[i]).text)
of nkOpenSymChoice, nkClosedSymChoice:
result = getRstName(n[0])
else:
@ -573,7 +572,7 @@ proc complexName(k: TSymKind, n: PNode, baseName: string): string =
of skTemplate: result.add(".t")
of skConverter: result.add(".c")
else: discard
if len(n) > paramsPos and n[paramsPos].kind == nkFormalParams:
if n.len > paramsPos and n[paramsPos].kind == nkFormalParams:
let params = renderParamTypes(n[paramsPos])
if params.len > 0:
result.add(defaultParamSeparator)
@ -653,8 +652,8 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
plainName.add(literal)
var pragmaNode: PNode = nil
if n.isCallable and n.sons[pragmasPos].kind != nkEmpty:
pragmaNode = findPragma(n.sons[pragmasPos], wDeprecated)
if n.isCallable and n[pragmasPos].kind != nkEmpty:
pragmaNode = findPragma(n[pragmasPos], wDeprecated)
inc(d.id)
let
@ -680,7 +679,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
let cwd = canonicalizePath(d.conf, getCurrentDir())
var path = toFullPath(d.conf, n.info)
if path.startsWith(cwd):
path = path[cwd.len+1 .. ^1].replace('\\', '/')
path = path[cwd.len+1..^1].replace('\\', '/')
let gitUrl = getConfigVar(d.conf, "git.url")
if gitUrl.len > 0:
let defaultBranch =
@ -692,7 +691,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
["path", "line", "url", "commit", "devel"], [rope path.string,
rope($n.info.line), rope gitUrl, rope commit, rope develBranch])])
add(d.section[k], ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item"),
d.section[k].add(ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item"),
["name", "header", "desc", "itemID", "header_plain", "itemSym",
"itemSymOrID", "itemSymEnc", "itemSymOrIDEnc", "seeSrc", "deprecationMsg"],
[nameRope, result, comm, itemIDRope, plainNameRope, plainSymbolRope,
@ -715,7 +714,7 @@ proc genItem(d: PDoc, n, nameNode: PNode, k: TSymKind) =
setIndexTerm(d[], external, symbolOrId, plain, nameNode.sym.name.s & '.' & plain,
xmltree.escape(getPlainDocstring(e).docstringSummary))
add(d.toc[k], ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item.toc"),
d.toc[k].add(ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.item.toc"),
["name", "header", "desc", "itemID", "header_plain", "itemSym",
"itemSymOrID", "itemSymEnc", "itemSymOrIDEnc", "attype"],
[rope(getName(d, nameNode, d.splitAfter)), result, comm,
@ -761,11 +760,11 @@ proc traceDeps(d: PDoc, it: PNode) =
a.add dir
a.add sep # dummy entry, replaced in the loop
for x in it[2]:
a.sons[2] = x
a[2] = x
traceDeps(d, a)
elif it.kind == nkSym and belongsToPackage(d.conf, it.sym):
let external = externalDep(d, it.sym)
if d.section[k] != nil: add(d.section[k], ", ")
if d.section[k] != nil: d.section[k].add(", ")
dispA(d.conf, d.section[k],
"<a class=\"reference external\" href=\"$2\">$1</a>",
"$1", [rope esc(d.target, changeFileExt(external, "")),
@ -775,7 +774,7 @@ proc exportSym(d: PDoc; s: PSym) =
const k = exportSection
if s.kind == skModule and belongsToPackage(d.conf, s):
let external = externalDep(d, s)
if d.section[k] != nil: add(d.section[k], ", ")
if d.section[k] != nil: d.section[k].add(", ")
dispA(d.conf, d.section[k],
"<a class=\"reference external\" href=\"$2\">$1</a>",
"$1", [rope esc(d.target, changeFileExt(external, "")),
@ -784,7 +783,7 @@ proc exportSym(d: PDoc; s: PSym) =
let module = originatingModule(s)
if belongsToPackage(d.conf, module):
let external = externalDep(d, module)
if d.section[k] != nil: add(d.section[k], ", ")
if d.section[k] != nil: d.section[k].add(", ")
# XXX proper anchor generation here
dispA(d.conf, d.section[k],
"<a href=\"$2#$1\"><span class=\"Identifier\">$1</span></a>",
@ -792,37 +791,37 @@ proc exportSym(d: PDoc; s: PSym) =
rope changeFileExt(external, "html")])
proc documentNewEffect(cache: IdentCache; n: PNode): PNode =
let s = n.sons[namePos].sym
let s = n[namePos].sym
if tfReturnsNew in s.typ.flags:
result = newIdentNode(getIdent(cache, "new"), n.info)
proc documentEffect(cache: IdentCache; n, x: PNode, effectType: TSpecialWord, idx: int): PNode =
let spec = effectSpec(x, effectType)
if isNil(spec):
let s = n.sons[namePos].sym
let s = n[namePos].sym
let actual = s.typ.n.sons[0]
let actual = s.typ.n[0]
if actual.len != effectListLen: return
let real = actual.sons[idx]
let real = actual[idx]
# warning: hack ahead:
var effects = newNodeI(nkBracket, n.info, real.len)
for i in 0 ..< real.len:
for i in 0..<real.len:
var t = typeToString(real[i].typ)
if t.startsWith("ref "): t = substr(t, 4)
effects.sons[i] = newIdentNode(getIdent(cache, t), n.info)
effects[i] = newIdentNode(getIdent(cache, t), n.info)
# set the type so that the following analysis doesn't screw up:
effects.sons[i].typ = real[i].typ
effects[i].typ = real[i].typ
result = newNode(nkExprColonExpr, n.info, @[
newIdentNode(getIdent(cache, specialWords[effectType]), n.info), effects])
proc documentWriteEffect(cache: IdentCache; n: PNode; flag: TSymFlag; pragmaName: string): PNode =
let s = n.sons[namePos].sym
let s = n[namePos].sym
let params = s.typ.n
var effects = newNodeI(nkBracket, n.info)
for i in 1 ..< params.len:
for i in 1..<params.len:
if params[i].kind == nkSym and flag in params[i].sym.flags:
effects.add params[i]
@ -831,8 +830,8 @@ proc documentWriteEffect(cache: IdentCache; n: PNode; flag: TSymFlag; pragmaName
newIdentNode(getIdent(cache, pragmaName), n.info), effects])
proc documentRaises*(cache: IdentCache; n: PNode) =
if n.sons[namePos].kind != nkSym: return
let pragmas = n.sons[pragmasPos]
if n[namePos].kind != nkSym: return
let pragmas = n[pragmasPos]
let p1 = documentEffect(cache, n, pragmas, wRaises, exceptionEffects)
let p2 = documentEffect(cache, n, pragmas, wTags, tagEffects)
let p3 = documentWriteEffect(cache, n, sfWrittenTo, "writes")
@ -841,59 +840,59 @@ proc documentRaises*(cache: IdentCache; n: PNode) =
if p1 != nil or p2 != nil or p3 != nil or p4 != nil or p5 != nil:
if pragmas.kind == nkEmpty:
n.sons[pragmasPos] = newNodeI(nkPragma, n.info)
if p1 != nil: n.sons[pragmasPos].add p1
if p2 != nil: n.sons[pragmasPos].add p2
if p3 != nil: n.sons[pragmasPos].add p3
if p4 != nil: n.sons[pragmasPos].add p4
if p5 != nil: n.sons[pragmasPos].add p5
n[pragmasPos] = newNodeI(nkPragma, n.info)
if p1 != nil: n[pragmasPos].add p1
if p2 != nil: n[pragmasPos].add p2
if p3 != nil: n[pragmasPos].add p3
if p4 != nil: n[pragmasPos].add p4
if p5 != nil: n[pragmasPos].add p5
proc generateDoc*(d: PDoc, n, orig: PNode) =
case n.kind
of nkPragma:
let pragmaNode = findPragma(n, wDeprecated)
add(d.modDeprecationMsg, genDeprecationMsg(d, pragmaNode))
of nkCommentStmt: add(d.modDesc, genComment(d, n))
d.modDeprecationMsg.add(genDeprecationMsg(d, pragmaNode))
of nkCommentStmt: d.modDesc.add(genComment(d, n))
of nkProcDef:
when useEffectSystem: documentRaises(d.cache, n)
genItem(d, n, n.sons[namePos], skProc)
genItem(d, n, n[namePos], skProc)
of nkFuncDef:
when useEffectSystem: documentRaises(d.cache, n)
genItem(d, n, n.sons[namePos], skFunc)
genItem(d, n, n[namePos], skFunc)
of nkMethodDef:
when useEffectSystem: documentRaises(d.cache, n)
genItem(d, n, n.sons[namePos], skMethod)
genItem(d, n, n[namePos], skMethod)
of nkIteratorDef:
when useEffectSystem: documentRaises(d.cache, n)
genItem(d, n, n.sons[namePos], skIterator)
of nkMacroDef: genItem(d, n, n.sons[namePos], skMacro)
of nkTemplateDef: genItem(d, n, n.sons[namePos], skTemplate)
genItem(d, n, n[namePos], skIterator)
of nkMacroDef: genItem(d, n, n[namePos], skMacro)
of nkTemplateDef: genItem(d, n, n[namePos], skTemplate)
of nkConverterDef:
when useEffectSystem: documentRaises(d.cache, n)
genItem(d, n, n.sons[namePos], skConverter)
genItem(d, n, n[namePos], skConverter)
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
for i in 0 ..< len(n):
if n.sons[i].kind != nkCommentStmt:
for i in 0..<n.len:
if n[i].kind != nkCommentStmt:
# order is always 'type var let const':
genItem(d, n.sons[i], n.sons[i].sons[0],
genItem(d, n[i], n[i][0],
succ(skType, ord(n.kind)-ord(nkTypeSection)))
of nkStmtList:
for i in 0 ..< len(n): generateDoc(d, n.sons[i], orig)
for i in 0..<n.len: generateDoc(d, n[i], orig)
of nkWhenStmt:
# generate documentation for the first branch only:
if not checkForFalse(n.sons[0].sons[0]):
generateDoc(d, lastSon(n.sons[0]), orig)
if not checkForFalse(n[0][0]):
generateDoc(d, lastSon(n[0]), orig)
of nkImportStmt:
for it in n: traceDeps(d, it)
of nkExportStmt:
for it in n:
if it.kind == nkSym: exportSym(d, it.sym)
of nkExportExceptStmt: discard "transformed into nkExportStmt by semExportExcept"
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n[0])
of nkCallKinds:
var comm: Rope = nil
getAllRunnableExamples(d, n, comm)
if comm != nil: add(d.modDesc, comm)
if comm != nil: d.modDesc.add(comm)
else: discard
proc add(d: PDoc; j: JsonNode) =
@ -905,39 +904,39 @@ proc generateJson*(d: PDoc, n: PNode, includeComments: bool = true) =
if includeComments:
d.add %*{"comment": genComment(d, n)}
else:
add(d.modDesc, genComment(d, n))
d.modDesc.add(genComment(d, n))
of nkProcDef:
when useEffectSystem: documentRaises(d.cache, n)
d.add genJsonItem(d, n, n.sons[namePos], skProc)
d.add genJsonItem(d, n, n[namePos], skProc)
of nkFuncDef:
when useEffectSystem: documentRaises(d.cache, n)
d.add genJsonItem(d, n, n.sons[namePos], skFunc)
d.add genJsonItem(d, n, n[namePos], skFunc)
of nkMethodDef:
when useEffectSystem: documentRaises(d.cache, n)
d.add genJsonItem(d, n, n.sons[namePos], skMethod)
d.add genJsonItem(d, n, n[namePos], skMethod)
of nkIteratorDef:
when useEffectSystem: documentRaises(d.cache, n)
d.add genJsonItem(d, n, n.sons[namePos], skIterator)
d.add genJsonItem(d, n, n[namePos], skIterator)
of nkMacroDef:
d.add genJsonItem(d, n, n.sons[namePos], skMacro)
d.add genJsonItem(d, n, n[namePos], skMacro)
of nkTemplateDef:
d.add genJsonItem(d, n, n.sons[namePos], skTemplate)
d.add genJsonItem(d, n, n[namePos], skTemplate)
of nkConverterDef:
when useEffectSystem: documentRaises(d.cache, n)
d.add genJsonItem(d, n, n.sons[namePos], skConverter)
d.add genJsonItem(d, n, n[namePos], skConverter)
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
for i in 0 ..< len(n):
if n.sons[i].kind != nkCommentStmt:
for i in 0..<n.len:
if n[i].kind != nkCommentStmt:
# order is always 'type var let const':
d.add genJsonItem(d, n.sons[i], n.sons[i].sons[0],
d.add genJsonItem(d, n[i], n[i][0],
succ(skType, ord(n.kind)-ord(nkTypeSection)))
of nkStmtList:
for i in 0 ..< len(n):
generateJson(d, n.sons[i], includeComments)
for i in 0..<n.len:
generateJson(d, n[i], includeComments)
of nkWhenStmt:
# generate documentation for the first branch only:
if not checkForFalse(n.sons[0].sons[0]):
generateJson(d, lastSon(n.sons[0]), includeComments)
if not checkForFalse(n[0][0]):
generateJson(d, lastSon(n[0]), includeComments)
else: discard
proc genTagsItem(d: PDoc, n, nameNode: PNode, k: TSymKind): string =
@ -951,36 +950,36 @@ proc generateTags*(d: PDoc, n: PNode, r: var Rope) =
r.add stripped
of nkProcDef:
when useEffectSystem: documentRaises(d.cache, n)
r.add genTagsItem(d, n, n.sons[namePos], skProc)
r.add genTagsItem(d, n, n[namePos], skProc)
of nkFuncDef:
when useEffectSystem: documentRaises(d.cache, n)
r.add genTagsItem(d, n, n.sons[namePos], skFunc)
r.add genTagsItem(d, n, n[namePos], skFunc)
of nkMethodDef:
when useEffectSystem: documentRaises(d.cache, n)
r.add genTagsItem(d, n, n.sons[namePos], skMethod)
r.add genTagsItem(d, n, n[namePos], skMethod)
of nkIteratorDef:
when useEffectSystem: documentRaises(d.cache, n)
r.add genTagsItem(d, n, n.sons[namePos], skIterator)
r.add genTagsItem(d, n, n[namePos], skIterator)
of nkMacroDef:
r.add genTagsItem(d, n, n.sons[namePos], skMacro)
r.add genTagsItem(d, n, n[namePos], skMacro)
of nkTemplateDef:
r.add genTagsItem(d, n, n.sons[namePos], skTemplate)
r.add genTagsItem(d, n, n[namePos], skTemplate)
of nkConverterDef:
when useEffectSystem: documentRaises(d.cache, n)
r.add genTagsItem(d, n, n.sons[namePos], skConverter)
r.add genTagsItem(d, n, n[namePos], skConverter)
of nkTypeSection, nkVarSection, nkLetSection, nkConstSection:
for i in 0 ..< len(n):
if n.sons[i].kind != nkCommentStmt:
for i in 0..<n.len:
if n[i].kind != nkCommentStmt:
# order is always 'type var let const':
r.add genTagsItem(d, n.sons[i], n.sons[i].sons[0],
r.add genTagsItem(d, n[i], n[i][0],
succ(skType, ord(n.kind)-ord(nkTypeSection)))
of nkStmtList:
for i in 0 ..< len(n):
generateTags(d, n.sons[i], r)
for i in 0..<n.len:
generateTags(d, n[i], r)
of nkWhenStmt:
# generate documentation for the first branch only:
if not checkForFalse(n.sons[0].sons[0]):
generateTags(d, lastSon(n.sons[0]), r)
if not checkForFalse(n[0][0]):
generateTags(d, lastSon(n[0]), r)
else: discard
proc genSection(d: PDoc, kind: TSymKind) =
@ -1005,12 +1004,12 @@ proc genOutFile(d: PDoc): Rope =
var tmp = ""
renderTocEntries(d[], j, 1, tmp)
var toc = tmp.rope
for i in low(TSymKind) .. high(TSymKind):
for i in low(TSymKind)..high(TSymKind):
genSection(d, i)
add(toc, d.toc[i])
toc.add(d.toc[i])
if toc != nil:
toc = ropeFormatNamedVars(d.conf, getConfigVar(d.conf, "doc.toc"), ["content"], [toc])
for i in low(TSymKind) .. high(TSymKind): add(code, d.section[i])
for i in low(TSymKind)..high(TSymKind): code.add(d.section[i])
# Extract the title. Non API modules generate an entry in the index table.
if d.meta[metaTitle].len != 0:

View file

@ -13,7 +13,7 @@ proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph): PSym =
result.typ = newType(tyProc, t.owner)
result.typ.n = newNodeI(nkFormalParams, info)
rawAddSon(result.typ, res.typ)
addSon(result.typ.n, newNodeI(nkEffectList, info))
result.typ.n.add newNodeI(nkEffectList, info)
result.typ.addParam dest
@ -22,7 +22,7 @@ proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph): PSym =
caseStmt.add(newSymNode dest)
# copy the branches over, but replace the fields with the for loop body:
for i in 0 ..< t.n.len:
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)
var field = t.n[i].sym
let val = if field.ast == nil: field.name.s else: field.ast.strVal
@ -33,11 +33,11 @@ proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph): PSym =
body.add(caseStmt)
var n = newNodeI(nkProcDef, info, bodyPos+2)
for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info)
n.sons[namePos] = newSymNode(result)
n.sons[paramsPos] = result.typ.n
n.sons[bodyPos] = body
n.sons[resultPos] = newSymNode(res)
for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
n[namePos] = newSymNode(result)
n[paramsPos] = result.typ.n
n[bodyPos] = body
n[resultPos] = newSymNode(res)
result.ast = n
incl result.flags, sfFromGeneric
@ -67,7 +67,7 @@ proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGra
result.typ = newType(tyProc, t.owner)
result.typ.n = newNodeI(nkFormalParams, info)
rawAddSon(result.typ, res.typ)
addSon(result.typ.n, newNodeI(nkEffectList, info))
result.typ.n.add newNodeI(nkEffectList, info)
result.typ.addParam dest
@ -77,10 +77,10 @@ proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGra
let subObj = searchObjCase(t.n, field)
doAssert subObj != nil
for i in 1 ..< subObj.len:
for i in 1..<subObj.len:
let ofBranch = subObj[i]
var newBranch = newNodeI(ofBranch.kind, ofBranch.info)
for j in 0..ofBranch.len-2:
for j in 0..<ofBranch.len-1:
newBranch.add ofBranch[j]
newBranch.add newTree(nkStmtList, newTree(nkFastAsgn, newSymNode(res), newIntNode(nkInt8Lit, i)))
@ -89,10 +89,10 @@ proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGra
body.add(caseStmt)
var n = newNodeI(nkProcDef, info, bodyPos+2)
for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info)
n.sons[namePos] = newSymNode(result)
n.sons[paramsPos] = result.typ.n
n.sons[bodyPos] = body
n.sons[resultPos] = newSymNode(res)
for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
n[namePos] = newSymNode(result)
n[paramsPos] = result.typ.n
n[bodyPos] = body
n[resultPos] = newSymNode(res)
result.ast = n
incl result.flags, sfFromGeneric

View file

@ -94,7 +94,7 @@ proc mapType(conf: ConfigRef, t: ast.PType): ptr libffi.TType =
tyTyped, tyTypeDesc, tyProc, tyArray, tyStatic, tyNil:
result = addr libffi.type_pointer
of tyDistinct, tyAlias, tySink:
result = mapType(conf, t.sons[0])
result = mapType(conf, t[0])
else:
result = nil
# too risky:
@ -120,16 +120,16 @@ proc packSize(conf: ConfigRef, v: PNode, typ: PType): int =
if v.kind in {nkNilLit, nkPtrLit}:
result = sizeof(pointer)
else:
result = sizeof(pointer) + packSize(conf, v.sons[0], typ.lastSon)
result = sizeof(pointer) + packSize(conf, v[0], typ.lastSon)
of tyDistinct, tyGenericInst, tyAlias, tySink:
result = packSize(conf, v, typ.sons[0])
result = packSize(conf, v, typ[0])
of tyArray:
# consider: ptr array[0..1000_000, int] which is common for interfacing;
# we use the real length here instead
if v.kind in {nkNilLit, nkPtrLit}:
result = sizeof(pointer)
elif v.len != 0:
result = v.len * packSize(conf, v.sons[0], typ.sons[1])
result = v.len * packSize(conf, v[0], typ[1])
else:
result = getSize(conf, typ).int
@ -138,16 +138,16 @@ 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 ..< len(n):
result = getField(conf, n.sons[i], position)
for i in 0..<n.len:
result = getField(conf, n[i], position)
if result != nil: return
of nkRecCase:
result = getField(conf, n.sons[0], position)
result = getField(conf, n[0], position)
if result != nil: return
for i in 1 ..< len(n):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = getField(conf, lastSon(n.sons[i]), position)
result = getField(conf, lastSon(n[i]), position)
if result != nil: return
else: internalError(conf, n.info, "getField(record case branch)")
of nkSym:
@ -158,12 +158,12 @@ 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) ..< len(x):
var it = x.sons[i]
for i in ord(x.kind == nkObjConstr)..<x.len:
var it = x[i]
if it.kind == nkExprColonExpr:
internalAssert conf, it.sons[0].kind == nkSym
let field = it.sons[0].sym
pack(conf, it.sons[1], field.typ, res +! field.offset)
internalAssert conf, it[0].kind == nkSym
let field = it[0].sym
pack(conf, it[1], field.typ, res +! field.offset)
elif typ.n != nil:
let field = getField(conf, typ.n, i)
pack(conf, it, field.typ, res +! field.offset)
@ -224,19 +224,19 @@ proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer) =
packRecCheck = 0
globalError(conf, v.info, "cannot map value to FFI " & typeToString(v.typ))
inc packRecCheck
pack(conf, v.sons[0], typ.lastSon, res +! sizeof(pointer))
pack(conf, v[0], typ.lastSon, res +! sizeof(pointer))
dec packRecCheck
awr(pointer, res +! sizeof(pointer))
of tyArray:
let baseSize = getSize(conf, typ.sons[1])
for i in 0 ..< v.len:
pack(conf, v.sons[i], typ.sons[1], res +! i * baseSize)
let baseSize = getSize(conf, typ[1])
for i in 0..<v.len:
pack(conf, v[i], typ[1], res +! i * baseSize)
of tyObject, tyTuple:
packObject(conf, v, typ, res)
of tyNil:
discard
of tyDistinct, tyGenericInst, tyAlias, tySink:
pack(conf, v, typ.sons[0], res)
pack(conf, v, typ[0], res)
else:
globalError(conf, v.info, "cannot map value to FFI " & typeToString(v.typ))
@ -245,14 +245,14 @@ 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 ..< len(n):
unpackObjectAdd(conf, x, n.sons[i], result)
for i in 0..<n.len:
unpackObjectAdd(conf, x, n[i], result)
of nkRecCase:
globalError(conf, result.info, "case objects cannot be unpacked")
of nkSym:
var pair = newNodeI(nkExprColonExpr, result.info, 2)
pair.sons[0] = n
pair.sons[1] = unpack(conf, x +! n.sym.offset, n.sym.typ, nil)
pair[0] = n
pair[1] = unpack(conf, x +! n.sym.offset, n.sym.typ, nil)
#echo "offset: ", n.sym.name.s, " ", n.sym.offset
result.add pair
else: discard
@ -275,15 +275,15 @@ 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) ..< len(n):
var it = n.sons[i]
for i in ord(n.kind == nkObjConstr)..<n.len:
var it = n[i]
if it.kind == nkExprColonExpr:
internalAssert conf, it.sons[0].kind == nkSym
let field = it.sons[0].sym
it.sons[1] = unpack(conf, x +! field.offset, field.typ, it.sons[1])
internalAssert conf, it[0].kind == nkSym
let field = it[0].sym
it[1] = unpack(conf, x +! field.offset, field.typ, it[1])
else:
let field = getField(conf, typ.n, i)
n.sons[i] = unpack(conf, x +! field.offset, field.typ, it)
n[i] = unpack(conf, x +! field.offset, field.typ, it)
proc unpackArray(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode =
if n.isNil:
@ -294,9 +294,9 @@ proc unpackArray(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode =
result = n
if result.kind != nkBracket:
globalError(conf, n.info, "cannot map value from FFI")
let baseSize = getSize(conf, typ.sons[1])
for i in 0 ..< result.len:
result.sons[i] = unpack(conf, x +! i * baseSize, typ.sons[1], result.sons[i])
let baseSize = getSize(conf, typ[1])
for i in 0..<result.len:
result[i] = unpack(conf, x +! i * baseSize, typ[1], result[i])
proc canonNodeKind(k: TNodeKind): TNodeKind =
case k
@ -376,7 +376,7 @@ proc unpack(conf: ConfigRef, x: pointer, typ: PType, n: PNode): PNode =
awi(nkPtrLit, cast[ByteAddress](p))
elif n != nil and n.len == 1:
internalAssert(conf, n.kind == nkRefTy)
n.sons[0] = unpack(conf, p, typ.lastSon, n.sons[0])
n[0] = unpack(conf, p, typ.lastSon, n[0])
result = n
else:
globalError(conf, n.info, "cannot map value from FFI " & typeToString(typ))
@ -419,41 +419,41 @@ proc fficast*(conf: ConfigRef, x: PNode, destTyp: PType): PNode =
dealloc a
proc callForeignFunction*(conf: ConfigRef, call: PNode): PNode =
internalAssert conf, call.sons[0].kind == nkPtrLit
internalAssert conf, call[0].kind == nkPtrLit
var cif: TCif
var sig: TParamList
# use the arguments' types for varargs support:
for i in 1..call.len-1:
sig[i-1] = mapType(conf, call.sons[i].typ)
for i in 1..<call.len:
sig[i-1] = mapType(conf, call[i].typ)
if sig[i-1].isNil:
globalError(conf, call.info, "cannot map FFI type")
let typ = call.sons[0].typ
let typ = call[0].typ
if prep_cif(cif, mapCallConv(conf, typ.callConv, call.info), cuint(call.len-1),
mapType(conf, typ.sons[0]), sig) != OK:
mapType(conf, typ[0]), sig) != OK:
globalError(conf, call.info, "error in FFI call")
var args: TArgList
let fn = cast[pointer](call.sons[0].intVal)
for i in 1 .. call.len-1:
var t = call.sons[i].typ
args[i-1] = alloc0(packSize(conf, call.sons[i], t))
pack(conf, call.sons[i], t, args[i-1])
let retVal = if isEmptyType(typ.sons[0]): pointer(nil)
else: alloc(getSize(conf, typ.sons[0]).int)
let fn = cast[pointer](call[0].intVal)
for i in 1..<call.len:
var t = call[i].typ
args[i-1] = alloc0(packSize(conf, call[i], t))
pack(conf, call[i], t, args[i-1])
let retVal = if isEmptyType(typ[0]): pointer(nil)
else: alloc(getSize(conf, typ[0]).int)
libffi.call(cif, fn, retVal, args)
if retVal.isNil:
result = newNode(nkEmpty)
else:
result = unpack(conf, retVal, typ.sons[0], nil)
result = unpack(conf, retVal, typ[0], nil)
result.info = call.info
if retVal != nil: dealloc retVal
for i in 1 .. call.len-1:
call.sons[i] = unpack(conf, args[i-1], typ.sons[i], call[i])
for i in 1..<call.len:
call[i] = unpack(conf, args[i-1], typ[i], call[i])
dealloc args[i-1]
proc callForeignFunction*(conf: ConfigRef, fn: PNode, fntyp: PType,
@ -467,34 +467,34 @@ proc callForeignFunction*(conf: ConfigRef, fn: PNode, fntyp: PType,
var aTyp = args[i+start].typ
if aTyp.isNil:
internalAssert conf, i+1 < fntyp.len
aTyp = fntyp.sons[i+1]
aTyp = fntyp[i+1]
args[i+start].typ = aTyp
sig[i] = mapType(conf, aTyp)
if sig[i].isNil: globalError(conf, info, "cannot map FFI type")
if prep_cif(cif, mapCallConv(conf, fntyp.callConv, info), cuint(len),
mapType(conf, fntyp.sons[0]), sig) != OK:
mapType(conf, fntyp[0]), sig) != OK:
globalError(conf, info, "error in FFI call")
var cargs: TArgList
let fn = cast[pointer](fn.intVal)
for i in 0 .. len-1:
for i in 0..len-1:
let t = args[i+start].typ
cargs[i] = alloc0(packSize(conf, args[i+start], t))
pack(conf, args[i+start], t, cargs[i])
let retVal = if isEmptyType(fntyp.sons[0]): pointer(nil)
else: alloc(getSize(conf, fntyp.sons[0]).int)
let retVal = if isEmptyType(fntyp[0]): pointer(nil)
else: alloc(getSize(conf, fntyp[0]).int)
libffi.call(cif, fn, retVal, cargs)
if retVal.isNil:
result = newNode(nkEmpty)
else:
result = unpack(conf, retVal, fntyp.sons[0], nil)
result = unpack(conf, retVal, fntyp[0], nil)
result.info = info
if retVal != nil: dealloc retVal
for i in 0 .. len-1:
for i in 0..len-1:
let t = args[i+start].typ
args[i+start] = unpack(conf, cargs[i], t, args[i+start])
dealloc cargs[i]

View file

@ -39,10 +39,10 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
var s = templ.sym
if (s.owner == nil and s.kind == skParam) or s.owner == c.owner:
if s.kind == skParam and {sfGenSym, sfTemplateParam} * s.flags == {sfTemplateParam}:
handleParam actual.sons[s.position]
handleParam actual[s.position]
elif (s.owner != nil) and (s.kind == skGenericParam or
s.kind == skType and s.typ != nil and s.typ.kind == tyGenericParam):
handleParam actual.sons[s.owner.typ.len + s.position - 1]
handleParam actual[s.owner.typ.len + s.position - 1]
else:
internalAssert c.config, sfGenSym in s.flags or s.kind == skType
var x = PSym(idTableGet(c.mapping, s))
@ -68,8 +68,8 @@ 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 ..< len(templ):
evalTemplateAux(templ.sons[i], actual, c, res)
for i in 0..<templ.len:
evalTemplateAux(templ[i], actual, c, res)
result.add res
else:
result.add newNodeI(nkEmpty, templ.info)
@ -82,8 +82,8 @@ 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 ..< len(templ):
evalTemplateAux(templ.sons[i], actual, c, res)
for i in 0..<templ.len:
evalTemplateAux(templ[i], actual, c, res)
result.add res
if isDeclarative: c.isDeclarative = false
@ -122,22 +122,22 @@ proc evalTemplateArgs(n: PNode, s: PSym; conf: ConfigRef; fromHlo: bool): PNode
n.renderTree)
result = newNodeI(nkArgList, n.info)
for i in 1 .. givenRegularParams:
result.addSon n[i]
for i in 1..givenRegularParams:
result.add n[i]
# handle parameters with default values, which were
# not supplied by the user
for i in givenRegularParams+1 .. expectedRegularParams:
let default = s.typ.n.sons[i].sym.ast
for i in givenRegularParams+1..expectedRegularParams:
let default = s.typ.n[i].sym.ast
if default.isNil or default.kind == nkEmpty:
localError(conf, n.info, errWrongNumberOfArguments)
addSon(result, newNodeI(nkEmpty, n.info))
result.add newNodeI(nkEmpty, n.info)
else:
addSon(result, default.copyTree)
result.add default.copyTree
# add any generic parameters
for i in 1 .. genericParams:
result.addSon n.sons[givenRegularParams + i]
for i in 1..genericParams:
result.add n[givenRegularParams + i]
# to prevent endless recursion in template instantiation
const evalTemplateLimit* = 1000
@ -155,7 +155,7 @@ proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
if x.kind in nkCallKinds:
for i in 1..<x.len:
if x[i].kind in nkCallKinds:
x.sons[i].info = info
x[i].info = info
else:
result = newNodeI(nkStmtListExpr, info)
var d = newNodeI(nkComesFrom, info)
@ -187,7 +187,7 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
if isAtom(body):
result = newNodeI(nkPar, body.info)
evalTemplateAux(body, args, ctx, result)
if result.len == 1: result = result.sons[0]
if result.len == 1: result = result[0]
else:
localError(conf, result.info, "illformed AST: " &
renderTree(result, {renderNoComments}))
@ -196,8 +196,8 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
ctx.instLines = sfCallsite in tmpl.flags
if ctx.instLines:
result.info = n.info
for i in 0 ..< safeLen(body):
evalTemplateAux(body.sons[i], args, ctx, result)
for i in 0..<body.safeLen:
evalTemplateAux(body[i], args, ctx, result)
result.flags.incl nfFromTemplate
result = wrapInComesFrom(n.info, tmpl, result)
#if ctx.debugActive:

View file

@ -384,13 +384,13 @@ proc libNameTmpl(conf: ConfigRef): string {.inline.} =
proc nameToCC*(name: string): TSystemCC =
## Returns the kind of compiler referred to by `name`, or ccNone
## if the name doesn't refer to any known compiler.
for i in succ(ccNone) .. high(TSystemCC):
for i in succ(ccNone)..high(TSystemCC):
if cmpIgnoreStyle(name, CC[i].name) == 0:
return i
result = ccNone
proc listCCnames(): seq[string] =
for i in succ(ccNone) .. high(TSystemCC):
for i in succ(ccNone)..high(TSystemCC):
result.add CC[i].name
proc isVSCompatible*(conf: ConfigRef): bool =
@ -431,12 +431,12 @@ proc setCC*(conf: ConfigRef; ccname: string; info: TLineInfo) =
conf.compileOptions = getConfigVar(conf, conf.cCompiler, ".options.always")
conf.linkOptions = ""
conf.cCompilerPath = getConfigVar(conf, conf.cCompiler, ".path")
for i in low(CC) .. high(CC): undefSymbol(conf.symbols, CC[i].name)
for i in low(CC)..high(CC): undefSymbol(conf.symbols, CC[i].name)
defineSymbol(conf.symbols, CC[conf.cCompiler].name)
proc addOpt(dest: var string, src: string) =
if len(dest) == 0 or dest[len(dest)-1] != ' ': add(dest, " ")
add(dest, src)
if dest.len == 0 or dest[^1] != ' ': dest.add(" ")
dest.add(src)
proc addLinkOption*(conf: ConfigRef; option: string) =
addOpt(conf.linkOptions, option)
@ -453,11 +453,11 @@ proc addCompileOptionCmd*(conf: ConfigRef; option: string) =
proc initVars*(conf: ConfigRef) =
# we need to define the symbol here, because ``CC`` may have never been set!
for i in low(CC) .. high(CC): undefSymbol(conf.symbols, CC[i].name)
for i in low(CC)..high(CC): undefSymbol(conf.symbols, CC[i].name)
defineSymbol(conf.symbols, CC[conf.cCompiler].name)
addCompileOption(conf, getConfigVar(conf, conf.cCompiler, ".options.always"))
#addLinkOption(getConfigVar(cCompiler, ".options.linker"))
if len(conf.cCompilerPath) == 0:
if conf.cCompilerPath.len == 0:
conf.cCompilerPath = getConfigVar(conf, conf.cCompiler, ".path")
proc completeCfilePath*(conf: ConfigRef; cfile: AbsoluteFile,
@ -607,7 +607,7 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
if needsExeExt(conf): exe = addFileExt(exe, "exe")
if (optGenDynLib in conf.globalOptions or (conf.hcrOn and not isMainFile)) and
ospNeedsPIC in platform.OS[conf.target.targetOS].props:
add(options, ' ' & CC[c].pic)
options.add(' ' & CC[c].pic)
var includeCmd, compilePattern: string
if not noAbsolutePaths(conf):
@ -660,8 +660,8 @@ proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
rawMessage(conf, hintUserRaw, "Couldn't produce assembler listing " &
"for the selected C compiler: " & CC[conf.cCompiler].name)
add(result, ' ')
addf(result, CC[c].compileTmpl, [
result.add(' ')
result.addf(CC[c].compileTmpl, [
"dfile", dfile,
"file", cfsh, "objfile", quoteShell(objfile),
"options", options, "include", includeCmd,
@ -720,12 +720,12 @@ proc compileCFiles(conf: ConfigRef; list: CfileList, script: var Rope, cmds: var
var compileCmd = getCompileCFileCmd(conf, it, currIdx == list.len - 1, produceOutput=true)
inc currIdx
if optCompileOnly notin conf.globalOptions:
add(cmds, compileCmd)
cmds.add(compileCmd)
let (_, name, _) = splitFile(it.cname)
add(prettyCmds, if hintCC in conf.notes: "CC: " & demanglePackageName(name) else: "")
prettyCmds.add(if hintCC in conf.notes: "CC: " & demanglePackageName(name) else: "")
if optGenScript in conf.globalOptions:
add(script, compileCmd)
add(script, "\n")
script.add(compileCmd)
script.add("\n")
proc getLinkCmd(conf: ConfigRef; output: AbsoluteFile,
objfiles: string, isDllBuild: bool): string =
@ -741,7 +741,7 @@ proc getLinkCmd(conf: ConfigRef; output: AbsoluteFile,
"objfiles", objfiles]
else:
var linkerExe = getConfigVar(conf, conf.cCompiler, ".linkerexe")
if len(linkerExe) == 0: linkerExe = getLinkerExe(conf, conf.cCompiler)
if linkerExe.len == 0: linkerExe = getLinkerExe(conf, conf.cCompiler)
# bug #6452: We must not use ``quoteShell`` here for ``linkerExe``
if needsExeExt(conf): linkerExe = addFileExt(linkerExe, "exe")
if noAbsolutePaths(conf): result = linkerExe
@ -771,7 +771,7 @@ proc getLinkCmd(conf: ConfigRef; output: AbsoluteFile,
"buildgui", buildgui, "options", linkOptions, "objfiles", objfiles,
"exefile", exefile, "nim", getPrefixDir(conf).string, "lib", conf.libpath.string])
result.add ' '
addf(result, linkTmpl, ["builddll", builddll,
result.addf(linkTmpl, ["builddll", builddll,
"mapfile", mapfile,
"buildgui", buildgui, "options", linkOptions,
"objfiles", objfiles, "exefile", exefile,
@ -849,7 +849,7 @@ proc execCmdsInParallel(conf: ConfigRef; cmds: seq[string]; prettyCb: proc (idx:
if conf.numberOfProcessors == 0: conf.numberOfProcessors = countProcessors()
var res = 0
if conf.numberOfProcessors <= 1:
for i in 0 .. high(cmds):
for i in 0..high(cmds):
tryExceptOSErrorMessage(conf, "invocation of external compiler program failed."):
res = execWithEcho(conf, cmds[i])
if res != 0:
@ -929,8 +929,8 @@ proc callCCompiler*(conf: ConfigRef) =
var objfiles = ""
for it in conf.externalToLink:
let objFile = if noAbsolutePaths(conf): it.extractFilename else: it
add(objfiles, ' ')
add(objfiles, quoteShell(
objfiles.add(' ')
objfiles.add(quoteShell(
addFileExt(objFile, CC[conf.cCompiler].objExt)))
if conf.hcrOn: # lets assume that optCompileOnly isn't on
@ -947,7 +947,7 @@ proc callCCompiler*(conf: ConfigRef) =
let objFile = conf.getObjFilePath(x)
let buildDll = idx != mainFileIdx
let linkTarget = conf.hcrLinkTargetName(objFile, not buildDll)
add(cmds, getLinkCmd(conf, linkTarget, objfiles & " " & quoteShell(objFile), buildDll))
cmds.add(getLinkCmd(conf, linkTarget, objfiles & " " & quoteShell(objFile), buildDll))
# try to remove all .pdb files for the current binary so they don't accumulate endlessly in the nimcache
# for more info check the comment inside of getLinkCmd() where the /PDB:<filename> MSVC flag is used
if isVSCompatible(conf):
@ -966,8 +966,8 @@ proc callCCompiler*(conf: ConfigRef) =
else:
for x in conf.toCompile:
let objFile = if noAbsolutePaths(conf): x.obj.extractFilename else: x.obj.string
add(objfiles, ' ')
add(objfiles, quoteShell(objFile))
objfiles.add(' ')
objfiles.add(quoteShell(objFile))
let mainOutput = if optGenScript notin conf.globalOptions: conf.prepareToWriteOutput
else: AbsoluteFile(conf.projectName)
linkCmd = getLinkCmd(conf, mainOutput, objfiles)
@ -983,8 +983,8 @@ proc callCCompiler*(conf: ConfigRef) =
else:
linkCmd = ""
if optGenScript in conf.globalOptions:
add(script, linkCmd)
add(script, "\n")
script.add(linkCmd)
script.add("\n")
generateScript(conf, script)
#from json import escapeJson
@ -1022,16 +1022,16 @@ proc writeJsonBuildInstructions*(conf: ConfigRef) =
let objfile = if noAbsolutePaths(conf): it.extractFilename
else: it
let objstr = addFileExt(objfile, CC[conf.cCompiler].objExt)
add(objfiles, ' ')
add(objfiles, objstr)
objfiles.add(' ')
objfiles.add(objstr)
if pastStart: lit ",\L"
str objstr
pastStart = true
for it in clist:
let objstr = quoteShell(it.obj)
add(objfiles, ' ')
add(objfiles, objstr)
objfiles.add(' ')
objfiles.add(objstr)
if pastStart: lit ",\L"
str objstr
pastStart = true
@ -1120,9 +1120,9 @@ proc runJsonBuildInstructions*(conf: ConfigRef; projectfile: AbsoluteFile) =
doAssert c.kind == JArray
doAssert c.len >= 2
add(cmds, c[1].getStr)
cmds.add(c[1].getStr)
let (_, name, _) = splitFile(c[0].getStr)
add(prettyCmds, "CC: " & demanglePackageName(name))
prettyCmds.add("CC: " & demanglePackageName(name))
let prettyCb = proc (idx: int) =
when declared(echo):
@ -1139,23 +1139,23 @@ proc runJsonBuildInstructions*(conf: ConfigRef; projectfile: AbsoluteFile) =
proc genMappingFiles(conf: ConfigRef; list: CfileList): Rope =
for it in list:
addf(result, "--file:r\"$1\"$N", [rope(it.cname.string)])
result.addf("--file:r\"$1\"$N", [rope(it.cname.string)])
proc writeMapping*(conf: ConfigRef; symbolMapping: Rope) =
if optGenMapping notin conf.globalOptions: return
var code = rope("[C_Files]\n")
add(code, genMappingFiles(conf, conf.toCompile))
add(code, "\n[C_Compiler]\nFlags=")
add(code, strutils.escape(getCompileOptions(conf)))
code.add(genMappingFiles(conf, conf.toCompile))
code.add("\n[C_Compiler]\nFlags=")
code.add(strutils.escape(getCompileOptions(conf)))
add(code, "\n[Linker]\nFlags=")
add(code, strutils.escape(getLinkOptions(conf) & " " &
code.add("\n[Linker]\nFlags=")
code.add(strutils.escape(getLinkOptions(conf) & " " &
getConfigVar(conf, conf.cCompiler, ".options.linker")))
add(code, "\n[Environment]\nlibpath=")
add(code, strutils.escape(conf.libpath.string))
code.add("\n[Environment]\nlibpath=")
code.add(strutils.escape(conf.libpath.string))
addf(code, "\n[Symbols]$n$1", [symbolMapping])
code.addf("\n[Symbols]$n$1", [symbolMapping])
let filename = conf.projectPath / RelativeFile"mapping.txt"
if not writeRope(code, filename):
rawMessage(conf, errGenerated, "could not write to file: " & filename.string)

View file

@ -75,7 +75,7 @@ proc parseLine(p: var TTmplParser) =
let d = j
var keyw = ""
while j < len and p.x[j] in PatternChars:
add(keyw, p.x[j])
keyw.add(p.x[j])
inc(j)
scanPar(p, j)

View file

@ -20,13 +20,13 @@ 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 ..< 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:
return n.sons[i].sons[1]
for i in 1..<n.len:
if n[i].kind == nkExprEqExpr:
if n[i][0].kind != nkIdent: invalidPragma(conf, n)
if cmpIgnoreStyle(n[i][0].ident.s, name) == 0:
return n[i][1]
elif i == pos:
return n.sons[i]
return n[i]
proc charArg*(conf: ConfigRef; n: PNode, name: string, pos: int, default: char): char =
var x = getArg(conf, n, name, pos)
@ -55,7 +55,7 @@ proc filterStrip*(conf: ConfigRef; stdin: PLLStream, filename: AbsoluteFile, cal
var line = newStringOfCap(80)
while llStreamReadLine(stdin, line):
var stripped = strip(line, leading, trailing)
if len(pattern) == 0 or startsWith(stripped, pattern):
if pattern.len == 0 or startsWith(stripped, pattern):
llStreamWriteln(result, stripped)
else:
llStreamWriteln(result, line)
@ -63,7 +63,7 @@ proc filterStrip*(conf: ConfigRef; stdin: PLLStream, filename: AbsoluteFile, cal
proc filterReplace*(conf: ConfigRef; stdin: PLLStream, filename: AbsoluteFile, call: PNode): PLLStream =
var sub = strArg(conf, call, "sub", 1, "")
if len(sub) == 0: invalidPragma(conf, call)
if sub.len == 0: invalidPragma(conf, call)
var by = strArg(conf, call, "by", 2, "")
result = llStreamOpen("")
var line = newStringOfCap(80)

View file

@ -45,13 +45,13 @@ proc counterInTree(n, loop: PNode; counter: PSym): bool =
for it in n:
if counterInTree(it.lastSon): return true
else:
for i in 0 ..< safeLen(n):
for i in 0..<n.safeLen:
if counterInTree(n[i], loop, counter): return true
proc copyExcept(n: PNode, x, dest: PNode) =
if x == n: return
if n.kind in {nkStmtList, nkStmtListExpr}:
for i in 0 ..< n.len: copyExcept(n[i], x, dest)
for i in 0..<n.len: copyExcept(n[i], x, dest)
else:
dest.add n

View file

@ -65,16 +65,16 @@ proc isLetLocation(m: PNode, isApprox: bool): bool =
while true:
case n.kind
of nkDotExpr, nkCheckedFieldExpr, nkObjUpConv, nkObjDownConv:
n = n.sons[0]
n = n[0]
of nkDerefExpr, nkHiddenDeref:
n = n.sons[0]
n = n[0]
inc derefs
of nkBracketExpr:
if isConstExpr(n.sons[1]) or isLet(n.sons[1]) or isConstExpr(n.sons[1].skipConv):
n = n.sons[0]
if isConstExpr(n[1]) or isLet(n[1]) or isConstExpr(n[1].skipConv):
n = n[0]
else: return
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
n = n.sons[1]
n = n[1]
else:
break
result = n.isLet and derefs <= ord(isApprox)
@ -105,34 +105,34 @@ proc initOperators*(g: ModuleGraph): Operators =
proc swapArgs(fact: PNode, newOp: PSym): PNode =
result = newNodeI(nkCall, fact.info, 3)
result.sons[0] = newSymNode(newOp)
result.sons[1] = fact.sons[2]
result.sons[2] = fact.sons[1]
result[0] = newSymNode(newOp)
result[1] = fact[2]
result[2] = fact[1]
proc neg(n: PNode; o: Operators): PNode =
if n == nil: return nil
case n.getMagic
of mNot:
result = n.sons[1]
result = n[1]
of someLt:
# not (a < b) == a >= b == b <= a
result = swapArgs(n, o.opLe)
of someLe:
result = swapArgs(n, o.opLt)
of mInSet:
if n.sons[1].kind != nkCurly: return nil
let t = n.sons[2].typ.skipTypes(abstractInst)
if n[1].kind != nkCurly: return nil
let t = n[2].typ.skipTypes(abstractInst)
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = n.sons[0]
result.sons[2] = n.sons[2]
result[0] = n[0]
result[2] = n[2]
if t.kind == tyEnum:
var s = newNodeIT(nkCurly, n.info, n.sons[1].typ)
var s = newNodeIT(nkCurly, n.info, n[1].typ)
for e in t.n:
let eAsNode = newIntNode(nkIntLit, e.sym.position)
if not inSet(n.sons[1], eAsNode): s.add eAsNode
result.sons[1] = s
if not inSet(n[1], eAsNode): s.add eAsNode
result[1] = s
#elif t.kind notin {tyString, tySequence} and lengthOrd(t) < 1000:
# result.sons[1] = complement(n.sons[1])
# result[1] = complement(n[1])
else:
# not ({2, 3, 4}.contains(x)) x != 2 and x != 3 and x != 4
# XXX todo
@ -140,13 +140,13 @@ proc neg(n: PNode; o: Operators): PNode =
of mOr:
# not (a or b) --> not a and not b
let
a = n.sons[1].neg(o)
b = n.sons[2].neg(o)
a = n[1].neg(o)
b = n[2].neg(o)
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opAnd)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(o.opAnd)
result[1] = a
result[2] = b
elif a != nil:
result = a
elif b != nil:
@ -154,19 +154,19 @@ proc neg(n: PNode; o: Operators): PNode =
else:
# leave not (a == 4) as it is
result = newNodeI(nkCall, n.info, 2)
result.sons[0] = newSymNode(o.opNot)
result.sons[1] = n
result[0] = newSymNode(o.opNot)
result[1] = n
proc buildCall(op: PSym; a: PNode): PNode =
result = newNodeI(nkCall, a.info, 2)
result.sons[0] = newSymNode(op)
result.sons[1] = a
result[0] = newSymNode(op)
result[1] = a
proc buildCall(op: PSym; a, b: PNode): PNode =
result = newNodeI(nkInfix, a.info, 3)
result.sons[0] = newSymNode(op)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(op)
result[1] = a
result[2] = b
proc `|+|`(a, b: PNode): PNode =
result = copyNode(a)
@ -254,8 +254,8 @@ proc canon*(n: PNode; o: Operators): PNode =
# XXX for now only the new code in 'semparallel' uses this
if n.safeLen >= 1:
result = shallowCopy(n)
for i in 0 ..< n.len:
result.sons[i] = canon(n.sons[i], o)
for i in 0..<n.len:
result[i] = canon(n[i], o)
elif n.kind == nkSym and n.sym.kind == skLet and
n.sym.astdef.getMagic in (someEq + someAdd + someMul + someMin +
someMax + someHigh + {mUnaryLt} + someSub + someLen + someDiv):
@ -265,8 +265,8 @@ proc canon*(n: PNode; o: Operators): PNode =
case result.getMagic
of someEq, someAdd, someMul, someMin, someMax:
# these are symmetric; put value as last:
if result.sons[1].isValue and not result.sons[2].isValue:
result = swapArgs(result, result.sons[0].sym)
if result[1].isValue and not result[2].isValue:
result = swapArgs(result, result[0].sym)
# (4 + foo) + 2 --> (foo + 4) + 2
of someHigh:
# high == len+(-1)
@ -277,7 +277,7 @@ proc canon*(n: PNode; o: Operators): PNode =
# x - 4 --> x + (-4)
result = negate(result[1], result[2], result, o)
of someLen:
result.sons[0] = o.opLen.newSymNode
result[0] = o.opLen.newSymNode
of someLt:
# x < y same as x <= y-1:
let y = n[2].canon(o)
@ -321,13 +321,13 @@ proc canon*(n: PNode; o: Operators): PNode =
elif x.isValue and y.getMagic in someAdd and y[2].isValue:
# 0 <= a.len + 3
# -3 <= a.len
result.sons[1] = x |-| y[2]
result.sons[2] = y[1]
result[1] = x |-| y[2]
result[2] = y[1]
elif x.isValue and y.getMagic in someSub and y[2].isValue:
# 0 <= a.len - 3
# 3 <= a.len
result.sons[1] = x |+| y[2]
result.sons[2] = y[1]
result[1] = x |+| y[2]
result[2] = y[1]
else: discard
proc buildAdd*(a: PNode; b: BiggestInt; o: Operators): PNode =
@ -336,41 +336,41 @@ proc buildAdd*(a: PNode; b: BiggestInt; o: Operators): PNode =
proc usefulFact(n: PNode; o: Operators): PNode =
case n.getMagic
of someEq:
if skipConv(n.sons[2]).kind == nkNilLit and (
isLetLocation(n.sons[1], false) or isVar(n.sons[1])):
result = o.opIsNil.buildCall(n.sons[1])
if skipConv(n[2]).kind == nkNilLit and (
isLetLocation(n[1], false) or isVar(n[1])):
result = o.opIsNil.buildCall(n[1])
else:
if isLetLocation(n.sons[1], true) or isLetLocation(n.sons[2], true):
if isLetLocation(n[1], true) or isLetLocation(n[2], true):
# XXX algebraic simplifications! 'i-1 < a.len' --> 'i < a.len+1'
result = n
of someLe+someLt:
if isLetLocation(n.sons[1], true) or isLetLocation(n.sons[2], true):
if isLetLocation(n[1], true) or isLetLocation(n[2], true):
# XXX algebraic simplifications! 'i-1 < a.len' --> 'i < a.len+1'
result = n
elif n[1].getMagic in someLen or n[2].getMagic in someLen:
# XXX Rethink this whole idea of 'usefulFact' for semparallel
result = n
of mIsNil:
if isLetLocation(n.sons[1], false) or isVar(n.sons[1]):
if isLetLocation(n[1], false) or isVar(n[1]):
result = n
of someIn:
if isLetLocation(n.sons[1], true):
if isLetLocation(n[1], true):
result = n
of mAnd:
let
a = usefulFact(n.sons[1], o)
b = usefulFact(n.sons[2], o)
a = usefulFact(n[1], o)
b = usefulFact(n[2], o)
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opAnd)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(o.opAnd)
result[1] = a
result[2] = b
elif a != nil:
result = a
elif b != nil:
result = b
of mNot:
let a = usefulFact(n.sons[1], o)
let a = usefulFact(n[1], o)
if a != nil:
result = a.neg(o)
of mOr:
@ -381,13 +381,13 @@ proc usefulFact(n: PNode; o: Operators): PNode =
# (x == 3) or (y == 2) ---> not ( not (x==3) and not (y == 2))
# not (x != 3 and y != 2)
let
a = usefulFact(n.sons[1], o).neg(o)
b = usefulFact(n.sons[2], o).neg(o)
a = usefulFact(n[1], o).neg(o)
b = usefulFact(n[2], o).neg(o)
if a != nil and b != nil:
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opAnd)
result.sons[1] = a
result.sons[2] = b
result[0] = newSymNode(o.opAnd)
result[1] = a
result[2] = b
result = result.neg(o)
elif n.kind == nkSym and n.sym.kind == skLet:
# consider:
@ -442,16 +442,16 @@ proc sameTree*(a, b: PNode): bool =
of nkType: result = a.typ == b.typ
of nkEmpty, nkNilLit: result = true
else:
if len(a) == len(b):
for i in 0 ..< len(a):
if not sameTree(a.sons[i], b.sons[i]): return
if a.len == b.len:
for i in 0..<a.len:
if not sameTree(a[i], b[i]): return
result = true
proc hasSubTree(n, x: PNode): bool =
if n.sameTree(x): result = true
else:
for i in 0..safeLen(n)-1:
if hasSubTree(n.sons[i], x): return true
for i in 0..n.safeLen-1:
if hasSubTree(n[i], x): return true
proc invalidateFacts*(m: var TModel, n: PNode) =
# We are able to guard local vars (as opposed to 'let' variables)!
@ -479,21 +479,21 @@ proc valuesUnequal(a, b: PNode): bool =
result = not sameValue(a, b)
proc impliesEq(fact, eq: PNode): TImplication =
let (loc, val) = if isLocation(eq.sons[1]): (1, 2) else: (2, 1)
let (loc, val) = if isLocation(eq[1]): (1, 2) else: (2, 1)
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], eq.sons[loc]):
if sameTree(fact[1], eq[loc]):
# this is not correct; consider: a == b; a == 1 --> unknown!
if sameTree(fact.sons[2], eq.sons[val]): result = impYes
elif valuesUnequal(fact.sons[2], eq.sons[val]): result = impNo
elif sameTree(fact.sons[2], eq.sons[loc]):
if sameTree(fact.sons[1], eq.sons[val]): result = impYes
elif valuesUnequal(fact.sons[1], eq.sons[val]): result = impNo
if sameTree(fact[2], eq[val]): result = impYes
elif valuesUnequal(fact[2], eq[val]): result = impNo
elif sameTree(fact[2], eq[loc]):
if sameTree(fact[1], eq[val]): result = impYes
elif valuesUnequal(fact[1], eq[val]): result = impNo
of mInSet:
# remember: mInSet is 'contains' so the set comes first!
if sameTree(fact.sons[2], eq.sons[loc]) and isValue(eq.sons[val]):
if inSet(fact.sons[1], eq.sons[val]): result = impYes
if sameTree(fact[2], eq[loc]) and isValue(eq[val]):
if inSet(fact[1], eq[val]): result = impYes
else: result = impNo
of mNot, mOr, mAnd: assert(false, "impliesEq")
else: discard
@ -536,28 +536,28 @@ proc compareSets(a, b: PNode): TImplication =
elif intersectSets(nil, a, b).len == 0: result = impNo
proc impliesIn(fact, loc, aSet: PNode): TImplication =
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], loc):
if inSet(aSet, fact.sons[2]): result = impYes
if sameTree(fact[1], loc):
if inSet(aSet, fact[2]): result = impYes
else: result = impNo
elif sameTree(fact.sons[2], loc):
if inSet(aSet, fact.sons[1]): result = impYes
elif sameTree(fact[2], loc):
if inSet(aSet, fact[1]): result = impYes
else: result = impNo
of mInSet:
if sameTree(fact.sons[2], loc):
result = compareSets(fact.sons[1], aSet)
if sameTree(fact[2], loc):
result = compareSets(fact[1], aSet)
of someLe:
if sameTree(fact.sons[1], loc):
result = leImpliesIn(fact.sons[1], fact.sons[2], aSet)
elif sameTree(fact.sons[2], loc):
result = geImpliesIn(fact.sons[2], fact.sons[1], aSet)
if sameTree(fact[1], loc):
result = leImpliesIn(fact[1], fact[2], aSet)
elif sameTree(fact[2], loc):
result = geImpliesIn(fact[2], fact[1], aSet)
of someLt:
if sameTree(fact.sons[1], loc):
result = leImpliesIn(fact.sons[1], fact.sons[2].pred, aSet)
elif sameTree(fact.sons[2], loc):
if sameTree(fact[1], loc):
result = leImpliesIn(fact[1], fact[2].pred, aSet)
elif sameTree(fact[2], loc):
# 4 < x --> 3 <= x
result = geImpliesIn(fact.sons[2], fact.sons[1].pred, aSet)
result = geImpliesIn(fact[2], fact[1].pred, aSet)
of mNot, mOr, mAnd: assert(false, "impliesIn")
else: discard
@ -567,90 +567,90 @@ proc valueIsNil(n: PNode): TImplication =
else: impUnknown
proc impliesIsNil(fact, eq: PNode): TImplication =
case fact.sons[0].sym.magic
case fact[0].sym.magic
of mIsNil:
if sameTree(fact.sons[1], eq.sons[1]):
if sameTree(fact[1], eq[1]):
result = impYes
of someEq:
if sameTree(fact.sons[1], eq.sons[1]):
result = valueIsNil(fact.sons[2].skipConv)
elif sameTree(fact.sons[2], eq.sons[1]):
result = valueIsNil(fact.sons[1].skipConv)
if sameTree(fact[1], eq[1]):
result = valueIsNil(fact[2].skipConv)
elif sameTree(fact[2], eq[1]):
result = valueIsNil(fact[1].skipConv)
of mNot, mOr, mAnd: assert(false, "impliesIsNil")
else: discard
proc impliesGe(fact, x, c: PNode): TImplication =
assert isLocation(x)
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x = 4; question x >= 56? --> true iff 4 >= 56
if leValue(c, fact.sons[2]): result = impYes
if leValue(c, fact[2]): result = impYes
else: result = impNo
elif sameTree(fact.sons[2], x):
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1]): result = impYes
elif sameTree(fact[2], x):
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1]): result = impYes
else: result = impNo
of someLt:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x < 4; question N <= x? --> false iff N <= 4
if leValue(fact.sons[2], c): result = impNo
if leValue(fact[2], c): result = impNo
# fact: x < 4; question 2 <= x? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 < x; question: N-1 < x ? --> true iff N-1 <= 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c.pred, fact.sons[1]): result = impYes
if isValue(fact[1]) and isValue(c):
if leValue(c.pred, fact[1]): result = impYes
of someLe:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x <= 4; question x >= 56? --> false iff 4 <= 56
if leValue(fact.sons[2], c): result = impNo
if leValue(fact[2], c): result = impNo
# fact: x <= 4; question x >= 2? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 <= x; question: x >= 2 ? --> true iff 2 <= 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1]): result = impYes
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1]): result = impYes
of mNot, mOr, mAnd: assert(false, "impliesGe")
else: discard
proc impliesLe(fact, x, c: PNode): TImplication =
if not isLocation(x):
return impliesGe(fact, c, x)
case fact.sons[0].sym.magic
case fact[0].sym.magic
of someEq:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x = 4; question x <= 56? --> true iff 4 <= 56
if leValue(fact.sons[2], c): result = impYes
if leValue(fact[2], c): result = impYes
else: result = impNo
elif sameTree(fact.sons[2], x):
if isValue(fact.sons[1]) and isValue(c):
if leValue(fact.sons[1], c): result = impYes
elif sameTree(fact[2], x):
if isValue(fact[1]) and isValue(c):
if leValue(fact[1], c): result = impYes
else: result = impNo
of someLt:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x < 4; question x <= N? --> true iff N-1 <= 4
if leValue(fact.sons[2], c.pred): result = impYes
if leValue(fact[2], c.pred): result = impYes
# fact: x < 4; question x <= 2? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 < x; question: x <= 1 ? --> false iff 1 <= 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1]): result = impNo
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1]): result = impNo
of someLe:
if sameTree(fact.sons[1], x):
if isValue(fact.sons[2]) and isValue(c):
if sameTree(fact[1], x):
if isValue(fact[2]) and isValue(c):
# fact: x <= 4; question x <= 56? --> true iff 4 <= 56
if leValue(fact.sons[2], c): result = impYes
if leValue(fact[2], c): result = impYes
# fact: x <= 4; question x <= 2? --> we don't know
elif sameTree(fact.sons[2], x):
elif sameTree(fact[2], x):
# fact: 3 <= x; question: x <= 2 ? --> false iff 2 < 3
if isValue(fact.sons[1]) and isValue(c):
if leValue(c, fact.sons[1].pred): result = impNo
if isValue(fact[1]) and isValue(c):
if leValue(c, fact[1].pred): result = impNo
of mNot, mOr, mAnd: assert(false, "impliesLe")
else: discard
@ -686,32 +686,32 @@ proc factImplies(fact, prop: PNode): TImplication =
# (not a) -> b compute as not (a -> b) ???
# == not a or not b == not (a and b)
let arg = fact.sons[1]
let arg = fact[1]
case arg.getMagic
of mIsNil, mEqRef:
return ~factImplies(arg, prop)
of mAnd:
# not (a and b) means not a or not b:
# a or b --> both need to imply 'prop'
let a = factImplies(arg.sons[1], prop)
let b = factImplies(arg.sons[2], prop)
let a = factImplies(arg[1], prop)
let b = factImplies(arg[2], prop)
if a == b: return ~a
return impUnknown
else:
return impUnknown
of mAnd:
result = factImplies(fact.sons[1], prop)
result = factImplies(fact[1], prop)
if result != impUnknown: return result
return factImplies(fact.sons[2], prop)
return factImplies(fact[2], prop)
else: discard
case prop.sons[0].sym.magic
of mNot: result = ~fact.factImplies(prop.sons[1])
case prop[0].sym.magic
of mNot: result = ~fact.factImplies(prop[1])
of mIsNil: result = impliesIsNil(fact, prop)
of someEq: result = impliesEq(fact, prop)
of someLe: result = impliesLe(fact, prop.sons[1], prop.sons[2])
of someLt: result = impliesLt(fact, prop.sons[1], prop.sons[2])
of mInSet: result = impliesIn(fact, prop.sons[2], prop.sons[1])
of someLe: result = impliesLe(fact, prop[1], prop[2])
of someLt: result = impliesLt(fact, prop[1], prop[2])
of mInSet: result = impliesIn(fact, prop[2], prop[1])
else: result = impUnknown
proc doesImply*(facts: TModel, prop: PNode): TImplication =
@ -881,8 +881,8 @@ proc replaceSubTree(n, x, by: PNode): PNode =
result = by
elif hasSubTree(n, x):
result = shallowCopy(n)
for i in 0 .. safeLen(n)-1:
result.sons[i] = replaceSubTree(n.sons[i], x, by)
for i in 0..n.safeLen-1:
result[i] = replaceSubTree(n[i], x, by)
else:
result = n
@ -971,37 +971,37 @@ proc settype(n: PNode): PType =
proc buildOf(it, loc: PNode; o: Operators): PNode =
var s = newNodeI(nkCurly, it.info, it.len-1)
s.typ = settype(loc)
for i in 0..it.len-2: s.sons[i] = it.sons[i]
for i in 0..<it.len-1: s[i] = it[i]
result = newNodeI(nkCall, it.info, 3)
result.sons[0] = newSymNode(o.opContains)
result.sons[1] = s
result.sons[2] = loc
result[0] = newSymNode(o.opContains)
result[1] = s
result[2] = loc
proc buildElse(n: PNode; o: Operators): PNode =
var s = newNodeIT(nkCurly, n.info, settype(n.sons[0]))
for i in 1..n.len-2:
let branch = n.sons[i]
var s = newNodeIT(nkCurly, n.info, settype(n[0]))
for i in 1..<n.len-1:
let branch = n[i]
assert branch.kind != nkElse
if branch.kind == nkOfBranch:
for j in 0..branch.len-2:
s.add(branch.sons[j])
for j in 0..<branch.len-1:
s.add(branch[j])
result = newNodeI(nkCall, n.info, 3)
result.sons[0] = newSymNode(o.opContains)
result.sons[1] = s
result.sons[2] = n.sons[0]
result[0] = newSymNode(o.opContains)
result[1] = s
result[2] = n[0]
proc addDiscriminantFact*(m: var TModel, n: PNode) =
var fact = newNodeI(nkCall, n.info, 3)
fact.sons[0] = newSymNode(m.o.opEq)
fact.sons[1] = n.sons[0]
fact.sons[2] = n.sons[1]
fact[0] = newSymNode(m.o.opEq)
fact[1] = n[0]
fact[2] = n[1]
m.s.add fact
proc addAsgnFact*(m: var TModel, key, value: PNode) =
var fact = newNodeI(nkCall, key.info, 3)
fact.sons[0] = newSymNode(m.o.opEq)
fact.sons[1] = key
fact.sons[2] = value
fact[0] = newSymNode(m.o.opEq)
fact[1] = key
fact[2] = value
m.s.add fact
proc sameSubexprs*(m: TModel; a, b: PNode): bool =
@ -1015,34 +1015,34 @@ proc sameSubexprs*(m: TModel; a, b: PNode): bool =
# However, nil checking requires exactly the same mechanism! But for now
# we simply use sameTree and live with the unsoundness of the analysis.
var check = newNodeI(nkCall, a.info, 3)
check.sons[0] = newSymNode(m.o.opEq)
check.sons[1] = a
check.sons[2] = b
check[0] = newSymNode(m.o.opEq)
check[1] = a
check[2] = b
result = m.doesImply(check) == impYes
proc addCaseBranchFacts*(m: var TModel, n: PNode, i: int) =
let branch = n.sons[i]
let branch = n[i]
if branch.kind == nkOfBranch:
m.s.add buildOf(branch, n.sons[0], m.o)
m.s.add buildOf(branch, n[0], m.o)
else:
m.s.add n.buildElse(m.o).neg(m.o)
proc buildProperFieldCheck(access, check: PNode; o: Operators): PNode =
if check.sons[1].kind == nkCurly:
if check[1].kind == nkCurly:
result = copyTree(check)
if access.kind == nkDotExpr:
var a = copyTree(access)
a.sons[1] = check.sons[2]
result.sons[2] = a
a[1] = check[2]
result[2] = a
# 'access.kind != nkDotExpr' can happen for object constructors
# which we don't check yet
else:
# it is some 'not'
assert check.getMagic == mNot
result = buildProperFieldCheck(access, check.sons[1], o).neg(o)
result = buildProperFieldCheck(access, check[1], o).neg(o)
proc checkFieldAccess*(m: TModel, n: PNode; conf: ConfigRef) =
for i in 1..n.len-1:
let check = buildProperFieldCheck(n.sons[0], n.sons[i], m.o)
for i in 1..<n.len:
let check = buildProperFieldCheck(n[0], n[i], m.o)
if check != nil and m.doesImply(check) != impYes:
message(conf, n.info, warnProveField, renderTree(n.sons[0])); break
message(conf, n.info, warnProveField, renderTree(n[0])); break

View file

@ -12,14 +12,14 @@
proc hlo(c: PContext, n: PNode): PNode
proc evalPattern(c: PContext, n, orig: PNode): PNode =
internalAssert c.config, n.kind == nkCall and n.sons[0].kind == nkSym
internalAssert c.config, n.kind == nkCall and n[0].kind == nkSym
# we need to ensure that the resulting AST is semchecked. However, it's
# awful to semcheck before macro invocation, so we don't and treat
# templates and macros as immediate in this context.
var rule: string
if optHints in c.config.options and hintPattern in c.config.notes:
rule = renderTree(n, {renderNoComments})
let s = n.sons[0].sym
let s = n[0].sym
case s.kind
of skMacro:
result = semMacroExpr(c, n, orig, s)
@ -50,7 +50,7 @@ proc applyPatterns(c: PContext, n: PNode): PNode =
c.patterns[i] = nil
if x.kind == nkStmtList:
assert x.len == 3
x.sons[1] = evalPattern(c, x.sons[1], result)
x[1] = evalPattern(c, x[1], result)
result = flattenStmts(x)
else:
result = evalPattern(c, x, result)
@ -68,17 +68,17 @@ proc hlo(c: PContext, n: PNode): PNode =
result = n
else:
if n.kind in {nkFastAsgn, nkAsgn, nkIdentDefs, nkVarTuple} and
n.sons[0].kind == nkSym and
{sfGlobal, sfPure} * n.sons[0].sym.flags == {sfGlobal, sfPure}:
n[0].kind == nkSym and
{sfGlobal, sfPure} * n[0].sym.flags == {sfGlobal, sfPure}:
# do not optimize 'var g {.global} = re(...)' again!
return n
result = applyPatterns(c, n)
if result == n:
# no optimization applied, try subtrees:
for i in 0 ..< safeLen(result):
let a = result.sons[i]
for i in 0..<result.safeLen:
let a = result[i]
let h = hlo(c, a)
if h != a: result.sons[i] = h
if h != a: result[i] = h
else:
# perform type checking, so that the replacement still fits:
if isEmptyType(n.typ) and isEmptyType(result.typ):

View file

@ -87,7 +87,7 @@ proc getIdent*(ic: IdentCache; identifier: cstring, length: int, h: Hash): PIden
new(result)
result.h = h
result.s = newString(length)
for i in 0 ..< length: result.s[i] = identifier[i]
for i in 0..<length: result.s[i] = identifier[i]
result.next = ic.buckets[idx]
ic.buckets[idx] = result
if id == 0:
@ -97,11 +97,11 @@ proc getIdent*(ic: IdentCache; identifier: cstring, length: int, h: Hash): PIden
result.id = id
proc getIdent*(ic: IdentCache; identifier: string): PIdent =
result = getIdent(ic, cstring(identifier), len(identifier),
result = getIdent(ic, cstring(identifier), identifier.len,
hashIgnoreStyle(identifier))
proc getIdent*(ic: IdentCache; identifier: string, h: Hash): PIdent =
result = getIdent(ic, cstring(identifier), len(identifier), h)
result = getIdent(ic, cstring(identifier), identifier.len, h)
proc newIdentCache*(): IdentCache =
result = IdentCache()
@ -110,7 +110,7 @@ proc newIdentCache*(): IdentCache =
result.idDelegator = result.getIdent":delegator"
result.emptyIdent = result.getIdent("")
# initialize the keywords:
for s in succ(low(specialWords)) .. high(specialWords):
for s in succ(low(specialWords))..high(specialWords):
result.getIdent(specialWords[s], hashIgnoreStyle(specialWords[s])).id = ord(s)
proc whichKeyword*(id: PIdent): TSpecialWord =

View file

@ -16,7 +16,7 @@ import
proc readExceptSet*(c: PContext, n: PNode): IntSet =
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
result = initIntSet()
for i in 1 ..< n.len:
for i in 1..<n.len:
let ident = lookups.considerQuotedIdent(c, n[i])
result.incl(ident.id)
@ -47,8 +47,8 @@ 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 ..< len(etyp.n):
var e = etyp.n.sons[j].sym
for j in 0..<etyp.n.len:
var e = etyp.n[j].sym
if e.kind != skEnumField:
internalError(c.config, s.info, "rawImportSymbol")
# BUGFIX: because of aliases for enums the symbol may already
@ -125,18 +125,18 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet; fromMod: PSym) =
of nkExportExceptStmt:
localError(c.config, n.info, "'export except' not implemented")
else:
for i in 0..safeLen(n)-1:
importForwarded(c, n.sons[i], exceptSet, fromMod)
for i in 0..n.safeLen-1:
importForwarded(c, n[i], exceptSet, fromMod)
proc importModuleAs(c: PContext; n: PNode, realModule: PSym): PSym =
result = realModule
c.unusedImports.add((realModule, n.info))
if n.kind != nkImportAs: discard
elif n.len != 2 or n.sons[1].kind != nkIdent:
elif n.len != 2 or n[1].kind != nkIdent:
localError(c.config, n.info, "module alias must be an identifier")
elif n.sons[1].ident.id != realModule.name.id:
elif n[1].ident.id != realModule.name.id:
# some misguided guy will write 'import abc.foo as foo' ...
result = createModuleAlias(realModule, n.sons[1].ident, realModule.info,
result = createModuleAlias(realModule, n[1].ident, realModule.info,
c.config.options)
proc myImportModule(c: PContext, n: PNode; importStmtResult: PNode): PSym =
@ -148,7 +148,7 @@ proc myImportModule(c: PContext, n: PNode; importStmtResult: PNode): PSym =
#echo "adding ", toFullPath(f), " at ", L+1
if recursion >= 0:
var err = ""
for i in recursion ..< L:
for i in recursion..<L:
if i > recursion: err.add "\n"
err.add toFullPath(c.config, c.graph.importStack[i]) & " imports " &
toFullPath(c.config, c.graph.importStack[i+1])
@ -178,8 +178,8 @@ proc myImportModule(c: PContext, n: PNode; importStmtResult: PNode): PSym =
proc transformImportAs(c: PContext; n: PNode): PNode =
if n.kind == nkInfix and considerQuotedIdent(c, n[0]).s == "as":
result = newNodeI(nkImportAs, n.info)
result.add n.sons[1]
result.add n.sons[2]
result.add n[1]
result.add n[2]
else:
result = n
@ -195,8 +195,8 @@ proc impMod(c: PContext; it: PNode; importStmtResult: PNode) =
proc evalImport*(c: PContext, n: PNode): PNode =
result = newNodeI(nkImportStmt, n.info)
for i in 0 ..< len(n):
let it = n.sons[i]
for i in 0..<n.len:
let it = n[i]
if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket:
let sep = it[0]
let dir = it[1]
@ -206,13 +206,13 @@ proc evalImport*(c: PContext, n: PNode): PNode =
imp.add sep # dummy entry, replaced in the loop
for x in it[2]:
# transform `a/b/[c as d]` to `/a/b/c as d`
if x.kind == nkInfix and x.sons[0].ident.s == "as":
if x.kind == nkInfix and x[0].ident.s == "as":
let impAs = copyTree(x)
imp.sons[2] = x.sons[1]
impAs.sons[1] = imp
imp[2] = x[1]
impAs[1] = imp
impMod(c, imp, result)
else:
imp.sons[2] = x
imp[2] = x
impMod(c, imp, result)
else:
impMod(c, it, result)
@ -220,22 +220,22 @@ proc evalImport*(c: PContext, n: PNode): PNode =
proc evalFrom*(c: PContext, n: PNode): PNode =
result = newNodeI(nkImportStmt, n.info)
checkMinSonsLen(n, 2, c.config)
n.sons[0] = transformImportAs(c, n.sons[0])
var m = myImportModule(c, n.sons[0], result)
n[0] = transformImportAs(c, n[0])
var m = myImportModule(c, n[0], result)
if m != nil:
n.sons[0] = newSymNode(m)
n[0] = newSymNode(m)
addDecl(c, m, n.info) # add symbol to symbol table of module
for i in 1 ..< len(n):
if n.sons[i].kind != nkNilLit:
importSymbol(c, n.sons[i], m)
for i in 1..<n.len:
if n[i].kind != nkNilLit:
importSymbol(c, n[i], m)
proc evalImportExcept*(c: PContext, n: PNode): PNode =
result = newNodeI(nkImportStmt, n.info)
checkMinSonsLen(n, 2, c.config)
n.sons[0] = transformImportAs(c, n.sons[0])
var m = myImportModule(c, n.sons[0], result)
n[0] = transformImportAs(c, n[0])
var m = myImportModule(c, n[0], result)
if m != nil:
n.sons[0] = newSymNode(m)
n[0] = newSymNode(m)
addDecl(c, m, n.info) # add symbol to symbol table of module
importAllSymbolsExcept(c, m, readExceptSet(c, n))
#importForwarded(c, m.ast, exceptSet, m)

View file

@ -259,7 +259,7 @@ proc destructiveMoveVar(n: PNode; c: var Con): PNode =
vpart[0] = tempAsNode
vpart[1] = c.emptyNode
vpart[2] = n
add(v, vpart)
v.add(vpart)
result.add v
result.add genWasMoved(skipConv(n), c)
@ -685,7 +685,7 @@ proc injectDefaultCalls(n: PNode, c: var Con) =
nkIteratorDef, nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef:
discard
else:
for i in 0..<safeLen(n):
for i in 0..<n.safeLen:
injectDefaultCalls(n[i], c)
proc extractDestroysForTemporaries(c: Con, destroys: PNode): PNode =

View file

@ -162,7 +162,7 @@ proc castToUInt64*(arg: Int128): uint64 =
cast[uint64](bitconcat(arg.udata[1], arg.udata[0]))
proc addToHex(result: var string; arg: uint32) =
for i in 0 ..< 8:
for i in 0..<8:
let idx = (arg shr ((7-i) * 4)) and 0xf
result.add "0123456789abcdef"[idx]
@ -430,7 +430,7 @@ proc divMod*(dividend, divisor: Int128): tuple[quotient, remainder: Int128] =
# Uses shift-subtract algorithm to divide dividend by denominator. The
# remainder will be left in dividend.
for i in 0 .. shift:
for i in 0..shift:
quotient = quotient shl 1
if dividend >= denominator:
dividend = dividend - denominator
@ -492,7 +492,7 @@ proc parseDecimalInt128*(arg: string, pos: int = 0): Int128 =
pos += 1
result = Zero
while pos < arg.len and arg[pos] in '0' .. '9':
while pos < arg.len and arg[pos] in '0'..'9':
result = result * Ten
result.inc(uint32(arg[pos]) - uint32('0'))
pos += 1
@ -652,8 +652,8 @@ when isMainModule:
d[37] = parseDecimalInt128("10000000000000000000000000000000000000")
d[38] = parseDecimalInt128("100000000000000000000000000000000000000")
for i in 0 ..< d.len:
for j in 0 ..< d.len:
for i in 0..<d.len:
for j in 0..<d.len:
doAssert(cmp(d[i], d[j]) == cmp(i,j))
if i + j < d.len:
doAssert d[i] * d[j] == d[i+j]
@ -670,8 +670,8 @@ when isMainModule:
for it in d.mitems:
it = -it
for i in 0 ..< d.len:
for j in 0 ..< d.len:
for i in 0..<d.len:
for j in 0..<d.len:
doAssert(cmp(d[i], d[j]) == -cmp(i,j))
if i + j < d.len:
doAssert d[i] * d[j] == -d[i+j]

File diff suppressed because it is too large Load diff

View file

@ -17,22 +17,20 @@ proc genTypeInfo(p: PProc, typ: PType): Rope
proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
var
s, u: Rope
length: int
field: PSym
b: PNode
result = nil
case n.kind
of nkRecList:
length = len(n)
if length == 1:
result = genObjectFields(p, typ, n.sons[0])
if n.len == 1:
result = genObjectFields(p, typ, n[0])
else:
s = nil
for i in 0 ..< length:
if i > 0: add(s, ", \L")
add(s, genObjectFields(p, typ, n.sons[i]))
for i in 0..<n.len:
if i > 0: s.add(", \L")
s.add(genObjectFields(p, typ, n[i]))
result = ("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}") % [rope(length), s]
"typ: null, name: null, sons: [$2]}") % [rope(n.len), s]
of nkSym:
field = n.sym
s = genTypeInfo(p, field.typ)
@ -41,29 +39,28 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
[mangleName(p.module, field), s,
makeJSString(field.name.s)]
of nkRecCase:
length = len(n)
if (n.sons[0].kind != nkSym): internalError(p.config, n.info, "genObjectFields")
field = n.sons[0].sym
if (n[0].kind != nkSym): internalError(p.config, n.info, "genObjectFields")
field = n[0].sym
s = genTypeInfo(p, field.typ)
for i in 1 ..< length:
b = n.sons[i] # branch
for i in 1..<n.len:
b = n[i] # branch
u = nil
case b.kind
of nkOfBranch:
if len(b) < 2:
if b.len < 2:
internalError(p.config, b.info, "genObjectFields; nkOfBranch broken")
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])),
rope(getOrdValue(b.sons[j].sons[1]))])
for j in 0..<b.len - 1:
if u != nil: u.add(", ")
if b[j].kind == nkRange:
u.addf("[$1, $2]", [rope(getOrdValue(b[j][0])),
rope(getOrdValue(b[j][1]))])
else:
add(u, rope(getOrdValue(b.sons[j])))
u.add(rope(getOrdValue(b[j])))
of nkElse:
u = rope(lengthOrd(p.config, field.typ))
else: internalError(p.config, n.info, "genObjectFields(nkRecCase)")
if result != nil: add(result, ", \L")
addf(result, "[setConstr($1), $2]",
if result != nil: result.add(", \L")
result.addf("[setConstr($1), $2]",
[u, genObjectFields(p, typ, lastSon(b))])
result = ("{kind: 3, offset: \"$1\", len: $3, " &
"typ: $2, name: $4, sons: [$5]}") % [
@ -72,27 +69,27 @@ proc genObjectFields(p: PProc, typ: PType, n: PNode): Rope =
else: internalError(p.config, n.info, "genObjectFields")
proc objHasTypeField(t: PType): bool {.inline.} =
tfInheritable in t.flags or t.sons[0] != nil
tfInheritable in t.flags or t[0] != nil
proc genObjectInfo(p: PProc, typ: PType, name: Rope) =
let kind = if objHasTypeField(typ): tyObject else: tyTuple
var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "var NNI$1 = $2;$n",
p.g.typeInfo.addf("var NNI$1 = $2;$n",
[rope(typ.id), genObjectFields(p, typ, typ.n)])
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
if (typ.kind == tyObject) and (typ.sons[0] != nil):
addf(p.g.typeInfo, "$1.base = $2;$n",
[name, genTypeInfo(p, typ.sons[0].skipTypes(skipPtrs))])
p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
if (typ.kind == tyObject) and (typ[0] != nil):
p.g.typeInfo.addf("$1.base = $2;$n",
[name, genTypeInfo(p, typ[0].skipTypes(skipPtrs))])
proc genTupleFields(p: PProc, typ: PType): Rope =
var s: Rope = nil
for i in 0 ..< typ.len:
if i > 0: add(s, ", \L")
for i in 0..<typ.len:
if i > 0: s.add(", \L")
s.addf("{kind: 1, offset: \"Field$1\", len: 0, " &
"typ: $2, name: \"Field$1\", sons: null}",
[i.rope, genTypeInfo(p, typ.sons[i])])
[i.rope, genTypeInfo(p, typ[i])])
result = ("{kind: 2, len: $1, offset: 0, " &
"typ: null, name: null, sons: [$2]}") % [rope(typ.len), s]
@ -100,30 +97,29 @@ proc genTupleInfo(p: PProc, typ: PType, name: Rope) =
var s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(typ.kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "var NNI$1 = $2;$n",
p.g.typeInfo.addf("var NNI$1 = $2;$n",
[rope(typ.id), genTupleFields(p, typ)])
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
proc genEnumInfo(p: PProc, typ: PType, name: Rope) =
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")
let field = typ.n.sons[i].sym
if i > 0: add(s, ", \L")
for i in 0..<typ.n.len:
if (typ.n[i].kind != nkSym): internalError(p.config, typ.n.info, "genEnumInfo")
let field = typ.n[i].sym
if i > 0: s.add(", \L")
let extName = if field.ast == nil: field.name.s else: field.ast.strVal
addf(s, "\"$1\": {kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}",
s.addf("\"$1\": {kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}",
[rope(field.position), name, makeJSString(extName)])
var n = ("var NNI$1 = {kind: 2, offset: 0, typ: null, " &
"name: null, len: $2, sons: {$3}};$n") % [rope(typ.id), rope(length), s]
"name: null, len: $2, sons: {$3}};$n") % [rope(typ.id), rope(typ.n.len), s]
s = ("var $1 = {size: 0, kind: $2, base: null, node: null, " &
"finalizer: null};$n") % [name, rope(ord(typ.kind))]
prepend(p.g.typeInfo, s)
add(p.g.typeInfo, n)
addf(p.g.typeInfo, "$1.node = NNI$2;$n", [name, rope(typ.id)])
if typ.sons[0] != nil:
addf(p.g.typeInfo, "$1.base = $2;$n",
[name, genTypeInfo(p, typ.sons[0])])
p.g.typeInfo.add(n)
p.g.typeInfo.addf("$1.node = NNI$2;$n", [name, rope(typ.id)])
if typ[0] != nil:
p.g.typeInfo.addf("$1.base = $2;$n",
[name, genTypeInfo(p, typ[0])])
proc genTypeInfo(p: PProc, typ: PType): Rope =
let t = typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned})
@ -131,7 +127,7 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
if containsOrIncl(p.g.typeInfoGenerated, t.id): return
case t.kind
of tyDistinct:
result = genTypeInfo(p, t.sons[0])
result = genTypeInfo(p, t[0])
of tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64:
var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
@ -142,15 +138,15 @@ proc genTypeInfo(p: PProc, typ: PType): Rope =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "$1.base = $2;$n",
p.g.typeInfo.addf("$1.base = $2;$n",
[result, genTypeInfo(p, t.lastSon)])
of tyArray:
var s =
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n" %
[result, rope(ord(t.kind))]
prepend(p.g.typeInfo, s)
addf(p.g.typeInfo, "$1.base = $2;$n",
[result, genTypeInfo(p, t.sons[1])])
p.g.typeInfo.addf("$1.base = $2;$n",
[result, genTypeInfo(p, t[1])])
of tyEnum: genEnumInfo(p, t, result)
of tyObject: genObjectInfo(p, t, result)
of tyTuple: genTupleInfo(p, t, result)

View file

@ -128,8 +128,8 @@ proc newCall(a: PSym, b: PNode): PNode =
proc createClosureIterStateType*(g: ModuleGraph; iter: PSym): PType =
var n = newNodeI(nkRange, iter.info)
addSon(n, newIntNode(nkIntLit, -1))
addSon(n, newIntNode(nkIntLit, 0))
n.add newIntNode(nkIntLit, -1)
n.add newIntNode(nkIntLit, 0)
result = newType(tyRange, iter)
result.n = n
var intType = nilOrSysInt(g)
@ -148,27 +148,27 @@ proc createEnvObj(g: ModuleGraph; owner: PSym; info: TLineInfo): PType =
proc getClosureIterResult*(g: ModuleGraph; iter: PSym): PSym =
if resultPos < iter.ast.len:
result = iter.ast.sons[resultPos].sym
result = iter.ast[resultPos].sym
else:
# XXX a bit hacky:
result = newSym(skResult, getIdent(g.cache, ":result"), iter, iter.info, {})
result.typ = iter.typ.sons[0]
result.typ = iter.typ[0]
incl(result.flags, sfUsed)
iter.ast.add newSymNode(result)
proc addHiddenParam(routine: PSym, param: PSym) =
assert param.kind == skParam
var params = routine.ast.sons[paramsPos]
var params = routine.ast[paramsPos]
# -1 is correct here as param.position is 0 based but we have at position 0
# some nkEffect node:
param.position = routine.typ.n.len-1
addSon(params, newSymNode(param))
params.add newSymNode(param)
#incl(routine.typ.flags, tfCapturesEnv)
assert sfFromGeneric in param.flags
#echo "produced environment: ", param.id, " for ", routine.id
proc getHiddenParam(g: ModuleGraph; routine: PSym): PSym =
let params = routine.ast.sons[paramsPos]
let params = routine.ast[paramsPos]
let hidden = lastSon(params)
if hidden.kind == nkSym and hidden.sym.kind == skParam and hidden.sym.name.s == paramName:
result = hidden.sym
@ -179,7 +179,7 @@ proc getHiddenParam(g: ModuleGraph; routine: PSym): PSym =
result = routine
proc getEnvParam*(routine: PSym): PSym =
let params = routine.ast.sons[paramsPos]
let params = routine.ast[paramsPos]
let hidden = lastSon(params)
if hidden.kind == nkSym and hidden.sym.name.s == paramName:
result = hidden.sym
@ -206,8 +206,8 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
# which is however the only case when we generate an assignment in the first
# place.
result = newNodeI(nkAsgn, info, 2)
result.sons[0] = le
result.sons[1] = ri
result[0] = le
result[1] = ri
proc makeClosure*(g: ModuleGraph; prc: PSym; env: PNode; info: TLineInfo): PNode =
result = newNodeIT(nkClosure, info, prc.typ)
@ -255,7 +255,7 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
var env: PNode
if owner.isIterator:
let it = getHiddenParam(g, owner)
addUniqueField(it.typ.skipTypes({tyOwned}).sons[0], hp, g.cache)
addUniqueField(it.typ.skipTypes({tyOwned})[0], hp, g.cache)
env = indirectAccess(newSymNode(it), hp, hp.info)
else:
let e = newSym(skLet, iter.name, owner, n.info)
@ -520,7 +520,7 @@ proc accessViaEnvParam(g: ModuleGraph; n: PNode; owner: PSym): PNode =
if not envParam.isNil:
var access = newSymNode(envParam)
while true:
let obj = access.typ.sons[0]
let obj = access.typ[0]
assert obj.kind == tyObject
let field = getFieldFromObj(obj, s)
if field != nil:
@ -539,7 +539,7 @@ proc newEnvVar(cache: IdentCache; owner: PSym; typ: PType; info: TLineInfo): PNo
when false:
if owner.kind == skIterator and owner.typ.callConv == ccClosure:
let it = getHiddenParam(owner)
addUniqueField(it.typ.sons[0], v)
addUniqueField(it.typ[0], v)
result = indirectAccess(newSymNode(it), v, v.info)
else:
result = newSymNode(v)
@ -679,7 +679,7 @@ proc accessViaEnvVar(n: PNode; owner: PSym; d: DetectionPass;
result = n
proc getStateField*(g: ModuleGraph; owner: PSym): PSym =
getHiddenParam(g, owner).typ.skipTypes({tyOwned, tyRef, tyPtr}).n.sons[0].sym
getHiddenParam(g, owner).typ.skipTypes({tyOwned, tyRef, tyPtr}).n[0].sym
proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
c: var LiftingPass): PNode
@ -748,13 +748,13 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
discard
of nkClosure:
if n[1].kind == nkNilLit:
n.sons[0] = liftCapturedVars(n[0], owner, d, c)
let x = n.sons[0].skipConv
n[0] = liftCapturedVars(n[0], owner, d, c)
let x = n[0].skipConv
if x.kind == nkClosure:
#localError(n.info, "internal error: closure to closure created")
# now we know better, so patch it:
n.sons[0] = x.sons[0]
n.sons[1] = x.sons[1]
n[0] = x[0]
n[1] = x[1]
of nkLambdaKinds, nkIteratorDef:
if n.typ != nil and n[namePos].kind == nkSym:
let oldInContainer = c.inContainer
@ -765,29 +765,29 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
c.inContainer = oldInContainer
of nkHiddenStdConv:
if n.len == 2:
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
n[1] = liftCapturedVars(n[1], owner, d, c)
if n[1].kind == nkClosure: result = n[1]
of nkReturnStmt:
if n[0].kind in {nkAsgn, nkFastAsgn}:
# we have a `result = result` expression produced by the closure
# transform, let's not touch the LHS in order to make the lifting pass
# correct when `result` is lifted
n[0].sons[1] = liftCapturedVars(n[0].sons[1], owner, d, c)
n[0][1] = liftCapturedVars(n[0][1], owner, d, c)
else:
n.sons[0] = liftCapturedVars(n[0], owner, d, c)
n[0] = liftCapturedVars(n[0], owner, d, c)
of nkTypeOfExpr:
result = n
else:
if owner.isIterator:
if nfLL in n.flags:
# special case 'when nimVm' due to bug #3636:
n.sons[1] = liftCapturedVars(n[1], owner, d, c)
n[1] = liftCapturedVars(n[1], owner, d, c)
return
let inContainer = n.kind in {nkObjConstr, nkBracket}
if inContainer: inc c.inContainer
for i in 0..<n.len:
n.sons[i] = liftCapturedVars(n[i], owner, d, c)
n[i] = liftCapturedVars(n[i], owner, d, c)
if inContainer: dec c.inContainer
# ------------------ old stuff -------------------------------------------
@ -911,11 +911,10 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
...
"""
if liftingHarmful(g.config, owner): return body
var L = body.len
if not (body.kind == nkForStmt and body[L-2].kind in nkCallKinds):
if not (body.kind == nkForStmt and body[^2].kind in nkCallKinds):
localError(g.config, body.info, "ignored invalid for loop")
return body
var call = body[L-2]
var call = body[^2]
result = newNodeI(nkStmtList, body.info)
@ -941,34 +940,34 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
elif op.kind == nkStmtListExpr:
let closure = op.lastSon
if closure.kind == nkClosure:
call.sons[0] = closure
for i in 0 .. op.len-2:
call[0] = closure
for i in 0..<op.len-1:
result.add op[i]
var loopBody = newNodeI(nkStmtList, body.info, 3)
var whileLoop = newNodeI(nkWhileStmt, body.info, 2)
whileLoop.sons[0] = newIntTypeNode(1, getSysType(g, body.info, tyBool))
whileLoop.sons[1] = loopBody
whileLoop[0] = newIntTypeNode(1, getSysType(g, body.info, tyBool))
whileLoop[1] = loopBody
result.add whileLoop
# setup loopBody:
# gather vars in a tuple:
var v2 = newNodeI(nkLetSection, body.info)
var vpart = newNodeI(if L == 3: nkIdentDefs else: nkVarTuple, body.info)
for i in 0 .. L-3:
var vpart = newNodeI(if body.len == 3: nkIdentDefs else: nkVarTuple, body.info)
for i in 0..<body.len-2:
if body[i].kind == nkSym:
body[i].sym.kind = skLet
addSon(vpart, body[i])
vpart.add body[i]
addSon(vpart, newNodeI(nkEmpty, body.info)) # no explicit type
vpart.add newNodeI(nkEmpty, body.info) # no explicit type
if not env.isNil:
call.sons[0] = makeClosure(g, call.sons[0].sym, env.newSymNode, body.info)
addSon(vpart, call)
addSon(v2, vpart)
call[0] = makeClosure(g, call[0].sym, env.newSymNode, body.info)
vpart.add call
v2.add vpart
loopBody.sons[0] = v2
loopBody[0] = v2
var bs = newNodeI(nkBreakState, body.info)
bs.addSon(call.sons[0])
bs.add call[0]
let ibs = newNodeI(nkIfStmt, body.info)
let elifBranch = newNodeI(nkElifBranch, body.info)
@ -980,5 +979,5 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
elifBranch.add(br)
ibs.add(elifBranch)
loopBody.sons[1] = ibs
loopBody.sons[2] = body[L-1]
loopBody[1] = ibs
loopBody[2] = body[^1]

View file

@ -146,7 +146,7 @@ proc optionalIsGood(em: var Emitter; pos, currentLen: int): bool =
proc lenOfNextTokens(em: Emitter; pos: int): int =
result = 0
for i in 1 ..< em.tokens.len-pos:
for i in 1..<em.tokens.len-pos:
if em.kinds[pos+i] in {ltCrucialNewline, ltSplittingNewline, ltOptionalNewline}: break
inc result, em.tokens[pos+i].len
@ -570,7 +570,7 @@ proc endsWith(em: Emitter; k: varargs[string]): bool =
return true
proc rfind(em: Emitter, t: string): int =
for i in 1 .. 5:
for i in 1..5:
if em.tokens[^i] == t:
return i

View file

@ -304,11 +304,11 @@ template tokenEndPrevious(tok, pos) =
tok.offsetB = L.offsetBase + pos
template eatChar(L: var TLexer, t: var TToken, replacementChar: char) =
add(t.literal, replacementChar)
t.literal.add(replacementChar)
inc(L.bufpos)
template eatChar(L: var TLexer, t: var TToken) =
add(t.literal, L.buf[L.bufpos])
t.literal.add(L.buf[L.bufpos])
inc(L.bufpos)
proc getNumber(L: var TLexer, result: var TToken) =
@ -317,7 +317,7 @@ proc getNumber(L: var TLexer, result: var TToken) =
result = 0
while true:
if L.buf[pos] in chars:
add(tok.literal, L.buf[pos])
tok.literal.add(L.buf[pos])
inc(pos)
inc(result)
else:
@ -328,14 +328,14 @@ proc getNumber(L: var TLexer, result: var TToken) =
"only single underscores may occur in a token and token may not " &
"end with an underscore: e.g. '1__1' and '1_' are invalid")
break
add(tok.literal, '_')
tok.literal.add('_')
inc(pos)
L.bufpos = pos
proc matchChars(L: var TLexer, tok: var TToken, chars: set[char]) =
var pos = L.bufpos # use registers for pos, buf
while L.buf[pos] in chars:
add(tok.literal, L.buf[pos])
tok.literal.add(L.buf[pos])
inc(pos)
L.bufpos = pos
@ -351,12 +351,12 @@ proc getNumber(L: var TLexer, result: var TToken) =
# We must verify +/- specifically so that we're not past the literal
if L.buf[L.bufpos] in {'+', '-'} and
L.buf[L.bufpos - 1] in {'e', 'E'}:
add(t.literal, L.buf[L.bufpos])
t.literal.add(L.buf[L.bufpos])
inc(L.bufpos)
matchChars(L, t, literalishChars)
if L.buf[L.bufpos] in {'\'', 'f', 'F', 'd', 'D', 'i', 'I', 'u', 'U'}:
inc(L.bufpos)
add(t.literal, L.buf[L.bufpos])
t.literal.add(L.buf[L.bufpos])
matchChars(L, t, {'0'..'9'})
L.bufpos = msgPos
lexMessage(L, msgKind, msg % t.literal)
@ -687,51 +687,51 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) =
if L.config.oldNewlines:
if tok.tokType == tkCharLit:
lexMessage(L, errGenerated, "\\n not allowed in character literal")
add(tok.literal, L.config.target.tnl)
tok.literal.add(L.config.target.tnl)
else:
add(tok.literal, '\L')
tok.literal.add('\L')
inc(L.bufpos)
of 'p', 'P':
if tok.tokType == tkCharLit:
lexMessage(L, errGenerated, "\\p not allowed in character literal")
add(tok.literal, L.config.target.tnl)
tok.literal.add(L.config.target.tnl)
inc(L.bufpos)
of 'r', 'R', 'c', 'C':
add(tok.literal, CR)
tok.literal.add(CR)
inc(L.bufpos)
of 'l', 'L':
add(tok.literal, LF)
tok.literal.add(LF)
inc(L.bufpos)
of 'f', 'F':
add(tok.literal, FF)
tok.literal.add(FF)
inc(L.bufpos)
of 'e', 'E':
add(tok.literal, ESC)
tok.literal.add(ESC)
inc(L.bufpos)
of 'a', 'A':
add(tok.literal, BEL)
tok.literal.add(BEL)
inc(L.bufpos)
of 'b', 'B':
add(tok.literal, BACKSPACE)
tok.literal.add(BACKSPACE)
inc(L.bufpos)
of 'v', 'V':
add(tok.literal, VT)
tok.literal.add(VT)
inc(L.bufpos)
of 't', 'T':
add(tok.literal, '\t')
tok.literal.add('\t')
inc(L.bufpos)
of '\'', '\"':
add(tok.literal, L.buf[L.bufpos])
tok.literal.add(L.buf[L.bufpos])
inc(L.bufpos)
of '\\':
add(tok.literal, '\\')
tok.literal.add('\\')
inc(L.bufpos)
of 'x', 'X':
inc(L.bufpos)
var xi = 0
handleHexChar(L, xi, 1)
handleHexChar(L, xi, 2)
add(tok.literal, chr(xi))
tok.literal.add(chr(xi))
of 'u', 'U':
if tok.tokType == tkCharLit:
lexMessage(L, errGenerated, "\\u not allowed in character literal")
@ -761,14 +761,14 @@ proc getEscapedChar(L: var TLexer, tok: var TToken) =
lexMessage(L, warnOctalEscape)
var xi = 0
handleDecChars(L, xi)
if (xi <= 255): add(tok.literal, chr(xi))
if (xi <= 255): tok.literal.add(chr(xi))
else: lexMessage(L, errGenerated, "invalid character constant")
else: lexMessage(L, errGenerated, "invalid character constant")
proc newString(s: cstring, len: int): string =
## XXX, how come there is no support for this?
result = newString(len)
for i in 0 ..< len:
for i in 0..<len:
result[i] = s[i]
proc handleCRLF(L: var TLexer, pos: int): int =
@ -815,12 +815,12 @@ proc getString(L: var TLexer, tok: var TToken, mode: StringMode) =
tokenEndIgnore(tok, pos+2)
L.bufpos = pos + 3 # skip the three """
break
add(tok.literal, '\"')
tok.literal.add('\"')
inc(pos)
of CR, LF:
tokenEndIgnore(tok, pos)
pos = handleCRLF(L, pos)
add(tok.literal, "\n")
tok.literal.add("\n")
of nimlexbase.EndOfFile:
tokenEndIgnore(tok, pos)
var line2 = L.lineNumber
@ -830,7 +830,7 @@ proc getString(L: var TLexer, tok: var TToken, mode: StringMode) =
L.bufpos = pos
break
else:
add(tok.literal, L.buf[pos])
tok.literal.add(L.buf[pos])
inc(pos)
else:
# ordinary string literal
@ -841,7 +841,7 @@ proc getString(L: var TLexer, tok: var TToken, mode: StringMode) =
if c == '\"':
if mode != normal and L.buf[pos+1] == '\"':
inc(pos, 2)
add(tok.literal, '"')
tok.literal.add('"')
else:
tokenEndIgnore(tok, pos)
inc(pos) # skip '"'
@ -855,7 +855,7 @@ proc getString(L: var TLexer, tok: var TToken, mode: StringMode) =
getEscapedChar(L, tok)
pos = L.bufpos
else:
add(tok.literal, c)
tok.literal.add(c)
inc(pos)
L.bufpos = pos
@ -947,15 +947,14 @@ proc getPrecedence*(tok: TToken, strongSpaces: bool): int =
case tok.tokType
of tkOpr:
let L = tok.ident.s.len
let relevantChar = tok.ident.s[0]
# arrow like?
if L > 1 and tok.ident.s[L-1] == '>' and
tok.ident.s[L-2] in {'-', '~', '='}: return considerStrongSpaces(1)
if tok.ident.s.len > 1 and tok.ident.s[^1] == '>' and
tok.ident.s[^2] in {'-', '~', '='}: return considerStrongSpaces(1)
template considerAsgn(value: untyped) =
result = if tok.ident.s[L-1] == '=': 1 else: value
result = if tok.ident.s[^1] == '=': 1 else: value
case relevantChar
of '$', '^': considerAsgn(10)
@ -1081,7 +1080,7 @@ proc scanComment(L: var TLexer, tok: var TToken) =
var lastBackslash = -1
while L.buf[pos] notin {CR, LF, nimlexbase.EndOfFile}:
if L.buf[pos] == '\\': lastBackslash = pos+1
add(tok.literal, L.buf[pos])
tok.literal.add(L.buf[pos])
inc(pos)
tokenEndIgnore(tok, pos)
pos = handleCRLF(L, pos)
@ -1351,7 +1350,7 @@ proc getPrecedence*(ident: PIdent): int =
initToken(tok)
tok.ident = ident
tok.tokType =
if tok.ident.id in ord(tokKeywordLow) - ord(tkSymbol) .. ord(tokKeywordHigh) - ord(tkSymbol):
if tok.ident.id in ord(tokKeywordLow) - ord(tkSymbol)..ord(tokKeywordHigh) - ord(tkSymbol):
TTokType(tok.ident.id + ord(tkSymbol))
else: tkOpr
getPrecedence(tok, false)

View file

@ -34,28 +34,28 @@ proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineIn
proc at(a, i: PNode, elemType: PType): PNode =
result = newNodeI(nkBracketExpr, a.info, 2)
result.sons[0] = a
result.sons[1] = i
result[0] = a
result[1] = i
result.typ = elemType
proc fillBodyTup(c: var TLiftCtx; t: PType; body, x, y: PNode) =
for i in 0 ..< t.len:
for i in 0..<t.len:
let lit = lowerings.newIntLit(c.g, x.info, i)
fillBody(c, t.sons[i], body, x.at(lit, t.sons[i]), y.at(lit, t.sons[i]))
fillBody(c, t[i], body, x.at(lit, t[i]), y.at(lit, t[i]))
proc dotField(x: PNode, f: PSym): PNode =
result = newNodeI(nkDotExpr, x.info, 2)
if x.typ.skipTypes(abstractInst).kind == tyVar:
result.sons[0] = x.newDeref
result[0] = x.newDeref
else:
result.sons[0] = x
result.sons[1] = newSymNode(f, x.info)
result[0] = x
result[1] = newSymNode(f, x.info)
result.typ = f.typ
proc newAsgnStmt(le, ri: PNode): PNode =
result = newNodeI(nkAsgn, le.info, 2)
result.sons[0] = le
result.sons[1] = ri
result[0] = le
result[1] = ri
proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
if c.kind != attachedDestructor:
@ -90,13 +90,12 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode) =
caseStmt.add(access)
var emptyBranches = 0
# copy the branches over, but replace the fields with the for loop body:
for i in 1 ..< n.len:
for i in 1..<n.len:
var branch = copyTree(n[i])
let L = branch.len
branch.sons[L-1] = newNodeI(nkStmtList, c.info)
branch[^1] = newNodeI(nkStmtList, c.info)
fillBodyObj(c, n[i].lastSon, branch.sons[L-1], x, y)
if branch.sons[L-1].len == 0: inc emptyBranches
fillBodyObj(c, n[i].lastSon, branch[^1], x, y)
if branch[^1].len == 0: inc emptyBranches
caseStmt.add(branch)
if emptyBranches != n.len-1:
body.add(caseStmt)
@ -106,17 +105,17 @@ proc fillBodyObj(c: var TLiftCtx; n, body, x, y: PNode) =
illFormedAstLocal(n, c.g.config)
proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
if t.len > 0 and t.sons[0] != nil:
fillBodyObjT(c, skipTypes(t.sons[0], abstractPtrs), body, x, y)
if t.len > 0 and t[0] != nil:
fillBodyObjT(c, skipTypes(t[0], abstractPtrs), body, x, y)
fillBodyObj(c, t.n, body, x, y)
proc genAddr(g: ModuleGraph; x: PNode): PNode =
if x.kind == nkHiddenDeref:
checkSonsLen(x, 1, g.config)
result = x.sons[0]
result = x[0]
else:
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(x.typ.owner, x.typ))
addSon(result, x)
result.add x
proc newAsgnCall(g: ModuleGraph; op: PSym; x, y: PNode): PNode =
#if sfError in op.flags:
@ -127,12 +126,12 @@ proc newAsgnCall(g: ModuleGraph; op: PSym; x, y: PNode): PNode =
result.add y
proc newOpCall(op: PSym; x: PNode): PNode =
result = newNodeIT(nkCall, x.info, op.typ.sons[0])
result = newNodeIT(nkCall, x.info, op.typ[0])
result.add(newSymNode(op))
result.add x
proc destructorCall(g: ModuleGraph; op: PSym; x: PNode): PNode =
result = newNodeIT(nkCall, x.info, op.typ.sons[0])
result = newNodeIT(nkCall, x.info, op.typ[0])
result.add(newSymNode(op))
result.add genAddr(g, x)
@ -246,10 +245,10 @@ proc considerUserDefinedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
proc addVar(father, v, value: PNode) =
var vpart = newNodeI(nkIdentDefs, v.info, 3)
vpart.sons[0] = v
vpart.sons[1] = newNodeI(nkEmpty, v.info)
vpart.sons[2] = value
addSon(father, vpart)
vpart[0] = v
vpart[1] = newNodeI(nkEmpty, v.info)
vpart[2] = value
father.add vpart
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), c.fn, c.info)
@ -271,8 +270,8 @@ proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
let cmp = genBuiltin(c.g, mLtI, "<", i)
cmp.add genLen(c.g, dest)
cmp.typ = getSysType(c.g, c.info, tyBool)
result.sons[0] = cmp
result.sons[1] = newNodeI(nkStmtList, c.info)
result[0] = cmp
result[1] = newNodeI(nkStmtList, c.info)
proc genIf(c: var TLiftCtx; cond, action: PNode): PNode =
result = newTree(nkIfStmt, newTree(nkElifBranch, cond, action))
@ -306,9 +305,9 @@ proc forallElements(c: var TLiftCtx; t: PType; body, x, y: PNode) =
let i = declareCounter(c, body, toInt64(firstOrd(c.g.config, t)))
let whileLoop = genWhileLoop(c, i, x)
let elemType = t.lastSon
fillBody(c, elemType, whileLoop.sons[1], x.at(i, elemType),
fillBody(c, elemType, whileLoop[1], x.at(i, elemType),
y.at(i, elemType))
addIncStmt(c, whileLoop.sons[1], i)
addIncStmt(c, whileLoop[1], i)
body.add whileLoop
proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
@ -481,8 +480,8 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
# have to go through some indirection; we delegate this to the codegen:
let call = newNodeI(nkCall, c.info, 2)
call.typ = t
call.sons[0] = newSymNode(createMagic(c.g, "deepCopy", mDeepCopy))
call.sons[1] = y
call[0] = newSymNode(createMagic(c.g, "deepCopy", mDeepCopy))
call[1] = y
body.add newAsgnStmt(x, call)
elif (optOwnedRefs in c.g.config.globalOptions and
optRefCheck in c.g.config.options) or c.g.config.selectedGC == gcDestructors:
@ -587,7 +586,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
fillBodyObjT(c, t, body, x, y)
of tyDistinct:
if not considerUserDefinedOp(c, t, body, x, y):
fillBody(c, t.sons[0], body, x, y)
fillBody(c, t[0], body, x, y)
of tyTuple:
fillBodyTup(c, t, body, x, y)
of tyVarargs, tyOpenArray:
@ -659,10 +658,10 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
fillBody(a, typ, body, newSymNode(dest).newDeref, newSymNode(src))
var n = newNodeI(nkProcDef, info, bodyPos+1)
for i in 0 ..< n.len: n.sons[i] = newNodeI(nkEmpty, info)
n.sons[namePos] = newSymNode(result)
n.sons[paramsPos] = result.typ.n
n.sons[bodyPos] = body
for i in 0..<n.len: n[i] = newNodeI(nkEmpty, info)
n[namePos] = newSymNode(result)
n[paramsPos] = result.typ.n
n[bodyPos] = body
result.ast = n
incl result.flags, sfFromGeneric
incl result.flags, sfGeneratedOp
@ -682,7 +681,7 @@ proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo) =
internalError(g.config, info, "resolved destructor is generic")
if t.destructor.magic == mDestroy:
internalError(g.config, info, "patching mDestroy with mDestroy?")
n.sons[0] = newSymNode(t.destructor)
n[0] = newSymNode(t.destructor)
for x in n: patchBody(g, c, x, info)
template inst(field, t) =

View file

@ -30,10 +30,10 @@ proc lookupOrAdd(c: var Ctx; s: PSym; info: TLineInfo): PNode =
let field = addUniqueField(c.objType, s, c.cache)
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = c.objType
add(deref, newSymNode(c.partialParam, info))
deref.add(newSymNode(c.partialParam, info))
result = newNodeI(nkDotExpr, info)
add(result, deref)
add(result, newSymNode(field))
result.add(deref)
result.add(newSymNode(field))
result.typ = field.typ
proc liftLocals(n: PNode; i: int; c: var Ctx) =
@ -44,12 +44,12 @@ proc liftLocals(n: PNode; i: int; c: var Ctx) =
n[i] = lookupOrAdd(c, it.sym, it.info)
of procDefs, nkTypeSection: discard
else:
for i in 0 ..< it.safeLen:
for i in 0..<it.safeLen:
liftLocals(it, i, c)
proc lookupParam(params, dest: PNode): PSym =
if dest.kind != nkIdent: return nil
for i in 1 ..< params.len:
for i in 1..<params.len:
if params[i].kind == nkSym and params[i].sym.name.id == dest.ident.id:
return params[i].sym

View file

@ -72,10 +72,9 @@ proc beautifyName(s: string, k: TSymKind): string =
proc differ*(line: string, a, b: int, x: string): string =
proc substrEq(s: string, pos, last: int, substr: string): bool =
var i = 0
var length = substr.len
while i < length and pos+i <= last and s[pos+i] == substr[i]:
while i < substr.len and pos+i <= last and s[pos+i] == substr[i]:
inc i
return i == length
return i == substr.len
let last = min(b, line.len)

View file

@ -109,12 +109,12 @@ proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
var line = newStringOfCap(120)
var triples = 0
while readLineFromStdin(if s.s.len == 0: ">>> " else: "... ", line):
add(s.s, line)
add(s.s, "\n")
s.s.add(line)
s.s.add("\n")
inc triples, countTriples(line)
if not continueLine(line, (triples and 1) == 1): break
inc(s.lineOffset)
result = min(bufLen, len(s.s) - s.rd)
result = min(bufLen, s.s.len - s.rd)
if result > 0:
copyMem(buf, addr(s.s[s.rd]), result)
inc(s.rd, result)
@ -124,7 +124,7 @@ proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int =
of llsNone:
result = 0
of llsString:
result = min(bufLen, len(s.s) - s.rd)
result = min(bufLen, s.s.len - s.rd)
if result > 0:
copyMem(buf, addr(s.s[0 + s.rd]), result)
inc(s.rd, result)
@ -139,7 +139,7 @@ proc llStreamReadLine*(s: PLLStream, line: var string): bool =
of llsNone:
result = true
of llsString:
while s.rd < len(s.s):
while s.rd < s.s.len:
case s.s[s.rd]
of '\x0D':
inc(s.rd)
@ -149,9 +149,9 @@ proc llStreamReadLine*(s: PLLStream, line: var string): bool =
inc(s.rd)
break
else:
add(line, s.s[s.rd])
line.add(s.s[s.rd])
inc(s.rd)
result = line.len > 0 or s.rd < len(s.s)
result = line.len > 0 or s.rd < s.s.len
of llsFile:
result = readLine(s.f, line)
of llsStdIn:
@ -162,8 +162,8 @@ proc llStreamWrite*(s: PLLStream, data: string) =
of llsNone, llsStdIn:
discard
of llsString:
add(s.s, data)
inc(s.wr, len(data))
s.s.add(data)
inc(s.wr, data.len)
of llsFile:
write(s.f, data)
@ -177,7 +177,7 @@ proc llStreamWrite*(s: PLLStream, data: char) =
of llsNone, llsStdIn:
discard
of llsString:
add(s.s, data)
s.s.add(data)
inc(s.wr)
of llsFile:
c = data
@ -189,7 +189,7 @@ proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int) =
discard
of llsString:
if buflen > 0:
setLen(s.s, len(s.s) + buflen)
setLen(s.s, s.s.len + buflen)
copyMem(addr(s.s[0 + s.wr]), buf, buflen)
inc(s.wr, buflen)
of llsFile:
@ -204,7 +204,7 @@ proc llStreamReadAll*(s: PLLStream): string =
of llsString:
if s.rd == 0: result = s.s
else: result = substr(s.s, s.rd)
s.rd = len(s.s)
s.rd = s.s.len
of llsFile:
result = newString(bufSize)
var bytes = readBuffer(s.f, addr(result[0]), bufSize)

View file

@ -36,11 +36,11 @@ proc considerQuotedIdent*(c: PContext; n: PNode, origin: PNode = nil): PIdent =
of nkAccQuoted:
case n.len
of 0: handleError(n, origin)
of 1: result = considerQuotedIdent(c, n.sons[0], origin)
of 1: result = considerQuotedIdent(c, n[0], origin)
else:
var id = ""
for i in 0..<n.len:
let x = n.sons[i]
let x = n[i]
case x.kind
of nkIdent: id.add(x.ident.s)
of nkSym: id.add(x.sym.name.s)
@ -49,7 +49,7 @@ proc considerQuotedIdent*(c: PContext; n: PNode, origin: PNode = nil): PIdent =
result = getIdent(c.cache, id)
of nkOpenSymChoice, nkClosedSymChoice:
if n[0].kind == nkSym:
result = n.sons[0].sym.name
result = n[0].sym.name
else:
handleError(n, origin)
else:
@ -105,7 +105,7 @@ when declared(echo):
var i = 0
for scope in walkScopes(c.currentScope):
echo "scope ", i
for h in 0 .. high(scope.symbols.data):
for h in 0..high(scope.symbols.data):
if scope.symbols.data[h] != nil:
echo scope.symbols.data[h].name.s
if i == limit: break
@ -124,7 +124,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
## creates an error symbol to avoid cascading errors (for IDE support)
var m = n
# ensure that 'considerQuotedIdent' can't fail:
if m.kind == nkDotExpr: m = m.sons[1]
if m.kind == nkDotExpr: m = m[1]
let ident = if m.kind in {nkIdent, nkSym, nkAccQuoted}:
considerQuotedIdent(c, m)
else:
@ -326,29 +326,29 @@ proc qualifiedLookUp*(c: PContext, n: PNode, flags: set[TLookupFlag]): PSym =
errorUseQualifier(c, n.info, n.sym)
of nkDotExpr:
result = nil
var m = qualifiedLookUp(c, n.sons[0], (flags*{checkUndeclared})+{checkModule})
var m = qualifiedLookUp(c, n[0], (flags*{checkUndeclared})+{checkModule})
if m != nil and m.kind == skModule:
var ident: PIdent = nil
if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n.sons[1])
if n[1].kind == nkIdent:
ident = n[1].ident
elif n[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n[1])
if ident != nil:
if m == c.module:
result = strTableGet(c.topLevelScope.symbols, ident).skipAlias(n, c.config)
else:
result = strTableGet(m.tab, ident).skipAlias(n, c.config)
if result == nil and checkUndeclared in flags:
fixSpelling(n.sons[1], ident, searchInScopes)
errorUndeclaredIdentifier(c, n.sons[1].info, ident.s)
result = errorSym(c, n.sons[1])
elif n.sons[1].kind == nkSym:
result = n.sons[1].sym
fixSpelling(n[1], ident, searchInScopes)
errorUndeclaredIdentifier(c, n[1].info, ident.s)
result = errorSym(c, n[1])
elif n[1].kind == nkSym:
result = n[1].sym
elif checkUndeclared in flags and
n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
localError(c.config, n.sons[1].info, "identifier expected, but got: " &
renderTree(n.sons[1]))
result = errorSym(c, n.sons[1])
n[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
localError(c.config, n[1].info, "identifier expected, but got: " &
renderTree(n[1]))
result = errorSym(c, n[1])
else:
result = nil
when false:
@ -372,13 +372,13 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.mode = oimDone
of nkDotExpr:
o.mode = oimOtherModule
o.m = qualifiedLookUp(c, n.sons[0], {checkUndeclared, checkModule})
o.m = qualifiedLookUp(c, n[0], {checkUndeclared, checkModule})
if o.m != nil and o.m.kind == skModule:
var ident: PIdent = nil
if n.sons[1].kind == nkIdent:
ident = n.sons[1].ident
elif n.sons[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n.sons[1], n)
if n[1].kind == nkIdent:
ident = n[1].ident
elif n[1].kind == nkAccQuoted:
ident = considerQuotedIdent(c, n[1], n)
if ident != nil:
if o.m == c.module:
# a module may access its private members:
@ -388,12 +388,12 @@ proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
else:
result = initIdentIter(o.it, o.m.tab, ident).skipAlias(n, c.config)
else:
noidentError(c.config, n.sons[1], n)
result = errorSym(c, n.sons[1])
noidentError(c.config, n[1], n)
result = errorSym(c, n[1])
of nkClosedSymChoice, nkOpenSymChoice:
o.mode = oimSymChoice
if n[0].kind == nkSym:
result = n.sons[0].sym
result = n[0].sym
else:
o.mode = oimDone
return nil
@ -430,8 +430,8 @@ 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 < len(n):
result = n.sons[o.symChoiceIndex].sym
if o.symChoiceIndex < n.len:
result = n[o.symChoiceIndex].sym
incl(o.inSymChoice, result.id)
inc o.symChoiceIndex
elif n.kind == nkOpenSymChoice:
@ -439,19 +439,19 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
o.mode = oimSymChoiceLocalLookup
o.scope = c.currentScope
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
n[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
n[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
of oimSymChoiceLocalLookup:
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice).skipAlias(n, c.config)
while result == nil:
o.scope = o.scope.parent
if o.scope == nil: break
result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
n[0].sym.name, o.inSymChoice).skipAlias(n, c.config)
when false:
if result != nil and result.kind == skStub: loadStub(result)

View file

@ -16,41 +16,41 @@ import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
lineinfos
proc newDeref*(n: PNode): PNode {.inline.} =
result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])
addSon(result, n)
result = newNodeIT(nkHiddenDeref, n.info, n.typ[0])
result.add n
proc newTupleAccess*(g: ModuleGraph; tup: PNode, i: int): PNode =
if tup.kind == nkHiddenAddr:
result = newNodeIT(nkHiddenAddr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}))
result.addSon(newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent}).sons[i]))
addSon(result[0], tup[0])
result.add newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(abstractInst+{tyPtr, tyVar, tyLent})[i])
result[0].add tup[0]
var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
lit.intVal = i
addSon(result[0], lit)
result[0].add lit
else:
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.skipTypes(
abstractInst).sons[i])
addSon(result, copyTree(tup))
abstractInst)[i])
result.add copyTree(tup)
var lit = newNodeIT(nkIntLit, tup.info, getSysType(g, tup.info, tyInt))
lit.intVal = i
addSon(result, lit)
result.add lit
proc addVar*(father, v: PNode) =
var vpart = newNodeI(nkIdentDefs, v.info, 3)
vpart.sons[0] = v
vpart.sons[1] = newNodeI(nkEmpty, v.info)
vpart.sons[2] = vpart[1]
addSon(father, vpart)
vpart[0] = v
vpart[1] = newNodeI(nkEmpty, v.info)
vpart[2] = vpart[1]
father.add vpart
proc newAsgnStmt*(le, ri: PNode): PNode =
result = newNodeI(nkAsgn, le.info, 2)
result.sons[0] = le
result.sons[1] = ri
result[0] = le
result[1] = ri
proc newFastAsgnStmt*(le, ri: PNode): PNode =
result = newNodeI(nkFastAsgn, le.info, 2)
result.sons[0] = le
result.sons[1] = ri
result[0] = le
result[1] = ri
proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
assert n.kind == nkVarTuple
@ -68,9 +68,9 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
result.add(v)
result.add newAsgnStmt(tempAsNode, value)
for i in 0 .. n.len-3:
if n.sons[i].kind == nkSym: v.addVar(n.sons[i])
result.add newAsgnStmt(n.sons[i], newTupleAccess(g, tempAsNode, i))
for i in 0..<n.len-2:
if n[i].kind == nkSym: v.addVar(n[i])
result.add newAsgnStmt(n[i], newTupleAccess(g, tempAsNode, i))
proc evalOnce*(g: ModuleGraph; value: PNode; owner: PSym): PNode =
## Turns (value) into (let tmp = value; tmp) so that 'value' can be re-used
@ -90,10 +90,10 @@ proc evalOnce*(g: ModuleGraph; value: PNode; owner: PSym): PNode =
proc newTupleAccessRaw*(tup: PNode, i: int): PNode =
result = newNodeI(nkBracketExpr, tup.info)
addSon(result, copyTree(tup))
result.add copyTree(tup)
var lit = newNodeI(nkIntLit, tup.info)
lit.intVal = i
addSon(result, lit)
result.add lit
proc newTryFinally*(body, final: PNode): PNode =
result = newTree(nkHiddenTryStmt, body, newTree(nkFinally, final))
@ -107,31 +107,31 @@ proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
let tempAsNode = newSymNode(temp) #newIdentNode(getIdent(genPrefix & $temp.id), value.info)
var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3)
vpart.sons[0] = tempAsNode
vpart.sons[1] = newNodeI(nkEmpty, value.info)
vpart.sons[2] = value
addSon(v, vpart)
vpart[0] = tempAsNode
vpart[1] = newNodeI(nkEmpty, value.info)
vpart[2] = value
v.add vpart
result.add(v)
let lhs = n.sons[0]
for i in 0 .. lhs.len-1:
result.add newAsgnStmt(lhs.sons[i], newTupleAccessRaw(tempAsNode, i))
let lhs = n[0]
for i in 0..<lhs.len:
result.add newAsgnStmt(lhs[i], newTupleAccessRaw(tempAsNode, i))
proc lowerSwap*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
result = newNodeI(nkStmtList, n.info)
# note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
var temp = newSym(skVar, getIdent(g.cache, genPrefix), owner, n.info, owner.options)
temp.typ = n.sons[1].typ
temp.typ = n[1].typ
incl(temp.flags, sfFromGeneric)
var v = newNodeI(nkVarSection, n.info)
let tempAsNode = newSymNode(temp)
var vpart = newNodeI(nkIdentDefs, v.info, 3)
vpart.sons[0] = tempAsNode
vpart.sons[1] = newNodeI(nkEmpty, v.info)
vpart.sons[2] = n[1]
addSon(v, vpart)
vpart[0] = tempAsNode
vpart[1] = newNodeI(nkEmpty, v.info)
vpart[2] = n[1]
v.add vpart
result.add(v)
result.add newFastAsgnStmt(n[1], n[2])
@ -159,8 +159,8 @@ template fieldCheck {.dirty.} =
proc rawAddField*(obj: PType; field: PSym) =
assert field.kind == skField
field.position = len(obj.n)
addSon(obj.n, newSymNode(field))
field.position = obj.n.len
obj.n.add newSymNode(field)
propagateToOwner(obj, field.typ)
fieldCheck()
@ -168,36 +168,36 @@ proc rawIndirectAccess*(a: PNode; field: PSym; info: TLineInfo): PNode =
# returns a[].field as a node
assert field.kind == skField
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
addSon(deref, a)
deref.typ = a.typ.skipTypes(abstractInst)[0]
deref.add a
result = newNodeI(nkDotExpr, info)
addSon(result, deref)
addSon(result, newSymNode(field))
result.add deref
result.add newSymNode(field)
result.typ = field.typ
proc rawDirectAccess*(obj, field: PSym): PNode =
# returns a.field as a node
assert field.kind == skField
result = newNodeI(nkDotExpr, field.info)
addSon(result, newSymNode obj)
addSon(result, newSymNode field)
result.add newSymNode(obj)
result.add newSymNode(field)
result.typ = field.typ
proc lookupInRecord(n: PNode, id: int): PSym =
result = nil
case n.kind
of nkRecList:
for i in 0 ..< len(n):
result = lookupInRecord(n.sons[i], id)
for i in 0..<n.len:
result = lookupInRecord(n[i], id)
if result != nil: return
of nkRecCase:
if n.sons[0].kind != nkSym: return
result = lookupInRecord(n.sons[0], id)
if n[0].kind != nkSym: return
result = lookupInRecord(n[0], id)
if result != nil: return
for i in 1 ..< len(n):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = lookupInRecord(lastSon(n.sons[i]), id)
result = lookupInRecord(lastSon(n[i]), id)
if result != nil: return
else: discard
of nkSym:
@ -214,8 +214,8 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) =
field.typ = t
assert t.kind != tyTyped
propagateToOwner(obj, t)
field.position = len(obj.n)
addSon(obj.n, newSymNode(field))
field.position = obj.n.len
obj.n.add newSymNode(field)
fieldCheck()
proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable.} =
@ -228,45 +228,45 @@ proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable
field.typ = t
assert t.kind != tyTyped
propagateToOwner(obj, t)
field.position = len(obj.n)
addSon(obj.n, newSymNode(field))
field.position = obj.n.len
obj.n.add newSymNode(field)
result = field
proc newDotExpr*(obj, b: PSym): PNode =
result = newNodeI(nkDotExpr, obj.info)
let field = lookupInRecord(obj.typ.n, b.id)
assert field != nil, b.name.s
addSon(result, newSymNode(obj))
addSon(result, newSymNode(field))
result.add newSymNode(obj)
result.add newSymNode(field)
result.typ = field.typ
proc indirectAccess*(a: PNode, b: int, info: TLineInfo): PNode =
# returns a[].b as a node
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
deref.typ = a.typ.skipTypes(abstractInst)[0]
var t = deref.typ.skipTypes(abstractInst)
var field: PSym
while true:
assert t.kind == tyObject
field = lookupInRecord(t.n, b)
if field != nil: break
t = t.sons[0]
t = t[0]
if t == nil: break
t = t.skipTypes(skipPtrs)
#if field == nil:
# echo "FIELD ", b
# debug deref.typ
assert field != nil
addSon(deref, a)
deref.add a
result = newNodeI(nkDotExpr, info)
addSon(result, deref)
addSon(result, newSymNode(field))
result.add deref
result.add newSymNode(field)
result.typ = field.typ
proc indirectAccess*(a: PNode, b: string, info: TLineInfo; cache: IdentCache): PNode =
# returns a[].b as a node
var deref = newNodeI(nkHiddenDeref, info)
deref.typ = a.typ.skipTypes(abstractInst).sons[0]
deref.typ = a.typ.skipTypes(abstractInst)[0]
var t = deref.typ.skipTypes(abstractInst)
var field: PSym
let bb = getIdent(cache, b)
@ -274,17 +274,17 @@ proc indirectAccess*(a: PNode, b: string, info: TLineInfo; cache: IdentCache): P
assert t.kind == tyObject
field = getSymFromList(t.n, bb)
if field != nil: break
t = t.sons[0]
t = t[0]
if t == nil: break
t = t.skipTypes(skipPtrs)
#if field == nil:
# echo "FIELD ", b
# debug deref.typ
assert field != nil
addSon(deref, a)
deref.add a
result = newNodeI(nkDotExpr, info)
addSon(result, deref)
addSon(result, newSymNode(field))
result.add deref
result.add newSymNode(field)
result.typ = field.typ
proc getFieldFromObj*(t: PType; v: PSym): PSym =
@ -294,7 +294,7 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
assert t.kind == tyObject
result = lookupInRecord(t.n, v.id)
if result != nil: break
t = t.sons[0]
t = t[0]
if t == nil: break
t = t.skipTypes(skipPtrs)
@ -307,13 +307,13 @@ proc indirectAccess*(a, b: PSym, info: TLineInfo): PNode =
proc genAddrOf*(n: PNode): PNode =
result = newNodeI(nkAddr, n.info, 1)
result.sons[0] = n
result[0] = n
result.typ = newType(tyPtr, n.typ.owner)
result.typ.rawAddSon(n.typ)
proc genDeref*(n: PNode; k = nkHiddenDeref): PNode =
result = newNodeIT(k, n.info,
n.typ.skipTypes(abstractInst).sons[0])
n.typ.skipTypes(abstractInst)[0])
result.add n
proc callCodegenProc*(g: ModuleGraph; name: string;
@ -329,9 +329,9 @@ proc callCodegenProc*(g: ModuleGraph; name: string;
if arg2 != nil: result.add arg2
if arg3 != nil: result.add arg3
if optionalArgs != nil:
for i in 1..optionalArgs.len-3:
for i in 1..<optionalArgs.len-2:
result.add optionalArgs[i]
result.typ = sym.typ.sons[0]
result.typ = sym.typ[0]
proc newIntLit*(g: ModuleGraph; info: TLineInfo; value: BiggestInt): PNode =
result = nkIntLit.newIntNode(value)
@ -343,8 +343,8 @@ proc genHigh*(g: ModuleGraph; n: PNode): PNode =
else:
result = newNodeI(nkCall, n.info, 2)
result.typ = getSysType(g, n.info, tyInt)
result.sons[0] = newSymNode(getSysMagic(g, n.info, "high", mHigh))
result.sons[1] = n
result[0] = newSymNode(getSysMagic(g, n.info, "high", mHigh))
result[1] = n
proc genLen*(g: ModuleGraph; n: PNode): PNode =
if skipTypes(n.typ, abstractVar).kind == tyArray:
@ -352,8 +352,8 @@ proc genLen*(g: ModuleGraph; n: PNode): PNode =
else:
result = newNodeI(nkCall, n.info, 2)
result.typ = getSysType(g, n.info, tyInt)
result.sons[0] = newSymNode(getSysMagic(g, n.info, "len", mLengthSeq))
result.sons[1] = n
result[0] = newSymNode(getSysMagic(g, n.info, "len", mLengthSeq))
result[1] = n
proc hoistExpr*(varSection, expr: PNode, name: PIdent, owner: PSym): PSym =
result = newSym(skLet, name, owner, varSection.info, owner.options)
@ -361,8 +361,8 @@ proc hoistExpr*(varSection, expr: PNode, name: PIdent, owner: PSym): PSym =
result.typ = expr.typ
var varDef = newNodeI(nkIdentDefs, varSection.info, 3)
varDef.sons[0] = newSymNode(result)
varDef.sons[1] = newNodeI(nkEmpty, varSection.info)
varDef.sons[2] = expr
varDef[0] = newSymNode(result)
varDef[1] = newNodeI(nkEmpty, varSection.info)
varDef[2] = expr
varSection.add varDef

View file

@ -40,7 +40,7 @@ proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSy
while r != nil:
if r.magic == m:
# prefer the tyInt variant:
if r.typ.sons[0] != nil and r.typ.sons[0].kind == tyInt: return r
if r.typ[0] != nil and r.typ[0].kind == tyInt: return r
result = r
r = nextIdentIter(ti, g.systemModule.tab)
if result != nil: return result
@ -123,7 +123,7 @@ proc addSonSkipIntLit*(father, son: PType) =
when not defined(nimNoNilSeqs):
if isNil(father.sons): father.sons = @[]
let s = son.skipIntLit
add(father.sons, s)
father.sons.add(s)
propagateToOwner(father, s)
proc setIntLitType*(g: ModuleGraph; result: PNode) =

View file

@ -139,7 +139,7 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string =
result.add modname
of nkPrefix:
when false:
if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$":
if n[0].kind == nkIdent and n[0].ident.s == "$":
result = lookupPackage(n[1], nil)
else:
discard
@ -149,7 +149,7 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string =
localError(conf, n.info, warnDeprecated, "using '.' instead of '/' in import paths is deprecated")
result = renderTree(n, {renderNoComments}).replace(".", "/")
of nkImportAs:
result = getModuleName(conf, n.sons[0])
result = getModuleName(conf, n[0])
else:
localError(conf, n.info, "invalid module name: '$1'" % n.renderTree)
result = ""

View file

@ -93,7 +93,7 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P
if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil)
graph.markClientsDirty(fileIdx)
proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PSym {.procvar.} =
proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PSym =
# this is called by the semantic checking phase
assert graph.config != nil
result = compileModule(graph, fileIdx, {})
@ -108,7 +108,7 @@ proc importModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PSym {.proc
if s.owner.id == graph.config.mainPackageId or isDefined(graph.config, "booting"): graph.config.mainPackageNotes
else: graph.config.foreignPackageNotes
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode {.procvar.} =
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode =
result = syntaxes.parseFile(fileIdx, graph.cache, graph.config)
graph.addDep(s, fileIdx)
graph.addIncludeDep(s.position.FileIndex, fileIdx)

View file

@ -26,13 +26,13 @@ proc makeCString*(s: string): Rope =
const MaxLineLength = 64
result = nil
var res = newStringOfCap(int(s.len.toFloat * 1.1) + 1)
add(res, "\"")
for i in 0 ..< len(s):
res.add("\"")
for i in 0..<s.len:
if (i + 1) mod MaxLineLength == 0:
add(res, "\"\L\"")
res.add("\"\L\"")
toCChar(s[i], res)
add(res, '\"')
add(result, rope(res))
res.add('\"')
result.add(rope(res))
proc newFileInfo(fullPath: AbsoluteFile, projPath: RelativeFile): TFileInfo =
@ -152,12 +152,11 @@ proc pushInfoContext*(conf: ConfigRef; info: TLineInfo; detail: string = "") =
conf.m.msgContext.add((info, detail))
proc popInfoContext*(conf: ConfigRef) =
setLen(conf.m.msgContext, len(conf.m.msgContext) - 1)
setLen(conf.m.msgContext, conf.m.msgContext.len - 1)
proc getInfoContext*(conf: ConfigRef; index: int): TLineInfo =
let L = conf.m.msgContext.len
let i = if index < 0: L + index else: index
if i >=% L: result = unknownLineInfo()
let i = if index < 0: conf.m.msgContext.len + index else: index
if i >=% conf.m.msgContext.len: result = unknownLineInfo()
else: result = conf.m.msgContext[i].info
const
@ -333,7 +332,7 @@ proc getMessageStr(msg: TMsgKind, arg: string): string =
type
TErrorHandling = enum doNothing, doAbort, doRaise
proc log*(s: string) {.procvar.} =
proc log*(s: string) =
var f: File
if open(f, getHomeDir() / "nimsuggest.log", fmAppend):
f.writeLine(s)
@ -374,7 +373,7 @@ proc writeContext(conf: ConfigRef; lastinfo: TLineInfo) =
const instantiationFrom = "template/generic instantiation from here"
const instantiationOfFrom = "template/generic instantiation of `$1` from here"
var info = lastinfo
for i in 0 ..< len(conf.m.msgContext):
for i in 0..<conf.m.msgContext.len:
let context = conf.m.msgContext[i]
if context.info != lastinfo and context.info != info:
if conf.structuredErrorHook != nil:

View file

@ -48,7 +48,7 @@ proc `<`*(ver: Version, ver2: Version): bool =
# Handling for normal versions such as "0.1.0" or "1.0".
var sVer = string(ver).split('.')
var sVer2 = string(ver2).split('.')
for i in 0..max(sVer.len, sVer2.len)-1:
for i in 0..<max(sVer.len, sVer2.len):
var sVerI = 0
if i < sVer.len:
discard parseInt(sVer[i], sVerI)
@ -82,7 +82,7 @@ proc getPathVersion*(p: string): tuple[name, version: string] =
result.name = p
return
result.name = p[0 .. sepIdx - 1]
result.name = p[0..sepIdx - 1]
result.version = p.substr(sepIdx + 1)
proc addPackage(conf: ConfigRef; packages: StringTableRef, p: string; info: TLineInfo) =

View file

@ -114,7 +114,7 @@ proc parseDirective(L: var TLexer, tok: var TToken; config: ConfigRef; condStack
ppGetTok(L, tok) # skip @
case whichKeyword(tok.ident)
of wIf:
setLen(condStack, len(condStack) + 1)
setLen(condStack, condStack.len + 1)
let res = evalppIf(L, tok, config)
condStack[high(condStack)] = res
if not res: jumpToDirective(L, tok, jdElseEndif, config, condStack)
@ -168,38 +168,38 @@ proc parseAssignment(L: var TLexer, tok: var TToken;
confTok(L, tok, config, condStack) # skip symbol
var val = ""
while tok.tokType == tkDot:
add(s, '.')
s.add('.')
confTok(L, tok, config, condStack)
checkSymbol(L, tok)
add(s, $tok)
s.add($tok)
confTok(L, tok, config, condStack)
if tok.tokType == tkBracketLe:
# BUGFIX: val, not s!
confTok(L, tok, config, condStack)
checkSymbol(L, tok)
add(val, '[')
add(val, $tok)
val.add('[')
val.add($tok)
confTok(L, tok, config, condStack)
if tok.tokType == tkBracketRi: confTok(L, tok, config, condStack)
else: lexMessage(L, errGenerated, "expected closing ']'")
add(val, ']')
val.add(']')
let percent = tok.ident != nil and tok.ident.s == "%="
if tok.tokType in {tkColon, tkEquals} or percent:
if len(val) > 0: add(val, ':')
if val.len > 0: val.add(':')
confTok(L, tok, config, condStack) # skip ':' or '=' or '%'
checkSymbol(L, tok)
add(val, $tok)
val.add($tok)
confTok(L, tok, config, condStack) # skip symbol
if tok.tokType in {tkColon, tkEquals}:
add(val, $tok) # add the :
val.add($tok) # add the :
confTok(L, tok, config, condStack) # skip symbol
checkSymbol(L, tok)
add(val, $tok) # add the token after it
val.add($tok) # add the token after it
confTok(L, tok, config, condStack) # skip symbol
while tok.ident != nil and tok.ident.s == "&":
confTok(L, tok, config, condStack)
checkSymbol(L, tok)
add(val, $tok)
val.add($tok)
confTok(L, tok, config, condStack)
if percent:
processSwitch(s, strtabs.`%`(val, config.configVars,
@ -221,7 +221,7 @@ proc readConfigFile*(filename: AbsoluteFile; cache: IdentCache;
var condStack: seq[bool] = @[]
confTok(L, tok, config, condStack) # read in the first token
while tok.tokType != tkEof: parseAssignment(L, tok, config, condStack)
if len(condStack) > 0: lexMessage(L, errGenerated, "expected @end")
if condStack.len > 0: lexMessage(L, errGenerated, "expected @end")
closeLexer(L)
return true
@ -245,7 +245,7 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef) =
template readConfigFile(path) =
let configPath = path
if readConfigFile(configPath, cache, conf):
add(configFiles, configPath)
configFiles.add(configPath)
if optSkipSystemConfigFile notin conf.globalOptions:
readConfigFile(getSystemConfigPath(conf, cfg))

View file

@ -157,7 +157,7 @@ proc getCurrentLine(L: TBaseLexer, marker: bool = true): string =
result = ""
var i = L.lineStart
while not (L.buf[i] in {CR, LF, EndOfFile}):
add(result, L.buf[i])
result.add(L.buf[i])
inc(i)
result.add("\n")
if marker:

View file

@ -17,13 +17,13 @@ proc inSet*(s: PNode, elem: PNode): bool =
if s.kind != nkCurly:
#internalError(s.info, "inSet")
return false
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]):
for i in 0..<s.len:
if s[i].kind == nkRange:
if leValue(s[i][0], elem) and
leValue(elem, s[i][1]):
return true
else:
if sameValue(s.sons[i], elem):
if sameValue(s[i], elem):
return true
result = false
@ -31,13 +31,13 @@ proc overlap*(a, b: PNode): bool =
if a.kind == nkRange:
if b.kind == nkRange:
# X..Y and C..D overlap iff (X <= D and C <= Y)
result = leValue(a.sons[0], b.sons[1]) and
leValue(b.sons[0], a.sons[1])
result = leValue(a[0], b[1]) and
leValue(b[0], a[1])
else:
result = leValue(a.sons[0], b) and leValue(b, a.sons[1])
result = leValue(a[0], b) and leValue(b, a[1])
else:
if b.kind == nkRange:
result = leValue(b.sons[0], a) and leValue(a, b.sons[1])
result = leValue(b[0], a) and leValue(a, b[1])
else:
result = sameValue(a, b)
@ -47,61 +47,61 @@ proc someInSet*(s: PNode, a, b: PNode): bool =
if s.kind != nkCurly:
#internalError(s.info, "SomeInSet")
return false
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]):
for i in 0..<s.len:
if s[i].kind == nkRange:
if leValue(s[i][0], b) and leValue(b, s[i][1]) or
leValue(s[i][0], a) and leValue(a, s[i][1]):
return true
else:
# a <= elem <= b
if leValue(a, s.sons[i]) and leValue(s.sons[i], b):
if leValue(a, s[i]) and leValue(s[i], b):
return true
result = false
proc toBitSet*(conf: ConfigRef; s: PNode, b: var TBitSet) =
var first, j: Int128
first = firstOrd(conf, s.typ.sons[0])
first = firstOrd(conf, s.typ[0])
bitSetInit(b, int(getSize(conf, s.typ)))
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):
for i in 0..<s.len:
if s[i].kind == nkRange:
j = getOrdValue(s[i][0], first)
while j <= getOrdValue(s[i][1], first):
bitSetIncl(b, toInt64(j - first))
inc(j)
else:
bitSetIncl(b, toInt64(getOrdValue(s.sons[i]) - first))
bitSetIncl(b, toInt64(getOrdValue(s[i]) - first))
proc toTreeSet*(conf: ConfigRef; s: TBitSet, settype: PType, info: TLineInfo): PNode =
var
a, b, e, first: BiggestInt # a, b are interval borders
elemType: PType
n: PNode
elemType = settype.sons[0]
elemType = settype[0]
first = firstOrd(conf, elemType).toInt64
result = newNodeI(nkCurly, info)
result.typ = settype
result.info = info
e = 0
while e < len(s) * ElemSize:
while e < s.len * ElemSize:
if bitSetIn(s, e):
a = e
b = e
while true:
inc(b)
if (b >= len(s) * ElemSize) or not bitSetIn(s, b): break
if (b >= s.len * ElemSize) or not bitSetIn(s, b): break
dec(b)
let aa = newIntTypeNode(a + first, elemType)
aa.info = info
if a == b:
addSon(result, aa)
result.add aa
else:
n = newNodeI(nkRange, info)
n.typ = elemType
addSon(n, aa)
n.add aa
let bb = newIntTypeNode(b + first, elemType)
bb.info = info
addSon(n, bb)
addSon(result, n)
n.add bb
result.add n
e = b
inc(e)
@ -132,7 +132,7 @@ proc equalSets*(conf: ConfigRef; a, b: PNode): bool =
proc complement*(conf: ConfigRef; a: PNode): PNode =
var x: TBitSet
toBitSet(conf, a, x)
for i in 0 .. high(x): x[i] = not x[i]
for i in 0..high(x): x[i] = not x[i]
result = toTreeSet(conf, x, a.typ, a.info)
proc deduplicate*(conf: ConfigRef; a: PNode): PNode =
@ -149,8 +149,8 @@ proc setHasRange*(s: PNode): bool =
assert s.kind == nkCurly
if s.kind != nkCurly:
return false
for i in 0 ..< len(s):
if s.sons[i].kind == nkRange:
for i in 0..<s.len:
if s[i].kind == nkRange:
return true
result = false

View file

@ -537,15 +537,15 @@ proc shortenDir*(conf: ConfigRef; dir: string): string {.
## returns the interesting part of a dir
var prefix = conf.projectPath.string & DirSep
if startsWith(dir, prefix):
return substr(dir, len(prefix))
return substr(dir, prefix.len)
prefix = getPrefixDir(conf).string & DirSep
if startsWith(dir, prefix):
return substr(dir, len(prefix))
return substr(dir, prefix.len)
result = dir
proc removeTrailingDirSep*(path: string): string =
if (len(path) > 0) and (path[len(path) - 1] == DirSep):
result = substr(path, 0, len(path) - 2)
if (path.len > 0) and (path[^1] == DirSep):
result = substr(path, 0, path.len - 2)
else:
result = path
@ -643,7 +643,7 @@ template patchModule(conf: ConfigRef) {.dirty.} =
let ov = conf.moduleOverrides[key]
if ov.len > 0: result = AbsoluteFile(ov)
proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): AbsoluteFile {.procvar.} =
proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): AbsoluteFile =
if f.isAbsolute:
result = if f.existsFile: AbsoluteFile(f) else: AbsoluteFile""
else:

View file

@ -46,7 +46,7 @@ proc patternError(n: PNode; conf: ConfigRef) =
localError(conf, n.info, "illformed AST: " & renderTree(n, {renderNoComments}))
proc add(code: var TPatternCode, op: TOpcode) {.inline.} =
add(code, chr(ord(op)))
code.add chr(ord(op))
proc whichAlias*(p: PSym): TAliasRequest =
if p.constraint != nil:
@ -57,29 +57,29 @@ proc whichAlias*(p: PSym): TAliasRequest =
proc compileConstraints(p: PNode, result: var TPatternCode; conf: ConfigRef) =
case p.kind
of nkCallKinds:
if p.sons[0].kind != nkIdent:
patternError(p.sons[0], conf)
if p[0].kind != nkIdent:
patternError(p[0], conf)
return
let op = p.sons[0].ident
let op = p[0].ident
if p.len == 3:
if op.s == "|" or op.id == ord(wOr):
compileConstraints(p.sons[1], result, conf)
compileConstraints(p.sons[2], result, conf)
compileConstraints(p[1], result, conf)
compileConstraints(p[2], result, conf)
result.add(ppOr)
elif op.s == "&" or op.id == ord(wAnd):
compileConstraints(p.sons[1], result, conf)
compileConstraints(p.sons[2], result, conf)
compileConstraints(p[1], result, conf)
compileConstraints(p[2], result, conf)
result.add(ppAnd)
else:
patternError(p, conf)
elif p.len == 2 and (op.s == "~" or op.id == ord(wNot)):
compileConstraints(p.sons[1], result, conf)
compileConstraints(p[1], result, conf)
result.add(ppNot)
else:
patternError(p, conf)
of nkAccQuoted, nkPar:
if p.len == 1:
compileConstraints(p.sons[0], result, conf)
compileConstraints(p[0], result, conf)
else:
patternError(p, conf)
of nkIdent:
@ -138,7 +138,7 @@ proc checkForSideEffects*(n: PNode): TSideEffectAnalysis =
case n.kind
of nkCallKinds:
# only calls can produce side effects:
let op = n.sons[0]
let op = n[0]
if op.kind == nkSym and isRoutine(op.sym):
let s = op.sym
if sfSideEffect in s.flags:
@ -152,8 +152,8 @@ proc checkForSideEffects*(n: PNode): TSideEffectAnalysis =
# indirect call: assume side effect:
return seSideEffect
# we need to check n[0] too: (FwithSideEffectButReturnsProcWithout)(args)
for i in 0 ..< n.len:
let ret = checkForSideEffects(n.sons[i])
for i in 0..<n.len:
let ret = checkForSideEffects(n[i])
if ret == seSideEffect: return ret
elif ret == seUnknown and result == seNoSideEffect:
result = seUnknown
@ -163,8 +163,8 @@ proc checkForSideEffects*(n: PNode): TSideEffectAnalysis =
else:
# assume no side effect:
result = seNoSideEffect
for i in 0 ..< n.len:
let ret = checkForSideEffects(n.sons[i])
for i in 0..<n.len:
let ret = checkForSideEffects(n[i])
if ret == seSideEffect: return ret
elif ret == seUnknown and result == seNoSideEffect:
result = seUnknown
@ -232,33 +232,33 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
let t = n.sym.typ.skipTypes({tyTypeDesc})
if t.kind == tyVar: result = arStrange
of nkDotExpr:
let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
let t = skipTypes(n[0].typ, abstractInst-{tyTypeDesc})
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
result = arLValue
elif isUnsafeAddr and t.kind == tyLent:
result = arLValue
else:
result = isAssignable(owner, n.sons[0], isUnsafeAddr)
result = isAssignable(owner, n[0], isUnsafeAddr)
if result != arNone and n[1].kind == nkSym and
sfDiscriminant in n[1].sym.flags:
result = arDiscriminant
of nkBracketExpr:
let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
let t = skipTypes(n[0].typ, abstractInst-{tyTypeDesc})
if t.kind in {tyVar, tySink, tyPtr, tyRef}:
result = arLValue
elif isUnsafeAddr and t.kind == tyLent:
result = arLValue
else:
result = isAssignable(owner, n.sons[0], isUnsafeAddr)
result = isAssignable(owner, n[0], isUnsafeAddr)
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
# Object and tuple conversions are still addressable, so we skip them
# XXX why is 'tyOpenArray' allowed here?
if skipTypes(n.typ, abstractPtrs-{tyTypeDesc}).kind in
{tyOpenArray, tyTuple, tyObject}:
result = isAssignable(owner, n.sons[1], isUnsafeAddr)
elif compareTypes(n.typ, n.sons[1].typ, dcEqIgnoreDistinct):
result = isAssignable(owner, n[1], isUnsafeAddr)
elif compareTypes(n.typ, n[1].typ, dcEqIgnoreDistinct):
# types that are equal modulo distinction preserve l-value:
result = isAssignable(owner, n.sons[1], isUnsafeAddr)
result = isAssignable(owner, n[1], isUnsafeAddr)
of nkHiddenDeref:
if isUnsafeAddr and n[0].typ.kind == tyLent: result = arLValue
elif n[0].typ.kind == tyLent: result = arDiscriminant
@ -266,11 +266,11 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
of nkDerefExpr, nkHiddenAddr:
result = arLValue
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
result = isAssignable(owner, n.sons[0], isUnsafeAddr)
result = isAssignable(owner, n[0], isUnsafeAddr)
of nkCallKinds:
# builtin slice keeps lvalue-ness:
if getMagic(n) in {mArrGet, mSlice}:
result = isAssignable(owner, n.sons[1], isUnsafeAddr)
result = isAssignable(owner, n[1], isUnsafeAddr)
elif n.typ != nil and n.typ.kind == tyVar:
result = arLValue
elif isUnsafeAddr and n.typ != nil and n.typ.kind == tyLent:

File diff suppressed because it is too large Load diff

View file

@ -67,21 +67,21 @@ proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym;
proc openPasses(g: ModuleGraph; a: var TPassContextArray;
module: PSym) =
for i in 0 ..< g.passes.len:
for i in 0..<g.passes.len:
if not isNil(g.passes[i].open):
a[i] = g.passes[i].open(g, module)
else: a[i] = nil
proc closePasses(graph: ModuleGraph; a: var TPassContextArray) =
var m: PNode = nil
for i in 0 ..< graph.passes.len:
for i in 0..<graph.passes.len:
if not isNil(graph.passes[i].close): m = graph.passes[i].close(graph, a[i], m)
a[i] = nil # free the memory here
proc processTopLevelStmt(graph: ModuleGraph, n: PNode, a: var TPassContextArray): bool =
# this implements the code transformation pipeline
var m = n
for i in 0 ..< graph.passes.len:
for i in 0..<graph.passes.len:
if not isNil(graph.passes[i].process):
m = graph.passes[i].process(a[i], m)
if isNil(m): return false
@ -104,7 +104,7 @@ proc processImplicits(graph: ModuleGraph; implicits: seq[string], nodeKind: TNod
var importStmt = newNodeI(nodeKind, m.info)
var str = newStrNode(nkStrLit, module)
str.info = m.info
importStmt.addSon str
importStmt.add str
if not processTopLevelStmt(graph, importStmt, a): break
const
@ -135,7 +135,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
prepareConfigNotes(graph, module)
if module.id < 0:
# new module caching mechanism:
for i in 0 ..< graph.passes.len:
for i in 0..<graph.passes.len:
if not isNil(graph.passes[i].open) and not graph.passes[i].isFrontend:
a[i] = graph.passes[i].open(graph, module)
else:
@ -144,14 +144,14 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
if not graph.stopCompile():
let n = loadNode(graph, module)
var m = n
for i in 0 ..< graph.passes.len:
for i in 0..<graph.passes.len:
if not isNil(graph.passes[i].process) and not graph.passes[i].isFrontend:
m = graph.passes[i].process(a[i], m)
if isNil(m):
break
var m: PNode = nil
for i in 0 ..< graph.passes.len:
for i in 0..<graph.passes.len:
if not isNil(graph.passes[i].close) and not graph.passes[i].isFrontend:
m = graph.passes[i].close(graph, a[i], m)
a[i] = nil

View file

@ -58,18 +58,18 @@ proc sameTrees*(a, b: PNode): bool =
of nkEmpty, nkNilLit: result = true
of nkType: result = sameTypeOrNil(a.typ, b.typ)
else:
if len(a) == len(b):
for i in 0 ..< len(a):
if not sameTrees(a.sons[i], b.sons[i]): return
if a.len == b.len:
for i in 0..<a.len:
if not sameTrees(a[i], b[i]): return
result = true
proc inSymChoice(sc, x: PNode): bool =
if sc.kind == nkClosedSymChoice:
for i in 0..<sc.len:
if sc.sons[i].sym == x.sym: return true
if sc[i].sym == x.sym: return true
elif sc.kind == nkOpenSymChoice:
# same name suffices for open sym choices!
result = sc.sons[0].sym.name.id == x.sym.name.id
result = sc[0].sym.name.id == x.sym.name.id
proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
# check param constraints first here as this is quite optimized:
@ -85,8 +85,8 @@ proc isPatternParam(c: PPatternContext, p: PNode): bool {.inline.} =
result = p.kind == nkSym and p.sym.kind == skParam and p.sym.owner == c.owner
proc matchChoice(c: PPatternContext, p, n: PNode): bool =
for i in 1 ..< p.len:
if matches(c, p.sons[i], n): return true
for i in 1..<p.len:
if matches(c, p[i], n): return true
proc bindOrCheck(c: PPatternContext, param: PSym, n: PNode): bool =
var pp = getLazy(c, param)
@ -103,7 +103,7 @@ proc gather(c: PPatternContext, param: PSym, n: PNode) =
pp.add(n)
else:
pp = newNodeI(nkArgList, n.info, 1)
pp.sons[0] = n
pp[0] = n
putLazy(c, param, pp)
proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
@ -111,24 +111,24 @@ proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
proc matchStarAux(c: PPatternContext, op, n, arglist: PNode,
rpn: bool): bool =
result = true
if n.kind in nkCallKinds and matches(c, op.sons[1], n.sons[0]):
for i in 1..len(n)-1:
if n.kind in nkCallKinds and matches(c, op[1], n[0]):
for i in 1..<n.len:
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:
let n = n.sons[1]
if rpn: arglist.add(n[0])
elif n.kind == nkHiddenStdConv and n[1].kind == nkBracket:
let n = n[1]
for i in 0..<n.len:
if not matchStarAux(c, op, n[i], arglist, rpn): return false
elif checkTypes(c, p.sons[2].sym, n):
add(arglist, n)
elif checkTypes(c, p[2].sym, n):
arglist.add(n)
else:
result = false
if n.kind notin nkCallKinds: return false
if matches(c, p.sons[1], n.sons[0]):
if matches(c, p[1], n[0]):
var arglist = newNodeI(nkArgList, n.info)
if matchStarAux(c, p, n, arglist, rpn):
result = bindOrCheck(c, p.sons[2].sym, arglist)
result = bindOrCheck(c, p[2].sym, arglist)
proc matches(c: PPatternContext, p, n: PNode): bool =
let n = skipHidden(n)
@ -146,24 +146,24 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
elif matches(c, p, n.sym.ast): result = true
elif p.kind == nkPattern:
# pattern operators: | *
let opr = p.sons[0].ident.s
let opr = p[0].ident.s
case opr
of "|": result = matchChoice(c, p, n)
of "*": result = matchNested(c, p, n, rpn=false)
of "**": result = matchNested(c, p, n, rpn=true)
of "~": result = not matches(c, p.sons[1], n)
of "~": result = not matches(c, p[1], n)
else: doAssert(false, "invalid pattern")
# template {add(a, `&` * b)}(a: string{noalias}, b: varargs[string]) =
# add(a, b)
# a.add(b)
elif p.kind == nkCurlyExpr:
if p.sons[1].kind == nkPrefix:
if matches(c, p.sons[0], n):
gather(c, p.sons[1].sons[1].sym, n)
if p[1].kind == nkPrefix:
if matches(c, p[0], n):
gather(c, p[1][1].sym, n)
result = true
else:
assert isPatternParam(c, p.sons[1])
if matches(c, p.sons[0], n):
result = bindOrCheck(c, p.sons[1].sym, n)
assert isPatternParam(c, p[1])
if matches(c, p[0], n):
result = bindOrCheck(c, p[1].sym, n)
elif sameKinds(p, n):
case p.kind
of nkSym: result = p.sym == n.sym
@ -174,42 +174,41 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
of nkEmpty, nkNilLit, nkType:
result = true
else:
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 <= len(n):
for i in 0 .. plen - 2:
if not matches(c, p.sons[i], n.sons[i]): return
if plen == len(n) and lastSon(n).kind == nkHiddenStdConv and
lastSon(n).sons[1].kind == nkBracket:
if p.len <= n.len:
for i in 0..<p.len - 1:
if not matches(c, p[i], n[i]): return
if p.len == n.len and lastSon(n).kind == nkHiddenStdConv and
lastSon(n)[1].kind == nkBracket:
# unpack varargs:
let n = lastSon(n).sons[1]
let n = lastSon(n)[1]
arglist = newNodeI(nkArgList, n.info, n.len)
for i in 0..<n.len: arglist.sons[i] = n.sons[i]
for i in 0..<n.len: arglist[i] = n[i]
else:
arglist = newNodeI(nkArgList, n.info, len(n) - plen + 1)
arglist = newNodeI(nkArgList, n.info, n.len - p.len + 1)
# f(1, 2, 3)
# p(X)
for i in 0 .. len(n) - plen:
arglist.sons[i] = n.sons[i + plen - 1]
for i in 0..n.len - p.len:
arglist[i] = n[i + p.len - 1]
return bindOrCheck(c, v.sym, arglist)
elif plen-1 == len(n):
for i in 0 .. plen - 2:
if not matches(c, p.sons[i], n.sons[i]): return
elif p.len-1 == n.len:
for i in 0..<p.len - 1:
if not matches(c, p[i], n[i]): return
arglist = newNodeI(nkArgList, n.info)
return bindOrCheck(c, v.sym, arglist)
if plen == len(n):
for i in 0 ..< len(p):
if not matches(c, p.sons[i], n.sons[i]): return
if p.len == n.len:
for i in 0..<p.len:
if not matches(c, p[i], n[i]): return
result = true
proc matchStmtList(c: PPatternContext, p, n: PNode): PNode =
proc matchRange(c: PPatternContext, p, n: PNode, i: int): bool =
for j in 0 ..< p.len:
if not matches(c, p.sons[j], n.sons[i+j]):
for j in 0..<p.len:
if not matches(c, p[j], n[i+j]):
# we need to undo any bindings:
when defined(nimNoNilSeqs):
c.mapping = @[]
@ -222,36 +221,36 @@ proc matchStmtList(c: PPatternContext, p, n: PNode): PNode =
if p.kind == nkStmtList and n.kind == p.kind and p.len < n.len:
let n = flattenStmts(n)
# no need to flatten 'p' here as that has already been done
for i in 0 .. n.len - p.len:
for i in 0..n.len - p.len:
if matchRange(c, p, n, i):
c.subMatch = true
result = newNodeI(nkStmtList, n.info, 3)
result.sons[0] = extractRange(nkStmtList, n, 0, i-1)
result.sons[1] = extractRange(nkStmtList, n, i, i+p.len-1)
result.sons[2] = extractRange(nkStmtList, n, i+p.len, n.len-1)
result[0] = extractRange(nkStmtList, n, 0, i-1)
result[1] = extractRange(nkStmtList, n, i, i+p.len-1)
result[2] = extractRange(nkStmtList, n, i+p.len, n.len-1)
break
elif matches(c, p, n):
result = n
proc aliasAnalysisRequested(params: PNode): bool =
if params.len >= 2:
for i in 1 ..< params.len:
let param = params.sons[i].sym
for i in 1..<params.len:
let param = params[i].sym
if whichAlias(param) != aqNone: return true
proc addToArgList(result, n: PNode) =
if n.typ != nil and n.typ.kind != tyTyped:
if n.kind != nkArgList: result.add(n)
else:
for i in 0 ..< n.len: result.add(n.sons[i])
for i in 0..<n.len: result.add(n[i])
proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
## returns a tree to semcheck if the rule triggered; nil otherwise
var ctx: TPatternContext
ctx.owner = s
ctx.c = c
ctx.formals = len(s.typ)-1
var m = matchStmtList(ctx, s.ast.sons[patternPos], n)
ctx.formals = s.typ.len-1
var m = matchStmtList(ctx, s.ast[patternPos], n)
if isNil(m): return nil
# each parameter should have been bound; we simply setup a call and
# let semantic checking deal with the rest :-)
@ -262,8 +261,8 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
var args: PNode
if requiresAA:
args = newNodeI(nkArgList, n.info)
for i in 1 ..< params.len:
let param = params.sons[i].sym
for i in 1..<params.len:
let param = params[i].sym
let x = getLazy(ctx, param)
# couldn't bind parameter:
if isNil(x): return nil
@ -271,9 +270,9 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
if requiresAA: addToArgList(args, x)
# perform alias analysis here:
if requiresAA:
for i in 1 ..< params.len:
var rs = result.sons[i]
let param = params.sons[i].sym
for i in 1..<params.len:
var rs = result[i]
let param = params[i].sym
case whichAlias(param)
of aqNone: discard
of aqShouldAlias:
@ -298,5 +297,5 @@ proc applyRule*(c: PContext, s: PSym, n: PNode): PNode =
markUsed(c, n.info, s)
if ctx.subMatch:
assert m.len == 3
m.sons[1] = result
m[1] = result
result = m

View file

@ -242,23 +242,23 @@ proc setTarget*(t: var Target; o: TSystemOS, c: TSystemCPU) =
t.tnl = OS[o].newLine
proc nameToOS*(name: string): TSystemOS =
for i in succ(osNone) .. high(TSystemOS):
for i in succ(osNone)..high(TSystemOS):
if cmpIgnoreStyle(name, OS[i].name) == 0:
return i
result = osNone
proc listOSnames*(): seq[string] =
for i in succ(osNone) .. high(TSystemOS):
for i in succ(osNone)..high(TSystemOS):
result.add OS[i].name
proc nameToCPU*(name: string): TSystemCPU =
for i in succ(cpuNone) .. high(TSystemCPU):
for i in succ(cpuNone)..high(TSystemCPU):
if cmpIgnoreStyle(name, CPU[i].name) == 0:
return i
result = cpuNone
proc listCPUnames*(): seq[string] =
for i in succ(cpuNone) .. high(TSystemCPU):
for i in succ(cpuNone)..high(TSystemCPU):
result.add CPU[i].name
proc setTargetFromSystem*(t: var Target) =

View file

@ -42,5 +42,5 @@ proc iterToProcImpl*(c: PContext, n: PNode): PNode =
pattern = c.graph.emptyNode, genericParams = c.graph.emptyNode,
pragmas = orig[pragmasPos], exceptions = c.graph.emptyNode)
prc.ast.add iter.sym.ast.sons[resultPos]
prc.ast.add iter.sym.ast[resultPos]
addInterfaceDecl(c, prc)

View file

@ -32,7 +32,7 @@ proc semLocals*(c: PContext, n: PNode): PNode =
field.position = counter
inc(counter)
addSon(tupleType.n, newSymNode(field))
tupleType.n.add newSymNode(field)
addSonSkipIntLit(tupleType, field.typ)
var a = newSymNode(it, result.info)

View file

@ -107,12 +107,12 @@ proc illegalCustomPragma*(c: PContext, n: PNode, s: PSym) =
proc pragmaAsm*(c: PContext, n: PNode): char =
result = '\0'
if n != nil:
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)
for i in 0..<n.len:
let it = n[i]
if it.kind in nkPragmaCallKinds and it.len == 2 and it[0].kind == nkIdent:
case whichKeyword(it[0].ident)
of wSubsChar:
if it.sons[1].kind == nkCharLit: result = chr(int(it.sons[1].intVal))
if it[1].kind == nkCharLit: result = chr(int(it[1].intVal))
else: invalidPragma(c, it)
else: invalidPragma(c, it)
else:
@ -176,9 +176,9 @@ proc getStrLitNode(c: PContext, n: PNode): PNode =
# error correction:
result = newEmptyStrNode(c, n)
else:
n.sons[1] = c.semConstExpr(c, n.sons[1])
case n.sons[1].kind
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1]
n[1] = c.semConstExpr(c, n[1])
case n[1].kind
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n[1]
else:
localError(c.config, n.info, errStringLiteralExpected)
# error correction:
@ -191,9 +191,9 @@ proc expectIntLit(c: PContext, n: PNode): int =
if n.kind notin nkPragmaCallKinds or n.len != 2:
localError(c.config, n.info, errIntLiteralExpected)
else:
n.sons[1] = c.semConstExpr(c, n.sons[1])
case n.sons[1].kind
of nkIntLit..nkInt64Lit: result = int(n.sons[1].intVal)
n[1] = c.semConstExpr(c, n[1])
case n[1].kind
of nkIntLit..nkInt64Lit: result = int(n[1].intVal)
else: localError(c.config, n.info, errIntLiteralExpected)
proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string =
@ -210,9 +210,9 @@ proc processMagic(c: PContext, n: PNode, s: PSym) =
localError(c.config, n.info, errStringLiteralExpected)
return
var v: string
if n.sons[1].kind == nkIdent: v = n.sons[1].ident.s
if n[1].kind == nkIdent: v = n[1].ident.s
else: v = expectStrLit(c, n)
for m in low(TMagic) .. high(TMagic):
for m in low(TMagic)..high(TMagic):
if substr($m, 1) == v:
s.magic = m
break
@ -225,8 +225,8 @@ proc wordToCallConv(sw: TSpecialWord): TCallingConvention =
proc isTurnedOn(c: PContext, n: PNode): bool =
if n.kind in nkPragmaCallKinds and n.len == 2:
let x = c.semConstBoolExpr(c, n.sons[1])
n.sons[1] = x
let x = c.semConstBoolExpr(c, n[1])
n[1] = x
if x.kind == nkIntLit: return x.intVal != 0
localError(c.config, n.info, "'on' or 'off' expected")
@ -248,8 +248,8 @@ proc pragmaNoForward(c: PContext, n: PNode; flag=sfNoForward) =
(if flag == sfNoForward: "{.noForward.}" else: "{.reorder.}") & " is deprecated")
proc processCallConv(c: PContext, n: PNode) =
if n.kind in nkPragmaCallKinds and n.len == 2 and n.sons[1].kind == nkIdent:
let sw = whichKeyword(n.sons[1].ident)
if n.kind in nkPragmaCallKinds and n.len == 2 and n[1].kind == nkIdent:
let sw = whichKeyword(n[1].ident)
case sw
of FirstCallConv..LastCallConv:
c.optionStack[^1].defaultCC = wordToCallConv(sw)
@ -276,7 +276,7 @@ proc expectDynlibNode(c: PContext, n: PNode): PNode =
else:
# For the OpenGL wrapper we support:
# {.dynlib: myGetProcAddr(...).}
result = c.semExpr(c, n.sons[1])
result = c.semExpr(c, n[1])
if result.kind == nkSym and result.sym.kind == skConst:
result = result.sym.ast # look it up
if result.typ == nil or result.typ.kind notin {tyPointer, tyString, tyProc}:
@ -304,7 +304,7 @@ proc processDynLib(c: PContext, n: PNode, sym: PSym) =
sym.typ.callConv = ccCDecl
proc processNote(c: PContext, n: PNode) =
if n.kind in nkPragmaCallKinds and len(n) == 2 and
if n.kind in nkPragmaCallKinds and n.len == 2 and
n[0].kind == nkBracketExpr and
n[0].len == 2 and
n[0][1].kind == nkIdent and n[0][0].kind == nkIdent:
@ -323,7 +323,7 @@ proc processNote(c: PContext, n: PNode) =
return
let x = c.semConstBoolExpr(c, n[1])
n.sons[1] = x
n[1] = x
if x.kind == nkIntLit and x.intVal != 0: incl(c.config.notes, nk)
else: excl(c.config.notes, nk)
else:
@ -379,10 +379,10 @@ proc processExperimental(c: PContext; n: PNode) =
proc tryProcessOption(c: PContext, n: PNode, resOptions: var TOptions): bool =
result = true
if n.kind notin nkPragmaCallKinds or n.len != 2: result = false
elif n.sons[0].kind == nkBracketExpr: processNote(c, n)
elif n.sons[0].kind != nkIdent: result = false
elif n[0].kind == nkBracketExpr: processNote(c, n)
elif n[0].kind != nkIdent: result = false
else:
let sw = whichKeyword(n.sons[0].ident)
let sw = whichKeyword(n[0].ident)
if sw == wExperimental:
processExperimental(c, n)
return true
@ -394,10 +394,10 @@ proc tryProcessOption(c: PContext, n: PNode, resOptions: var TOptions): bool =
of wCallconv: processCallConv(c, n)
of wDynlib: processDynLib(c, n, nil)
of wOptimization:
if n.sons[1].kind != nkIdent:
if n[1].kind != nkIdent:
invalidPragma(c, n)
else:
case n.sons[1].ident.s.normalize
case n[1].ident.s.normalize
of "speed":
incl(resOptions, optOptimizeSpeed)
excl(resOptions, optOptimizeSize)
@ -416,15 +416,15 @@ proc processOption(c: PContext, n: PNode, resOptions: var TOptions) =
localError(c.config, n.info, "option expected")
proc processPush(c: PContext, n: PNode, start: int) =
if n.sons[start-1].kind in nkPragmaCallKinds:
if n[start-1].kind in nkPragmaCallKinds:
localError(c.config, n.info, "'push' cannot have arguments")
var x = pushOptionEntry(c)
for i in start ..< len(n):
if not tryProcessOption(c, n.sons[i], c.config.options):
for i in start..<n.len:
if not tryProcessOption(c, n[i], c.config.options):
# simply store it somewhere:
if x.otherPragmas.isNil:
x.otherPragmas = newNodeI(nkPragma, n.info)
x.otherPragmas.add n.sons[i]
x.otherPragmas.add n[i]
#localError(c.config, n.info, errOptionExpected)
# If stacktrace is disabled globally we should not enable it
@ -474,7 +474,7 @@ proc processCompile(c: PContext, n: PNode) =
recordPragma(c, it, "compile", src.string, dest.string)
proc getStrLit(c: PContext, n: PNode; i: int): string =
n.sons[i] = c.semConstExpr(c, n[i])
n[i] = c.semConstExpr(c, n[i])
case n[i].kind
of nkStrLit, nkRStrLit, nkTripleStrLit:
shallowCopy(result, n[i].strVal)
@ -482,7 +482,7 @@ proc processCompile(c: PContext, n: PNode) =
localError(c.config, n.info, errStringLiteralExpected)
result = ""
let it = if n.kind in nkPragmaCallKinds and n.len == 2: n.sons[1] else: n
let it = if n.kind in nkPragmaCallKinds and n.len == 2: n[1] else: n
if it.kind in {nkPar, nkTupleConstr} and it.len == 2:
let s = getStrLit(c, it, 0)
let dest = getStrLit(c, it, 1)
@ -507,10 +507,10 @@ proc processLink(c: PContext, n: PNode) =
recordPragma(c, n, "link", found.string)
proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
case n.sons[1].kind
case n[1].kind
of nkStrLit, nkRStrLit, nkTripleStrLit:
result = newNode(if n.kind == nkAsmStmt: nkAsmStmt else: nkArgList, n.info)
var str = n.sons[1].strVal
var str = n[1].strVal
if str == "":
localError(con.config, n.info, "empty 'asm' statement")
return
@ -519,7 +519,7 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
while true:
var b = strutils.find(str, marker, a)
var sub = if b < 0: substr(str, a) else: substr(str, a, b - 1)
if sub != "": addSon(result, newStrNode(nkStrLit, sub))
if sub != "": result.add newStrNode(nkStrLit, sub)
if b < 0: break
var c = strutils.find(str, marker, b + 1)
if c < 0: sub = substr(str, b + 1)
@ -530,12 +530,12 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
when false:
if e.kind == skStub: loadStub(e)
incl(e.flags, sfUsed)
addSon(result, newSymNode(e))
result.add newSymNode(e)
else:
addSon(result, newStrNode(nkStrLit, sub))
result.add newStrNode(nkStrLit, sub)
else:
# an empty '``' produces a single '`'
addSon(result, newStrNode(nkStrLit, $marker))
result.add newStrNode(nkStrLit, $marker)
if c < 0: break
a = c + 1
else:
@ -550,13 +550,13 @@ proc pragmaEmit(c: PContext, n: PNode) =
if n1.kind == nkBracket:
var b = newNodeI(nkBracket, n1.info, n1.len)
for i in 0..<n1.len:
b.sons[i] = c.semExpr(c, n1[i])
n.sons[1] = b
b[i] = c.semExpr(c, n1[i])
n[1] = b
else:
n.sons[1] = c.semConstExpr(c, n1)
case n.sons[1].kind
n[1] = c.semConstExpr(c, n1)
case n[1].kind
of nkStrLit, nkRStrLit, nkTripleStrLit:
n.sons[1] = semAsmOrEmit(c, n, '`')
n[1] = semAsmOrEmit(c, n, '`')
else:
localError(c.config, n.info, errStringLiteralExpected)
@ -569,20 +569,20 @@ proc pragmaUnroll(c: PContext, n: PNode) =
elif n.kind in nkPragmaCallKinds and n.len == 2:
var unrollFactor = expectIntLit(c, n)
if unrollFactor <% 32:
n.sons[1] = newIntNode(nkIntLit, unrollFactor)
n[1] = newIntNode(nkIntLit, unrollFactor)
else:
invalidPragma(c, n)
proc pragmaLine(c: PContext, n: PNode) =
if n.kind in nkPragmaCallKinds and n.len == 2:
n.sons[1] = c.semConstExpr(c, n.sons[1])
let a = n.sons[1]
n[1] = c.semConstExpr(c, n[1])
let a = n[1]
if a.kind in {nkPar, nkTupleConstr}:
# unpack the tuple
var x = a.sons[0]
var y = a.sons[1]
if x.kind == nkExprColonExpr: x = x.sons[1]
if y.kind == nkExprColonExpr: y = y.sons[1]
var x = a[0]
var y = a[1]
if x.kind == nkExprColonExpr: x = x[1]
if y.kind == nkExprColonExpr: y = y[1]
if x.kind != nkStrLit:
localError(c.config, n.info, errStringLiteralExpected)
elif y.kind != nkIntLit:
@ -614,7 +614,7 @@ proc pragmaRaisesOrTags(c: PContext, n: PNode) =
x.typ = t
if n.kind in nkPragmaCallKinds and n.len == 2:
let it = n.sons[1]
let it = n[1]
if it.kind notin {nkCurly, nkBracket}:
processExc(c, it)
else:
@ -630,8 +630,8 @@ proc pragmaLockStmt(c: PContext; it: PNode) =
if n.kind != nkBracket:
localError(c.config, n.info, errGenerated, "locks pragma takes a list of expressions")
else:
for i in 0 ..< n.len:
n.sons[i] = c.semExpr(c, n.sons[i])
for i in 0..<n.len:
n[i] = c.semExpr(c, n[i])
proc pragmaLocks(c: PContext, it: PNode): TLockLevel =
if it.kind notin nkPragmaCallKinds or it.len != 2:
@ -652,7 +652,7 @@ proc pragmaLocks(c: PContext, it: PNode): TLockLevel =
proc typeBorrow(c: PContext; sym: PSym, n: PNode) =
if n.kind in nkPragmaCallKinds and n.len == 2:
let it = n.sons[1]
let it = n[1]
if it.kind != nkAccQuoted:
localError(c.config, n.info, "a type can only borrow `.` for now")
incl(sym.typ.flags, tfBorrowDot)
@ -684,7 +684,7 @@ proc deprecatedStmt(c: PContext; outerPragma: PNode) =
incl(alias.flags, sfExported)
if sfCompilerProc in dest.flags: markCompilerProc(c, alias)
addInterfaceDecl(c, alias)
n.sons[1] = newSymNode(dest)
n[1] = newSymNode(dest)
else:
localError(c.config, n.info, "key:value pair expected")
@ -739,13 +739,13 @@ proc semCustomPragma(c: PContext, n: PNode): PNode =
proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
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
var it = n[i]
var key = if it.kind in nkPragmaCallKinds and it.len > 1: it[0] else: it
if key.kind == nkBracketExpr:
processNote(c, it)
return
elif key.kind notin nkIdentKinds:
n.sons[i] = semCustomPragma(c, it)
n[i] = semCustomPragma(c, it)
return
let ident = considerQuotedIdent(c, key)
var userPragma = strTableGet(c.userPragmas, ident)
@ -1108,7 +1108,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
if it.kind notin nkPragmaCallKinds or it.len != 2:
localError(c.config, it.info, "expression expected")
else:
it.sons[1] = c.semExpr(c, it.sons[1])
it[1] = c.semExpr(c, it[1])
of wExperimental:
if not isTopLevel(c):
localError(c.config, n.info, "'experimental' pragma only valid as toplevel statement or in a 'push' environment")
@ -1144,7 +1144,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
else:
if sym == nil or (sym.kind in {skVar, skLet, skParam,
skField, skProc, skFunc, skConverter, skMethod, skType}):
n.sons[i] = semCustomPragma(c, it)
n[i] = semCustomPragma(c, it)
elif sym != nil:
illegalCustomPragma(c, it, sym)
else:
@ -1152,7 +1152,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
proc overwriteLineInfo(n: PNode; info: TLineInfo) =
n.info = info
for i in 0..<safeLen(n):
for i in 0..<n.safeLen:
overwriteLineInfo(n[i], info)
proc mergePragmas(n, pragmas: PNode) =
@ -1161,7 +1161,7 @@ proc mergePragmas(n, pragmas: PNode) =
if n[pragmasPos].kind == nkEmpty:
n[pragmasPos] = pragmas
else:
for p in pragmas: n.sons[pragmasPos].add p
for p in pragmas: n[pragmasPos].add p
proc implicitPragmas*(c: PContext, sym: PSym, n: PNode,
validPragmas: TSpecialWords) =

View file

@ -20,14 +20,13 @@ proc prefixMatch*(p, s: string): PrefixMatch =
template eq(a, b): bool = a.toLowerAscii == b.toLowerAscii
if p.len > s.len: return PrefixMatch.None
var i = 0
let L = s.len
# check for prefix/contains:
while i < L:
while i < s.len:
if s[i] == '_': inc i
if i < L and eq(s[i], p[0]):
if i < s.len and eq(s[i], p[0]):
var ii = i+1
var jj = 1
while ii < L and jj < p.len:
while ii < s.len and jj < p.len:
if p[jj] == '_': inc jj
if s[ii] == '_': inc ii
if not eq(s[ii], p[jj]): break

View file

@ -14,14 +14,14 @@ import
ast, astalgo, msgs, semdata, types, trees, strutils
proc equalGenericParams(procA, procB: PNode): bool =
if len(procA) != len(procB): return false
for i in 0 ..< len(procA):
if procA.sons[i].kind != nkSym:
if procA.len != procB.len: return false
for i in 0..<procA.len:
if procA[i].kind != nkSym:
return false
if procB.sons[i].kind != nkSym:
if procB[i].kind != nkSym:
return false
let a = procA.sons[i].sym
let b = procB.sons[i].sym
let a = procA[i].sym
let b = procB[i].sym
if a.name.id != b.name.id or
not sameTypeOrNil(a.typ, b.typ, {ExactTypeDescValues}): return
if a.ast != nil and b.ast != nil:
@ -40,11 +40,11 @@ proc searchForProcOld*(c: PContext, scope: PScope, fn: PSym): PSym =
# not kept in the AST ..
while result != nil:
if result.kind == fn.kind and isGenericRoutine(result):
let genR = result.ast.sons[genericParamsPos]
let genF = fn.ast.sons[genericParamsPos]
let genR = result.ast[genericParamsPos]
let genF = fn.ast[genericParamsPos]
if exprStructuralEquivalent(genR, genF) and
exprStructuralEquivalent(result.ast.sons[paramsPos],
fn.ast.sons[paramsPos]) and
exprStructuralEquivalent(result.ast[paramsPos],
fn.ast[paramsPos]) and
equalGenericParams(genR, genF):
return
result = nextIdentIter(it, scope.symbols)
@ -95,15 +95,14 @@ proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym =
when false:
proc paramsFitBorrow(child, parent: PNode): bool =
var length = len(child)
result = false
if length == len(parent):
for i in 1 ..< length:
var m = child.sons[i].sym
var n = parent.sons[i].sym
if child.len == parent.len:
for i in 1..<child.len:
var m = child[i].sym
var n = parent[i].sym
assert((m.kind == skParam) and (n.kind == skParam))
if not compareTypes(m.typ, n.typ, dcEqOrDistinctOf): return
if not compareTypes(child.sons[0].typ, parent.sons[0].typ,
if not compareTypes(child[0].typ, parent[0].typ,
dcEqOrDistinctOf): return
result = true
@ -116,7 +115,7 @@ when false:
while result != nil:
# watchout! result must not be the same as fn!
if (result.Kind == fn.kind) and (result.id != fn.id):
if equalGenericParams(result.ast.sons[genericParamsPos],
fn.ast.sons[genericParamsPos]):
if equalGenericParams(result.ast[genericParamsPos],
fn.ast[genericParamsPos]):
if paramsFitBorrow(fn.typ.n, result.typ.n): return
result = NextIdentIter(it, scope.symbols)

View file

@ -82,7 +82,7 @@ when defined(nimpretty):
result = (n.info.line.int, n.info.line.int + countLines(n.comment))
else:
result = (n.info.line.int, n.info.line.int)
for i in 0 ..< safeLen(n):
for i in 0..<n.safeLen:
let (currMin, currMax) = minmaxLine(n[i])
if currMin < result[0]: result[0] = currMin
if currMax > result[1]: result[1] = currMax
@ -109,12 +109,11 @@ proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags; config: ConfigRef) =
g.config = config
proc addTok(g: var TSrcGen, kind: TTokType, s: string; sym: PSym = nil) =
var length = len(g.tokens)
setLen(g.tokens, length + 1)
g.tokens[length].kind = kind
g.tokens[length].length = int16(len(s))
g.tokens[length].sym = sym
add(g.buf, s)
setLen(g.tokens, g.tokens.len + 1)
g.tokens[^1].kind = kind
g.tokens[^1].length = int16(s.len)
g.tokens[^1].sym = sym
g.buf.add(s)
proc addPendingNL(g: var TSrcGen) =
if g.pendingNL >= 0:
@ -172,17 +171,17 @@ proc dedent(g: var TSrcGen) =
proc put(g: var TSrcGen, kind: TTokType, s: string; sym: PSym = nil) =
if kind != tkSpaces:
addPendingNL(g)
if len(s) > 0:
if s.len > 0:
addTok(g, kind, s, sym)
inc(g.lineLen, len(s))
inc(g.lineLen, s.len)
else:
g.pendingWhitespace = s.len
proc putComment(g: var TSrcGen, s: string) =
if s.len == 0: return
var i = 0
let hi = len(s) - 1
var isCode = (len(s) >= 2) and (s[1] != ' ')
let hi = s.len - 1
var isCode = (s.len >= 2) and (s[1] != ' ')
var ind = g.lineLen
var com = "## "
while i <= hi:
@ -201,7 +200,7 @@ proc putComment(g: var TSrcGen, s: string) =
inc(i)
optNL(g, ind)
of ' ', '\x09':
add(com, s[i])
com.add(s[i])
inc(i)
else:
# we may break the comment into a multi-line comment if the line
@ -214,7 +213,7 @@ proc putComment(g: var TSrcGen, s: string) =
optNL(g, ind)
com = "## "
while i <= hi and s[i] > ' ':
add(com, s[i])
com.add(s[i])
inc(i)
put(g, tkComment, com)
optNL(g)
@ -222,7 +221,7 @@ proc putComment(g: var TSrcGen, s: string) =
proc maxLineLength(s: string): int =
if s.len == 0: return 0
var i = 0
let hi = len(s) - 1
let hi = s.len - 1
var lineLen = 0
while i <= hi:
case s[i]
@ -243,7 +242,7 @@ proc maxLineLength(s: string): int =
proc putRawStr(g: var TSrcGen, kind: TTokType, s: string) =
var i = 0
let hi = len(s) - 1
let hi = s.len - 1
var str = ""
while i <= hi:
case s[i]
@ -259,12 +258,12 @@ proc putRawStr(g: var TSrcGen, kind: TTokType, s: string) =
inc(i)
optNL(g, 0)
else:
add(str, s[i])
str.add(s[i])
inc(i)
put(g, kind, str)
proc containsNL(s: string): bool =
for i in 0 ..< len(s):
for i in 0..<s.len:
case s[i]
of '\x0D', '\x0A':
return true
@ -273,9 +272,8 @@ proc containsNL(s: string): bool =
result = false
proc pushCom(g: var TSrcGen, n: PNode) =
var length = len(g.comStack)
setLen(g.comStack, length + 1)
g.comStack[length] = n
setLen(g.comStack, g.comStack.len + 1)
g.comStack[^1] = n
proc popAllComs(g: var TSrcGen) =
setLen(g.comStack, 0)
@ -292,11 +290,11 @@ proc shouldRenderComment(g: var TSrcGen, n: PNode): bool =
proc gcom(g: var TSrcGen, n: PNode) =
assert(n != nil)
if shouldRenderComment(g, n):
if (g.pendingNL < 0) and (len(g.buf) > 0) and (g.buf[len(g.buf)-1] != ' '):
if (g.pendingNL < 0) and (g.buf.len > 0) and (g.buf[^1] != ' '):
put(g, tkSpaces, Space)
# Before long comments we cannot make sure that a newline is generated,
# because this might be wrong. But it is no problem in practice.
if (g.pendingNL < 0) and (len(g.buf) > 0) and
if (g.pendingNL < 0) and (g.buf.len > 0) and
(g.lineLen < LineCommentColumn):
var ml = maxLineLength(n.comment)
if ml + LineCommentColumn <= MaxLineLen:
@ -304,7 +302,7 @@ proc gcom(g: var TSrcGen, n: PNode) =
putComment(g, n.comment) #assert(g.comStack[high(g.comStack)] = n);
proc gcoms(g: var TSrcGen) =
for i in 0 .. high(g.comStack): gcom(g, g.comStack[i])
for i in 0..high(g.comStack): gcom(g, g.comStack[i])
popAllComs(g)
proc lsub(g: TSrcGen; n: PNode): int
@ -398,8 +396,8 @@ 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 .. len(n) + theEnd:
let param = n.sons[i]
for i in start..n.len + theEnd:
let param = n[i]
if nfDefaultParam notin param.flags:
inc(result, lsub(g, param))
inc(result, 2) # for ``, ``
@ -409,7 +407,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 .. len(n) + theEnd: inc(result, lsub(g, n.sons[i]))
for i in start..n.len + theEnd: inc(result, lsub(g, n[i]))
proc lsub(g: TSrcGen; n: PNode): int =
# computes the length of a tree
@ -419,17 +417,17 @@ proc lsub(g: TSrcGen; n: PNode): int =
of nkEmpty: result = 0
of nkTripleStrLit:
if containsNL(n.strVal): result = MaxLineLen + 1
else: result = len(atom(g, n))
else: result = atom(g, n).len
of succ(nkEmpty)..pred(nkTripleStrLit), succ(nkTripleStrLit)..nkNilLit:
result = len(atom(g, n))
result = atom(g, n).len
of nkCall, nkBracketExpr, nkCurlyExpr, nkConv, nkPattern, nkObjConstr:
result = lsub(g, n.sons[0]) + lcomma(g, n, 1) + 2
result = lsub(g, n[0]) + lcomma(g, n, 1) + 2
of nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv: result = lsub(g, n[1])
of nkCast: result = lsub(g, n.sons[0]) + lsub(g, n.sons[1]) + len("cast[]()")
of nkAddr: result = (if n.len>0: lsub(g, n.sons[0]) + len("addr()") else: 4)
of nkStaticExpr: result = lsub(g, n.sons[0]) + len("static_")
of nkHiddenAddr, nkHiddenDeref, nkStringToCString, nkCStringToString: result = lsub(g, n.sons[0])
of nkCommand: result = lsub(g, n.sons[0]) + lcomma(g, n, 1) + 1
of nkCast: result = lsub(g, n[0]) + lsub(g, n[1]) + len("cast[]()")
of nkAddr: result = (if n.len>0: lsub(g, n[0]) + len("addr()") else: 4)
of nkStaticExpr: result = lsub(g, n[0]) + len("static_")
of nkHiddenAddr, nkHiddenDeref, nkStringToCString, nkCStringToString: result = lsub(g, n[0])
of nkCommand: result = lsub(g, n[0]) + lcomma(g, n, 1) + 1
of nkExprEqExpr, nkAsgn, nkFastAsgn: result = lsons(g, n) + 3
of nkPar, nkCurly, nkBracket, nkClosure: result = lcomma(g, n) + 2
of nkTupleConstr:
@ -439,93 +437,92 @@ 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("()") + len(n) - 1
result = lsons(g, n) + len("()") + n.len - 1
of nkTupleTy: result = lcomma(g, n) + len("tuple[]")
of nkTupleClassTy: result = len("tuple")
of nkDotExpr: result = lsons(g, n) + 1
of nkBind: result = lsons(g, n) + len("bind_")
of nkBindStmt: result = lcomma(g, n) + len("bind_")
of nkMixinStmt: result = lcomma(g, n) + len("mixin_")
of nkCheckedFieldExpr: result = lsub(g, n.sons[0])
of nkCheckedFieldExpr: result = lsub(g, n[0])
of nkLambda: result = lsons(g, n) + len("proc__=_")
of nkDo: result = lsons(g, n) + len("do__:_")
of nkConstDef, nkIdentDefs:
result = lcomma(g, n, 0, - 3)
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
if n[^2].kind != nkEmpty: result = result + lsub(g, n[^2]) + 2
if n[^1].kind != nkEmpty: result = result + lsub(g, n[^1]) + 3
of nkVarTuple: result = lcomma(g, n, 0, - 3) + len("() = ") + lsub(g, lastSon(n))
of nkChckRangeF: result = len("chckRangeF") + 2 + lcomma(g, n)
of nkChckRange64: result = len("chckRange64") + 2 + lcomma(g, n)
of nkChckRange: result = len("chckRange") + 2 + lcomma(g, n)
of nkObjDownConv, nkObjUpConv:
result = 2
if len(n) >= 1: result = result + lsub(g, n.sons[0])
if n.len >= 1: result = result + lsub(g, n[0])
result = result + lcomma(g, n, 1)
of nkExprColonExpr: result = lsons(g, n) + 2
of nkInfix: result = lsons(g, n) + 2
of nkPrefix:
result = lsons(g, n)+1+(if n.len > 0 and n.sons[1].kind == nkInfix: 2 else: 0)
result = lsons(g, n)+1+(if n.len > 0 and n[1].kind == nkInfix: 2 else: 0)
of nkPostfix: result = lsons(g, n)
of nkCallStrLit: result = lsons(g, n)
of nkPragmaExpr: result = lsub(g, n.sons[0]) + lcomma(g, n, 1)
of nkPragmaExpr: result = lsub(g, n[0]) + lcomma(g, n, 1)
of nkRange: result = lsons(g, n) + 2
of nkDerefExpr: result = lsub(g, n.sons[0]) + 2
of nkDerefExpr: result = lsub(g, n[0]) + 2
of nkAccQuoted: result = lsons(g, n) + 2
of nkIfExpr:
result = lsub(g, n.sons[0].sons[0]) + lsub(g, n.sons[0].sons[1]) + lsons(g, n, 1) +
result = lsub(g, n[0][0]) + lsub(g, n[0][1]) + lsons(g, n, 1) +
len("if_:_")
of nkElifExpr: result = lsons(g, n) + len("_elif_:_")
of nkElseExpr: result = lsub(g, n.sons[0]) + len("_else:_") # type descriptions
of nkTypeOfExpr: result = (if n.len > 0: lsub(g, n.sons[0]) else: 0)+len("typeof()")
of nkRefTy: result = (if n.len > 0: lsub(g, n.sons[0])+1 else: 0) + len("ref")
of nkPtrTy: result = (if n.len > 0: lsub(g, n.sons[0])+1 else: 0) + len("ptr")
of nkVarTy: result = (if n.len > 0: lsub(g, n.sons[0])+1 else: 0) + len("var")
of nkElseExpr: result = lsub(g, n[0]) + len("_else:_") # type descriptions
of nkTypeOfExpr: result = (if n.len > 0: lsub(g, n[0]) else: 0)+len("typeof()")
of nkRefTy: result = (if n.len > 0: lsub(g, n[0])+1 else: 0) + len("ref")
of nkPtrTy: result = (if n.len > 0: lsub(g, n[0])+1 else: 0) + len("ptr")
of nkVarTy: result = (if n.len > 0: lsub(g, n[0])+1 else: 0) + len("var")
of nkDistinctTy:
result = len("distinct") + (if n.len > 0: lsub(g, n.sons[0])+1 else: 0)
result = len("distinct") + (if n.len > 0: lsub(g, n[0])+1 else: 0)
if n.len > 1:
result += (if n[1].kind == nkWith: len("_with_") else: len("_without_"))
result += lcomma(g, n[1])
of nkStaticTy: result = (if n.len > 0: lsub(g, n.sons[0]) else: 0) +
of nkStaticTy: result = (if n.len > 0: lsub(g, n[0]) else: 0) +
len("static[]")
of nkTypeDef: result = lsons(g, n) + 3
of nkOfInherit: result = lsub(g, n.sons[0]) + len("of_")
of nkOfInherit: result = lsub(g, n[0]) + len("of_")
of nkProcTy: result = lsons(g, n) + len("proc_")
of nkIteratorTy: result = lsons(g, n) + len("iterator_")
of nkSharedTy: result = lsons(g, n) + len("shared_")
of nkEnumTy:
if len(n) > 0:
result = lsub(g, n.sons[0]) + lcomma(g, n, 1) + len("enum_")
if n.len > 0:
result = lsub(g, n[0]) + lcomma(g, n, 1) + len("enum_")
else:
result = len("enum")
of nkEnumFieldDef: result = lsons(g, n) + 3
of nkVarSection, nkLetSection:
if len(n) > 1: result = MaxLineLen + 1
if n.len > 1: result = MaxLineLen + 1
else: result = lsons(g, n) + len("var_")
of nkUsingStmt:
if len(n) > 1: result = MaxLineLen + 1
if n.len > 1: result = MaxLineLen + 1
else: result = lsons(g, n) + len("using_")
of nkReturnStmt:
if n.len > 0 and n[0].kind == nkAsgn:
result = len("return_") + lsub(g, n[0][1])
else:
result = len("return_") + lsub(g, n[0])
of nkRaiseStmt: result = lsub(g, n.sons[0]) + len("raise_")
of nkYieldStmt: result = lsub(g, n.sons[0]) + len("yield_")
of nkDiscardStmt: result = lsub(g, n.sons[0]) + len("discard_")
of nkBreakStmt: result = lsub(g, n.sons[0]) + len("break_")
of nkContinueStmt: result = lsub(g, n.sons[0]) + len("continue_")
of nkRaiseStmt: result = lsub(g, n[0]) + len("raise_")
of nkYieldStmt: result = lsub(g, n[0]) + len("yield_")
of nkDiscardStmt: result = lsub(g, n[0]) + len("discard_")
of nkBreakStmt: result = lsub(g, n[0]) + len("break_")
of nkContinueStmt: result = lsub(g, n[0]) + len("continue_")
of nkPragma: result = lcomma(g, n) + 4
of nkCommentStmt: result = len(n.comment)
of nkCommentStmt: result = n.comment.len
of nkOfBranch: result = lcomma(g, n, 0, - 2) + lsub(g, lastSon(n)) + len("of_:_")
of nkImportAs: result = lsub(g, n.sons[0]) + len("_as_") + lsub(g, n.sons[1])
of nkImportAs: result = lsub(g, n[0]) + len("_as_") + lsub(g, n[1])
of nkElifBranch: result = lsons(g, n) + len("elif_:_")
of nkElse: result = lsub(g, n.sons[0]) + len("else:_")
of nkFinally: result = lsub(g, n.sons[0]) + len("finally:_")
of nkElse: result = lsub(g, n[0]) + len("else:_")
of nkFinally: result = lsub(g, n[0]) + len("finally:_")
of nkGenericParams: result = lcomma(g, n) + 2
of nkFormalParams:
result = lcomma(g, n, 1) + 2
if n.sons[0].kind != nkEmpty: result = result + lsub(g, n.sons[0]) + 2
if n[0].kind != nkEmpty: result = result + lsub(g, n[0]) + 2
of nkExceptBranch:
result = lcomma(g, n, 0, -2) + lsub(g, lastSon(n)) + len("except_:_")
else: result = MaxLineLen + 1
@ -559,8 +556,8 @@ proc hasCom(n: PNode): bool =
case n.kind
of nkEmpty..nkNilLit: discard
else:
for i in 0 ..< len(n):
if hasCom(n.sons[i]): return true
for i in 0..<n.len:
if hasCom(n[i]): return true
proc putWithSpace(g: var TSrcGen, kind: TTokType, s: string) =
put(g, kind, s)
@ -568,16 +565,16 @@ 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 .. len(n) + theEnd:
var c = i < len(n) + theEnd
var sublen = lsub(g, n.sons[i]) + ord(c)
for i in start..n.len + theEnd:
var c = i < n.len + theEnd
var sublen = lsub(g, n[i]) + ord(c)
if not fits(g, sublen) and (ind + sublen < MaxLineLen): optNL(g, ind)
let oldLen = g.tokens.len
gsub(g, n.sons[i])
gsub(g, n[i])
if c:
if g.tokens.len > oldLen:
putWithSpace(g, separator, TokTypeToStr[separator])
if hasCom(n.sons[i]):
if hasCom(n[i]):
gcoms(g)
optNL(g, ind)
@ -603,17 +600,17 @@ 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 .. len(n) + theEnd: gsub(g, n.sons[i], c)
for i in start..n.len + theEnd: gsub(g, n[i], c)
proc gsection(g: var TSrcGen, n: PNode, c: TContext, kind: TTokType,
k: string) =
if len(n) == 0: return # empty var sections are possible
if n.len == 0: return # empty var sections are possible
putWithSpace(g, kind, k)
gcoms(g)
indentNL(g)
for i in 0 ..< len(n):
for i in 0..<n.len:
optNL(g)
gsub(g, n.sons[i], c)
gsub(g, n[i], c)
gcoms(g)
dedent(g)
@ -621,8 +618,8 @@ 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 .. len(n) + theEnd:
if (lsub(g, n.sons[i]) > MaxLineLen):
for i in start..n.len + theEnd:
if (lsub(g, n[i]) > MaxLineLen):
result = true
break
@ -630,8 +627,7 @@ proc gstmts(g: var TSrcGen, n: PNode, c: TContext, doIndent=true) =
if n.kind == nkEmpty: return
if n.kind in {nkStmtList, nkStmtListExpr, nkStmtListType}:
if doIndent: indentNL(g)
let L = n.len
for i in 0 .. L-1:
for i in 0..<n.len:
if i > 0:
optNL(g, n[i-1], n[i])
else:
@ -659,34 +655,33 @@ proc gcond(g: var TSrcGen, n: PNode) =
proc gif(g: var TSrcGen, n: PNode) =
var c: TContext
gcond(g, n.sons[0].sons[0])
gcond(g, n[0][0])
initContext(c)
putWithSpace(g, tkColon, ":")
if longMode(g, n) or (lsub(g, n.sons[0].sons[1]) + g.lineLen > MaxLineLen):
if longMode(g, n) or (lsub(g, n[0][1]) + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcoms(g) # a good place for comments
gstmts(g, n.sons[0].sons[1], c)
var length = len(n)
for i in 1 ..< length:
gstmts(g, n[0][1], c)
for i in 1..<n.len:
optNL(g)
gsub(g, n.sons[i], c)
gsub(g, n[i], c)
proc gwhile(g: var TSrcGen, n: PNode) =
var c: TContext
putWithSpace(g, tkWhile, "while")
gcond(g, n.sons[0])
gcond(g, n[0])
putWithSpace(g, tkColon, ":")
initContext(c)
if longMode(g, n) or (lsub(g, n.sons[1]) + g.lineLen > MaxLineLen):
if longMode(g, n) or (lsub(g, n[1]) + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcoms(g) # a good place for comments
gstmts(g, n.sons[1], c)
gstmts(g, n[1], c)
proc gpattern(g: var TSrcGen, n: PNode) =
var c: TContext
put(g, tkCurlyLe, "{")
initContext(c)
if longMode(g, n) or (lsub(g, n.sons[0]) + g.lineLen > MaxLineLen):
if longMode(g, n) or (lsub(g, n[0]) + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcoms(g) # a good place for comments
gstmts(g, n, c)
@ -694,58 +689,55 @@ proc gpattern(g: var TSrcGen, n: PNode) =
proc gpragmaBlock(g: var TSrcGen, n: PNode) =
var c: TContext
gsub(g, n.sons[0])
gsub(g, n[0])
putWithSpace(g, tkColon, ":")
initContext(c)
if longMode(g, n) or (lsub(g, n.sons[1]) + g.lineLen > MaxLineLen):
if longMode(g, n) or (lsub(g, n[1]) + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcoms(g) # a good place for comments
gstmts(g, n.sons[1], c)
gstmts(g, n[1], c)
proc gtry(g: var TSrcGen, n: PNode) =
var c: TContext
put(g, tkTry, "try")
putWithSpace(g, tkColon, ":")
initContext(c)
if longMode(g, n) or (lsub(g, n.sons[0]) + g.lineLen > MaxLineLen):
if longMode(g, n) or (lsub(g, n[0]) + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcoms(g) # a good place for comments
gstmts(g, n.sons[0], c)
gstmts(g, n[0], c)
gsons(g, n, c, 1)
proc gfor(g: var TSrcGen, n: PNode) =
var c: TContext
var length = len(n)
putWithSpace(g, tkFor, "for")
initContext(c)
if longMode(g, n) or
(lsub(g, n.sons[length - 1]) + lsub(g, n.sons[length - 2]) + 6 + g.lineLen >
MaxLineLen):
(lsub(g, n[^1]) + lsub(g, n[^2]) + 6 + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcomma(g, n, c, 0, - 3)
put(g, tkSpaces, Space)
putWithSpace(g, tkIn, "in")
gsub(g, n.sons[length - 2], c)
gsub(g, n[^2], c)
putWithSpace(g, tkColon, ":")
gcoms(g)
gstmts(g, n.sons[length - 1], c)
gstmts(g, n[^1], c)
proc gcase(g: var TSrcGen, n: PNode) =
var c: TContext
initContext(c)
var length = len(n)
if length == 0: return
var last = if n.sons[length-1].kind == nkElse: -2 else: -1
if n.len == 0: return
var last = if n[^1].kind == nkElse: -2 else: -1
if longMode(g, n, 0, last): incl(c.flags, rfLongMode)
putWithSpace(g, tkCase, "case")
gcond(g, n.sons[0])
gcond(g, n[0])
gcoms(g)
optNL(g)
gsons(g, n, c, 1, last)
if last == - 2:
initContext(c)
if longMode(g, n.sons[length - 1]): incl(c.flags, rfLongMode)
gsub(g, n.sons[length - 1], c)
if longMode(g, n[^1]): incl(c.flags, rfLongMode)
gsub(g, n[^1], c)
proc genSymSuffix(result: var string, s: PSym) {.inline.} =
if sfGenSym in s.flags:
@ -754,36 +746,36 @@ proc genSymSuffix(result: var string, s: PSym) {.inline.} =
proc gproc(g: var TSrcGen, n: PNode) =
var c: TContext
if n.sons[namePos].kind == nkSym:
let s = n.sons[namePos].sym
if n[namePos].kind == nkSym:
let s = n[namePos].sym
var ret = renderDefinitionName(s)
ret.genSymSuffix(s)
put(g, tkSymbol, ret)
else:
gsub(g, n.sons[namePos])
gsub(g, n[namePos])
if n.sons[patternPos].kind != nkEmpty:
gpattern(g, n.sons[patternPos])
if n[patternPos].kind != nkEmpty:
gpattern(g, n[patternPos])
let oldInGenericParams = g.inGenericParams
g.inGenericParams = true
if renderNoBody in g.flags and n[miscPos].kind != nkEmpty and
n[miscPos][1].kind != nkEmpty:
gsub(g, n[miscPos][1])
else:
gsub(g, n.sons[genericParamsPos])
gsub(g, n[genericParamsPos])
g.inGenericParams = oldInGenericParams
gsub(g, n.sons[paramsPos])
gsub(g, n[paramsPos])
if renderNoPragmas notin g.flags:
gsub(g, n.sons[pragmasPos])
gsub(g, n[pragmasPos])
if renderNoBody notin g.flags:
if n.sons[bodyPos].kind != nkEmpty:
if n[bodyPos].kind != nkEmpty:
put(g, tkSpaces, Space)
putWithSpace(g, tkEquals, "=")
indentNL(g)
gcoms(g)
dedent(g)
initContext(c)
gstmts(g, n.sons[bodyPos], c)
gstmts(g, n[bodyPos], c)
putNL(g)
else:
indentNL(g)
@ -806,33 +798,33 @@ proc gTypeClassTy(g: var TSrcGen, n: PNode) =
proc gblock(g: var TSrcGen, n: PNode) =
var c: TContext
initContext(c)
if n.sons[0].kind != nkEmpty:
if n[0].kind != nkEmpty:
putWithSpace(g, tkBlock, "block")
gsub(g, n.sons[0])
gsub(g, n[0])
else:
put(g, tkBlock, "block")
putWithSpace(g, tkColon, ":")
if longMode(g, n) or (lsub(g, n.sons[1]) + g.lineLen > MaxLineLen):
if longMode(g, n) or (lsub(g, n[1]) + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcoms(g)
gstmts(g, n.sons[1], c)
gstmts(g, n[1], c)
proc gstaticStmt(g: var TSrcGen, n: PNode) =
var c: TContext
putWithSpace(g, tkStatic, "static")
putWithSpace(g, tkColon, ":")
initContext(c)
if longMode(g, n) or (lsub(g, n.sons[0]) + g.lineLen > MaxLineLen):
if longMode(g, n) or (lsub(g, n[0]) + g.lineLen > MaxLineLen):
incl(c.flags, rfLongMode)
gcoms(g) # a good place for comments
gstmts(g, n.sons[0], c)
gstmts(g, n[0], c)
proc gasm(g: var TSrcGen, n: PNode) =
putWithSpace(g, tkAsm, "asm")
gsub(g, n.sons[0])
gsub(g, n[0])
gcoms(g)
if n.sons.len > 1:
gsub(g, n.sons[1])
if n.len > 1:
gsub(g, n[1])
proc gident(g: var TSrcGen, n: PNode) =
if g.inGenericParams and n.kind == nkSym:
@ -866,9 +858,9 @@ proc doParamsAux(g: var TSrcGen, params: PNode) =
gsemicolon(g, params, 1)
put(g, tkParRi, ")")
if params.len > 0 and params.sons[0].kind != nkEmpty:
if params.len > 0 and params[0].kind != nkEmpty:
putWithSpace(g, tkOpr, "->")
gsub(g, params.sons[0])
gsub(g, params[0])
proc gsub(g: var TSrcGen; n: PNode; i: int) =
if i < n.len:
@ -970,19 +962,19 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkColon, ":")
gsub(g, n, n.len-1)
else:
if len(n) >= 1: accentedName(g, n[0])
if n.len >= 1: accentedName(g, n[0])
put(g, tkParLe, "(")
gcomma(g, n, 1)
put(g, tkParRi, ")")
of nkCallStrLit:
if n.len > 0: accentedName(g, n[0])
if n.len > 1 and n.sons[1].kind == nkRStrLit:
if n.len > 1 and n[1].kind == nkRStrLit:
put(g, tkRStrLit, '\"' & replace(n[1].strVal, "\"", "\"\"") & '\"')
else:
gsub(g, n, 1)
of nkHiddenStdConv, nkHiddenSubConv, nkHiddenCallConv:
if n.len >= 2:
gsub(g, n.sons[1])
gsub(g, n[1])
else:
put(g, tkSymbol, "(wrong conv)")
of nkCast:
@ -997,7 +989,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkAddr, "addr")
if n.len > 0:
put(g, tkParLe, "(")
gsub(g, n.sons[0])
gsub(g, n[0])
put(g, tkParRi, ")")
of nkStaticExpr:
put(g, tkStatic, "static")
@ -1050,23 +1042,23 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gcomma(g, n)
put(g, tkParRi, ")")
of nkObjDownConv, nkObjUpConv:
if len(n) >= 1: gsub(g, n.sons[0])
if n.len >= 1: gsub(g, n[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 ..< len(n):
for i in 0..<n.len:
if i > 0: put(g, tkOpr, "|")
if n.sons[i].kind == nkSym:
if n[i].kind == nkSym:
let s = n[i].sym
if s.owner != nil:
put g, tkSymbol, n[i].sym.owner.name.s
put g, tkOpr, "."
put g, tkSymbol, n[i].sym.name.s
else:
gsub(g, n.sons[i], c)
gsub(g, n[i], c)
put(g, tkParRi, if n.kind == nkOpenSymChoice: "|...)" else: ")")
else:
gsub(g, n, 0)
@ -1113,20 +1105,19 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkDo:
putWithSpace(g, tkDo, "do")
if paramsPos < n.len:
doParamsAux(g, n.sons[paramsPos])
doParamsAux(g, n[paramsPos])
gsub(g, n, pragmasPos)
put(g, tkColon, ":")
gsub(g, n, bodyPos)
of nkConstDef, nkIdentDefs:
gcomma(g, n, 0, -3)
var L = len(n)
if L >= 2 and n.sons[L - 2].kind != nkEmpty:
if n.len >= 2 and n[^2].kind != nkEmpty:
putWithSpace(g, tkColon, ":")
gsub(g, n, L - 2)
if L >= 1 and n.sons[L - 1].kind != nkEmpty:
gsub(g, n, n.len - 2)
if n.len >= 1 and n[^1].kind != nkEmpty:
put(g, tkSpaces, Space)
putWithSpace(g, tkEquals, "=")
gsub(g, n.sons[L - 1], c)
gsub(g, n[^1], c)
of nkVarTuple:
put(g, tkParLe, "(")
gcomma(g, n, 0, -3)
@ -1142,7 +1133,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
infixArgument(g, n, 1)
put(g, tkSpaces, Space)
gsub(g, n, 0) # binary operator
if n.len == 3 and not fits(g, lsub(g, n.sons[2]) + lsub(g, n.sons[0]) + 1):
if n.len == 3 and not fits(g, lsub(g, n[2]) + lsub(g, n[0]) + 1):
optNL(g, g.indent + longIndentWid)
else:
put(g, tkSpaces, Space)
@ -1162,10 +1153,10 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkSpaces, Space)
if nNext.kind == nkInfix:
put(g, tkParLe, "(")
gsub(g, n.sons[1])
gsub(g, n[1])
put(g, tkParRi, ")")
else:
gsub(g, n.sons[1])
gsub(g, n[1])
of nkPostfix:
gsub(g, n, 1)
gsub(g, n, 0)
@ -1178,16 +1169,16 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkOpr, "[]")
of nkAccQuoted:
put(g, tkAccent, "`")
if n.len > 0: gsub(g, n.sons[0])
for i in 1 ..< n.len:
if n.len > 0: gsub(g, n[0])
for i in 1..<n.len:
put(g, tkSpaces, Space)
gsub(g, n.sons[i])
gsub(g, n[i])
put(g, tkAccent, "`")
of nkIfExpr:
putWithSpace(g, tkIf, "if")
if n.len > 0: gcond(g, n.sons[0].sons[0])
if n.len > 0: gcond(g, n[0][0])
putWithSpace(g, tkColon, ":")
if n.len > 0: gsub(g, n.sons[0], 1)
if n.len > 0: gsub(g, n[0], 1)
gsons(g, n, emptyContext, 1)
of nkElifExpr:
putWithSpace(g, tkElif, " elif")
@ -1201,30 +1192,30 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkTypeOfExpr:
put(g, tkType, "typeof")
put(g, tkParLe, "(")
if n.len > 0: gsub(g, n.sons[0])
if n.len > 0: gsub(g, n[0])
put(g, tkParRi, ")")
of nkRefTy:
if len(n) > 0:
if n.len > 0:
putWithSpace(g, tkRef, "ref")
gsub(g, n.sons[0])
gsub(g, n[0])
else:
put(g, tkRef, "ref")
of nkPtrTy:
if len(n) > 0:
if n.len > 0:
putWithSpace(g, tkPtr, "ptr")
gsub(g, n.sons[0])
gsub(g, n[0])
else:
put(g, tkPtr, "ptr")
of nkVarTy:
if len(n) > 0:
if n.len > 0:
putWithSpace(g, tkVar, "var")
gsub(g, n.sons[0])
gsub(g, n[0])
else:
put(g, tkVar, "var")
of nkDistinctTy:
if n.len > 0:
putWithSpace(g, tkDistinct, "distinct")
gsub(g, n.sons[0])
gsub(g, n[0])
if n.len > 1:
if n[1].kind == nkWith:
putWithSpace(g, tkSymbol, " with")
@ -1234,32 +1225,32 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
else:
put(g, tkDistinct, "distinct")
of nkTypeDef:
if n.sons[0].kind == nkPragmaExpr:
if n[0].kind == nkPragmaExpr:
# generate pragma after generic
gsub(g, n.sons[0], 0)
gsub(g, n[0], 0)
gsub(g, n, 1)
gsub(g, n.sons[0], 1)
gsub(g, n[0], 1)
else:
gsub(g, n, 0)
gsub(g, n, 1)
put(g, tkSpaces, Space)
if n.len > 2 and n.sons[2].kind != nkEmpty:
if n.len > 2 and n[2].kind != nkEmpty:
putWithSpace(g, tkEquals, "=")
gsub(g, n.sons[2])
gsub(g, n[2])
of nkObjectTy:
if len(n) > 0:
if n.len > 0:
putWithSpace(g, tkObject, "object")
gsub(g, n.sons[0])
gsub(g, n.sons[1])
gsub(g, n[0])
gsub(g, n[1])
gcoms(g)
gsub(g, n.sons[2])
gsub(g, n[2])
else:
put(g, tkObject, "object")
of nkRecList:
indentNL(g)
for i in 0 ..< len(n):
for i in 0..<n.len:
optNL(g)
gsub(g, n.sons[i], c)
gsub(g, n[i], c)
gcoms(g)
dedent(g)
putNL(g)
@ -1267,14 +1258,14 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
putWithSpace(g, tkOf, "of")
gsub(g, n, 0)
of nkProcTy:
if len(n) > 0:
if n.len > 0:
putWithSpace(g, tkProc, "proc")
gsub(g, n, 0)
gsub(g, n, 1)
else:
put(g, tkProc, "proc")
of nkIteratorTy:
if len(n) > 0:
if n.len > 0:
putWithSpace(g, tkIterator, "iterator")
gsub(g, n, 0)
gsub(g, n, 1)
@ -1284,12 +1275,12 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkStatic, "static")
put(g, tkBracketLe, "[")
if n.len > 0:
gsub(g, n.sons[0])
gsub(g, n[0])
put(g, tkBracketRi, "]")
of nkEnumTy:
if len(n) > 0:
if n.len > 0:
putWithSpace(g, tkEnum, "enum")
gsub(g, n.sons[0])
gsub(g, n[0])
gcoms(g)
indentNL(g)
gcommaAux(g, n, g.indent, 1)
@ -1345,21 +1336,20 @@ 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 = len(n)
if L == 0: return
if n.len == 0: return
if n.kind == nkVarSection: putWithSpace(g, tkVar, "var")
elif n.kind == nkLetSection: putWithSpace(g, tkLet, "let")
else: putWithSpace(g, tkUsing, "using")
if L > 1:
if n.len > 1:
gcoms(g)
indentNL(g)
for i in 0 ..< L:
for i in 0..<n.len:
optNL(g)
gsub(g, n.sons[i])
gsub(g, n[i])
gcoms(g)
dedent(g)
else:
gsub(g, n.sons[0])
gsub(g, n[0])
of nkReturnStmt:
putWithSpace(g, tkReturn, "return")
if n.len > 0 and n[0].kind == nkAsgn:
@ -1454,13 +1444,13 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gsub(g, n, 0)
putWithSpace(g, tkColon, ":")
gcoms(g)
gstmts(g, n.sons[1], c)
gstmts(g, n[1], c)
of nkElse:
optNL(g)
put(g, tkElse, "else")
putWithSpace(g, tkColon, ":")
gcoms(g)
gstmts(g, n.sons[0], c)
gstmts(g, n[0], c)
of nkFinally, nkDefer:
optNL(g)
if n.kind == nkFinally:
@ -1469,7 +1459,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkDefer, "defer")
putWithSpace(g, tkColon, ":")
gcoms(g)
gstmts(g, n.sons[0], c)
gstmts(g, n[0], c)
of nkExceptBranch:
optNL(g)
if n.len != 1:
@ -1495,9 +1485,9 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
put(g, tkParLe, "(")
gsemicolon(g, n, 1)
put(g, tkParRi, ")")
if n.len > 0 and n.sons[0].kind != nkEmpty:
if n.len > 0 and n[0].kind != nkEmpty:
putWithSpace(g, tkColon, ":")
gsub(g, n.sons[0])
gsub(g, n[0])
of nkTupleTy:
put(g, tkTuple, "tuple")
put(g, tkBracketLe, "[")
@ -1558,10 +1548,10 @@ proc renderModule*(n: PNode, infile, outfile: string,
g: TSrcGen
initSrcGen(g, renderFlags, conf)
g.fid = fid
for i in 0 ..< len(n):
gsub(g, n.sons[i])
for i in 0..<n.len:
gsub(g, n[i])
optNL(g)
case n.sons[i].kind
case n[i].kind
of nkTypeSection, nkConstSection, nkVarSection, nkLetSection,
nkCommentStmt: putNL(g)
else: discard
@ -1577,9 +1567,9 @@ proc initTokRender*(r: var TSrcGen, n: PNode, renderFlags: TRenderFlags = {}) =
gsub(r, n)
proc getNextTok*(r: var TSrcGen, kind: var TTokType, literal: var string) =
if r.idx < len(r.tokens):
if r.idx < r.tokens.len:
kind = r.tokens[r.idx].kind
var length = r.tokens[r.idx].length.int
let length = r.tokens[r.idx].length.int
literal = substr(r.buf, r.pos, r.pos + length - 1)
inc(r.pos, length)
inc(r.idx)
@ -1587,7 +1577,7 @@ proc getNextTok*(r: var TSrcGen, kind: var TTokType, literal: var string) =
kind = tkEof
proc getTokSym*(r: TSrcGen): PSym =
if r.idx > 0 and r.idx <= len(r.tokens):
if r.idx > 0 and r.idx <= r.tokens.len:
result = r.tokens[r.idx-1].sym
else:
result = nil

View file

@ -35,7 +35,7 @@ proc newDepN(id: int, pnode: PNode): DepN =
proc accQuoted(cache: IdentCache; n: PNode): PIdent =
var id = ""
for i in 0 ..< n.len:
for i in 0..<n.len:
let x = n[i]
case x.kind
of nkIdent: id.add(x.ident.s)
@ -75,8 +75,8 @@ proc computeDeps(cache: IdentCache; n: PNode, declares, uses: var IntSet; topLev
of nkLetSection, nkVarSection, nkUsingStmt:
for a in n:
if a.kind in {nkIdentDefs, nkVarTuple}:
for j in 0 .. a.len-3: decl(a[j])
for j in a.len-2..a.len-1: deps(a[j])
for j in 0..<a.len-2: decl(a[j])
for j in a.len-2..<a.len: deps(a[j])
of nkConstSection, nkTypeSection:
for a in n:
if a.len >= 3:
@ -95,19 +95,19 @@ proc computeDeps(cache: IdentCache; n: PNode, declares, uses: var IntSet; topLev
of nkSym: uses.incl n.sym.name.id
of nkAccQuoted: uses.incl accQuoted(cache, n).id
of nkOpenSymChoice, nkClosedSymChoice:
uses.incl n.sons[0].sym.name.id
uses.incl n[0].sym.name.id
of nkStmtList, nkStmtListExpr, nkWhenStmt, nkElifBranch, nkElse, nkStaticStmt:
for i in 0..<len(n): computeDeps(cache, n[i], declares, uses, topLevel)
for i in 0..<n.len: computeDeps(cache, n[i], declares, uses, topLevel)
of nkPragma:
let a = n.sons[0]
if a.kind == nkExprColonExpr and a.sons[0].kind == nkIdent and
a.sons[0].ident.s == "pragma":
let a = n[0]
if a.kind == nkExprColonExpr and a[0].kind == nkIdent and
a[0].ident.s == "pragma":
# user defined pragma
decl(a.sons[1])
decl(a[1])
else:
for i in 0..<safeLen(n): deps(n[i])
for i in 0..<n.safeLen: deps(n[i])
else:
for i in 0..<safeLen(n): deps(n[i])
for i in 0..<n.safeLen: deps(n[i])
proc cleanPath(s: string): string =
# Here paths may have the form A / B or "A/B"
@ -136,7 +136,7 @@ proc hasIncludes(n:PNode): bool =
if a.kind == nkIncludeStmt:
return true
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode {.procvar.} =
proc includeModule*(graph: ModuleGraph; s: PSym, fileIdx: FileIndex): PNode =
result = syntaxes.parseFile(fileIdx, graph.cache, graph.config)
graph.addDep(s, fileIdx)
graph.addIncludeDep(FileIndex s.position, fileIdx)
@ -150,7 +150,7 @@ proc expandIncludes(graph: ModuleGraph, module: PSym, n: PNode,
for a in n:
if a.kind == nkIncludeStmt:
for i in 0..<a.len:
var f = checkModuleName(graph.config, a.sons[i])
var f = checkModuleName(graph.config, a[i])
if f != InvalidFileIdx:
if containsOrIncl(includedFiles, f.int):
localError(graph.config, a.info, "recursive dependency: '$1'" %
@ -206,7 +206,7 @@ proc mergeSections(conf: ConfigRef; comps: seq[seq[DepN]], res: PNode) =
# need to merge them
var sn = newNode(kind)
for dn in cs:
sn.add dn.pnode.sons[0]
sn.add dn.pnode[0]
res.add sn
else:
# Problematic circular dependency, we arrange the nodes into
@ -340,7 +340,7 @@ proc buildGraph(n: PNode, deps: seq[(IntSet, IntSet)]): DepG =
# Build a dependency graph
result = newSeqOfCap[DepN](deps.len)
for i in 0..<deps.len:
result.add newDepN(i, n.sons[i])
result.add newDepN(i, n[i])
for i in 0..<deps.len:
var ni = result[i]
let uses = deps[i][1]

View file

@ -156,31 +156,31 @@ proc encodeNode(g: ModuleGraph; fInfo: TLineInfo, n: PNode,
encodeVInt(n.sym.id, result)
pushSym(w, n.sym)
else:
for i in 0 ..< len(n):
encodeNode(g, n.info, n.sons[i], result)
add(result, ')')
for i in 0..<n.len:
encodeNode(g, n.info, n[i], result)
result.add(')')
proc encodeLoc(g: ModuleGraph; loc: TLoc, result: var string) =
var oldLen = result.len
result.add('<')
if loc.k != low(loc.k): encodeVInt(ord(loc.k), result)
if loc.storage != low(loc.storage):
add(result, '*')
result.add('*')
encodeVInt(ord(loc.storage), result)
if loc.flags != {}:
add(result, '$')
result.add('$')
encodeVInt(cast[int32](loc.flags), result)
if loc.lode != nil:
add(result, '^')
result.add('^')
encodeNode(g, unknownLineInfo(), loc.lode, result)
if loc.r != nil:
add(result, '!')
result.add('!')
encodeStr($loc.r, result)
if oldLen + 1 == result.len:
# no data was necessary, so remove the '<' again:
setLen(result, oldLen)
else:
add(result, '>')
result.add('>')
proc encodeType(g: ModuleGraph, t: PType, result: var string) =
if t == nil:
@ -191,73 +191,73 @@ proc encodeType(g: ModuleGraph, t: PType, result: var string) =
if t.kind == tyForward: internalError(g.config, "encodeType: tyForward")
# for the new rodfile viewer we use a preceding [ so that the data section
# can easily be disambiguated:
add(result, '[')
result.add('[')
encodeVInt(ord(t.kind), result)
add(result, '+')
result.add('+')
encodeVInt(t.uniqueId, result)
if t.id != t.uniqueId:
add(result, '+')
result.add('+')
encodeVInt(t.id, result)
if t.n != nil:
encodeNode(g, unknownLineInfo(), t.n, result)
if t.flags != {}:
add(result, '$')
result.add('$')
encodeVInt(cast[int32](t.flags), result)
if t.callConv != low(t.callConv):
add(result, '?')
result.add('?')
encodeVInt(ord(t.callConv), result)
if t.owner != nil:
add(result, '*')
result.add('*')
encodeVInt(t.owner.id, result)
pushSym(w, t.owner)
if t.sym != nil:
add(result, '&')
result.add('&')
encodeVInt(t.sym.id, result)
pushSym(w, t.sym)
if t.size != - 1:
add(result, '/')
result.add('/')
encodeVBiggestInt(t.size, result)
if t.align != 2:
add(result, '=')
result.add('=')
encodeVInt(t.align, result)
if t.lockLevel.ord != UnspecifiedLockLevel.ord:
add(result, '\14')
result.add('\14')
encodeVInt(t.lockLevel.int16, result)
if t.paddingAtEnd != 0:
add(result, '\15')
result.add('\15')
encodeVInt(t.paddingAtEnd, result)
for a in t.attachedOps:
add(result, '\16')
result.add('\16')
if a == nil:
encodeVInt(-1, result)
else:
encodeVInt(a.id, result)
pushSym(w, a)
for i, s in items(t.methods):
add(result, '\19')
result.add('\19')
encodeVInt(i, result)
add(result, '\20')
result.add('\20')
encodeVInt(s.id, result)
pushSym(w, s)
encodeLoc(g, t.loc, result)
if t.typeInst != nil:
add(result, '\21')
result.add('\21')
encodeVInt(t.typeInst.uniqueId, result)
pushType(w, t.typeInst)
for i in 0 ..< len(t):
if t.sons[i] == nil:
add(result, "^()")
for i in 0..<t.len:
if t[i] == nil:
result.add("^()")
else:
add(result, '^')
encodeVInt(t.sons[i].uniqueId, result)
pushType(w, t.sons[i])
result.add('^')
encodeVInt(t[i].uniqueId, result)
pushType(w, t[i])
proc encodeLib(g: ModuleGraph, lib: PLib, info: TLineInfo, result: var string) =
add(result, '|')
result.add('|')
encodeVInt(ord(lib.kind), result)
add(result, '|')
result.add('|')
encodeStr($lib.name, result)
add(result, '|')
result.add('|')
encodeNode(g, info, lib.path, result)
proc encodeInstantiations(g: ModuleGraph; s: seq[PInstantiation];
@ -316,7 +316,7 @@ proc encodeSym(g: ModuleGraph, s: PSym, result: var string) =
encodeLoc(g, s.loc, result)
if s.annex != nil: encodeLib(g, s.annex, s.info, result)
if s.constraint != nil:
add(result, '#')
result.add('#')
encodeNode(g, unknownLineInfo(), s.constraint, result)
case s.kind
of skType, skGenericParam:

View file

@ -51,10 +51,10 @@ proc toStrMaxPrecision*(f: BiggestFloat, literalPostfix = ""): string =
setLen(result, n)
proc encodeStr*(s: string, result: var string) =
for i in 0 ..< len(s):
for i in 0..<s.len:
case s[i]
of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i])
else: add(result, '\\' & toHex(ord(s[i]), 2))
of 'a'..'z', 'A'..'Z', '0'..'9', '_': result.add(s[i])
else: result.add('\\' & toHex(ord(s[i]), 2))
proc hexChar(c: char, xi: var int) =
case c
@ -73,9 +73,9 @@ proc decodeStr*(s: cstring, pos: var int): string =
var xi = 0
hexChar(s[i-2], xi)
hexChar(s[i-1], xi)
add(result, chr(xi))
result.add(chr(xi))
of 'a'..'z', 'A'..'Z', '0'..'9', '_':
add(result, s[i])
result.add(s[i])
inc(i)
else: break
pos = i
@ -96,7 +96,7 @@ template encodeIntImpl(self) =
var v = x
var rem = v mod 190
if rem < 0:
add(result, '-')
result.add('-')
v = - (v div 190)
rem = - rem
else:
@ -105,7 +105,7 @@ template encodeIntImpl(self) =
if idx < 62: d = chars[idx]
else: d = chr(idx - 62 + 128)
if v != 0: self(v, result)
add(result, d)
result.add(d)
proc encodeVBiggestIntAux(x: BiggestInt, result: var string) =
## encode a biggest int as a variable length base 190 int.

View file

@ -79,7 +79,7 @@ proc len*(a: Rope): int =
proc newRope(data: string = ""): Rope =
new(result)
result.L = -len(data)
result.L = -data.len
result.data = data
when not compileOption("threads"):
@ -157,7 +157,7 @@ proc `&`*(a: string, b: Rope): Rope =
proc `&`*(a: openArray[Rope]): Rope =
## the concatenation operator for an openarray of ropes.
for i in 0 .. high(a): result = result & a[i]
for i in 0..high(a): result = result & a[i]
proc add*(a: var Rope, b: Rope) =
## adds `b` to the rope `a`.
@ -202,30 +202,29 @@ proc `$`*(r: Rope): string =
## converts a rope back to a string.
result = newString(r.len)
setLen(result, 0)
for s in leaves(r): add(result, s)
for s in leaves(r): result.add(s)
proc ropeConcat*(a: varargs[Rope]): Rope =
# not overloaded version of concat to speed-up `rfmt` a little bit
for i in 0 .. high(a): result = result & a[i]
for i in 0..high(a): result = result & a[i]
proc prepend*(a: var Rope, b: Rope) = a = b & a
proc prepend*(a: var Rope, b: string) = a = b & a
proc runtimeFormat*(frmt: FormatStr, args: openArray[Rope]): Rope =
var i = 0
var length = len(frmt)
result = nil
var num = 0
while i < length:
while i < frmt.len:
if frmt[i] == '$':
inc(i) # skip '$'
case frmt[i]
of '$':
add(result, "$")
result.add("$")
inc(i)
of '#':
inc(i)
add(result, args[num])
result.add(args[num])
inc(num)
of '0'..'9':
var j = 0
@ -237,7 +236,7 @@ proc runtimeFormat*(frmt: FormatStr, args: openArray[Rope]): Rope =
if j > high(args) + 1:
doAssert false, "invalid format string: " & frmt
else:
add(result, args[j-1])
result.add(args[j-1])
of '{':
inc(i)
var j = 0
@ -252,21 +251,21 @@ proc runtimeFormat*(frmt: FormatStr, args: openArray[Rope]): Rope =
if j > high(args) + 1:
doAssert false, "invalid format string: " & frmt
else:
add(result, args[j-1])
result.add(args[j-1])
of 'n':
add(result, "\n")
result.add("\n")
inc(i)
of 'N':
add(result, "\n")
result.add("\n")
inc(i)
else:
doAssert false, "invalid format string: " & frmt
var start = i
while i < length:
while i < frmt.len:
if frmt[i] != '$': inc(i)
else: break
if i - 1 >= start:
add(result, substr(frmt, start, i - 1))
result.add(substr(frmt, start, i - 1))
assert(ropeInvariant(result))
proc `%`*(frmt: static[FormatStr], args: openArray[Rope]): Rope =
@ -274,7 +273,7 @@ proc `%`*(frmt: static[FormatStr], args: openArray[Rope]): Rope =
template addf*(c: var Rope, frmt: FormatStr, args: openArray[Rope]) =
## shortcut for ``add(c, frmt % args)``.
add(c, frmt % args)
c.add(frmt % args)
when true:
template `~`*(r: string): Rope = r % []
@ -301,9 +300,8 @@ proc equalsFile*(r: Rope, f: File): bool =
for s in leaves(r):
var spos = 0
let slen = s.len
rtotal += slen
while spos < slen:
rtotal += s.len
while spos < s.len:
if bpos == blen:
# Read more data
bpos = 0
@ -312,7 +310,7 @@ proc equalsFile*(r: Rope, f: File): bool =
if blen == 0: # no more data in file
result = false
return
let n = min(blen - bpos, slen - spos)
let n = min(blen - bpos, s.len - spos)
# TODO There's gotta be a better way of comparing here...
if not equalMem(addr(buf[bpos]), cast[pointer](cast[int](cstring(s))+spos), n):
result = false

View file

@ -36,7 +36,7 @@ proc `|abs|`*(a: BiggestInt): BiggestInt =
result = low(a)
proc `|div|`*(a, b: BiggestInt): BiggestInt =
# (0..5) div (0..4) == (0..5) div (1..4) == (0 div 4) .. (5 div 1)
# (0..5) div (0..4) == (0..5) div (1..4) == (0 div 4)..(5 div 1)
if b == 0'i64:
# make the same as ``div 1``:
result = a

View file

@ -28,9 +28,8 @@ when not defined(leanCompiler):
# implementation
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.procvar.}
proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode {.
procvar.}
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc semExprNoType(c: PContext, n: PNode): PNode
proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode
proc semProcBody(c: PContext, n: PNode): PNode
@ -128,17 +127,17 @@ proc commonType*(x, y: PType): PType =
a.kind == b.kind:
# check for seq[empty] vs. seq[int]
let idx = ord(b.kind == tyArray)
if a.sons[idx].kind == tyEmpty: return y
if a[idx].kind == tyEmpty: return y
elif a.kind == tyTuple and b.kind == tyTuple and a.len == b.len:
var nt: PType
for i in 0..<a.len:
let aEmpty = isEmptyContainer(a.sons[i])
let bEmpty = isEmptyContainer(b.sons[i])
let aEmpty = isEmptyContainer(a[i])
let bEmpty = isEmptyContainer(b[i])
if aEmpty != bEmpty:
if nt.isNil: nt = copyType(a, a.owner, false)
nt.sons[i] = if aEmpty: b.sons[i] else: a.sons[i]
nt[i] = if aEmpty: b[i] else: a[i]
if not nt.isNil: result = nt
#elif b.sons[idx].kind == tyEmpty: return x
#elif b[idx].kind == tyEmpty: return x
elif a.kind == tyRange and b.kind == tyRange:
# consider: (range[0..3], range[0..4]) here. We should make that
# range[0..4]. But then why is (range[0..4], 6) not range[0..6]?
@ -278,7 +277,7 @@ when false:
proc hasCycle(n: PNode): bool =
incl n.flags, nfNone
for i in 0..<safeLen(n):
for i in 0..<n.safeLen:
if nfNone in n[i].flags or hasCycle(n[i]):
result = true
break
@ -382,7 +381,7 @@ when false:
# hopefully not required:
proc resetSemFlag(n: PNode) =
excl n.flags, nfSem
for i in 0 ..< n.safeLen:
for i in 0..<n.safeLen:
resetSemFlag(n[i])
proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
@ -400,10 +399,10 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
result = macroResult
excl(result.flags, nfSem)
#resetSemFlag n
if s.typ.sons[0] == nil:
if s.typ[0] == nil:
result = semStmt(c, result, flags)
else:
var retType = s.typ.sons[0]
var retType = s.typ[0]
if retType.kind == tyTypeDesc and tfUnresolved in retType.flags and
retType.len == 1:
# bug #11941: template fails(T: type X, v: auto): T
@ -441,7 +440,7 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
result = semExpr(c, result, flags)
result = fitNode(c, retType, result, result.info)
#globalError(s.info, errInvalidParamKindX, typeToString(s.typ.sons[0]))
#globalError(s.info, errInvalidParamKindX, typeToString(s.typ[0]))
dec(c.config.evalTemplateCounter)
discard c.friendModules.pop()
@ -496,13 +495,13 @@ proc semConceptBody(c: PContext, n: PNode): PNode
include semtypes, semtempl, semgnrc, semstmts, semexprs
proc addCodeForGenerics(c: PContext, n: PNode) =
for i in c.lastGenericIdx ..< c.generics.len:
for i in c.lastGenericIdx..<c.generics.len:
var prc = c.generics[i].inst.sym
if prc.kind in {skProc, skFunc, skMethod, skConverter} and prc.magic == mNone:
if prc.ast == nil or prc.ast.sons[bodyPos] == nil:
if prc.ast == nil or prc.ast[bodyPos] == nil:
internalError(c.config, prc.info, "no code for " & prc.name.s)
else:
addSon(n, prc.ast)
n.add prc.ast
c.lastGenericIdx = c.generics.len
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext =
@ -575,9 +574,9 @@ proc semStmtAndGenerateGenerics(c: PContext, n: PNode): PNode =
if c.lastGenericIdx < c.generics.len:
var a = newNodeI(nkStmtList, n.info)
addCodeForGenerics(c, a)
if len(a) > 0:
if a.len > 0:
# a generic has been added to `a`:
if result.kind != nkEmpty: addSon(a, result)
if result.kind != nkEmpty: a.add result
result = a
result = hloStmt(c, result)
if c.config.cmd == cmdInteractive and not isEmptyType(result.typ):

View file

@ -156,11 +156,11 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
for err in errors:
var errProto = ""
let n = err.sym.typ.n
for i in 1 ..< n.len:
var p = n.sons[i]
for i in 1..<n.len:
var p = n[i]
if p.kind == nkSym:
add(errProto, typeToString(p.sym.typ, preferName))
if i != n.len-1: add(errProto, ", ")
errProto.add(typeToString(p.sym.typ, preferName))
if i != n.len-1: errProto.add(", ")
# else: ignore internal error as we're already in error handling mode
if errProto == proto:
prefer = preferModuleInfo
@ -185,11 +185,11 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
inc skipped
continue
if err.sym.kind in routineKinds and err.sym.ast != nil:
add(candidates, renderTree(err.sym.ast,
candidates.add(renderTree(err.sym.ast,
{renderNoBody, renderNoComments, renderNoPragmas}))
else:
add(candidates, getProcHeader(c.config, err.sym, prefer))
add(candidates, "\n")
candidates.add(getProcHeader(c.config, err.sym, prefer))
candidates.add("\n")
let nArg = if err.firstMismatch.arg < n.len: n[err.firstMismatch.arg] else: nil
let nameParam = if err.firstMismatch.formal != nil: err.firstMismatch.formal.name.s else: ""
if n.len > 1:
@ -255,10 +255,10 @@ proc notFoundError*(c: PContext, n: PNode, errors: CandidateErrors) =
let (prefer, candidates) = presentFailedCandidates(c, n, errors)
var result = errTypeMismatch
add(result, describeArgs(c, n, 1, prefer))
add(result, '>')
result.add(describeArgs(c, n, 1, prefer))
result.add('>')
if candidates != "":
add(result, "\n" & errButExpected & "\n" & candidates)
result.add("\n" & errButExpected & "\n" & candidates)
localError(c.config, n.info, result & "\nexpression: " & $n)
proc bracketNotFoundError(c: PContext; n: PNode) =
@ -297,14 +297,14 @@ proc getMsgDiagnostic(c: PContext, flags: TExprFlags, n, f: PNode): string =
let ident = considerQuotedIdent(c, f, n).s
if nfDotField in n.flags and nfExplicitCall notin n.flags:
let sym = n.sons[1].typ.sym
let sym = n[1].typ.sym
var typeHint = ""
if sym == nil:
# Perhaps we're in a `compiles(foo.bar)` expression, or
# in a concept, eg:
# ExplainedConcept {.explain.} = concept x
# x.foo is int
# We could use: `(c.config $ n.sons[1].info)` to get more context.
# We could use: `(c.config $ n[1].info)` to get more context.
discard
else:
typeHint = " for type " & getProcHeader(c.config, sym)
@ -319,12 +319,12 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
errorsEnabled: bool): TCandidate =
var initialBinding: PNode
var alt: TCandidate
var f = n.sons[0]
var f = n[0]
if f.kind == nkBracketExpr:
# fill in the bindings:
semOpAux(c, f)
initialBinding = f
f = f.sons[0]
f = f[0]
else:
initialBinding = nil
@ -362,8 +362,8 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
template tryOp(x) =
let op = newIdentNode(getIdent(c.cache, x), n.info)
n.sons[0] = op
orig.sons[0] = op
n[0] = op
orig[0] = op
pickBest(op)
if nfExplicitCall in n.flags:
@ -374,7 +374,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
elif nfDotSetter in n.flags and f.kind == nkIdent and n.len == 3:
# we need to strip away the trailing '=' here:
let calleeName = newIdentNode(getIdent(c.cache, f.ident.s[0..f.ident.s.len-2]), n.info)
let calleeName = newIdentNode(getIdent(c.cache, f.ident.s[0..^2]), n.info)
let callOp = newIdentNode(getIdent(c.cache, ".="), n.info)
n.sons[0..1] = [callOp, n[1], calleeName]
orig.sons[0..1] = [callOp, orig[1], calleeName]
@ -392,7 +392,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
if {nfDotField, nfDotSetter} * n.flags != {}:
# clean up the inserted ops
n.sons.delete(2)
n.sons[0] = f
n[0] = f
return
if alt.state == csMatch and cmpCandidates(result, alt) == 0 and
not sameMethodDispatcher(result.calleeSym, alt.calleeSym):
@ -405,10 +405,10 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
elif c.config.errorCounter == 0:
# don't cascade errors
var args = "("
for i in 1 ..< len(n):
if i > 1: add(args, ", ")
add(args, typeToString(n.sons[i].typ))
add(args, ")")
for i in 1..<n.len:
if i > 1: args.add(", ")
args.add(typeToString(n[i].typ))
args.add(")")
localError(c.config, n.info, errAmbiguousCallXYZ % [
getProcHeader(c.config, result.calleeSym),
@ -417,31 +417,29 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
proc instGenericConvertersArg*(c: PContext, a: PNode, x: TCandidate) =
let a = if a.kind == nkHiddenDeref: a[0] else: a
if a.kind == nkHiddenCallConv and a.sons[0].kind == nkSym:
let s = a.sons[0].sym
if a.kind == nkHiddenCallConv and a[0].kind == nkSym:
let s = a[0].sym
if s.ast != nil and s.ast[genericParamsPos].kind != nkEmpty:
let finalCallee = generateInstance(c, s, x.bindings, a.info)
a.sons[0].sym = finalCallee
a.sons[0].typ = finalCallee.typ
#a.typ = finalCallee.typ.sons[0]
a[0].sym = finalCallee
a[0].typ = finalCallee.typ
#a.typ = finalCallee.typ[0]
proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
assert n.kind in nkCallKinds
if x.genericConverter:
for i in 1 ..< n.len:
instGenericConvertersArg(c, n.sons[i], x)
for i in 1..<n.len:
instGenericConvertersArg(c, n[i], x)
proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode =
var m: TCandidate
initCandidate(c, m, f)
var m = newCandidate(c, f)
result = paramTypesMatch(m, f, a, arg, nil)
if m.genericConverter and result != nil:
instGenericConvertersArg(c, result, m)
proc inferWithMetatype(c: PContext, formal: PType,
arg: PNode, coerceDistincts = false): PNode =
var m: TCandidate
initCandidate(c, m, formal)
var m = newCandidate(c, formal)
m.coerceDistincts = coerceDistincts
result = paramTypesMatch(m, formal, arg.typ, arg, nil)
if m.genericConverter and result != nil:
@ -475,8 +473,8 @@ proc updateDefaultParams(call: PNode) =
proc getCallLineInfo(n: PNode): TLineInfo =
case n.kind
of nkAccQuoted, nkBracketExpr, nkCall, nkCallStrLit, nkCommand:
getCallLineInfo(n.sons[0])
of nkDotExpr: getCallLineInfo(n.sons[1])
getCallLineInfo(n[0])
of nkDotExpr: getCallLineInfo(n[1])
else: n.info
proc semResolvedCall(c: PContext, x: TCandidate,
@ -489,12 +487,12 @@ proc semResolvedCall(c: PContext, x: TCandidate,
assert finalCallee.ast != nil
if x.hasFauxMatch:
result = x.call
result.sons[0] = newSymNode(finalCallee, getCallLineInfo(result.sons[0]))
result[0] = newSymNode(finalCallee, getCallLineInfo(result[0]))
if containsGenericType(result.typ) or x.fauxMatch == tyUnknown:
result.typ = newTypeS(x.fauxMatch, c)
if result.typ.kind == tyError: incl result.typ.flags, tfCheckedForDestructor
return
let gp = finalCallee.ast.sons[genericParamsPos]
let gp = finalCallee.ast[genericParamsPos]
if gp.kind != nkEmpty:
if x.calleeSym.kind notin {skMacro, skTemplate}:
if x.calleeSym.magic in {mArrGet, mArrPut}:
@ -516,7 +514,7 @@ proc semResolvedCall(c: PContext, x: TCandidate,
result = x.call
instGenericConvertersSons(c, result, x)
result[0] = newSymNode(finalCallee, getCallLineInfo(result[0]))
result.typ = finalCallee.typ.sons[0]
result.typ = finalCallee.typ[0]
updateDefaultParams(result)
proc canDeref(n: PNode): bool {.inline.} =
@ -525,8 +523,8 @@ proc canDeref(n: PNode): bool {.inline.} =
proc tryDeref(n: PNode): PNode =
result = newNodeI(nkHiddenDeref, n.info)
result.typ = n.typ.skipTypes(abstractInst).sons[0]
result.addSon(n)
result.typ = n.typ.skipTypes(abstractInst)[0]
result.add n
proc semOverloadedCall(c: PContext, n, nOrig: PNode,
filter: TSymKinds, flags: TExprFlags): PNode =
@ -548,12 +546,12 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
# inside `resolveOverloads` or it could be moved all the way
# into sigmatch with hidden conversion produced there
#
n.sons[1] = n.sons[1].tryDeref
n[1] = n[1].tryDeref
var r = resolveOverloads(c, n, nOrig, filter, flags, errors, efExplain in flags)
if r.state == csMatch: result = semResolvedCall(c, r, n, flags)
else:
# get rid of the deref again for a better error message:
n.sons[1] = n.sons[1].sons[0]
n[1] = n[1][0]
#notFoundError(c, n, errors)
if efExplain notin flags:
# repeat the overload resolution,
@ -574,12 +572,11 @@ proc explicitGenericInstError(c: PContext; n: PNode): PNode =
result = n
proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
var m: TCandidate
# binding has to stay 'nil' for this to work!
initCandidate(c, m, s, nil)
var m = newCandidate(c, s, nil)
for i in 1..len(n)-1:
let formal = s.ast.sons[genericParamsPos].sons[i-1].typ
for i in 1..<n.len:
let formal = s.ast[genericParamsPos][i-1].typ
var arg = n[i].typ
# try transforming the argument into a static one before feeding it into
# typeRel
@ -600,19 +597,19 @@ 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..len(n)-1:
let e = semExpr(c, n.sons[i])
for i in 1..<n.len:
let e = semExpr(c, n[i])
if e.typ == nil:
n.sons[i].typ = errorType(c)
n[i].typ = errorType(c)
else:
n.sons[i].typ = e.typ.skipTypes({tyTypeDesc})
n[i].typ = e.typ.skipTypes({tyTypeDesc})
var s = s
var a = n.sons[0]
var a = n[0]
if a.kind == nkSym:
# common case; check the only candidate has the right
# number of generic type parameters:
if safeLen(s.ast.sons[genericParamsPos]) != n.len-1:
let expected = safeLen(s.ast.sons[genericParamsPos])
if s.ast[genericParamsPos].safeLen != n.len-1:
let expected = s.ast[genericParamsPos].safeLen
localError(c.config, getCallLineInfo(n), errGenerated, "cannot instantiate: '" & renderTree(n) &
"'; got " & $(n.len-1) & " type(s) but expected " & $expected)
return n
@ -623,13 +620,13 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
# XXX I think this could be improved by reusing sigmatch.paramTypesMatch.
# It's good enough for now.
result = newNodeI(a.kind, getCallLineInfo(n))
for i in 0 ..< len(a):
var candidate = a.sons[i].sym
for i in 0..<a.len:
var candidate = a[i].sym
if candidate.kind in {skProc, skMethod, skConverter,
skFunc, skIterator}:
# it suffices that the candidate has the proper number of generic
# type parameters:
if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
if candidate.ast[genericParamsPos].safeLen == n.len-1:
let x = explicitGenericSym(c, n, candidate)
if x != nil: result.add(x)
# get rid of nkClosedSymChoice if not ambiguous:
@ -649,7 +646,7 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
var hasDistinct = false
call.add(newIdentNode(fn.name, fn.info))
for i in 1..<fn.typ.n.len:
let param = fn.typ.n.sons[i]
let param = fn.typ.n[i]
let t = skipTypes(param.typ, abstractVar-{tyTypeDesc, tyDistinct})
if t.kind == tyDistinct or param.typ.kind == tyDistinct: hasDistinct = true
var x: PType
@ -662,8 +659,8 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
if hasDistinct:
var resolved = semOverloadedCall(c, call, call, {fn.kind}, {})
if resolved != nil:
result = resolved.sons[0].sym
if not compareTypes(result.typ.sons[0], fn.typ.sons[0], dcEqIgnoreDistinct):
result = resolved[0].sym
if not compareTypes(result.typ[0], fn.typ[0], dcEqIgnoreDistinct):
result = nil
elif result.magic in {mArrPut, mArrGet}:
# cannot borrow these magics for now

View file

@ -162,11 +162,10 @@ proc getCurrOwner*(c: PContext): PSym =
result = c.graph.owners[^1]
proc pushOwner*(c: PContext; owner: PSym) =
add(c.graph.owners, owner)
c.graph.owners.add(owner)
proc popOwner*(c: PContext) =
var length = len(c.graph.owners)
if length > 0: setLen(c.graph.owners, length - 1)
if c.graph.owners.len > 0: setLen(c.graph.owners, c.graph.owners.len - 1)
else: internalError(c.config, "popOwner")
proc lastOptionEntry*(c: PContext): POptionEntry =
@ -203,7 +202,7 @@ proc considerGenSyms*(c: PContext; n: PNode) =
n.sym = s
else:
for i in 0..<n.safeLen:
considerGenSyms(c, n.sons[i])
considerGenSyms(c, n[i])
proc newOptionEntry*(conf: ConfigRef): POptionEntry =
new(result)
@ -250,11 +249,9 @@ proc newContext*(graph: ModuleGraph; module: PSym): PContext =
result.features = graph.config.features
proc inclSym(sq: var seq[PSym], s: PSym) =
var L = len(sq)
for i in 0 ..< L:
for i in 0..<sq.len:
if sq[i].id == s.id: return
setLen(sq, L + 1)
sq[L] = s
sq.add s
proc addConverter*(c: PContext, conv: PSym) =
inclSym(c.converters, conv)
@ -407,8 +404,8 @@ proc makeRangeType*(c: PContext; first, last: BiggestInt;
info: TLineInfo; intType: PType = nil): PType =
let intType = if intType != nil: intType else: getSysType(c.graph, info, tyInt)
var n = newNodeI(nkRange, info)
addSon(n, newIntTypeNode(first, intType))
addSon(n, newIntTypeNode(last, intType))
n.add newIntTypeNode(first, intType)
n.add newIntTypeNode(last, intType)
result = newTypeS(tyRange, c)
result.n = n
addSonSkipIntLit(result, intType) # basetype of range
@ -425,16 +422,16 @@ proc illFormedAstLocal*(n: PNode; conf: ConfigRef) =
localError(conf, n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc checkSonsLen*(n: PNode, length: int; conf: ConfigRef) =
if len(n) != length: illFormedAst(n, conf)
if n.len != length: illFormedAst(n, conf)
proc checkMinSonsLen*(n: PNode, length: int; conf: ConfigRef) =
if len(n) < length: illFormedAst(n, conf)
if n.len < length: illFormedAst(n, conf)
proc isTopLevel*(c: PContext): bool {.inline.} =
result = c.currentScope.depthLevel <= 2
proc pushCaseContext*(c: PContext, caseNode: PNode) =
add(c.p.caseContext, (caseNode, 0))
c.p.caseContext.add((caseNode, 0))
proc popCaseContext*(c: PContext) =
discard pop(c.p.caseContext)

File diff suppressed because it is too large Load diff

View file

@ -27,19 +27,18 @@ proc instFieldLoopBody(c: TFieldInstCtx, n: PNode, forLoop: PNode): PNode =
of nkIdent, nkSym:
result = n
let ident = considerQuotedIdent(c.c, n)
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
elif c.tupleType.n.isNil: "Field" & $c.tupleIndex
else: c.tupleType.n.sons[c.tupleIndex].sym.name.s
else: c.tupleType.n[c.tupleIndex].sym.name.s
result = newStrNode(nkStrLit, fieldName)
return
# other fields:
for i in ord(c.replaceByFieldName)..L-3:
for i in ord(c.replaceByFieldName)..<forLoop.len-2:
if ident.id == considerQuotedIdent(c.c, forLoop[i]).id:
var call = forLoop.sons[L-2]
var tupl = call.sons[i+1-ord(c.replaceByFieldName)]
var call = forLoop[^2]
var tupl = call[i+1-ord(c.replaceByFieldName)]
if c.field.isNil:
result = newNodeI(nkBracketExpr, n.info)
result.add(tupl)
@ -54,9 +53,9 @@ 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, len(n))
for i in 0 ..< len(n):
result.sons[i] = instFieldLoopBody(c, n.sons[i], forLoop)
newSons(result, n.len)
for i in 0..<n.len:
result[i] = instFieldLoopBody(c, n[i], forLoop)
type
TFieldsCtx = object
@ -78,8 +77,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
closeScope(c.c)
of nkNilLit: discard
of nkRecCase:
let L = forLoop.len
let call = forLoop.sons[L-2]
let call = forLoop[^2]
if call.len > 2:
localError(c.c.config, forLoop.info,
"parallel 'fields' iterator does not work for 'case' objects")
@ -90,15 +88,14 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
var caseStmt = newNodeI(nkCaseStmt, forLoop.info)
# generate selector:
var access = newNodeI(nkDotExpr, forLoop.info, 2)
access.sons[0] = call.sons[1]
access.sons[1] = newSymNode(typ.sons[0].sym, forLoop.info)
access[0] = call[1]
access[1] = newSymNode(typ[0].sym, forLoop.info)
caseStmt.add(semExprWithType(c.c, access))
# copy the branches over, but replace the fields with the for loop body:
for i in 1 ..< typ.len:
for i in 1..<typ.len:
var branch = copyTree(typ[i])
let L = branch.len
branch.sons[L-1] = newNodeI(nkStmtList, forLoop.info)
semForObjectFields(c, typ[i].lastSon, forLoop, branch[L-1])
branch[^1] = newNodeI(nkStmtList, forLoop.info)
semForObjectFields(c, typ[i].lastSon, forLoop, branch[^1])
caseStmt.add(branch)
father.add(caseStmt)
of nkRecList:
@ -116,30 +113,29 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
trueSymbol = newSym(skUnknown, getIdent(c.cache, "true"), getCurrOwner(c), n.info)
trueSymbol.typ = getSysType(c.graph, n.info, tyBool)
result.sons[0] = newSymNode(trueSymbol, n.info)
result[0] = newSymNode(trueSymbol, n.info)
var stmts = newNodeI(nkStmtList, n.info)
result.sons[1] = stmts
result[1] = stmts
var length = len(n)
var call = n.sons[length-2]
if length-2 != len(call)-1 + ord(m==mFieldPairs):
var call = n[^2]
if n.len-2 != call.len-1 + ord(m==mFieldPairs):
localError(c.config, n.info, errWrongNumberOfVariables)
return result
const skippedTypesForFields = abstractVar - {tyTypeDesc} + tyUserTypeClasses
var tupleTypeA = skipTypes(call.sons[1].typ, skippedTypesForFields)
var tupleTypeA = skipTypes(call[1].typ, skippedTypesForFields)
if tupleTypeA.kind notin {tyTuple, tyObject}:
localError(c.config, n.info, errGenerated, "no object or tuple type")
return result
for i in 1..call.len-1:
var tupleTypeB = skipTypes(call.sons[i].typ, skippedTypesForFields)
for i in 1..<call.len:
var tupleTypeB = skipTypes(call[i].typ, skippedTypesForFields)
if not sameType(tupleTypeA, tupleTypeB):
typeMismatch(c.config, call.sons[i].info, tupleTypeA, tupleTypeB)
typeMismatch(c.config, call[i].info, tupleTypeA, tupleTypeB)
inc(c.p.nestedLoopCounter)
if tupleTypeA.kind == tyTuple:
var loopBody = n.sons[length-1]
for i in 0..len(tupleTypeA)-1:
var loopBody = n[^1]
for i in 0..<tupleTypeA.len:
openScope(c)
var fc: TFieldInstCtx
fc.tupleType = tupleTypeA
@ -158,8 +154,8 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
var t = tupleTypeA
while t.kind == tyObject:
semForObjectFields(fc, t.n, n, stmts)
if t.sons[0] == nil: break
t = skipTypes(t.sons[0], skipPtrs)
if t[0] == nil: break
t = skipTypes(t[0], skipPtrs)
dec(c.p.nestedLoopCounter)
# for TR macros this 'while true: ...; break' loop is pretty bad, so
# we avoid it now if we can:

View file

@ -104,9 +104,9 @@ proc ordinalValToString*(a: PNode; g: ModuleGraph): string =
result = $chr(toInt64(x) and 0xff)
of tyEnum:
var n = t.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
for i in 0..<n.len:
if n[i].kind != nkSym: internalError(g.config, a.info, "ordinalValToString")
var field = n[i].sym
if field.position == x:
if field.ast == nil:
return field.name.s
@ -119,10 +119,10 @@ proc ordinalValToString*(a: PNode; g: ModuleGraph): string =
result = $x
proc isFloatRange(t: PType): bool {.inline.} =
result = t.kind == tyRange and t.sons[0].kind in {tyFloat..tyFloat128}
result = t.kind == tyRange and t[0].kind in {tyFloat..tyFloat128}
proc isIntRange(t: PType): bool {.inline.} =
result = t.kind == tyRange and t.sons[0].kind in {
result = t.kind == tyRange and t[0].kind in {
tyInt..tyInt64, tyUInt8..tyUInt32}
proc pickIntRange(a, b: PType): PType =
@ -144,16 +144,16 @@ proc makeRange(typ: PType, first, last: BiggestInt; g: ModuleGraph): PType =
result = typ
else:
var n = newNode(nkRange)
addSon(n, lowerNode)
addSon(n, newIntNode(nkIntLit, maxA))
n.add lowerNode
n.add newIntNode(nkIntLit, maxA)
result = newType(tyRange, typ.owner)
result.n = n
addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
proc makeRangeF(typ: PType, first, last: BiggestFloat; g: ModuleGraph): PType =
var n = newNode(nkRange)
addSon(n, newFloatNode(nkFloatLit, min(first.float, last.float)))
addSon(n, newFloatNode(nkFloatLit, max(first.float, last.float)))
n.add newFloatNode(nkFloatLit, min(first.float, last.float))
n.add newFloatNode(nkFloatLit, max(first.float, last.float))
result = newType(tyRange, typ.owner)
result.n = n
addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
@ -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(len(a)), n, g)
result = newIntNodeT(toInt128(a.len), n, g)
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
# XXX: Hides overflow/underflow
of mAbsI: result = foldAbs(getInt(a), n, g)
@ -372,17 +372,17 @@ 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 ..< len(n):
var it = n.sons[i]
for i in 0..<n.len:
var it = n[i]
if it.len == 2:
var e = getConstExpr(c, it.sons[0], g)
var e = getConstExpr(c, it[0], g)
if e == nil: return nil
if getOrdValue(e) != 0:
if result == nil:
result = getConstExpr(c, it.sons[1], g)
result = getConstExpr(c, it[1], g)
if result == nil: return
elif it.len == 1:
if result == nil: result = getConstExpr(c, it.sons[0], g)
if result == nil: result = getConstExpr(c, it[0], g)
else: internalError(g.config, it.info, "getConstIfExpr()")
proc leValueConv*(a, b: PNode): bool =
@ -401,17 +401,17 @@ proc leValueConv*(a, b: PNode): bool =
else: result = false # internalError(a.info, "leValueConv")
proc magicCall(m: PSym, n: PNode; g: ModuleGraph): PNode =
if len(n) <= 1: return
if n.len <= 1: return
var s = n.sons[0].sym
var a = getConstExpr(m, n.sons[1], g)
var s = n[0].sym
var a = getConstExpr(m, n[1], g)
var b, c: PNode
if a == nil: return
if len(n) > 2:
b = getConstExpr(m, n.sons[2], g)
if n.len > 2:
b = getConstExpr(m, n[2], g)
if b == nil: return
if len(n) > 3:
c = getConstExpr(m, n.sons[3], g)
if n.len > 3:
c = getConstExpr(m, n[3], g)
if c == nil: return
result = evalOp(s.magic, n, a, b, c, g)
@ -478,58 +478,58 @@ proc getArrayConstr(m: PSym, n: PNode; g: ModuleGraph): PNode =
if result == nil: result = n
proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
var x = getConstExpr(m, n.sons[0], g)
var x = getConstExpr(m, n[0], g)
if x == nil or x.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind == tyTypeDesc:
return
var y = getConstExpr(m, n.sons[1], g)
var y = getConstExpr(m, n[1], g)
if y == nil: return
var idx = toInt64(getOrdValue(y))
case x.kind
of nkPar, nkTupleConstr:
if idx >= 0 and idx < len(x):
if idx >= 0 and idx < x.len:
result = x.sons[idx]
if result.kind == nkExprColonExpr: result = result.sons[1]
if result.kind == nkExprColonExpr: result = result[1]
else:
localError(g.config, n.info, formatErrorIndexBound(idx, len(x)-1) & $n)
localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
of nkBracket:
idx = idx - toInt64(firstOrd(g.config, x.typ))
if idx >= 0 and idx < x.len: result = x.sons[int(idx)]
if idx >= 0 and idx < x.len: result = x[int(idx)]
else: localError(g.config, n.info, formatErrorIndexBound(idx, x.len-1) & $n)
of nkStrLit..nkTripleStrLit:
result = newNodeIT(nkCharLit, x.info, n.typ)
if idx >= 0 and idx < len(x.strVal):
if idx >= 0 and idx < x.strVal.len:
result.intVal = ord(x.strVal[int(idx)])
elif idx == len(x.strVal) and optLaxStrings in g.config.options:
elif idx == x.strVal.len and optLaxStrings in g.config.options:
discard
else:
localError(g.config, n.info, formatErrorIndexBound(idx, len(x.strVal)-1) & $n)
localError(g.config, n.info, formatErrorIndexBound(idx, x.strVal.len-1) & $n)
else: discard
proc foldFieldAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
# a real field access; proc calls have already been transformed
var x = getConstExpr(m, n.sons[0], g)
var x = getConstExpr(m, n[0], g)
if x == nil or x.kind notin {nkObjConstr, nkPar, nkTupleConstr}: return
var field = n.sons[1].sym
for i in ord(x.kind == nkObjConstr) ..< len(x):
var it = x.sons[i]
var field = n[1].sym
for i in ord(x.kind == nkObjConstr)..<x.len:
var it = x[i]
if it.kind != nkExprColonExpr:
# lookup per index:
result = x.sons[field.position]
if result.kind == nkExprColonExpr: result = result.sons[1]
result = x[field.position]
if result.kind == nkExprColonExpr: result = result[1]
return
if it.sons[0].sym.name.id == field.name.id:
result = x.sons[i].sons[1]
if it[0].sym.name.id == field.name.id:
result = x[i][1]
return
localError(g.config, n.info, "field not found: " & field.name.s)
proc foldConStrStr(m: PSym, n: PNode; g: ModuleGraph): PNode =
result = newNodeIT(nkStrLit, n.info, n.typ)
result.strVal = ""
for i in 1 ..< len(n):
let a = getConstExpr(m, n.sons[i], g)
for i in 1..<n.len:
let a = getConstExpr(m, n[i], g)
if a == nil: return nil
result.strVal.add(getStrOrChar(a))
@ -606,8 +606,8 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
of nkIfExpr:
result = getConstIfExpr(m, n, g)
of nkCallKinds:
if n.sons[0].kind != nkSym: return
var s = n.sons[0].sym
if n[0].kind != nkSym: return
var s = n[0].sym
if s.kind != skProc and s.kind != skFunc: return
try:
case s.magic
@ -615,33 +615,33 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
# If it has no sideEffect, it should be evaluated. But not here.
return
of mLow:
if skipTypes(n.sons[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
result = newFloatNodeT(firstFloat(n.sons[1].typ), n, g)
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
result = newFloatNodeT(firstFloat(n[1].typ), n, g)
else:
result = newIntNodeT(firstOrd(g.config, n.sons[1].typ), n, g)
result = newIntNodeT(firstOrd(g.config, n[1].typ), n, g)
of mHigh:
if skipTypes(n.sons[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
if skipTypes(n[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
{tySequence, tyString, tyCString, tyOpenArray, tyVarargs}:
if skipTypes(n.sons[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
result = newFloatNodeT(lastFloat(n.sons[1].typ), n, g)
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
result = newFloatNodeT(lastFloat(n[1].typ), n, g)
else:
result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g)
else:
var a = getArrayConstr(m, n.sons[1], g)
var a = getArrayConstr(m, n[1], g)
if a.kind == nkBracket:
# we can optimize it away:
result = newIntNodeT(toInt128(len(a)-1), n, g)
result = newIntNodeT(toInt128(a.len-1), n, g)
of mLengthOpenArray:
var a = getArrayConstr(m, n.sons[1], g)
var a = getArrayConstr(m, n[1], g)
if a.kind == nkBracket:
# we can optimize it away! This fixes the bug ``len(134)``.
result = newIntNodeT(toInt128(len(a)), n, g)
result = newIntNodeT(toInt128(a.len), n, g)
else:
result = magicCall(m, n, g)
of mLengthArray:
# It doesn't matter if the argument is const or not for mLengthArray.
# This fixes bug #544.
result = newIntNodeT(lengthOrd(g.config, n.sons[1].typ), n, g)
result = newIntNodeT(lengthOrd(g.config, n[1].typ), n, g)
of mSizeOf:
result = foldSizeOf(g.config, n, nil)
of mAlignOf:
@ -663,10 +663,10 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
except DivByZeroError:
localError(g.config, n.info, "division by zero")
of nkAddr:
var a = getConstExpr(m, n.sons[0], g)
var a = getConstExpr(m, n[0], g)
if a != nil:
result = n
n.sons[0] = a
n[0] = a
of nkBracket, nkCurly:
result = copyNode(n)
for i, son in n.pairs:
@ -675,24 +675,24 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
result.add a
incl(result.flags, nfAllConst)
of nkRange:
var a = getConstExpr(m, n.sons[0], g)
var a = getConstExpr(m, n[0], g)
if a == nil: return
var b = getConstExpr(m, n.sons[1], g)
var b = getConstExpr(m, n[1], g)
if b == nil: return
result = copyNode(n)
addSon(result, a)
addSon(result, b)
result.add a
result.add b
#of nkObjConstr:
# result = copyTree(n)
# for i in 1 ..< len(n):
# var a = getConstExpr(m, n.sons[i].sons[1])
# for i in 1..<n.len:
# var a = getConstExpr(m, n[i][1])
# if a == nil: return nil
# result.sons[i].sons[1] = a
# result[i][1] = a
# incl(result.flags, nfAllConst)
of nkPar, nkTupleConstr:
# tuple constructor
result = copyNode(n)
if (len(n) > 0) and (n.sons[0].kind == nkExprColonExpr):
if (n.len > 0) and (n[0].kind == nkExprColonExpr):
for i, expr in n.pairs:
let exprNew = copyNode(expr) # nkExprColonExpr
exprNew.add expr[0]
@ -707,26 +707,26 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
result.add a
incl(result.flags, nfAllConst)
of nkChckRangeF, nkChckRange64, nkChckRange:
var a = getConstExpr(m, n.sons[0], g)
var a = getConstExpr(m, n[0], g)
if a == nil: return
if leValueConv(n.sons[1], a) and leValueConv(a, n.sons[2]):
if leValueConv(n[1], a) and leValueConv(a, n[2]):
result = a # a <= x and x <= b
result.typ = n.typ
else:
localError(g.config, n.info,
"conversion from $1 to $2 is invalid" %
[typeToString(n.sons[0].typ), typeToString(n.typ)])
[typeToString(n[0].typ), typeToString(n.typ)])
of nkStringToCString, nkCStringToString:
var a = getConstExpr(m, n.sons[0], g)
var a = getConstExpr(m, n[0], g)
if a == nil: return
result = a
result.typ = n.typ
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
var a = getConstExpr(m, n.sons[1], g)
var a = getConstExpr(m, n[1], g)
if a == nil: return
result = foldConv(n, a, g, check=true)
of nkCast:
var a = getConstExpr(m, n.sons[1], g)
var a = getConstExpr(m, n[1], g)
if a == nil: return
if n.typ != nil and n.typ.kind in NilableTypes:
# we allow compile-time 'cast' for pointer types:

View file

@ -19,8 +19,8 @@
proc getIdentNode(c: PContext; n: PNode): PNode =
case n.kind
of nkPostfix: result = getIdentNode(c, n.sons[1])
of nkPragmaExpr: result = getIdentNode(c, n.sons[0])
of nkPostfix: result = getIdentNode(c, n[1])
of nkPragmaExpr: result = getIdentNode(c, n[0])
of nkIdent, nkAccQuoted, nkSym: result = n
else:
illFormedAst(n, c.config)
@ -134,7 +134,7 @@ proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
proc newDot(n, b: PNode): PNode =
result = newNodeI(nkDotExpr, n.info)
result.add(n.sons[0])
result.add(n[0])
result.add(b)
proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
@ -148,7 +148,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
if s != nil:
result = semGenericStmtSymbol(c, n, s, ctx, flags)
else:
n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx)
n[0] = semGenericStmt(c, n[0], flags, ctx)
result = n
let n = n[1]
let ident = considerQuotedIdent(c, n)
@ -208,13 +208,13 @@ proc semGenericStmt(c: PContext, n: PNode,
# in the generic instantiation process...
discard
of nkBind:
result = semGenericStmt(c, n.sons[0], flags+{withinBind}, ctx)
result = semGenericStmt(c, n[0], flags+{withinBind}, ctx)
of nkMixinStmt:
result = semMixinStmt(c, n, ctx.toMixin)
of nkCall, nkHiddenCallConv, nkInfix, nkPrefix, nkCommand, nkCallStrLit:
# check if it is an expression macro:
checkMinSonsLen(n, 1, c.config)
let fn = n.sons[0]
let fn = n[0]
var s = qualifiedLookUp(c, fn, {})
if s == nil and
{withinMixin, withinConcept}*flags == {} and
@ -235,7 +235,7 @@ proc semGenericStmt(c: PContext, n: PNode,
result = semMacroExpr(c, n, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, flags, ctx)
else:
n.sons[0] = sc
n[0] = sc
result = n
mixinContext = true
of skTemplate:
@ -244,7 +244,7 @@ proc semGenericStmt(c: PContext, n: PNode,
result = semTemplateExpr(c, n, s, {efNoSemCheck})
result = semGenericStmt(c, result, flags, ctx)
else:
n.sons[0] = sc
n[0] = sc
result = n
# BUGFIX: we must not return here, we need to do first phase of
# symbol lookup. Also since templates and macros can do scope injections
@ -255,242 +255,236 @@ proc semGenericStmt(c: PContext, n: PNode,
# Leave it as an identifier.
discard
of skProc, skFunc, skMethod, skIterator, skConverter, skModule:
result.sons[0] = sc
result[0] = sc
first = 1
# We're not interested in the example code during this pass so let's
# skip it
if s.magic == mRunnableExamples:
inc first
of skGenericParam:
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
result[0] = newSymNodeTypeDesc(s, fn.info)
onUse(fn.info, s)
first = 1
of skType:
# bad hack for generics:
if (s.typ != nil) and (s.typ.kind != tyGenericParam):
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
result[0] = newSymNodeTypeDesc(s, fn.info)
onUse(fn.info, s)
first = 1
else:
result.sons[0] = newSymNode(s, fn.info)
result[0] = newSymNode(s, fn.info)
onUse(fn.info, s)
first = 1
elif fn.kind == nkDotExpr:
result.sons[0] = fuzzyLookup(c, fn, flags, ctx, mixinContext)
result[0] = fuzzyLookup(c, fn, flags, ctx, mixinContext)
first = 1
# Consider 'when declared(globalsSlot): ThreadVarSetValue(globalsSlot, ...)'
# in threads.nim: the subtle preprocessing here binds 'globalsSlot' which
# is not exported and yet the generic 'threadProcWrapper' works correctly.
let flags = if mixinContext: flags+{withinMixin} else: flags
for i in first ..< safeLen(result):
result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx)
for i in first..<result.safeLen:
result[i] = semGenericStmt(c, result[i], flags, ctx)
of nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.cache, "{}"), n.info)
for i in 0 ..< n.len: result.add(n[i])
for i in 0..<n.len: result.add(n[i])
result = semGenericStmt(c, result, flags, ctx)
of nkBracketExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.cache, "[]"), n.info)
for i in 0 ..< n.len: result.add(n[i])
withBracketExpr ctx, n.sons[0]:
for i in 0..<n.len: result.add(n[i])
withBracketExpr ctx, n[0]:
result = semGenericStmt(c, result, flags, ctx)
of nkAsgn, nkFastAsgn:
checkSonsLen(n, 2, c.config)
let a = n.sons[0]
let b = n.sons[1]
let a = n[0]
let b = n[1]
let k = a.kind
case k
of nkCurlyExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.cache, "{}="), n.info)
for i in 0 ..< a.len: result.add(a[i])
for i in 0..<a.len: result.add(a[i])
result.add(b)
result = semGenericStmt(c, result, flags, ctx)
of nkBracketExpr:
result = newNodeI(nkCall, n.info)
result.add newIdentNode(getIdent(c.cache, "[]="), n.info)
for i in 0 ..< a.len: result.add(a[i])
for i in 0..<a.len: result.add(a[i])
result.add(b)
withBracketExpr ctx, a.sons[0]:
withBracketExpr ctx, a[0]:
result = semGenericStmt(c, result, flags, ctx)
else:
for i in 0 ..< len(n):
result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
for i in 0..<n.len:
result[i] = semGenericStmt(c, n[i], flags, ctx)
of nkIfStmt:
for i in 0 ..< len(n):
n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, ctx)
for i in 0..<n.len:
n[i] = semGenericStmtScope(c, n[i], flags, ctx)
of nkWhenStmt:
for i in 0 ..< len(n):
for i in 0..<n.len:
# bug #8603: conditions of 'when' statements are not
# in a 'mixin' context:
let it = n[i]
if it.kind in {nkElifExpr, nkElifBranch}:
n.sons[i].sons[0] = semGenericStmt(c, it[0], flags, ctx)
n.sons[i].sons[1] = semGenericStmt(c, it[1], flags+{withinMixin}, ctx)
n[i][0] = semGenericStmt(c, it[0], flags, ctx)
n[i][1] = semGenericStmt(c, it[1], flags+{withinMixin}, ctx)
else:
n.sons[i] = semGenericStmt(c, it, flags+{withinMixin}, ctx)
n[i] = semGenericStmt(c, it, flags+{withinMixin}, ctx)
of nkWhileStmt:
openScope(c)
for i in 0 ..< len(n):
n.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
for i in 0..<n.len:
n[i] = semGenericStmt(c, n[i], flags, ctx)
closeScope(c)
of nkCaseStmt:
openScope(c)
n.sons[0] = semGenericStmt(c, n.sons[0], flags, ctx)
for i in 1 ..< len(n):
var a = n.sons[i]
n[0] = semGenericStmt(c, n[0], flags, ctx)
for i in 1..<n.len:
var a = n[i]
checkMinSonsLen(a, 1, c.config)
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)
for j in 0..<a.len-1:
a[j] = semGenericStmt(c, a[j], flags, ctx)
a[^1] = semGenericStmtScope(c, a[^1], flags, ctx)
closeScope(c)
of nkForStmt, nkParForStmt:
var L = len(n)
openScope(c)
n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, ctx)
for i in 0 .. L - 3:
if (n.sons[i].kind == nkVarTuple):
for s in n.sons[i]:
n[^2] = semGenericStmt(c, n[^2], flags, ctx)
for i in 0..<n.len - 2:
if (n[i].kind == nkVarTuple):
for s in n[i]:
if (s.kind == nkIdent):
addTempDecl(c,s,skForVar)
else:
addTempDecl(c, n.sons[i], skForVar)
addTempDecl(c, n[i], skForVar)
openScope(c)
n.sons[L - 1] = semGenericStmt(c, n.sons[L-1], flags, ctx)
n[^1] = semGenericStmt(c, n[^1], flags, ctx)
closeScope(c)
closeScope(c)
of nkBlockStmt, nkBlockExpr, nkBlockType:
checkSonsLen(n, 2, c.config)
openScope(c)
if n.sons[0].kind != nkEmpty:
addTempDecl(c, n.sons[0], skLabel)
n.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx)
if n[0].kind != nkEmpty:
addTempDecl(c, n[0], skLabel)
n[1] = semGenericStmt(c, n[1], flags, ctx)
closeScope(c)
of nkTryStmt, nkHiddenTryStmt:
checkMinSonsLen(n, 2, c.config)
n.sons[0] = semGenericStmtScope(c, n.sons[0], flags, ctx)
for i in 1 ..< len(n):
var a = n.sons[i]
n[0] = semGenericStmtScope(c, n[0], flags, ctx)
for i in 1..<n.len:
var a = n[i]
checkMinSonsLen(a, 1, c.config)
var L = len(a)
openScope(c)
for j in 0 .. L-2:
if a.sons[j].isInfixAs():
addTempDecl(c, getIdentNode(c, a.sons[j][2]), skLet)
a.sons[j].sons[1] = semGenericStmt(c, a.sons[j][1], flags+{withinTypeDesc}, ctx)
for j in 0..<a.len-1:
if a[j].isInfixAs():
addTempDecl(c, getIdentNode(c, a[j][2]), skLet)
a[j][1] = semGenericStmt(c, a[j][1], flags+{withinTypeDesc}, ctx)
else:
a.sons[j] = semGenericStmt(c, a.sons[j], flags+{withinTypeDesc}, ctx)
a.sons[L-1] = semGenericStmtScope(c, a.sons[L-1], flags, ctx)
a[j] = semGenericStmt(c, a[j], flags+{withinTypeDesc}, ctx)
a[^1] = semGenericStmtScope(c, a[^1], flags, ctx)
closeScope(c)
of nkVarSection, nkLetSection:
for i in 0 ..< len(n):
var a = n.sons[i]
for i in 0..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkIdentDefs) and (a.kind != nkVarTuple): illFormedAst(a, c.config)
checkMinSonsLen(a, 3, c.config)
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)
a[^2] = semGenericStmt(c, a[^2], flags+{withinTypeDesc}, ctx)
a[^1] = semGenericStmt(c, a[^1], flags, ctx)
for j in 0..<a.len-2:
addTempDecl(c, getIdentNode(c, a[j]), skVar)
of nkGenericParams:
for i in 0 ..< len(n):
var a = n.sons[i]
for i in 0..<n.len:
var a = n[i]
if (a.kind != nkIdentDefs): illFormedAst(a, c.config)
checkMinSonsLen(a, 3, c.config)
var L = len(a)
a.sons[L-2] = semGenericStmt(c, a.sons[L-2], flags+{withinTypeDesc}, ctx)
a[^2] = semGenericStmt(c, a[^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)
for j in 0..<a.len-2:
addTempDecl(c, getIdentNode(c, a[j]), skType)
of nkConstSection:
for i in 0 ..< len(n):
var a = n.sons[i]
for i in 0..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkConstDef): illFormedAst(a, c.config)
checkSonsLen(a, 3, c.config)
addTempDecl(c, getIdentNode(c, a.sons[0]), skConst)
a.sons[1] = semGenericStmt(c, a.sons[1], flags+{withinTypeDesc}, ctx)
a.sons[2] = semGenericStmt(c, a.sons[2], flags, ctx)
addTempDecl(c, getIdentNode(c, a[0]), skConst)
a[1] = semGenericStmt(c, a[1], flags+{withinTypeDesc}, ctx)
a[2] = semGenericStmt(c, a[2], flags, ctx)
of nkTypeSection:
for i in 0 ..< len(n):
var a = n.sons[i]
for i in 0..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkTypeDef): illFormedAst(a, c.config)
checkSonsLen(a, 3, c.config)
addTempDecl(c, getIdentNode(c, a.sons[0]), skType)
for i in 0 ..< len(n):
var a = n.sons[i]
addTempDecl(c, getIdentNode(c, a[0]), skType)
for i in 0..<n.len:
var a = n[i]
if a.kind == nkCommentStmt: continue
if (a.kind != nkTypeDef): illFormedAst(a, c.config)
checkSonsLen(a, 3, c.config)
if a.sons[1].kind != nkEmpty:
if a[1].kind != nkEmpty:
openScope(c)
a.sons[1] = semGenericStmt(c, a.sons[1], flags, ctx)
a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx)
a[1] = semGenericStmt(c, a[1], flags, ctx)
a[2] = semGenericStmt(c, a[2], flags+{withinTypeDesc}, ctx)
closeScope(c)
else:
a.sons[2] = semGenericStmt(c, a.sons[2], flags+{withinTypeDesc}, ctx)
a[2] = semGenericStmt(c, a[2], flags+{withinTypeDesc}, ctx)
of nkEnumTy:
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 ..< len(n):
if n[0].kind != nkEmpty:
n[0] = semGenericStmt(c, n[0], flags+{withinTypeDesc}, ctx)
for i in 1..<n.len:
var a: PNode
case n.sons[i].kind
of nkEnumFieldDef: a = n.sons[i].sons[0]
of nkIdent: a = n.sons[i]
case n[i].kind
of nkEnumFieldDef: a = n[i][0]
of nkIdent: a = n[i]
else: illFormedAst(n, c.config)
addDecl(c, newSymS(skUnknown, getIdentNode(c, a), c))
of nkObjectTy, nkTupleTy, nkTupleClassTy:
discard
of nkFormalParams:
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 ..< len(n):
var a = n.sons[i]
if n[0].kind != nkEmpty:
n[0] = semGenericStmt(c, n[0], flags+{withinTypeDesc}, ctx)
for i in 1..<n.len:
var a = n[i]
if (a.kind != nkIdentDefs): illFormedAst(a, c.config)
checkMinSonsLen(a, 3, c.config)
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]), skParam)
a[^2] = semGenericStmt(c, a[^2], flags+{withinTypeDesc}, ctx)
a[^1] = semGenericStmt(c, a[^1], flags, ctx)
for j in 0..<a.len-2:
addTempDecl(c, getIdentNode(c, a[j]), skParam)
of nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, nkTemplateDef,
nkFuncDef, nkIteratorDef, nkLambdaKinds:
checkSonsLen(n, bodyPos + 1, c.config)
if n.sons[namePos].kind != nkEmpty:
addTempDecl(c, getIdentNode(c, n.sons[0]), skProc)
if n[namePos].kind != nkEmpty:
addTempDecl(c, getIdentNode(c, n[0]), skProc)
openScope(c)
n.sons[genericParamsPos] = semGenericStmt(c, n.sons[genericParamsPos],
n[genericParamsPos] = semGenericStmt(c, n[genericParamsPos],
flags, ctx)
if n.sons[paramsPos].kind != nkEmpty:
if n.sons[paramsPos].sons[0].kind != nkEmpty:
if n[paramsPos].kind != nkEmpty:
if n[paramsPos][0].kind != nkEmpty:
addPrelimDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nil, n.info))
n.sons[paramsPos] = semGenericStmt(c, n.sons[paramsPos], flags, ctx)
n.sons[pragmasPos] = semGenericStmt(c, n.sons[pragmasPos], flags, ctx)
n[paramsPos] = semGenericStmt(c, n[paramsPos], flags, ctx)
n[pragmasPos] = semGenericStmt(c, n[pragmasPos], flags, ctx)
var body: PNode
if n.sons[namePos].kind == nkSym:
let s = n.sons[namePos].sym
if n[namePos].kind == nkSym:
let s = n[namePos].sym
if sfGenSym in s.flags and s.ast == nil:
body = n.sons[bodyPos]
body = n[bodyPos]
else:
body = s.getBody
else: body = n.sons[bodyPos]
n.sons[bodyPos] = semGenericStmtScope(c, body, flags, ctx)
else: body = n[bodyPos]
n[bodyPos] = semGenericStmtScope(c, body, flags, ctx)
closeScope(c)
of nkPragma, nkPragmaExpr: discard
of nkExprColonExpr, nkExprEqExpr:
checkMinSonsLen(n, 2, c.config)
result.sons[1] = semGenericStmt(c, n.sons[1], flags, ctx)
result[1] = semGenericStmt(c, n[1], flags, ctx)
else:
for i in 0 ..< len(n):
result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
for i in 0..<n.len:
result[i] = semGenericStmt(c, n[i], flags, ctx)
when defined(nimsuggest):
if withinTypeDesc in flags: dec c.inTypeContext

View file

@ -14,11 +14,11 @@ proc addObjFieldsToLocalScope(c: PContext; n: PNode) =
template rec(n) = addObjFieldsToLocalScope(c, n)
case n.kind
of nkRecList:
for i in 0 ..< len(n):
for i in 0..<n.len:
rec n[i]
of nkRecCase:
if n.len > 0: rec n.sons[0]
for i in 1 ..< len(n):
if n.len > 0: rec n[0]
for i in 1..<n.len:
if n[i].kind in {nkOfBranch, nkElse}: rec lastSon(n[i])
of nkSym:
let f = n.sym
@ -47,8 +47,8 @@ proc rawHandleSelf(c: PContext; owner: PSym) =
var t = c.p.selfSym.typ.skipTypes(abstractPtrs)
while t.kind == tyObject:
addObjFieldsToLocalScope(c, t.n)
if t.sons[0] == nil: break
t = t.sons[0].skipTypes(skipPtrs)
if t[0] == nil: break
t = t[0].skipTypes(skipPtrs)
proc pushProcCon*(c: PContext; owner: PSym) =
rawPushProcCon(c, owner)
@ -123,24 +123,24 @@ proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) =
idTablePut(symMap, s, x)
n.sym = x
else:
for i in 0 ..< safeLen(n): freshGenSyms(n.sons[i], owner, orig, symMap)
for i in 0..<n.safeLen: freshGenSyms(n[i], owner, orig, symMap)
proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind)
proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
if n.sons[bodyPos].kind != nkEmpty:
if n[bodyPos].kind != nkEmpty:
let procParams = result.typ.n
for i in 1 ..< procParams.len:
for i in 1..<procParams.len:
addDecl(c, procParams[i].sym)
maybeAddResult(c, result, result.ast)
inc c.inGenericInst
# add it here, so that recursive generic procs are possible:
var b = n.sons[bodyPos]
var b = n[bodyPos]
var symMap: TIdTable
initIdTable symMap
if params != nil:
for i in 1 ..< params.len:
for i in 1..<params.len:
let param = params[i].sym
if sfGenSym in param.flags:
idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym)
@ -152,7 +152,7 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
dec c.inGenericInst
proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
for i in 0 ..< c.generics.len:
for i in 0..<c.generics.len:
if c.generics[i].genericSym.id == s.id:
var oldPrc = c.generics[i].inst.sym
pushProcCon(c, oldPrc)
@ -160,7 +160,7 @@ proc fixupInstantiatedSymbols(c: PContext, s: PSym) =
pushInfoContext(c.config, oldPrc.info)
openScope(c)
var n = oldPrc.ast
n.sons[bodyPos] = copyTree(s.getBody)
n[bodyPos] = copyTree(s.getBody)
instantiateBody(c, n, oldPrc.typ.n, oldPrc, s)
closeScope(c)
popInfoContext(c.config)
@ -195,7 +195,7 @@ proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
# perhaps the code can be extracted in a shared function.
openScope(c)
let genericTyp = header.base
for i in 0 .. (genericTyp.len - 2):
for i in 0..<genericTyp.len - 1:
let genParam = genericTyp[i]
var param: PSym
@ -248,7 +248,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
var result = instCopyType(cl, prc.typ)
let originalParams = result.n
result.n = originalParams.shallowCopy
for i in 1 ..< result.len:
for i in 1..<result.len:
# twrong_field_caching requires these 'resetIdTable' calls:
if i > 1:
resetIdTable(cl.symMap)
@ -280,7 +280,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
if oldParam.ast != nil:
var def = oldParam.ast.copyTree
if def.kind == nkCall:
for i in 1 ..< def.len:
for i in 1..<def.len:
def[i] = replaceTypeVarsN(cl, def[i])
def = semExprWithType(c, def)
@ -307,11 +307,11 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
resetIdTable(cl.symMap)
resetIdTable(cl.localCache)
cl.isReturnType = true
result.sons[0] = replaceTypeVarsT(cl, result.sons[0])
result[0] = replaceTypeVarsT(cl, result[0])
cl.isReturnType = false
result.n.sons[0] = originalParams[0].copyTree
if result.sons[0] != nil:
propagateToOwner(result, result.sons[0])
result.n[0] = originalParams[0].copyTree
if result[0] != nil:
propagateToOwner(result, result[0])
eraseVoidParams(result)
skipIntLiteralParams(result)
@ -346,9 +346,9 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
pushOwner(c, result)
openScope(c)
let gp = n.sons[genericParamsPos]
let gp = n[genericParamsPos]
internalAssert c.config, gp.kind != nkEmpty
n.sons[namePos] = newSymNode(result)
n[namePos] = newSymNode(result)
pushInfoContext(c.config, info, fn.detailedInfo)
var entry = TInstantiation.new
entry.sym = result
@ -363,12 +363,12 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
inc i
rawPushProcCon(c, result)
instantiateProcType(c, pt, result, info)
for j in 1 .. result.typ.len-1:
entry.concreteTypes[i] = result.typ.sons[j]
for j in 1..<result.typ.len:
entry.concreteTypes[i] = result.typ[j]
inc i
if tfTriggersCompileTime in result.typ.flags:
incl(result.flags, sfCompileTime)
n.sons[genericParamsPos] = c.graph.emptyNode
n[genericParamsPos] = c.graph.emptyNode
var oldPrc = genericCacheGet(fn, entry[], c.compilesContextId)
if oldPrc == nil:
# we MUST not add potentially wrong instantiations to the caching mechanism.
@ -380,10 +380,10 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
entry.compilesId = c.compilesContextId
fn.procInstCache.add(entry)
c.generics.add(makeInstPair(fn, entry))
if n.sons[pragmasPos].kind != nkEmpty:
pragma(c, result, n.sons[pragmasPos], allRoutinePragmas)
if isNil(n.sons[bodyPos]):
n.sons[bodyPos] = copyTree(fn.getBody)
if n[pragmasPos].kind != nkEmpty:
pragma(c, result, n[pragmasPos], allRoutinePragmas)
if isNil(n[bodyPos]):
n[bodyPos] = copyTree(fn.getBody)
if c.inGenericContext == 0:
instantiateBody(c, n, fn.typ.n, result, fn)
sideEffectsCheck(c, result)

View file

@ -16,17 +16,17 @@ proc ithField(n: PNode, field: var int): PSym =
result = nil
case n.kind
of nkRecList:
for i in 0 ..< len(n):
result = ithField(n.sons[i], field)
for i in 0..<n.len:
result = ithField(n[i], field)
if result != nil: return
of nkRecCase:
if n.sons[0].kind != nkSym: return
result = ithField(n.sons[0], field)
if n[0].kind != nkSym: return
result = ithField(n[0], field)
if result != nil: return
for i in 1 ..< len(n):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = ithField(lastSon(n.sons[i]), field)
result = ithField(lastSon(n[i]), field)
if result != nil: return
else: discard
of nkSym:
@ -35,12 +35,12 @@ proc ithField(n: PNode, field: var int): PSym =
else: discard
proc ithField(t: PType, field: var int): PSym =
var base = t.sons[0]
var base = t[0]
while base != nil:
let b = skipTypes(base, skipPtrs)
result = ithField(b.n, field)
if result != nil: return result
base = b.sons[0]
base = b[0]
result = ithField(t.n, field)
proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
@ -51,20 +51,20 @@ proc annotateType*(n: PNode, t: PType; conf: ConfigRef) =
of nkObjConstr:
let x = t.skipTypes(abstractPtrs)
n.typ = t
for i in 1 ..< n.len:
for i in 1..<n.len:
var j = i-1
let field = x.ithField(j)
if field.isNil:
globalError conf, n.info, "invalid field at index " & $i
else:
internalAssert(conf, n.sons[i].kind == nkExprColonExpr)
annotateType(n.sons[i].sons[1], field.typ, conf)
internalAssert(conf, n[i].kind == nkExprColonExpr)
annotateType(n[i][1], field.typ, conf)
of nkPar, nkTupleConstr:
if x.kind == tyTuple:
n.typ = t
for i in 0 ..< n.len:
for i in 0..<n.len:
if i >= x.len: globalError conf, n.info, "invalid field at index " & $i
else: annotateType(n.sons[i], x.sons[i], conf)
else: annotateType(n[i], x[i], conf)
elif x.kind == tyProc and x.callConv == ccClosure:
n.typ = t
else:

View file

@ -43,7 +43,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode
proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode
proc skipAddr(n: PNode): PNode {.inline.} =
(if n.kind == nkHiddenAddr: n.sons[0] else: n)
(if n.kind == nkHiddenAddr: n[0] else: n)
proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
result = newNodeI(nkBracketExpr, n.info)
@ -51,7 +51,7 @@ proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
result = semSubscript(c, result, flags)
if result.isNil:
let x = copyTree(n)
x.sons[0] = newIdentNode(getIdent(c.cache, "[]"), n.info)
x[0] = newIdentNode(getIdent(c.cache, "[]"), n.info)
bracketNotFoundError(c, x)
#localError(c.config, n.info, "could not resolve: " & $n)
result = n
@ -60,16 +60,16 @@ proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode =
# rewrite `[]=`(a, i, x) back to ``a[i] = x``.
let b = newNodeI(nkBracketExpr, n.info)
b.add(n[1].skipAddr)
for i in 2..n.len-2: b.add(n[i])
for i in 2..<n.len-1: b.add(n[i])
result = newNodeI(nkAsgn, n.info, 2)
result.sons[0] = b
result.sons[1] = n.lastSon
result[0] = b
result[1] = n.lastSon
result = semAsgn(c, result, noOverloadedSubscript)
proc semAsgnOpr(c: PContext; n: PNode): PNode =
result = newNodeI(nkAsgn, n.info, 2)
result.sons[0] = n[1]
result.sons[1] = n[2]
result[0] = n[1]
result[1] = n[2]
result = semAsgn(c, result, noOverloadedAsgn)
proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode =
@ -84,8 +84,8 @@ proc expectIntLit(c: PContext, n: PNode): int =
proc semInstantiationInfo(c: PContext, n: PNode): PNode =
result = newNodeIT(nkTupleConstr, n.info, n.typ)
let idx = expectIntLit(c, n.sons[1])
let useFullPaths = expectIntLit(c, n.sons[2])
let idx = expectIntLit(c, n[1])
let useFullPaths = expectIntLit(c, n[2])
let info = getInfoContext(c.config, idx)
var filename = newNodeIT(nkStrLit, n.info, getSysType(c.graph, n.info, tyString))
filename.strVal = if useFullPaths != 0: toFullPath(c.config, info) else: toFilename(c.config, info)
@ -118,7 +118,7 @@ proc uninstantiate(t: PType): PType =
result = case t.kind
of tyMagicGenerics: t
of tyUserDefinedGenerics: t.base
of tyCompositeTypeClass: uninstantiate t.sons[1]
of tyCompositeTypeClass: uninstantiate t[1]
else: t
proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym): PNode =
@ -128,7 +128,7 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
var operand = operand.skipTypes(skippedTypes)
template operand2: PType =
traitCall.sons[2].typ.skipTypes({tyTypeDesc})
traitCall[2].typ.skipTypes({tyTypeDesc})
template typeWithSonsResult(kind, sons): PNode =
newTypeWithSons(context, kind, sons).toNode(traitCall.info)
@ -143,8 +143,8 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
return typeWithSonsResult(tyNot, @[operand])
of "typeToString":
var prefer = preferTypeName
if traitCall.sons.len >= 2:
let preferStr = traitCall.sons[2].strVal
if traitCall.len >= 2:
let preferStr = traitCall[2].strVal
prefer = parseEnum[TPreferedDesc](preferStr)
result = newStrNode(nkStrLit, operand.typeToString(prefer))
result.typ = newType(tyString, context)
@ -178,7 +178,7 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
proc semTypeTraits(c: PContext, n: PNode): PNode =
checkMinSonsLen(n, 2, c.config)
let t = n.sons[1].typ
let t = n[1].typ
internalAssert c.config, t != nil and t.kind == tyTypeDesc
if t.len > 0:
# This is either a type known to sem or a typedesc
@ -190,7 +190,7 @@ proc semTypeTraits(c: PContext, n: PNode): PNode =
proc semOrd(c: PContext, n: PNode): PNode =
result = n
let parType = n.sons[1].typ
let parType = n[1].typ
if isOrdinalType(parType, allowEnumWithHoles=true):
discard
elif parType.kind == tySet:
@ -203,17 +203,17 @@ proc semOrd(c: PContext, n: PNode): PNode =
proc semBindSym(c: PContext, n: PNode): PNode =
result = copyNode(n)
result.add(n.sons[0])
result.add(n[0])
let sl = semConstExpr(c, n.sons[1])
let sl = semConstExpr(c, n[1])
if sl.kind notin {nkStrLit, nkRStrLit, nkTripleStrLit}:
localError(c.config, n.sons[1].info, errStringLiteralExpected)
localError(c.config, n[1].info, errStringLiteralExpected)
return errorNode(c, n)
let isMixin = semConstExpr(c, n.sons[2])
let isMixin = semConstExpr(c, n[2])
if isMixin.kind != nkIntLit or isMixin.intVal < 0 or
isMixin.intVal > high(TSymChoiceRule).int:
localError(c.config, n.sons[2].info, errConstExprExpected)
localError(c.config, n[2].info, errConstExprExpected)
return errorNode(c, n)
let id = newIdentNode(getIdent(c.cache, sl.strVal), n.info)
@ -227,7 +227,7 @@ proc semBindSym(c: PContext, n: PNode): PNode =
return sc
result.add(sc)
else:
errorUndeclaredIdentifier(c, n.sons[1].info, sl.strVal)
errorUndeclaredIdentifier(c, n[1].info, sl.strVal)
proc opBindSym(c: PContext, scope: PScope, n: PNode, isMixin: int, info: PNode): PNode =
if n.kind notin {nkStrLit, nkRStrLit, nkTripleStrLit, nkIdent}:
@ -293,15 +293,15 @@ proc semDynamicBindSym(c: PContext, n: PNode): PNode =
proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode
proc semOf(c: PContext, n: PNode): PNode =
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])
#restoreOldStyleType(n.sons[2])
let a = skipTypes(n.sons[1].typ, abstractPtrs)
let b = skipTypes(n.sons[2].typ, abstractPtrs)
let x = skipTypes(n.sons[1].typ, abstractPtrs-{tyTypeDesc})
let y = skipTypes(n.sons[2].typ, abstractPtrs-{tyTypeDesc})
if n.len == 3:
n[1] = semExprWithType(c, n[1])
n[2] = semExprWithType(c, n[2], {efDetermineType})
#restoreOldStyleType(n[1])
#restoreOldStyleType(n[2])
let a = skipTypes(n[1].typ, abstractPtrs)
let b = skipTypes(n[2].typ, abstractPtrs)
let x = skipTypes(n[1].typ, abstractPtrs-{tyTypeDesc})
let y = skipTypes(n[2].typ, abstractPtrs-{tyTypeDesc})
if x.kind == tyTypeDesc or y.kind != tyTypeDesc:
localError(c.config, n.info, "'of' takes object types")
@ -349,14 +349,13 @@ proc semUnown(c: PContext; n: PNode): PNode =
for e in elems: result.rawAddSon(e)
else:
result = t
of tyOwned: result = t.sons[0]
of tyOwned: result = t[0]
of tySequence, tyOpenArray, tyArray, tyVarargs, tyVar, tyLent,
tyGenericInst, tyAlias:
let L = t.len-1
let b = unownedType(c, t[L])
if b != t[L]:
let b = unownedType(c, t[^1])
if b != t[^1]:
result = copyType(t, t.owner, keepId = false)
result[L] = b
result[^1] = b
result.flags.excl tfHasOwned
else:
result = t
@ -366,7 +365,7 @@ proc semUnown(c: PContext; n: PNode): PNode =
result = copyTree(n[1])
result.typ = unownedType(c, result.typ)
# little hack for injectdestructors.nim (see bug #11350):
#result.sons[0].typ = nil
#result[0].typ = nil
proc magicsAfterOverloadResolution(c: PContext, n: PNode,
flags: TExprFlags): PNode =
@ -437,7 +436,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
result = n
let t = n[1].typ.skipTypes(abstractVar)
if t.destructor != nil:
result.sons[0] = newSymNode(t.destructor)
result[0] = newSymNode(t.destructor)
of mUnown:
result = semUnown(c, n)
else: result = n

View file

@ -48,7 +48,7 @@ proc invalidObjConstr(c: PContext, n: PNode) =
proc locateFieldInInitExpr(c: PContext, field: PSym, initExpr: PNode): PNode =
# Returns the assignment nkExprColonExpr node or nil
let fieldId = field.name.id
for i in 1 ..< initExpr.len:
for i in 1..<initExpr.len:
let assignment = initExpr[i]
if assignment.kind != nkExprColonExpr:
invalidObjConstr(c, assignment)
@ -70,13 +70,13 @@ proc semConstrField(c: PContext, flags: TExprFlags,
var initValue = semExprFlagDispatched(c, assignment[1], flags)
if initValue != nil:
initValue = fitNode(c, field.typ, initValue, assignment.info)
assignment.sons[0] = newSymNode(field)
assignment.sons[1] = initValue
assignment[0] = newSymNode(field)
assignment[1] = initValue
assignment.flags.incl nfSem
return initValue
proc caseBranchMatchesExpr(branch, matched: PNode): bool =
for i in 0 .. branch.len-2:
for i in 0..<branch.len-1:
if branch[i].kind == nkRange:
if overlap(branch[i], matched): return true
elif exprStructuralEquivalent(branch[i], matched):
@ -86,11 +86,11 @@ proc caseBranchMatchesExpr(branch, matched: PNode): bool =
template processBranchVals(b, op) =
if b.kind != nkElifBranch:
for i in 0 .. b.len-2:
for i in 0..<b.len-1:
if b[i].kind == nkIntLit:
result.op(b[i].intVal.int)
elif b[i].kind == nkRange:
for i in b[i][0].intVal .. b[i][1].intVal:
for i in b[i][0].intVal..b[i][1].intVal:
result.op(i.int)
proc allPossibleValues(c: PContext, t: PType): IntSet =
@ -100,7 +100,7 @@ proc allPossibleValues(c: PContext, t: PType): IntSet =
for field in t.n.sons:
result.incl(field.sym.position)
else:
for i in toInt64(firstOrd(c.config, t)) .. toInt64(lastOrd(c.config, t)):
for i in toInt64(firstOrd(c.config, t))..toInt64(lastOrd(c.config, t)):
result.incl(i.int)
proc branchVals(c: PContext, caseNode: PNode, caseIdx: int,
@ -109,15 +109,15 @@ proc branchVals(c: PContext, caseNode: PNode, caseIdx: int,
result = initIntSet()
processBranchVals(caseNode[caseIdx], incl)
else:
result = allPossibleValues(c, caseNode.sons[0].typ)
for i in 1 .. caseNode.len-2:
result = allPossibleValues(c, caseNode[0].typ)
for i in 1..<caseNode.len-1:
processBranchVals(caseNode[i], excl)
proc rangeTypVals(rangeTyp: PType): IntSet =
assert rangeTyp.kind == tyRange
let (a, b) = (rangeTyp.n.sons[0].intVal, rangeTyp.n.sons[1].intVal)
let (a, b) = (rangeTyp.n[0].intVal, rangeTyp.n[1].intVal)
result = initIntSet()
for it in a .. b:
for it in a..b:
result.incl(it.int)
proc formatUnsafeBranchVals(t: PType, diffVals: IntSet): string =
@ -127,8 +127,8 @@ proc formatUnsafeBranchVals(t: PType, diffVals: IntSet): string =
if t.kind in {tyEnum, tyBool}:
var i = 0
for val in diffVals:
while t.n.sons[i].sym.position < val: inc(i)
strs.add(t.n.sons[i].sym.name.s)
while t.n[i].sym.position < val: inc(i)
strs.add(t.n[i].sym.name.s)
else:
for val in diffVals:
strs.add($val)
@ -145,7 +145,7 @@ proc findUsefulCaseContext(c: PContext, discrimator: PNode): (PNode, int) =
proc pickCaseBranch(caseExpr, matched: PNode): PNode =
# XXX: Perhaps this proc already exists somewhere
let endsWithElse = caseExpr[^1].kind == nkElse
for i in 1 .. caseExpr.len - 1 - int(endsWithElse):
for i in 1..<caseExpr.len - int(endsWithElse):
if caseExpr[i].caseBranchMatchesExpr(matched):
return caseExpr[i]
@ -203,19 +203,19 @@ proc semConstructFields(c: PContext, recNode: PNode,
of nkRecCase:
template fieldsPresentInBranch(branchIdx: int): string =
let branch = recNode[branchIdx]
let fields = branch[branch.len - 1]
let fields = branch[^1]
fieldsPresentInInitExpr(c, fields, initExpr)
template checkMissingFields(branchNode: PNode) =
if branchNode != nil:
let fields = branchNode[branchNode.len - 1]
let fields = branchNode[^1]
checkForMissingFields(c, fields, initExpr)
let discriminator = recNode.sons[0]
let discriminator = recNode[0]
internalAssert c.config, discriminator.kind == nkSym
var selectedBranch = -1
for i in 1 ..< recNode.len:
for i in 1..<recNode.len:
let innerRecords = recNode[i][^1]
let status = semConstructFields(c, innerRecords, initExpr, flags)
if status notin {initNone, initUnknown}:
@ -252,7 +252,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
localError(c.config, discriminatorVal.info, ("possible values " &
"$2are in conflict with discriminator values for " &
"selected object branch $1.") % [$selectedBranch,
formatUnsafeBranchVals(recNode.sons[0].typ, valsDiff)])
formatUnsafeBranchVals(recNode[0].typ, valsDiff)])
let branchNode = recNode[selectedBranch]
let flags = flags*{efAllowDestructor} + {efPreferStatic,
@ -264,7 +264,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
if discriminatorVal.kind notin nkLiterals and (
not isOrdinalType(discriminatorVal.typ, true) or
lengthOrd(c.config, discriminatorVal.typ) > MaxSetElements or
lengthOrd(c.config, recNode.sons[0].typ) > MaxSetElements):
lengthOrd(c.config, recNode[0].typ) > MaxSetElements):
localError(c.config, discriminatorVal.info,
"branch initialization with a runtime discriminator only " &
"supports ordinal types with 2^16 elements or less.")
@ -305,7 +305,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
failedBranch = selectedBranch
else:
# With an else clause, check that all other branches don't match:
for i in 1 .. (recNode.len - 2):
for i in 1..<recNode.len - 1:
if recNode[i].caseBranchMatchesExpr(discriminatorVal):
failedBranch = i
break
@ -345,7 +345,7 @@ proc semConstructFields(c: PContext, recNode: PNode,
else:
# All bets are off. If any of the branches has a mandatory
# fields we must produce an error:
for i in 1 ..< recNode.len: checkMissingFields recNode[i]
for i in 1..<recNode.len: checkMissingFields recNode[i]
of nkSym:
let field = recNode.sym
@ -364,12 +364,12 @@ proc semConstructType(c: PContext, initExpr: PNode,
mergeInitStatus(result, status)
if status in {initPartial, initNone, initUnknown}:
checkForMissingFields c, t.n, initExpr
let base = t.sons[0]
let base = t[0]
if base == nil: break
t = skipTypes(base, skipPtrs)
proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
var t = semTypeNode(c, n.sons[0], nil)
var t = semTypeNode(c, n[0], nil)
result = newNodeIT(nkObjConstr, n.info, t)
for child in n: result.add child
@ -379,7 +379,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
t = skipTypes(t, {tyGenericInst, tyAlias, tySink, tyOwned})
if t.kind == tyRef:
t = skipTypes(t.sons[0], {tyGenericInst, tyAlias, tySink, tyOwned})
t = skipTypes(t[0], {tyGenericInst, tyAlias, tySink, tyOwned})
if optOwnedRefs in c.config.globalOptions:
result.typ = makeVarType(c, result.typ, tyOwned)
# we have to watch out, there are also 'owned proc' types that can be used
@ -418,7 +418,7 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
let id = considerQuotedIdent(c, field[0])
# This node was not processed. There are two possible reasons:
# 1) It was shadowed by a field with the same name on the left
for j in 1 ..< i:
for j in 1..<i:
let prevId = considerQuotedIdent(c, result[j][0])
if prevId.id == id.id:
localError(c.config, field.info, errFieldInitTwice % id.s)

View file

@ -92,10 +92,9 @@ proc lookupSlot(c: AnalysisCtx; s: PSym): int =
proc getSlot(c: var AnalysisCtx; v: PSym): ptr MonotonicVar =
let s = lookupSlot(c, v)
if s >= 0: return addr(c.locals[s])
let L = c.locals.len
c.locals.setLen(L+1)
c.locals[L].v = v
return addr(c.locals[L])
c.locals.setLen(c.locals.len+1)
c.locals[^1].v = v
return addr(c.locals[^1])
proc gatherArgs(c: var AnalysisCtx; n: PNode) =
for i in 0..<n.safeLen:
@ -123,7 +122,7 @@ proc checkLocal(c: AnalysisCtx; n: PNode) =
if s >= 0 and c.locals[s].stride != nil:
localError(c.graph.config, n.info, "invalid usage of counter after increment")
else:
for i in 0 ..< n.safeLen: checkLocal(c, n.sons[i])
for i in 0..<n.safeLen: checkLocal(c, n[i])
template `?`(x): untyped = x.renderTree
@ -184,7 +183,7 @@ proc stride(c: AnalysisCtx; n: PNode): BiggestInt =
if s >= 0 and c.locals[s].stride != nil:
result = c.locals[s].stride.intVal
else:
for i in 0 ..< n.safeLen: result += stride(c, n.sons[i])
for i in 0..<n.safeLen: result += stride(c, n[i])
proc subStride(c: AnalysisCtx; n: PNode): PNode =
# substitute with stride:
@ -196,7 +195,7 @@ proc subStride(c: AnalysisCtx; n: PNode): PNode =
result = n
elif n.safeLen > 0:
result = shallowCopy(n)
for i in 0 ..< n.len: result.sons[i] = subStride(c, n.sons[i])
for i in 0..<n.len: result[i] = subStride(c, n[i])
else:
result = n
@ -216,8 +215,8 @@ proc checkSlicesAreDisjoint(c: var AnalysisCtx) =
#
# Or even worse:
# while true:
# spawn f(a[i+1 .. i+3])
# spawn f(a[i+4 .. i+5])
# spawn f(a[i+1..i+3])
# spawn f(a[i+4..i+5])
# inc i, 4
# Prove that i*k*stride + 3 != i*k'*stride + 5
# For the correct example this amounts to
@ -226,15 +225,15 @@ proc checkSlicesAreDisjoint(c: var AnalysisCtx) =
# For now, we don't try to prove things like that at all, even though it'd
# be feasible for many useful examples. Instead we attach the slice to
# a spawn and if the attached spawns differ, we bail out:
for i in 0 .. high(c.slices):
for j in i+1 .. high(c.slices):
for i in 0..high(c.slices):
for j in i+1..high(c.slices):
let x = c.slices[i]
let y = c.slices[j]
if x.spawnId != y.spawnId and guards.sameTree(x.x, y.x):
if not x.inLoop or not y.inLoop:
# XXX strictly speaking, 'or' is not correct here and it needs to
# be 'and'. However this prevents too many obviously correct programs
# like f(a[0..x]); for i in x+1 .. a.high: f(a[i])
# like f(a[0..x]); for i in x+1..a.high: f(a[i])
overlap(c.guards, c.graph.config, x.a, x.b, y.a, y.b)
elif (let k = simpleSlice(x.a, x.b); let m = simpleSlice(y.a, y.b);
k >= 0 and m >= 0):
@ -255,7 +254,7 @@ proc checkSlicesAreDisjoint(c: var AnalysisCtx) =
proc analyse(c: var AnalysisCtx; n: PNode)
proc analyseSons(c: var AnalysisCtx; n: PNode) =
for i in 0 ..< safeLen(n): analyse(c, n[i])
for i in 0..<n.safeLen: analyse(c, n[i])
proc min(a, b: PNode): PNode =
if a.isNil: result = b
@ -295,31 +294,31 @@ proc analyseCall(c: var AnalysisCtx; n: PNode; op: PSym) =
analyseSons(c, n)
proc analyseCase(c: var AnalysisCtx; n: PNode) =
analyse(c, n.sons[0])
analyse(c, n[0])
let oldFacts = c.guards.s.len
for i in 1..<n.len:
let branch = n.sons[i]
let branch = n[i]
setLen(c.guards.s, oldFacts)
addCaseBranchFacts(c.guards, n, i)
for i in 0 ..< branch.len:
analyse(c, branch.sons[i])
for i in 0..<branch.len:
analyse(c, branch[i])
setLen(c.guards.s, oldFacts)
proc analyseIf(c: var AnalysisCtx; n: PNode) =
analyse(c, n.sons[0].sons[0])
analyse(c, n[0][0])
let oldFacts = c.guards.s.len
addFact(c.guards, canon(n.sons[0].sons[0], c.guards.o))
addFact(c.guards, canon(n[0][0], c.guards.o))
analyse(c, n.sons[0].sons[1])
analyse(c, n[0][1])
for i in 1..<n.len:
let branch = n.sons[i]
let branch = n[i]
setLen(c.guards.s, oldFacts)
for j in 0..i-1:
addFactNeg(c.guards, canon(n.sons[j].sons[0], c.guards.o))
addFactNeg(c.guards, canon(n[j][0], c.guards.o))
if branch.len > 1:
addFact(c.guards, canon(branch.sons[0], c.guards.o))
for i in 0 ..< branch.len:
analyse(c, branch.sons[i])
addFact(c.guards, canon(branch[0], c.guards.o))
for i in 0..<branch.len:
analyse(c, branch[i])
setLen(c.guards.s, oldFacts)
proc analyse(c: var AnalysisCtx; n: PNode) =
@ -365,7 +364,7 @@ proc analyse(c: var AnalysisCtx; n: PNode) =
gatherArgs(c, value[1])
analyseSons(c, value[1])
if value.kind != nkEmpty:
for j in 0 .. it.len-3:
for j in 0..<it.len-2:
if it[j].isLocal:
let slot = c.getSlot(it[j].sym)
if slot.lower.isNil: slot.lower = value
@ -374,22 +373,22 @@ proc analyse(c: var AnalysisCtx; n: PNode) =
of nkCaseStmt: analyseCase(c, n)
of nkWhen, nkIfStmt, nkIfExpr: analyseIf(c, n)
of nkWhileStmt:
analyse(c, n.sons[0])
analyse(c, n[0])
# 'while true' loop?
inc c.inLoop
if isTrue(n.sons[0]):
analyseSons(c, n.sons[1])
if isTrue(n[0]):
analyseSons(c, n[1])
else:
# loop may never execute:
let oldState = c.locals.len
let oldFacts = c.guards.s.len
addFact(c.guards, canon(n.sons[0], c.guards.o))
analyse(c, n.sons[1])
addFact(c.guards, canon(n[0], c.guards.o))
analyse(c, n[1])
setLen(c.locals, oldState)
setLen(c.guards.s, oldFacts)
# we know after the loop the negation holds:
if not hasSubnodeWith(n.sons[1], nkBreakStmt):
addFactNeg(c.guards, canon(n.sons[0], c.guards.o))
if not hasSubnodeWith(n[1], nkBreakStmt):
addFactNeg(c.guards, canon(n[0], c.guards.o))
dec c.inLoop
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
nkMacroDef, nkTemplateDef, nkConstSection, nkPragma, nkFuncDef:
@ -412,16 +411,16 @@ proc transformSlices(g: ModuleGraph; n: PNode): PNode =
return result
if n.safeLen > 0:
result = shallowCopy(n)
for i in 0 ..< n.len:
result.sons[i] = transformSlices(g, n.sons[i])
for i in 0..<n.len:
result[i] = transformSlices(g, n[i])
else:
result = n
proc transformSpawn(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode
proc transformSpawnSons(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode =
result = shallowCopy(n)
for i in 0 ..< n.len:
result.sons[i] = transformSpawn(g, owner, n.sons[i], barrier)
for i in 0..<n.len:
result[i] = transformSpawn(g, owner, n[i], barrier)
proc transformSpawn(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode =
case n.kind
@ -435,16 +434,16 @@ proc transformSpawn(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode =
if result.isNil:
result = newNodeI(nkStmtList, n.info)
result.add n
let t = b[1][0].typ.sons[0]
let t = b[1][0].typ[0]
if spawnResult(t, true) == srByVar:
result.add wrapProcForSpawn(g, owner, m, b.typ, barrier, it[0])
it.sons[it.len-1] = newNodeI(nkEmpty, it.info)
it[^1] = newNodeI(nkEmpty, it.info)
else:
it.sons[it.len-1] = wrapProcForSpawn(g, owner, m, b.typ, barrier, nil)
it[^1] = wrapProcForSpawn(g, owner, m, b.typ, barrier, nil)
if result.isNil: result = n
of nkAsgn, nkFastAsgn:
let b = n[1]
if getMagic(b) == mSpawn and (let t = b[1][0].typ.sons[0];
if getMagic(b) == mSpawn and (let t = b[1][0].typ[0];
spawnResult(t, true) == srByVar):
let m = transformSlices(g, b)
return wrapProcForSpawn(g, owner, m, b.typ, barrier, n[0])

View file

@ -91,7 +91,7 @@ proc isLocalVar(a: PEffects, s: PSym): bool =
proc getLockLevel(t: PType): TLockLevel =
var t = t
# tyGenericInst(TLock {tyGenericBody}, tyStatic, tyObject):
if t.kind == tyGenericInst and t.len == 3: t = t.sons[1]
if t.kind == tyGenericInst and t.len == 3: t = t[1]
if t.kind == tyStatic and t.n != nil and t.n.kind in {nkCharLit..nkInt64Lit}:
result = t.n.intVal.TLockLevel
@ -131,21 +131,21 @@ proc guardGlobal(a: PEffects; n: PNode; guard: PSym) =
# 'guard*' are checks which are concerned with 'guard' annotations
# (var x{.guard: y.}: int)
proc guardDotAccess(a: PEffects; n: PNode) =
let ri = n.sons[1]
let ri = n[1]
if ri.kind != nkSym or ri.sym.kind != skField: return
var g = ri.sym.guard
if g.isNil or a.isTopLevel: return
# fixup guard:
if g.kind == skUnknown:
var field: PSym = nil
var ty = n.sons[0].typ.skipTypes(abstractPtrs)
var ty = n[0].typ.skipTypes(abstractPtrs)
if ty.kind == tyTuple and not ty.n.isNil:
field = lookupInRecord(ty.n, g.name)
else:
while ty != nil and ty.kind == tyObject:
field = lookupInRecord(ty.n, g.name)
if field != nil: break
ty = ty.sons[0]
ty = ty[0]
if ty == nil: break
ty = ty.skipTypes(skipPtrs)
if field == nil:
@ -156,8 +156,8 @@ proc guardDotAccess(a: PEffects; n: PNode) =
# XXX unfortunately this is not correct for generic instantiations!
if g.kind == skField:
let dot = newNodeI(nkDotExpr, n.info, 2)
dot.sons[0] = n.sons[0]
dot.sons[1] = newSymNode(g)
dot[0] = n[0]
dot[1] = newSymNode(g)
dot.typ = g.typ
for L in a.locked:
#if a.guards.sameSubexprs(dot, L): return
@ -305,7 +305,7 @@ proc createTag(g: ModuleGraph; n: PNode): PNode =
proc addEffect(a: PEffects, e: PNode, useLineInfo=true) =
assert e.kind != nkRaiseStmt
var aa = a.exc
for i in a.bottom ..< aa.len:
for i in a.bottom..<aa.len:
if sameType(a.graph.excType(aa[i]), a.graph.excType(e)):
if not useLineInfo or a.config.cmd == cmdDoc: return
elif aa[i].info == e.info: return
@ -313,7 +313,7 @@ proc addEffect(a: PEffects, e: PNode, useLineInfo=true) =
proc addTag(a: PEffects, e: PNode, useLineInfo=true) =
var aa = a.tags
for i in 0 ..< aa.len:
for i in 0..<aa.len:
if sameType(aa[i].typ.skipTypes(skipPtrs), e.typ.skipTypes(skipPtrs)):
if not useLineInfo or a.config.cmd == cmdDoc: return
elif aa[i].info == e.info: return
@ -344,7 +344,7 @@ proc catches(tracked: PEffects, e: PType) =
while i < L:
# r supertype of e?
if safeInheritanceDiff(tracked.graph.excType(tracked.exc[i]), e) <= 0:
tracked.exc.sons[i] = tracked.exc.sons[L-1]
tracked.exc[i] = tracked.exc[L-1]
dec L
else:
inc i
@ -366,7 +366,7 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
var inter: TIntersection = @[]
inc tracked.inTryStmt
track(tracked, n.sons[0])
track(tracked, n[0])
dec tracked.inTryStmt
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
@ -375,35 +375,33 @@ proc trackTryStmt(tracked: PEffects, n: PNode) =
var hasFinally = false
# Collect the exceptions caught by the except branches
for i in 1 ..< n.len:
let b = n.sons[i]
let blen = len(b)
for i in 1..<n.len:
let b = n[i]
if b.kind == nkExceptBranch:
inc branches
if blen == 1:
if b.len == 1:
catchesAll(tracked)
else:
for j in 0 .. blen - 2:
if b.sons[j].isInfixAs():
assert(b.sons[j][1].kind == nkType)
catches(tracked, b.sons[j][1].typ)
for j in 0..<b.len - 1:
if b[j].isInfixAs():
assert(b[j][1].kind == nkType)
catches(tracked, b[j][1].typ)
else:
assert(b.sons[j].kind == nkType)
catches(tracked, b.sons[j].typ)
assert(b[j].kind == nkType)
catches(tracked, b[j].typ)
else:
assert b.kind == nkFinally
# Add any other exception raised in the except bodies
for i in 1 ..< n.len:
let b = n.sons[i]
let blen = len(b)
for i in 1..<n.len:
let b = n[i]
if b.kind == nkExceptBranch:
setLen(tracked.init, oldState)
track(tracked, b.sons[blen-1])
track(tracked, b[^1])
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
else:
setLen(tracked.init, oldState)
track(tracked, b.sons[blen-1])
track(tracked, b[^1])
hasFinally = true
tracked.bottom = oldBottom
@ -427,8 +425,8 @@ 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 ..< len(n):
var it = n.sons[i]
for i in 0..<n.len:
var it = n[i]
if whichPragma(it) == wEffects:
# list the computed effects up to here:
listEffects(tracked)
@ -459,7 +457,7 @@ proc mergeLockLevels(tracked: PEffects, n: PNode, lockLevel: TLockLevel) =
tracked.maxLockLevel = max(tracked.maxLockLevel, lockLevel)
proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) =
let pragma = s.ast.sons[pragmasPos]
let pragma = s.ast[pragmasPos]
let spec = effectSpec(pragma, wRaises)
mergeEffects(tracked, spec, n)
@ -531,8 +529,8 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType; caller: PNode)
let op = a.typ
# assume indirect calls are taken here:
if op != nil and op.kind == tyProc and n.skipConv.kind != nkNilLit and not isTrival(caller):
internalAssert tracked.config, op.n.sons[0].kind == nkEffectList
var effectList = op.n.sons[0]
internalAssert tracked.config, op.n[0].kind == nkEffectList
var effectList = op.n[0]
var s = n.skipConv
if s.kind == nkCast and s[1].typ.kind == tyProc:
s = s[1]
@ -553,8 +551,8 @@ proc trackOperand(tracked: PEffects, n: PNode, paramType: PType; caller: PNode)
elif tfNoSideEffect notin op.flags and not isOwnedProcVar(a, tracked.owner):
markSideEffect(tracked, a)
else:
mergeEffects(tracked, effectList.sons[exceptionEffects], n)
mergeTags(tracked, effectList.sons[tagEffects], n)
mergeEffects(tracked, effectList[exceptionEffects], n)
mergeTags(tracked, effectList[tagEffects], n)
if notGcSafe(op):
if warnGcUnsafe in tracked.config.notes: warnAboutGcUnsafe(n, tracked.config)
markGcUnsafe(tracked, a)
@ -582,23 +580,23 @@ proc breaksBlock(n: PNode): bool =
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
proc trackCase(tracked: PEffects, n: PNode) =
track(tracked, n.sons[0])
track(tracked, n[0])
let oldState = tracked.init.len
let oldFacts = tracked.guards.s.len
let stringCase = skipTypes(n.sons[0].typ,
let stringCase = skipTypes(n[0].typ,
abstractVarRange-{tyTypeDesc}).kind in {tyFloat..tyFloat128, tyString}
let interesting = not stringCase and interestingCaseExpr(n.sons[0]) and
let interesting = not stringCase and interestingCaseExpr(n[0]) and
warnProveField in tracked.config.notes
var inter: TIntersection = @[]
var toCover = 0
for i in 1..<n.len:
let branch = n.sons[i]
let branch = n[i]
setLen(tracked.init, oldState)
if interesting:
setLen(tracked.guards.s, oldFacts)
addCaseBranchFacts(tracked.guards, n, i)
for i in 0 ..< branch.len:
track(tracked, branch.sons[i])
for i in 0..<branch.len:
track(tracked, branch[i])
if not breaksBlock(branch.lastSon): inc toCover
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
@ -611,28 +609,28 @@ proc trackCase(tracked: PEffects, n: PNode) =
setLen(tracked.guards.s, oldFacts)
proc trackIf(tracked: PEffects, n: PNode) =
track(tracked, n.sons[0].sons[0])
track(tracked, n[0][0])
let oldFacts = tracked.guards.s.len
addFact(tracked.guards, n.sons[0].sons[0])
addFact(tracked.guards, n[0][0])
let oldState = tracked.init.len
var inter: TIntersection = @[]
var toCover = 0
track(tracked, n.sons[0].sons[1])
if not breaksBlock(n.sons[0].sons[1]): inc toCover
track(tracked, n[0][1])
if not breaksBlock(n[0][1]): inc toCover
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
for i in 1..<n.len:
let branch = n.sons[i]
let branch = n[i]
setLen(tracked.guards.s, oldFacts)
for j in 0..i-1:
addFactNeg(tracked.guards, n.sons[j].sons[0])
addFactNeg(tracked.guards, n[j][0])
if branch.len > 1:
addFact(tracked.guards, branch.sons[0])
addFact(tracked.guards, branch[0])
setLen(tracked.init, oldState)
for i in 0 ..< branch.len:
track(tracked, branch.sons[i])
for i in 0..<branch.len:
track(tracked, branch[i])
if not breaksBlock(branch.lastSon): inc toCover
for i in oldState..<tracked.init.len:
addToIntersection(inter, tracked.init[i])
@ -647,14 +645,14 @@ proc trackBlock(tracked: PEffects, n: PNode) =
if n.kind in {nkStmtList, nkStmtListExpr}:
var oldState = -1
for i in 0..<n.len:
if hasSubnodeWith(n.sons[i], nkBreakStmt):
if hasSubnodeWith(n[i], nkBreakStmt):
# block:
# x = def
# if ...: ... break # some nested break
# y = def
# --> 'y' not defined after block!
if oldState < 0: oldState = tracked.init.len
track(tracked, n.sons[i])
track(tracked, n[i])
if oldState > 0: setLen(tracked.init, oldState)
else:
track(tracked, n)
@ -664,10 +662,10 @@ proc isTrue*(n: PNode): bool =
n.kind == nkIntLit and n.intVal != 0
proc paramType(op: PType, i: int): PType =
if op != nil and i < op.len: result = op.sons[i]
if op != nil and i < op.len: result = op[i]
proc cstringCheck(tracked: PEffects; n: PNode) =
if n.sons[0].typ.kind == tyCString and (let a = skipConv(n[1]);
if n[0].typ.kind == tyCString and (let a = skipConv(n[1]);
a.typ.kind == tyString and a.kind notin {nkStrLit..nkTripleStrLit}):
message(tracked.config, n.info, warnUnsafeCode, renderTree(n))
@ -696,11 +694,11 @@ proc track(tracked: PEffects, n: PNode) =
tracked.owner.flags.incl sfInjectDestructors
of nkRaiseStmt:
if n[0].kind != nkEmpty:
n.sons[0].info = n.info
#throws(tracked.exc, n.sons[0])
addEffect(tracked, n.sons[0], useLineInfo=false)
for i in 0 ..< safeLen(n):
track(tracked, n.sons[i])
n[0].info = n.info
#throws(tracked.exc, n[0])
addEffect(tracked, n[0], useLineInfo=false)
for i in 0..<n.safeLen:
track(tracked, n[i])
createTypeBoundOps(tracked, n[0].typ, n.info)
else:
# A `raise` with no arguments means we're going to re-raise the exception
@ -709,7 +707,7 @@ proc track(tracked: PEffects, n: PNode) =
addEffect(tracked, createRaise(tracked.graph, n))
of nkCallKinds:
# p's effects are ours too:
var a = n.sons[0]
var a = n[0]
let op = a.typ
if n.typ != nil:
if tracked.owner.kind != skMacro and n.typ.skipTypes(abstractVar).kind != tyOpenArray:
@ -722,7 +720,7 @@ proc track(tracked: PEffects, n: PNode) =
# calling getAst(templateOrMacro()). Currently, templates and macros
# are indistinguishable from normal procs (both have tyProc type) and
# we can detect them only by checking for attached nkEffectList.
if op != nil and op.kind == tyProc and op.n.sons[0].kind == nkEffectList:
if op != nil and op.kind == tyProc and op.n[0].kind == nkEffectList:
if a.kind == nkSym:
if a.sym == tracked.owner: tracked.isRecursive = true
# even for recursive calls we need to check the lock levels (!):
@ -730,7 +728,7 @@ proc track(tracked: PEffects, n: PNode) =
if sfSideEffect in a.sym.flags: markSideEffect(tracked, a)
else:
mergeLockLevels(tracked, n, op.lockLevel)
var effectList = op.n.sons[0]
var effectList = op.n[0]
if a.kind == nkSym and a.sym.kind == skMethod:
propagateEffects(tracked, n, a.sym)
elif isNoEffectList(effectList):
@ -740,14 +738,14 @@ proc track(tracked: PEffects, n: PNode) =
assumeTheWorst(tracked, n, op)
gcsafeAndSideeffectCheck()
else:
mergeEffects(tracked, effectList.sons[exceptionEffects], n)
mergeTags(tracked, effectList.sons[tagEffects], n)
mergeEffects(tracked, effectList[exceptionEffects], n)
mergeTags(tracked, effectList[tagEffects], n)
gcsafeAndSideeffectCheck()
if a.kind != nkSym or a.sym.magic != mNBindSym:
for i in 1 ..< n.len: trackOperand(tracked, n.sons[i], paramType(op, i), a)
for i in 1..<n.len: trackOperand(tracked, n[i], paramType(op, i), a)
if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}:
# may not look like an assignment, but it is:
let arg = n.sons[1]
let arg = n[1]
initVarViaNew(tracked, arg)
if arg.typ.len != 0 and {tfNeedsInit} * arg.typ.lastSon.flags != {}:
if a.sym.magic == mNewSeq and n[2].kind in {nkCharLit..nkUInt64Lit} and
@ -760,24 +758,24 @@ proc track(tracked: PEffects, n: PNode) =
if n[1].typ.len > 0:
createTypeBoundOps(tracked, n[1].typ.lastSon, n.info)
createTypeBoundOps(tracked, n[1].typ, n.info)
for i in 0 ..< safeLen(n):
track(tracked, n.sons[i])
for i in 0..<n.safeLen:
track(tracked, n[i])
of nkDotExpr:
guardDotAccess(tracked, n)
for i in 0 ..< n.len: track(tracked, n.sons[i])
for i in 0..<n.len: track(tracked, n[i])
of nkCheckedFieldExpr:
track(tracked, n.sons[0])
track(tracked, n[0])
if warnProveField in tracked.config.notes:
checkFieldAccess(tracked.guards, n, tracked.config)
of nkTryStmt: trackTryStmt(tracked, n)
of nkPragma: trackPragmaStmt(tracked, n)
of nkAsgn, nkFastAsgn:
track(tracked, n.sons[1])
initVar(tracked, n.sons[0], volatileCheck=true)
invalidateFacts(tracked.guards, n.sons[0])
track(tracked, n.sons[0])
addAsgnFact(tracked.guards, n.sons[0], n.sons[1])
notNilCheck(tracked, n.sons[1], n.sons[0].typ)
track(tracked, n[1])
initVar(tracked, n[0], volatileCheck=true)
invalidateFacts(tracked.guards, n[0])
track(tracked, n[0])
addAsgnFact(tracked.guards, n[0], n[1])
notNilCheck(tracked, n[1], n[0].typ)
when false: cstringCheck(tracked, n)
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked, n[0].typ, n.info)
@ -788,17 +786,17 @@ proc track(tracked: PEffects, n: PNode) =
if tracked.owner.kind != skMacro:
if child.kind == nkVarTuple:
createTypeBoundOps(tracked, child[^1].typ, child.info)
for i in 0..child.len-3:
for i in 0..<child.len-2:
createTypeBoundOps(tracked, child[i].typ, child.info)
else:
createTypeBoundOps(tracked, child[0].typ, child.info)
if child.kind == nkIdentDefs and last.kind != nkEmpty:
for i in 0 .. child.len-3:
initVar(tracked, child.sons[i], volatileCheck=false)
addAsgnFact(tracked.guards, child.sons[i], last)
notNilCheck(tracked, last, child.sons[i].typ)
for i in 0..<child.len-2:
initVar(tracked, child[i], volatileCheck=false)
addAsgnFact(tracked.guards, child[i], last)
notNilCheck(tracked, last, child[i].typ)
elif child.kind == nkVarTuple and last.kind != nkEmpty:
for i in 0 .. child.len-2:
for i in 0..<child.len-1:
if child[i].kind == nkEmpty or
child[i].kind == nkSym and child[i].sym.name.s == "_":
continue
@ -814,24 +812,24 @@ proc track(tracked: PEffects, n: PNode) =
track(tracked, last)
of nkCaseStmt: trackCase(tracked, n)
of nkWhen, nkIfStmt, nkIfExpr: trackIf(tracked, n)
of nkBlockStmt, nkBlockExpr: trackBlock(tracked, n.sons[1])
of nkBlockStmt, nkBlockExpr: trackBlock(tracked, n[1])
of nkWhileStmt:
track(tracked, n.sons[0])
track(tracked, n[0])
# 'while true' loop?
if isTrue(n.sons[0]):
trackBlock(tracked, n.sons[1])
if isTrue(n[0]):
trackBlock(tracked, n[1])
else:
# loop may never execute:
let oldState = tracked.init.len
let oldFacts = tracked.guards.s.len
addFact(tracked.guards, n.sons[0])
track(tracked, n.sons[1])
addFact(tracked.guards, n[0])
track(tracked, n[1])
setLen(tracked.init, oldState)
setLen(tracked.guards.s, oldFacts)
of nkForStmt, nkParForStmt:
# we are very conservative here and assume the loop is never executed:
let oldState = tracked.init.len
for i in 0 .. n.len-3:
for i in 0..<n.len-2:
let it = n[i]
track(tracked, it)
if tracked.owner.kind != skMacro:
@ -840,8 +838,8 @@ proc track(tracked: PEffects, n: PNode) =
createTypeBoundOps(tracked, x.typ, x.info)
else:
createTypeBoundOps(tracked, it.typ, it.info)
let iterCall = n[n.len-2]
let loopBody = n[n.len-1]
let iterCall = n[^2]
let loopBody = n[^1]
if tracked.owner.kind != skMacro and iterCall.safeLen > 1:
# XXX this is a bit hacky:
if iterCall[1].typ != nil and iterCall[1].typ.skipTypes(abstractVar).kind notin {tyVarargs, tyOpenArray}:
@ -850,26 +848,26 @@ proc track(tracked: PEffects, n: PNode) =
track(tracked, loopBody)
setLen(tracked.init, oldState)
of nkObjConstr:
when false: track(tracked, n.sons[0])
when false: track(tracked, n[0])
let oldFacts = tracked.guards.s.len
for i in 1 ..< n.len:
let x = n.sons[i]
for i in 1..<n.len:
let x = n[i]
track(tracked, x)
if x.sons[0].kind == nkSym and sfDiscriminant in x.sons[0].sym.flags:
if x[0].kind == nkSym and sfDiscriminant in x[0].sym.flags:
addDiscriminantFact(tracked.guards, x)
setLen(tracked.guards.s, oldFacts)
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked, n.typ, n.info)
of nkPragmaBlock:
let pragmaList = n.sons[0]
let pragmaList = n[0]
let oldLocked = tracked.locked.len
let oldLockLevel = tracked.currLockLevel
var enforcedGcSafety = false
var enforceNoSideEffects = false
for i in 0 ..< pragmaList.len:
let pragma = whichPragma(pragmaList.sons[i])
for i in 0..<pragmaList.len:
let pragma = whichPragma(pragmaList[i])
if pragma == wLocks:
lockLocations(tracked, pragmaList.sons[i])
lockLocations(tracked, pragmaList[i])
elif pragma == wGcSafe:
enforcedGcSafety = true
elif pragma == wNoSideEffect:
@ -885,15 +883,15 @@ proc track(tracked: PEffects, n: PNode) =
nkMacroDef, nkTemplateDef, nkLambda, nkDo, nkFuncDef:
discard
of nkCast, nkHiddenStdConv, nkHiddenSubConv, nkConv:
if n.len == 2: track(tracked, n.sons[1])
if n.len == 2: track(tracked, n[1])
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
if n.len == 1: track(tracked, n.sons[0])
if n.len == 1: track(tracked, n[0])
of nkBracket:
for i in 0 ..< safeLen(n): track(tracked, n.sons[i])
for i in 0..<n.safeLen: track(tracked, n[i])
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked, n.typ, n.info)
else:
for i in 0 ..< safeLen(n): track(tracked, n.sons[i])
for i in 0..<n.safeLen: track(tracked, n[i])
proc subtypeRelation(g: ModuleGraph; spec, real: PNode): bool =
result = safeInheritanceDiff(g.excType(real), spec.typ) <= 0
@ -905,7 +903,7 @@ proc checkRaisesSpec(g: ModuleGraph; spec, real: PNode, msg: string, hints: bool
var used = initIntSet()
for r in items(real):
block search:
for s in 0 ..< spec.len:
for s in 0..<spec.len:
if effectPredicate(g, spec[s], r):
used.incl(s)
break search
@ -915,23 +913,23 @@ proc checkRaisesSpec(g: ModuleGraph; spec, real: PNode, msg: string, hints: bool
popInfoContext(g.config)
# hint about unnecessarily listed exception types:
if hints:
for s in 0 ..< spec.len:
for s in 0..<spec.len:
if not used.contains(s):
message(g.config, spec[s].info, hintXDeclaredButNotUsed, renderTree(spec[s]))
proc checkMethodEffects*(g: ModuleGraph; disp, branch: PSym) =
## checks for consistent effects for multi methods.
let actual = branch.typ.n.sons[0]
let actual = branch.typ.n[0]
if actual.len != effectListLen: return
let p = disp.ast.sons[pragmasPos]
let p = disp.ast[pragmasPos]
let raisesSpec = effectSpec(p, wRaises)
if not isNil(raisesSpec):
checkRaisesSpec(g, raisesSpec, actual.sons[exceptionEffects],
checkRaisesSpec(g, raisesSpec, actual[exceptionEffects],
"can raise an unlisted exception: ", hints=off, subtypeRelation)
let tagsSpec = effectSpec(p, wTags)
if not isNil(tagsSpec):
checkRaisesSpec(g, tagsSpec, actual.sons[tagEffects],
checkRaisesSpec(g, tagsSpec, actual[tagEffects],
"can have an unlisted effect: ", hints=off, subtypeRelation)
if sfThread in disp.flags and notGcSafe(branch.typ):
localError(g.config, branch.info, "base method is GC-safe, but '$1' is not" %
@ -963,14 +961,14 @@ proc setEffectsForProcType*(g: ModuleGraph; t: PType, n: PNode) =
proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects; c: PContext) =
newSeq(effects.sons, effectListLen)
effects.sons[exceptionEffects] = newNodeI(nkArgList, s.info)
effects.sons[tagEffects] = newNodeI(nkArgList, s.info)
effects.sons[usesEffects] = g.emptyNode
effects.sons[writeEffects] = g.emptyNode
effects.sons[pragmasEffects] = g.emptyNode
effects[exceptionEffects] = newNodeI(nkArgList, s.info)
effects[tagEffects] = newNodeI(nkArgList, s.info)
effects[usesEffects] = g.emptyNode
effects[writeEffects] = g.emptyNode
effects[pragmasEffects] = g.emptyNode
t.exc = effects.sons[exceptionEffects]
t.tags = effects.sons[tagEffects]
t.exc = effects[exceptionEffects]
t.tags = effects[tagEffects]
t.owner = s
t.ownerModule = s.getModule
t.init = @[]
@ -983,7 +981,7 @@ proc initEffects(g: ModuleGraph; effects: PNode; s: PSym; t: var TEffects; c: PC
proc trackProc*(c: PContext; s: PSym, body: PNode) =
let g = c.graph
var effects = s.typ.n.sons[0]
var effects = s.typ.n[0]
if effects.kind != nkEffectList: return
# effects already computed?
if sfForward in s.flags: return
@ -995,32 +993,32 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =
if s.kind != skMacro:
let params = s.typ.n
for i in 1 ..< params.len:
for i in 1..<params.len:
let param = params[i].sym
if isSinkTypeForParam(param.typ):
createTypeBoundOps(t.graph, t.c, param.typ, param.info)
if not isEmptyType(s.typ.sons[0]) and
({tfNeedsInit, tfNotNil} * s.typ.sons[0].flags != {} or
s.typ.sons[0].skipTypes(abstractInst).kind == tyVar) and
if not isEmptyType(s.typ[0]) and
({tfNeedsInit, tfNotNil} * s.typ[0].flags != {} or
s.typ[0].skipTypes(abstractInst).kind == tyVar) and
s.kind in {skProc, skFunc, skConverter, skMethod}:
var res = s.ast.sons[resultPos].sym # get result symbol
var res = s.ast[resultPos].sym # get result symbol
if res.id notin t.init:
message(g.config, body.info, warnProveInit, "result")
let p = s.ast.sons[pragmasPos]
let p = s.ast[pragmasPos]
let raisesSpec = effectSpec(p, wRaises)
if not isNil(raisesSpec):
checkRaisesSpec(g, raisesSpec, t.exc, "can raise an unlisted exception: ",
hints=on, subtypeRelation)
# after the check, use the formal spec:
effects.sons[exceptionEffects] = raisesSpec
effects[exceptionEffects] = raisesSpec
let tagsSpec = effectSpec(p, wTags)
if not isNil(tagsSpec):
checkRaisesSpec(g, tagsSpec, t.tags, "can have an unlisted effect: ",
hints=off, subtypeRelation)
# after the check, use the formal spec:
effects.sons[tagEffects] = tagsSpec
effects[tagEffects] = tagsSpec
if sfThread in s.flags and t.gcUnsafe:
if optThreads in g.config.globalOptions and optThreadAnalysis in g.config.globalOptions:

File diff suppressed because it is too large Load diff

View file

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

File diff suppressed because it is too large Load diff

View file

@ -16,32 +16,32 @@ const
tfInstClearedFlags = {tfHasMeta, tfUnresolved}
proc checkPartialConstructedType(conf: ConfigRef; info: TLineInfo, t: PType) =
if t.kind in {tyVar, tyLent} and t.sons[0].kind in {tyVar, tyLent}:
if t.kind in {tyVar, tyLent} and t[0].kind in {tyVar, tyLent}:
localError(conf, info, "type 'var var' is not allowed")
proc checkConstructedType*(conf: ConfigRef; info: TLineInfo, typ: PType) =
var t = typ.skipTypes({tyDistinct})
if t.kind in tyTypeClasses: discard
elif t.kind in {tyVar, tyLent} and t.sons[0].kind in {tyVar, tyLent}:
elif t.kind in {tyVar, tyLent} and t[0].kind in {tyVar, tyLent}:
localError(conf, info, "type 'var var' is not allowed")
elif computeSize(conf, t) == szIllegalRecursion or isTupleRecursive(t):
localError(conf, info, "illegal recursion in type '" & typeToString(t) & "'")
when false:
if t.kind == tyObject and t.sons[0] != nil:
if t.sons[0].kind != tyObject or tfFinal in t.sons[0].flags:
if t.kind == tyObject and t[0] != nil:
if t[0].kind != tyObject or tfFinal in t[0].flags:
localError(info, errInheritanceOnlyWithNonFinalObjects)
proc searchInstTypes*(key: PType): PType =
let genericTyp = key.sons[0]
let genericTyp = key[0]
if not (genericTyp.kind == tyGenericBody and
key.sons[0] == genericTyp and genericTyp.sym != nil): return
key[0] == genericTyp and genericTyp.sym != nil): return
when not defined(nimNoNilSeqs):
if genericTyp.sym.typeInstCache == nil: return
for inst in genericTyp.sym.typeInstCache:
if inst.id == key.id: return inst
if inst.sons.len < key.sons.len:
if inst.len < key.len:
# XXX: This happens for prematurely cached
# types such as Channel[empty]. Why?
# See the notes for PActor in handleGenericInvocation
@ -50,9 +50,9 @@ proc searchInstTypes*(key: PType): PType =
continue
block matchType:
for j in 1 .. high(key.sons):
for j in 1..high(key.sons):
# XXX sameType is not really correct for nested generics?
if not compareTypes(inst.sons[j], key.sons[j],
if not compareTypes(inst[j], key[j],
flags = {ExactGenericParams}):
break matchType
@ -61,7 +61,7 @@ proc searchInstTypes*(key: PType): PType =
proc cacheTypeInst*(inst: PType) =
# XXX: add to module's generics
# update the refcount
let gt = inst.sons[0]
let gt = inst[0]
let t = if gt.kind == tyGenericBody: gt.lastSon else: gt
if t.kind in {tyStatic, tyError, tyGenericParam} + tyTypeClasses:
return
@ -129,7 +129,7 @@ proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode =
result.typ = t
if result.kind == nkSym: result.sym = replaceTypeVarsS(cl, n.sym)
let isCall = result.kind in nkCallKinds
for i in 0 ..< n.safeLen:
for i in 0..<n.safeLen:
# XXX HACK: ``f(a, b)``, avoid to instantiate `f`
if isCall and i == 0: result.add(n[i])
else: result.add(prepareNode(cl, n[i]))
@ -151,14 +151,14 @@ proc reResolveCallsWithTypedescParams(cl: var TReplTypeVars, n: PNode): PNode =
# overload resolution is executed again (which may trigger generateInstance).
if n.kind in nkCallKinds and sfFromGeneric in n[0].sym.flags:
var needsFixing = false
for i in 1 ..< n.safeLen:
for i in 1..<n.safeLen:
if isTypeParam(n[i]): needsFixing = true
if needsFixing:
n.sons[0] = newSymNode(n.sons[0].sym.owner)
n[0] = newSymNode(n[0].sym.owner)
return cl.c.semOverloadedCall(cl.c, n, n, {skProc, skFunc}, {})
for i in 0 ..< n.safeLen:
n.sons[i] = reResolveCallsWithTypedescParams(cl, n[i])
for i in 0..<n.safeLen:
n[i] = reResolveCallsWithTypedescParams(cl, n[i])
return n
@ -169,20 +169,20 @@ proc replaceObjBranches(cl: TReplTypeVars, n: PNode): PNode =
discard
of nkRecWhen:
var branch: PNode = nil # the branch to take
for i in 0 ..< len(n):
var it = n.sons[i]
for i in 0..<n.len:
var it = n[i]
if it == nil: illFormedAst(n, cl.c.config)
case it.kind
of nkElifBranch:
checkSonsLen(it, 2, cl.c.config)
var cond = it.sons[0]
var cond = it[0]
var e = cl.c.semConstExpr(cl.c, cond)
if e.kind != nkIntLit:
internalError(cl.c.config, e.info, "ReplaceTypeVarsN: when condition not a bool")
if e.intVal != 0 and branch == nil: branch = it.sons[1]
if e.intVal != 0 and branch == nil: branch = it[1]
of nkElse:
checkSonsLen(it, 1, cl.c.config)
if branch == nil: branch = it.sons[0]
if branch == nil: branch = it[0]
else: illFormedAst(n, cl.c.config)
if branch != nil:
result = replaceObjBranches(cl, branch)
@ -190,7 +190,7 @@ proc replaceObjBranches(cl: TReplTypeVars, n: PNode): PNode =
result = newNodeI(nkRecList, n.info)
else:
for i in 0..<n.len:
n.sons[i] = replaceObjBranches(cl, n.sons[i])
n[i] = replaceObjBranches(cl, n[i])
proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0): PNode =
if n == nil: return
@ -209,20 +209,20 @@ 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 ..< len(n):
var it = n.sons[i]
for i in 0..<n.len:
var it = n[i]
if it == nil: illFormedAst(n, cl.c.config)
case it.kind
of nkElifBranch:
checkSonsLen(it, 2, cl.c.config)
var cond = prepareNode(cl, it.sons[0])
var cond = prepareNode(cl, it[0])
var e = cl.c.semConstExpr(cl.c, cond)
if e.kind != nkIntLit:
internalError(cl.c.config, e.info, "ReplaceTypeVarsN: when condition not a bool")
if e.intVal != 0 and branch == nil: branch = it.sons[1]
if e.intVal != 0 and branch == nil: branch = it[1]
of nkElse:
checkSonsLen(it, 1, cl.c.config)
if branch == nil: branch = it.sons[0]
if branch == nil: branch = it[0]
else: illFormedAst(n, cl.c.config)
if branch != nil:
result = replaceTypeVarsN(cl, branch)
@ -234,13 +234,12 @@ 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 = len(n)
if length > 0:
newSons(result, length)
if n.len > 0:
newSons(result, n.len)
if start > 0:
result.sons[0] = n.sons[0]
for i in start ..< length:
result.sons[i] = replaceTypeVarsN(cl, n.sons[i])
result[0] = n[0]
for i in start..<n.len:
result[i] = replaceTypeVarsN(cl, n[i])
proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
if s == nil: return nil
@ -317,7 +316,7 @@ proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
# tyGenericInvocation[A, tyGenericInvocation[A, B]]
# is difficult to handle:
var body = t.sons[0]
var body = t[0]
if body.kind != tyGenericBody:
internalError(cl.c.config, cl.info, "no generic body")
var header: PType = t
@ -331,13 +330,13 @@ 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 ..< len(t):
var x = t.sons[i]
for i in 1..<t.len:
var x = t[i]
if x.kind in {tyGenericParam}:
x = lookupTypeVar(cl, x)
if x != nil:
if header == t: header = instCopyType(cl, t)
header.sons[i] = x
header[i] = x
propagateToOwner(header, x)
else:
propagateToOwner(header, x)
@ -353,10 +352,10 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
else:
header = instCopyType(cl, t)
result = newType(tyGenericInst, t.sons[0].owner)
result = newType(tyGenericInst, t[0].owner)
result.flags = header.flags
# be careful not to propagate unnecessary flags here (don't use rawAddSon)
result.sons = @[header.sons[0]]
result.sons = @[header[0]]
# ugh need another pass for deeply recursive generic types (e.g. PActor)
# we need to add the candidate here, before it's fully instantiated for
# recursive instantions:
@ -371,17 +370,17 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
var typeMapLayer = newTypeMapLayer(cl)
cl.typeMap = addr(typeMapLayer)
for i in 1 ..< len(t):
var x = replaceTypeVarsT(cl, t.sons[i])
for i in 1..<t.len:
var x = replaceTypeVarsT(cl, t[i])
assert x.kind != tyGenericInvocation
header.sons[i] = x
header[i] = x
propagateToOwner(header, x)
cl.typeMap.put(body.sons[i-1], x)
cl.typeMap.put(body[i-1], x)
for i in 1 ..< len(t):
for i in 1..<t.len:
# if one of the params is not concrete, we cannot do anything
# but we already raised an error!
rawAddSon(result, header.sons[i])
rawAddSon(result, header[i])
if body.kind == tyError:
return
@ -443,35 +442,35 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
proc eraseVoidParams*(t: PType) =
# transform '(): void' into '()' because old parts of the compiler really
# don't deal with '(): void':
if t.sons[0] != nil and t.sons[0].kind == tyVoid:
t.sons[0] = nil
if t[0] != nil and t[0].kind == tyVoid:
t[0] = nil
for i in 1 ..< t.len:
for i in 1..<t.len:
# don't touch any memory unless necessary
if t.sons[i].kind == tyVoid:
if t[i].kind == tyVoid:
var pos = i
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]
for j in i+1..<t.len:
if t[j].kind != tyVoid:
t[pos] = t[j]
t.n[pos] = t.n[j]
inc pos
setLen t.sons, pos
setLen t.n.sons, pos
break
proc skipIntLiteralParams*(t: PType) =
for i in 0 ..< t.len:
let p = t.sons[i]
for i in 0..<t.len:
let p = t[i]
if p == nil: continue
let skipped = p.skipIntLit
if skipped != p:
t.sons[i] = skipped
if i > 0: t.n.sons[i].sym.typ = skipped
t[i] = skipped
if i > 0: t.n[i].sym.typ = skipped
# when the typeof operator is used on a static input
# param, the results gets infected with static as well:
if t.sons[0] != nil and t.sons[0].kind == tyStatic:
t.sons[0] = t.sons[0].base
if t[0] != nil and t[0].kind == tyStatic:
t[0] = t[0].base
proc propagateFieldFlags(t: PType, n: PNode) =
# This is meant for objects and tuples
@ -563,8 +562,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
result = makeTypeDesc(cl.c, result)
elif tfUnresolved in t.flags or cl.skipTypedesc:
result = result.base
elif t.sons[0].kind != tyNone:
result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t.sons[0]))
elif t[0].kind != tyNone:
result = makeTypeDesc(cl.c, replaceTypeVarsT(cl, t[0]))
of tyUserTypeClass, tyStatic:
result = t
@ -573,8 +572,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
bailout()
result = instCopyType(cl, t)
idTablePut(cl.localCache, t, result)
for i in 1 ..< result.len:
result.sons[i] = replaceTypeVarsT(cl, result.sons[i])
for i in 1..<result.len:
result[i] = replaceTypeVarsT(cl, result[i])
propagateToOwner(result, result.lastSon)
else:
@ -586,28 +585,28 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
#if not cl.allowMetaTypes:
idTablePut(cl.localCache, t, result)
for i in 0 ..< len(result):
if result.sons[i] != nil:
if result.sons[i].kind == tyGenericBody:
for i in 0..<result.len:
if result[i] != nil:
if result[i].kind == tyGenericBody:
localError(cl.c.config, if t.sym != nil: t.sym.info else: cl.info,
"cannot instantiate '" &
typeToString(result.sons[i], preferDesc) &
typeToString(result[i], preferDesc) &
"' inside of type definition: '" &
t.owner.name.s & "'; Maybe generic arguments are missing?")
var r = replaceTypeVarsT(cl, result.sons[i])
var r = replaceTypeVarsT(cl, result[i])
if result.kind == tyObject:
# carefully coded to not skip the precious tyGenericInst:
let r2 = r.skipTypes({tyAlias, tySink, tyOwned})
if r2.kind in {tyPtr, tyRef}:
r = skipTypes(r2, {tyPtr, tyRef})
result.sons[i] = r
result[i] = r
if result.kind != tyArray or i != 0:
propagateToOwner(result, r)
# bug #4677: Do not instantiate effect lists
result.n = replaceTypeVarsN(cl, result.n, ord(result.kind==tyProc))
case result.kind
of tyArray:
let idx = result.sons[0]
let idx = result[0]
internalAssert cl.c.config, idx.kind != tyStatic
of tyObject, tyTuple:
@ -674,16 +673,16 @@ proc replaceTypesForLambda*(p: PContext, pt: TIdTable, n: PNode;
popInfoContext(p.config)
proc recomputeFieldPositions*(t: PType; obj: PNode; currPosition: var int) =
if t != nil and t.len > 0 and t.sons[0] != nil:
let b = skipTypes(t.sons[0], skipPtrs)
if t != nil and t.len > 0 and t[0] != nil:
let b = skipTypes(t[0], skipPtrs)
recomputeFieldPositions(b, b.n, currPosition)
case obj.kind
of nkRecList:
for i in 0 ..< len(obj): recomputeFieldPositions(nil, obj.sons[i], currPosition)
for i in 0..<obj.len: recomputeFieldPositions(nil, obj[i], currPosition)
of nkRecCase:
recomputeFieldPositions(nil, obj.sons[0], currPosition)
for i in 1 ..< len(obj):
recomputeFieldPositions(nil, lastSon(obj.sons[i]), currPosition)
recomputeFieldPositions(nil, obj[0], currPosition)
for i in 1..<obj.len:
recomputeFieldPositions(nil, lastSon(obj[i]), currPosition)
of nkSym:
obj.sym.position = currPosition
inc currPosition

View file

@ -84,7 +84,7 @@ proc hashTree(c: var MD5Context, n: PNode) =
of nkStrLit..nkTripleStrLit:
c &= n.strVal
else:
for i in 0..<n.len: hashTree(c, n.sons[i])
for i in 0..<n.len: hashTree(c, n[i])
proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
if t == nil:
@ -93,8 +93,8 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
case t.kind
of tyGenericInvocation:
for i in 0 ..< len(t):
c.hashType t.sons[i], flags
for i in 0..<t.len:
c.hashType t[i], flags
of tyDistinct:
if CoDistinct in flags:
if t.sym != nil: c.hashSym(t.sym)
@ -110,8 +110,8 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
# We cannot trust the `lastSon` to hold a properly populated and unique
# value for each instantiation, so we hash the generic parameters here:
let normalizedType = t.skipGenericAlias
for i in 0 .. normalizedType.len - 2:
c.hashType t.sons[i], flags
for i in 0..<normalizedType.len - 1:
c.hashType t[i], flags
else:
c.hashType t.lastSon, flags
of tyAlias, tySink, tyUserTypeClasses, tyInferred:
@ -132,8 +132,8 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
let inst = t.typeInst
t.typeInst = nil
assert inst.kind == tyGenericInst
for i in 0 .. inst.len - 2:
c.hashType inst.sons[i], flags
for i in 0..<inst.len - 1:
c.hashType inst[i], flags
t.typeInst = inst
return
c &= char(t.kind)
@ -168,8 +168,8 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
c &= ".empty"
else:
c &= t.id
if t.len > 0 and t.sons[0] != nil:
hashType c, t.sons[0], flags
if t.len > 0 and t[0] != nil:
hashType c, t[0], flags
of tyRef, tyPtr, tyGenericBody, tyVar:
c &= char(t.kind)
c.hashType t.lastSon, flags
@ -180,24 +180,24 @@ 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(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
assert(t.n.len == t.len)
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)
c &= t.n[i].sym.name.s
c &= ':'
c.hashType(t.sons[i], flags+{CoIgnoreRange})
c.hashType(t[i], flags+{CoIgnoreRange})
c &= ','
else:
for i in 0 ..< len(t): c.hashType t.sons[i], flags+{CoIgnoreRange}
for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange}
of tyRange:
if CoIgnoreRange notin flags:
c &= char(t.kind)
c.hashTree(t.n)
c.hashType(t.sons[0], flags)
c.hashType(t[0], flags)
of tyStatic:
c &= char(t.kind)
c.hashTree(t.n)
c.hashType(t.sons[0], flags)
c.hashType(t[0], flags)
of tyProc:
c &= char(t.kind)
c &= (if tfIterator in t.flags: "iterator " else: "proc ")
@ -209,9 +209,9 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
c &= ':'
c.hashType(param.typ, flags)
c &= ','
c.hashType(t.sons[0], flags)
c.hashType(t[0], flags)
else:
for i in 0..<t.len: c.hashType(t.sons[i], flags)
for i in 0..<t.len: c.hashType(t[i], flags)
c &= char(t.callConv)
# purity of functions doesn't have to affect the mangling (which is in fact
# problematic for HCR - someone could have cached a pointer to another
@ -223,10 +223,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
if tfVarargs in t.flags: c &= ".varargs"
of tyArray:
c &= char(t.kind)
for i in 0..<t.len: c.hashType(t.sons[i], flags-{CoIgnoreRange})
for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange})
else:
c &= char(t.kind)
for i in 0..<t.len: c.hashType(t.sons[i], flags)
for i in 0..<t.len: c.hashType(t[i], flags)
if tfNotNil in t.flags and CoType notin flags: c &= "not nil"
when defined(debugSigHashes):
@ -352,7 +352,7 @@ proc hashBodyTree(graph: ModuleGraph, c: var MD5Context, n: PNode) =
c &= n.strVal
else:
for i in 0..<n.len:
hashBodyTree(graph, c, n.sons[i])
hashBodyTree(graph, c, n[i])
proc symBodyDigest*(graph: ModuleGraph, sym: PSym): SigHash =
## compute unique digest of the proc/func/method symbols

View file

@ -167,8 +167,8 @@ 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(len(typeParams), len(binding)-1):
var formalTypeParam = typeParams.sons[i-1].typ
for i in 1..min(typeParams.len, binding.len-1):
var formalTypeParam = typeParams[i-1].typ
var bound = binding[i].typ
if bound != nil:
if formalTypeParam.kind == tyTypeDesc:
@ -220,7 +220,7 @@ proc sumGeneric(t: PType): int =
inc result, maxBranch
break
of tyVar:
t = t.sons[0]
t = t[0]
inc result
inc isvar
of tyTypeDesc:
@ -229,12 +229,12 @@ proc sumGeneric(t: PType): int =
inc result
of tyGenericInvocation, tyTuple, tyProc, tyAnd:
result += ord(t.kind in {tyGenericInvocation, tyAnd})
for i in 0 ..< t.len:
if t.sons[i] != nil:
result += sumGeneric(t.sons[i])
for i in 0..<t.len:
if t[i] != nil:
result += sumGeneric(t[i])
break
of tyStatic:
return sumGeneric(t.sons[0]) + 1
return sumGeneric(t[0]) + 1
of tyGenericParam, tyUntyped, tyTyped: break
of tyAlias, tySink: t = t.lastSon
of tyBool, tyChar, tyEnum, tyObject, tyPointer,
@ -249,12 +249,12 @@ proc sumGeneric(t: PType): int =
proc complexDisambiguation(a, b: PType): int =
# 'a' matches better if *every* argument matches better or equal than 'b'.
var winner = 0
for i in 1 ..< min(a.len, b.len):
let x = a.sons[i].sumGeneric
let y = b.sons[i].sumGeneric
for i in 1..<min(a.len, b.len):
let x = a[i].sumGeneric
let y = b[i].sumGeneric
#if ggDebug:
#echo "came herA ", typeToString(a.sons[i]), " ", x
#echo "came herB ", typeToString(b.sons[i]), " ", y
#echo "came herA ", typeToString(a[i]), " ", x
#echo "came herB ", typeToString(b[i]), " ", y
if x != y:
if winner == 0:
if x > y: winner = 1
@ -269,8 +269,8 @@ proc complexDisambiguation(a, b: PType): int =
result = winner
when false:
var x, y: int
for i in 1 ..< a.len: x += a.sons[i].sumGeneric
for i in 1 ..< b.len: y += b.sons[i].sumGeneric
for i in 1..<a.len: x += a[i].sumGeneric
for i in 1..<b.len: y += b[i].sumGeneric
result = x - y
proc writeMatches*(c: TCandidate) =
@ -305,7 +305,7 @@ proc cmpCandidates*(a, b: TCandidate): int =
proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string =
if arg.kind in nkSymChoices:
result = typeToString(arg[0].typ, prefer)
for i in 1 ..< arg.len:
for i in 1..<arg.len:
result.add(" | ")
result.add typeToString(arg[i].typ, prefer)
elif arg.typ == nil:
@ -316,25 +316,25 @@ proc argTypeToString(arg: PNode; prefer: TPreferedDesc): string =
proc describeArgs*(c: PContext, n: PNode, startIdx = 1;
prefer: TPreferedDesc = preferName): string =
result = ""
for i in startIdx ..< n.len:
var arg = n.sons[i]
if n.sons[i].kind == nkExprEqExpr:
add(result, renderTree(n.sons[i].sons[0]))
add(result, ": ")
for i in startIdx..<n.len:
var arg = n[i]
if n[i].kind == nkExprEqExpr:
result.add(renderTree(n[i][0]))
result.add(": ")
if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo}:
# XXX we really need to 'tryExpr' here!
arg = c.semOperand(c, n.sons[i].sons[1])
n.sons[i].typ = arg.typ
n.sons[i].sons[1] = arg
arg = c.semOperand(c, n[i][1])
n[i].typ = arg.typ
n[i][1] = arg
else:
if arg.typ.isNil and arg.kind notin {nkStmtList, nkDo, nkElse,
nkOfBranch, nkElifBranch,
nkExceptBranch}:
arg = c.semOperand(c, n.sons[i])
n.sons[i] = arg
arg = c.semOperand(c, n[i])
n[i] = arg
if arg.typ != nil and arg.typ.kind == tyError: return
add(result, argTypeToString(arg, prefer))
if i != len(n) - 1: add(result, ", ")
result.add(argTypeToString(arg, prefer))
if i != n.len - 1: result.add(", ")
proc typeRel*(c: var TCandidate, f, aOrig: PType,
flags: TTypeRelFlags = {}): TTypeRelation
@ -345,7 +345,7 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
if c.isNoCall: result = t
else: result = nil
of tySequence, tySet:
if t.sons[0].kind == tyEmpty: result = nil
if t[0].kind == tyEmpty: result = nil
else: result = t
of tyGenericParam, tyAnything:
result = t
@ -362,7 +362,7 @@ proc concreteType(c: TCandidate, t: PType; f: PType = nil): PType =
of tyOwned:
# bug #11257: the comparison system.`==`[T: proc](x, y: T) works
# better without the 'owned' type:
if f != nil and f.len > 0 and f.sons[0].skipTypes({tyBuiltInTypeClass}).kind == tyProc:
if f != nil and f.len > 0 and f[0].skipTypes({tyBuiltInTypeClass}).kind == tyProc:
result = t.lastSon
else:
result = t
@ -440,10 +440,10 @@ 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 ..< len(fGenericOrigin):
let x = PType(idTableGet(c.bindings, fGenericOrigin.sons[i]))
for i in 1..<fGenericOrigin.len:
let x = PType(idTableGet(c.bindings, fGenericOrigin[i]))
if x == nil:
put(c, fGenericOrigin.sons[i], last.sons[i])
put(c, fGenericOrigin[i], last[i])
proc isObjectSubtype(c: var TCandidate; a, f, fGenericOrigin: PType): int =
var t = a
@ -452,7 +452,7 @@ proc isObjectSubtype(c: var TCandidate; a, f, fGenericOrigin: PType): int =
var last = a
while t != nil and not sameObjectTypes(f, t):
assert t.kind == tyObject
t = t.sons[0]
t = t[0]
if t == nil: break
last = t
t = skipTypes(t, skipPtrs)
@ -473,7 +473,7 @@ proc skipToObject(t: PType; skipped: var SkippedPtr): PType =
while r != nil:
case r.kind
of tyGenericInvocation:
r = r.sons[0]
r = r[0]
of tyRef:
inc ptrs
skipped = skippedRef
@ -500,7 +500,7 @@ proc isGenericSubtype(c: var TCandidate; a, f: PType, d: var int, fGenericOrigin
# XXX sameObjectType can return false here. Need to investigate
# why that is but sameObjectType does way too much work here anyway.
while t != nil and r.sym != t.sym and askip == fskip:
t = t.sons[0]
t = t[0]
if t == nil: break
last = t
t = t.skipToObject(askip)
@ -518,22 +518,22 @@ proc recordRel(c: var TCandidate, f, a: PType): TTypeRelation =
result = isNone
if sameType(f, a):
result = isEqual
elif len(a) == len(f):
elif a.len == f.len:
result = isEqual
let firstField = if f.kind == tyTuple: 0
else: 1
for i in firstField ..< len(f):
var m = typeRel(c, f.sons[i], a.sons[i])
for i in firstField..<f.len:
var m = typeRel(c, f[i], a[i])
if m < isSubtype: return isNone
result = minRel(result, m)
if f.n != nil and a.n != nil:
for i in 0 ..< len(f.n):
for i in 0..<f.n.len:
# check field names:
if f.n.sons[i].kind != nkSym: return isNone
elif a.n.sons[i].kind != nkSym: return isNone
if f.n[i].kind != nkSym: return isNone
elif a.n[i].kind != nkSym: return isNone
else:
var x = f.n.sons[i].sym
var y = a.n.sons[i].sym
var x = f.n[i].sym
var y = a.n[i].sym
if f.kind == tyObject and typeRel(c, x.typ, y.typ) < isSubtype:
return isNone
if x.name.id != y.name.id: return isNone
@ -552,7 +552,7 @@ proc inconsistentVarTypes(f, a: PType): bool {.inline.} =
proc procParamTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
## For example we have:
## .. code-block:: nim
##..code-block:: nim
## proc myMap[T,S](sIn: seq[T], f: proc(x: T): S): seq[S] = ...
## proc innerProc[Q,W](q: Q): W = ...
## And we want to match: myMap(@[1,2,3], innerProc)
@ -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 len(f) != len(a): return
if f.len != a.len: return
result = isEqual # start with maximum; also correct for no
# params at all
@ -617,15 +617,15 @@ 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.len:
checkParam(f.sons[i], a.sons[i])
for i in 1..<f.len:
checkParam(f[i], a[i])
if f.sons[0] != nil:
if a.sons[0] != nil:
checkParam(f.sons[0], a.sons[0])
if f[0] != nil:
if a[0] != nil:
checkParam(f[0], a[0])
else:
return isNone
elif a.sons[0] != nil:
elif a[0] != nil:
return isNone
if tfNoSideEffect in f.flags and tfNoSideEffect notin a.flags:
@ -687,20 +687,20 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
openScope(c)
matchedConceptContext.candidateType = a
typeClass[0].sons[0] = a
typeClass[0][0] = a
c.matchedConcept = addr(matchedConceptContext)
defer:
c.matchedConcept = prevMatchedConcept
typeClass[0].sons[0] = prevCandidateType
typeClass[0][0] = prevCandidateType
closeScope(c)
var typeParams: seq[(PSym, PType)]
if ff.kind == tyUserTypeClassInst:
for i in 1 ..< (ff.len - 1):
for i in 1..<(ff.len - 1):
var
typeParamName = ff.base.sons[i-1].sym.name
typ = ff.sons[i]
typeParamName = ff.base[i-1].sym.name
typ = ff[i]
param: PSym
alreadyBound = PType(idTableGet(m.bindings, typ))
@ -944,8 +944,8 @@ proc isCovariantPtr(c: var TCandidate, f, a: PType): bool =
let body = f.base
return body == a.base and
a.len == 3 and
tfWeakCovariant notin body.sons[0].flags and
baseTypesCheck(f.sons[1], a.sons[1])
tfWeakCovariant notin body[0].flags and
baseTypesCheck(f[1], a[1])
else:
return false
@ -1038,7 +1038,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
result = typeRel(c, aOrig.base, candidate)
if result != isNone:
c.inferredTypes.add aOrig
aOrig.sons.add candidate
aOrig.add candidate
result = isEqual
return
@ -1146,7 +1146,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
# that may appear in the range:
for i in 0..1:
if f.n[i].kind == nkStaticExpr:
f.n.sons[i] = tryResolvingStaticExpr(c, f.n[i])
f.n[i] = tryResolvingStaticExpr(c, f.n[i])
result = typeRangeRel(f, a)
else:
if skipTypes(f, {tyRange}).kind == a.kind:
@ -1174,20 +1174,20 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
of tyArray:
case a.kind
of tyArray:
var fRange = f.sons[0]
var aRange = a.sons[0]
var fRange = f[0]
var aRange = a[0]
if fRange.kind == tyGenericParam:
var prev = PType(idTableGet(c.bindings, fRange))
if prev == nil:
put(c, fRange, a.sons[0])
put(c, fRange, a[0])
fRange = a
else:
fRange = prev
let ff = f.sons[1].skipTypes({tyTypeDesc})
let ff = f[1].skipTypes({tyTypeDesc})
# This typeDesc rule is wrong, see bug #7331
let aa = a.sons[1] #.skipTypes({tyTypeDesc})
let aa = a[1] #.skipTypes({tyTypeDesc})
if f.sons[0].kind != tyGenericParam and aa.kind == tyEmpty:
if f[0].kind != tyGenericParam and aa.kind == tyEmpty:
result = isGeneric
else:
result = typeRel(c, ff, aa)
@ -1220,7 +1220,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
if f.kind == tyVarargs:
if tfVarargs in a.flags:
return typeRel(c, f.base, a.lastSon)
if f.sons[0].kind == tyTyped: return
if f[0].kind == tyTyped: return
template matchArrayOrSeq(aBase: PType) =
let ff = f.base
@ -1239,29 +1239,29 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
result = typeRel(c, base(f), base(a))
if result < isGeneric: result = isNone
of tyArray:
if (f.sons[0].kind != tyGenericParam) and (a.sons[1].kind == tyEmpty):
if (f[0].kind != tyGenericParam) and (a[1].kind == tyEmpty):
return isSubtype
matchArrayOrSeq(a.sons[1])
matchArrayOrSeq(a[1])
of tySequence:
if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty):
if (f[0].kind != tyGenericParam) and (a[0].kind == tyEmpty):
return isConvertible
matchArrayOrSeq(a.sons[0])
matchArrayOrSeq(a[0])
of tyString:
if f.kind == tyOpenArray:
if f.sons[0].kind == tyChar:
if f[0].kind == tyChar:
result = isConvertible
elif f.sons[0].kind == tyGenericParam and a.len > 0 and
elif f[0].kind == tyGenericParam and a.len > 0 and
typeRel(c, base(f), base(a)) >= isGeneric:
result = isConvertible
else: discard
of tySequence:
case a.kind
of tySequence:
if (f.sons[0].kind != tyGenericParam) and (a.sons[0].kind == tyEmpty):
if (f[0].kind != tyGenericParam) and (a[0].kind == tyEmpty):
result = isSubtype
else:
let ff = f.sons[0]
let aa = a.sons[0]
let ff = f[0]
let aa = a[0]
result = typeRel(c, ff, aa)
if result < isGeneric:
if nimEnableCovariance and
@ -1277,11 +1277,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
else: discard
of tyOrdinal:
if isOrdinalType(a):
var x = if a.kind == tyOrdinal: a.sons[0] else: a
if f.sons[0].kind == tyNone:
var x = if a.kind == tyOrdinal: a[0] else: a
if f[0].kind == tyNone:
result = isGeneric
else:
result = typeRel(c, f.sons[0], x)
result = typeRel(c, f[0], x)
if result < isGeneric: result = isNone
elif a.kind == tyGenericParam:
result = isGeneric
@ -1314,10 +1314,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
elif c.coerceDistincts: result = typeRel(c, f.base, a)
of tySet:
if a.kind == tySet:
if f.sons[0].kind != tyGenericParam and a.sons[0].kind == tyEmpty:
if f[0].kind != tyGenericParam and a[0].kind == tyEmpty:
result = isSubtype
else:
result = typeRel(c, f.sons[0], a.sons[0])
result = typeRel(c, f[0], a[0])
if result <= isConvertible:
result = isNone # BUGFIX!
of tyPtr, tyRef:
@ -1325,8 +1325,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
if a.kind == f.kind:
# ptr[R, T] can be passed to ptr[T], but not the other way round:
if a.len < f.len: return isNone
for i in 0..f.len-2:
if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
for i in 0..<f.len-1:
if typeRel(c, f[i], a[i]) == isNone: return isNone
result = typeRel(c, f.lastSon, a.lastSon, flags + {trNoCovariance})
subtypeCheck()
if result <= isIntConv: result = isNone
@ -1384,13 +1384,13 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
of tyPtr:
# ptr[Tag, char] is not convertible to 'cstring' for now:
if a.len == 1:
let pointsTo = a.sons[0].skipTypes(abstractInst)
let pointsTo = a[0].skipTypes(abstractInst)
if pointsTo.kind == tyChar: result = isConvertible
elif pointsTo.kind == tyUncheckedArray and pointsTo.sons[0].kind == tyChar:
elif pointsTo.kind == tyUncheckedArray and pointsTo[0].kind == tyChar:
result = isConvertible
elif pointsTo.kind == tyArray and firstOrd(nil, pointsTo.sons[0]) == 0 and
skipTypes(pointsTo.sons[0], {tyRange}).kind in {tyInt..tyInt64} and
pointsTo.sons[1].kind == tyChar:
elif pointsTo.kind == tyArray and firstOrd(nil, pointsTo[0]) == 0 and
skipTypes(pointsTo[0], {tyRange}).kind in {tyInt..tyInt64} and
pointsTo[1].kind == tyChar:
result = isConvertible
else: discard
@ -1416,14 +1416,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
# YYYY
result = isEqual
for i in 1 .. rootf.len-2:
let ff = rootf.sons[i]
let aa = roota.sons[i]
for i in 1..<rootf.len-1:
let ff = rootf[i]
let aa = roota[i]
let res = typeRel(c, ff, aa, nextFlags)
if res != isEqual: result = isGeneric
if res notin {isEqual, isGeneric}:
if trNoCovariance notin flags and ff.kind == aa.kind:
let paramFlags = rootf.base.sons[i-1].flags
let paramFlags = rootf.base[i-1].flags
hasCovariance =
if tfCovariant in paramFlags:
if tfWeakCovariant in paramFlags:
@ -1471,7 +1471,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
of tyGenericBody:
considerPreviousT:
if a == f or a.kind == tyGenericInst and a.sons[0] == f:
if a == f or a.kind == tyGenericInst and a[0] == f:
bindingRet isGeneric
let ff = lastSon(f)
if ff != nil:
@ -1480,7 +1480,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
of tyGenericInvocation:
var x = a.skipGenericAlias
var preventHack = false
if x.kind == tyOwned and f.sons[0].kind != tyOwned:
if x.kind == tyOwned and f[0].kind != tyOwned:
preventHack = true
x = x.lastSon
# XXX: This is very hacky. It should be moved back into liftTypeParam
@ -1492,21 +1492,21 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
return typeRel(c, inst, a)
var depth = 0
if x.kind == tyGenericInvocation or f.sons[0].kind != tyGenericBody:
if x.kind == tyGenericInvocation or f[0].kind != tyGenericBody:
#InternalError("typeRel: tyGenericInvocation -> tyGenericInvocation")
# simply no match for now:
discard
elif x.kind == tyGenericInst and f.sons[0] == x.sons[0] and
len(x) - 1 == len(f):
for i in 1 ..< len(f):
if x.sons[i].kind == tyGenericParam:
elif x.kind == tyGenericInst and f[0] == x[0] and
x.len - 1 == f.len:
for i in 1..<f.len:
if x[i].kind == tyGenericParam:
internalError(c.c.graph.config, "wrong instantiated type!")
elif typeRel(c, f.sons[i], x.sons[i]) <= isSubtype:
elif typeRel(c, f[i], x[i]) <= isSubtype:
# Workaround for regression #4589
if f.sons[i].kind != tyTypeDesc: return
if f[i].kind != tyTypeDesc: return
result = isGeneric
elif x.kind == tyGenericInst and isGenericSubtype(c, x, f, depth, f) and
(len(x) - 1 == len(f)):
(x.len - 1 == f.len):
# do not recurse here in order to not K bind twice for this code:
#
# type
@ -1518,7 +1518,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
c.inheritancePenalty += depth
result = isGeneric
else:
let genericBody = f.sons[0]
let genericBody = f[0]
var askip = skippedNone
var fskip = skippedNone
let aobj = x.skipToObject(askip)
@ -1538,14 +1538,14 @@ 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 ..< len(f):
let x = PType(idTableGet(c.bindings, genericBody.sons[i-1]))
for i in 1..<f.len:
let x = PType(idTableGet(c.bindings, genericBody[i-1]))
if x == nil:
discard "maybe fine (for eg. a==tyNil)"
elif x.kind in {tyGenericInvocation, tyGenericParam}:
internalError(c.c.graph.config, "wrong instantiated type!")
else:
let key = f.sons[i]
let key = f[i]
let old = PType(idTableGet(c.bindings, key))
if old == nil:
put(c, key, x)
@ -1612,7 +1612,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
of tyBuiltInTypeClass:
considerPreviousT:
let targetKind = f.sons[0].kind
let targetKind = f[0].kind
let effectiveArgType = a.skipTypes({tyRange, tyGenericInst,
tyBuiltInTypeClass, tyAlias, tySink, tyOwned})
let typeClassMatches = targetKind == effectiveArgType.kind and
@ -1643,9 +1643,9 @@ 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.len-2:
let ff = rootf.sons[i]
let aa = roota.sons[i]
for i in 1..<rootf.len-1:
let ff = rootf[i]
let aa = roota[i]
result = typeRel(c, ff, aa)
if result == isNone: return
if ff.kind == tyRange and result != isEqual: return isNone
@ -1689,9 +1689,9 @@ 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.len > 0 and f.sons[0].kind != tyNone:
if f.len > 0 and f[0].kind != tyNone:
let oldInheritancePenalty = c.inheritancePenalty
result = typeRel(c, f.sons[0], a, flags + {trDontBind})
result = typeRel(c, f[0], a, flags + {trDontBind})
if doBind and result notin {isNone, isGeneric}:
let concrete = concreteType(c, a, f)
if concrete == nil: return isNone
@ -1772,7 +1772,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
result = typeRel(c, f.base, a)
if result != isNone:
c.inferredTypes.add f
f.sons.add a
f.add a
of tyTypeDesc:
var prev = PType(idTableGet(c.bindings, f))
@ -1846,8 +1846,7 @@ when false:
echo f, " <- ", aOrig, " res ", result
proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation =
var m: TCandidate
initCandidate(c, m, f)
var m = newCandidate(c, f)
result = typeRel(m, f, a)
proc getInstantiatedType(c: PContext, arg: PNode, m: TCandidate,
@ -1870,15 +1869,15 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
else:
result.typ = f
if result.typ == nil: internalError(c.graph.config, arg.info, "implicitConv")
addSon(result, c.graph.emptyNode)
addSon(result, arg)
result.add c.graph.emptyNode
result.add arg
proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
arg: PNode): PNode =
result = nil
for i in 0 ..< len(c.converters):
var src = c.converters[i].typ.sons[1]
var dest = c.converters[i].typ.sons[0]
for i in 0..<c.converters.len:
var src = c.converters[i].typ[1]
var dest = c.converters[i].typ[0]
# for generic type converters we need to check 'src <- a' before
# 'f <- dest' in order to not break the unification:
# see tests/tgenericconverter:
@ -1902,7 +1901,7 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
s.typ = c.converters[i].typ
s.info = arg.info
result = newNodeIT(nkHiddenCallConv, arg.info, dest)
addSon(result, s)
result.add s
# We build the call expression by ourselves in order to avoid passing this
# expression trough the semantic check phase once again so let's make sure
# it is correct
@ -1912,10 +1911,10 @@ proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
elif src.kind == tyVar:
# Analyse the converter return type
param = newNodeIT(nkHiddenAddr, arg.info, s.typ[1])
param.addSon(copyTree(arg))
param.add copyTree(arg)
else:
param = copyTree(arg)
addSon(result, param)
result.add param
if dest.kind in {tyVar, tyLent}:
dest.flags.incl tfVarIsPtr
@ -1942,7 +1941,7 @@ proc localConvMatch(c: PContext, m: var TCandidate, f, a: PType,
if result != nil:
if result.typ == nil: return nil
# resulting type must be consistent with the other arguments:
var r = typeRel(m, f.sons[0], result.typ)
var r = typeRel(m, f[0], result.typ)
if r < isGeneric: return nil
if result.kind == nkCall: result.kind = nkHiddenCallConv
inc(m.convMatches)
@ -1962,8 +1961,8 @@ proc incMatches(m: var TCandidate; r: TTypeRelation; convMatch = 1) =
of isNone: discard
template matchesVoidProc(t: PType): bool =
(t.kind == tyProc and t.len == 1 and t.sons[0] == nil) or
(t.kind == tyBuiltInTypeClass and t.sons[0].kind == tyProc)
(t.kind == tyProc and t.len == 1 and t[0] == nil) or
(t.kind == tyBuiltInTypeClass and t[0].kind == tyProc)
proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
argSemantized, argOrig: PNode): PNode =
@ -2174,31 +2173,31 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
# this correctly is inefficient. We have to copy `m` here to be able to
# roll back the side effects of the unification algorithm.
let c = m.c
var x, y, z: TCandidate
initCandidate(c, x, m.callee)
initCandidate(c, y, m.callee)
initCandidate(c, z, m.callee)
var
x = newCandidate(c, m.callee)
y = newCandidate(c, m.callee)
z = newCandidate(c, m.callee)
x.calleeSym = m.calleeSym
y.calleeSym = m.calleeSym
z.calleeSym = m.calleeSym
var best = -1
for i in 0 ..< arg.len:
if arg.sons[i].sym.kind in {skProc, skFunc, skMethod, skConverter,
for i in 0..<arg.len:
if arg[i].sym.kind in {skProc, skFunc, skMethod, skConverter,
skIterator, skMacro, skTemplate}:
copyCandidate(z, m)
z.callee = arg.sons[i].typ
z.callee = arg[i].typ
if tfUnresolved in z.callee.flags: continue
z.calleeSym = arg.sons[i].sym
#if arg.sons[i].sym.name.s == "cmp":
z.calleeSym = arg[i].sym
#if arg[i].sym.name.s == "cmp":
# ggDebug = true
# echo "CALLLEEEEEEEE A ", typeToString(z.callee)
# XXX this is still all wrong: (T, T) should be 2 generic matches
# and (int, int) 2 exact matches, etc. Essentially you cannot call
# typeRel here and expect things to work!
let r = typeRel(z, f, arg.sons[i].typ)
let r = typeRel(z, f, arg[i].typ)
incMatches(z, r, 2)
#if arg.sons[i].sym.name.s == "cmp": # and arg.info.line == 606:
# echo "M ", r, " ", arg.info, " ", typeToString(arg.sons[i].sym.typ)
#if arg[i].sym.name.s == "cmp": # and arg.info.line == 606:
# echo "M ", r, " ", arg.info, " ", typeToString(arg[i].sym.typ)
# writeMatches(z)
if r != isNone:
z.state = csMatch
@ -2226,10 +2225,9 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
else: result = nil
else:
# only one valid interpretation found:
markUsed(m.c, arg.info, arg.sons[best].sym)
onUse(arg.info, arg.sons[best].sym)
result = paramTypesMatchAux(m, f, arg.sons[best].typ, arg.sons[best],
argOrig)
markUsed(m.c, arg.info, arg[best].sym)
onUse(arg.info, arg[best].sym)
result = paramTypesMatchAux(m, f, arg[best].typ, arg[best], argOrig)
when false:
if m.calleeSym != nil and m.calleeSym.name.s == "[]":
echo m.c.config $ arg.info, " for ", m.calleeSym.name.s, " ", m.c.config $ m.calleeSym.info
@ -2239,10 +2237,10 @@ proc setSon(father: PNode, at: int, son: PNode) =
let oldLen = father.len
if oldLen <= at:
setLen(father.sons, at + 1)
father.sons[at] = son
father[at] = son
# insert potential 'void' parameters:
#for i in oldLen ..< at:
# father.sons[i] = newNodeIT(nkEmpty, son.info, getSysType(tyVoid))
#for i in oldLen..<at:
# father[i] = newNodeIT(nkEmpty, son.info, getSysType(tyVoid))
# we are allowed to modify the calling node in the 'prepare*' procs:
proc prepareOperand(c: PContext; formal: PType; a: PNode): PNode =
@ -2271,9 +2269,9 @@ proc prepareOperand(c: PContext; a: PNode): PNode =
considerGenSyms(c, result)
proc prepareNamedParam(a: PNode; c: PContext) =
if a.sons[0].kind != nkIdent:
var info = a.sons[0].info
a.sons[0] = newIdentNode(considerQuotedIdent(c, a.sons[0]), info)
if a[0].kind != nkIdent:
var info = a[0].info
a[0] = newIdentNode(considerQuotedIdent(c, a[0]), info)
proc arrayConstr(c: PContext, n: PNode): PType =
result = newTypeS(tyArray, c)
@ -2288,10 +2286,10 @@ proc arrayConstr(c: PContext, info: TLineInfo): PType =
proc incrIndexType(t: PType) =
assert t.kind == tyArray
inc t.sons[0].n.sons[1].intVal
inc t[0].n[1].intVal
template isVarargsUntyped(x): untyped =
x.kind == tyVarargs and x.sons[0].kind == tyUntyped
x.kind == tyVarargs and x[0].kind == tyUntyped
proc matchesAux(c: PContext, n, nOrig: PNode,
m: var TCandidate, marker: var IntSet) =
@ -2333,37 +2331,37 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
m.call = newNodeI(n.kind, n.info)
m.call.typ = base(m.callee) # may be nil
var formalLen = m.callee.n.len
addSon(m.call, n.sons[0])
m.call.add n[0]
var container: PNode = nil # constructed container
formal = if formalLen > 1: m.callee.n.sons[1].sym else: nil
formal = if formalLen > 1: m.callee.n[1].sym else: nil
while a < n.len:
if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped:
formal = m.callee.n.sons[f].sym
formal = m.callee.n[f].sym
incl(marker, formal.position)
if n.sons[a].kind == nkHiddenStdConv:
doAssert n.sons[a].sons[0].kind == nkEmpty and
n.sons[a].sons[1].kind in {nkBracket, nkArgList}
if n[a].kind == nkHiddenStdConv:
doAssert n[a][0].kind == nkEmpty and
n[a][1].kind in {nkBracket, nkArgList}
# Steal the container and pass it along
setSon(m.call, formal.position + 1, n.sons[a].sons[1])
setSon(m.call, formal.position + 1, n[a][1])
else:
if container.isNil:
container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
container = newNodeIT(nkArgList, n[a].info, arrayConstr(c, n.info))
setSon(m.call, formal.position + 1, container)
else:
incrIndexType(container.typ)
addSon(container, n.sons[a])
elif n.sons[a].kind == nkExprEqExpr:
container.add n[a]
elif n[a].kind == nkExprEqExpr:
# named param
m.firstMismatch.kind = kUnknownNamedParam
# check if m.callee has such a param:
prepareNamedParam(n.sons[a], c)
if n.sons[a].sons[0].kind != nkIdent:
localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
prepareNamedParam(n[a], c)
if n[a][0].kind != nkIdent:
localError(c.config, n[a].info, "named parameter has to be an identifier")
noMatch()
return
formal = getNamedParamFromList(m.callee.n, n.sons[a].sons[0].ident)
formal = getNamedParamFromList(m.callee.n, n[a][0].ident)
if formal == nil:
# no error message!
noMatch()
@ -2374,24 +2372,24 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
# we used to produce 'errCannotBindXTwice' here but see
# bug #3836 of why that is not sound (other overload with
# different parameter names could match later on):
when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
when false: localError(n[a].info, errCannotBindXTwice, formal.name.s)
noMatch()
return
m.baseTypeMatch = false
m.typedescMatched = false
n.sons[a].sons[1] = prepareOperand(c, formal.typ, n.sons[a].sons[1])
n.sons[a].typ = n.sons[a].sons[1].typ
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
n.sons[a].sons[1], n.sons[a].sons[1])
n[a][1] = prepareOperand(c, formal.typ, n[a][1])
n[a].typ = n[a][1].typ
arg = paramTypesMatch(m, formal.typ, n[a].typ,
n[a][1], n[a][1])
m.firstMismatch.kind = kTypeMismatch
if arg == nil:
noMatch()
return
checkConstraint(n.sons[a].sons[1])
checkConstraint(n[a][1])
if m.baseTypeMatch:
#assert(container == nil)
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
addSon(container, arg)
container = newNodeIT(nkBracket, n[a].info, arrayConstr(c, arg))
container.add arg
setSon(m.call, formal.position + 1, container)
if f != formalLen - 1: container = nil
else:
@ -2404,13 +2402,13 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
if tfVarargs in m.callee.flags:
# is ok... but don't increment any counters...
# we have no formal here to snoop at:
n.sons[a] = prepareOperand(c, n.sons[a])
if skipTypes(n.sons[a].typ, abstractVar-{tyTypeDesc}).kind==tyString:
addSon(m.call, implicitConv(nkHiddenStdConv,
getSysType(c.graph, n.sons[a].info, tyCString),
copyTree(n.sons[a]), m, c))
n[a] = prepareOperand(c, n[a])
if skipTypes(n[a].typ, abstractVar-{tyTypeDesc}).kind==tyString:
m.call.add implicitConv(nkHiddenStdConv,
getSysType(c.graph, n[a].info, tyCString),
copyTree(n[a]), m, c)
else:
addSon(m.call, copyTree(n.sons[a]))
m.call.add copyTree(n[a])
elif formal != nil and formal.typ.kind == tyVarargs:
m.firstMismatch.kind = kTypeMismatch
# beware of the side-effects in 'prepareOperand'! So only do it for
@ -2418,13 +2416,13 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
m.baseTypeMatch = false
m.typedescMatched = false
incl(marker, formal.position)
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
n.sons[a], nOrig.sons[a])
n[a] = prepareOperand(c, formal.typ, n[a])
arg = paramTypesMatch(m, formal.typ, n[a].typ,
n[a], nOrig[a])
if arg != nil and m.baseTypeMatch and container != nil:
addSon(container, arg)
container.add arg
incrIndexType(container.typ)
checkConstraint(n.sons[a])
checkConstraint(n[a])
else:
noMatch()
return
@ -2433,32 +2431,32 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
noMatch()
return
else:
if m.callee.n.sons[f].kind != nkSym:
internalError(c.config, n.sons[a].info, "matches")
if m.callee.n[f].kind != nkSym:
internalError(c.config, n[a].info, "matches")
noMatch()
return
formal = m.callee.n.sons[f].sym
formal = m.callee.n[f].sym
m.firstMismatch.kind = kTypeMismatch
if containsOrIncl(marker, formal.position) and container.isNil:
m.firstMismatch.kind = kPositionalAlreadyGiven
# positional param already in namedParams: (see above remark)
when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
when false: localError(n[a].info, errCannotBindXTwice, formal.name.s)
noMatch()
return
if formal.typ.isVarargsUntyped:
if container.isNil:
container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info))
container = newNodeIT(nkArgList, n[a].info, arrayConstr(c, n.info))
setSon(m.call, formal.position + 1, container)
else:
incrIndexType(container.typ)
addSon(container, n.sons[a])
container.add n[a]
else:
m.baseTypeMatch = false
m.typedescMatched = false
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
n.sons[a], nOrig.sons[a])
n[a] = prepareOperand(c, formal.typ, n[a])
arg = paramTypesMatch(m, formal.typ, n[a].typ,
n[a], nOrig[a])
if arg == nil:
noMatch()
return
@ -2466,11 +2464,11 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
assert formal.typ.kind == tyVarargs
#assert(container == nil)
if container.isNil:
container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, arg))
container = newNodeIT(nkBracket, n[a].info, arrayConstr(c, arg))
container.typ.flags.incl tfVarargs
else:
incrIndexType(container.typ)
addSon(container, arg)
container.add arg
setSon(m.call, formal.position + 1,
implicitConv(nkHiddenStdConv, formal.typ, container, m, c))
#if f != formalLen - 1: container = nil
@ -2487,11 +2485,11 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
# a container
#assert arg.kind == nkHiddenStdConv # for 'nim check'
# this assertion can be off
localError(c.config, n.sons[a].info, "cannot convert $1 to $2" % [
typeToString(n.sons[a].typ), typeToString(formal.typ) ])
localError(c.config, n[a].info, "cannot convert $1 to $2" % [
typeToString(n[a].typ), typeToString(formal.typ) ])
noMatch()
return
checkConstraint(n.sons[a])
checkConstraint(n[a])
inc(a)
# for some edge cases (see tdont_return_unowned_from_owned test case)
m.firstMismatch.arg = a
@ -2500,8 +2498,8 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
proc semFinishOperands*(c: PContext, n: PNode) =
# this needs to be called to ensure that after overloading resolution every
# argument has been sem'checked:
for i in 1 ..< n.len:
n.sons[i] = prepareOperand(c, n.sons[i])
for i in 1..<n.len:
n[i] = prepareOperand(c, n[i])
proc partialMatch*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
# for 'suggest' support:
@ -2522,9 +2520,8 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
matchesAux(c, n, nOrig, m, marker)
if m.state == csNoMatch: return
# check that every formal parameter got a value:
var f = 1
while f < len(m.callee.n):
var formal = m.callee.n.sons[f].sym
for f in 1..<m.callee.n.len:
var formal = m.callee.n[f].sym
if not containsOrIncl(marker, formal.position):
if formal.ast == nil:
if formal.typ.kind == tyVarargs:
@ -2563,15 +2560,13 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
put(m, formal.typ, defaultValue.typ)
defaultValue.flags.incl nfDefaultParam
setSon(m.call, formal.position + 1, defaultValue)
inc(f)
# forget all inferred types if the overload matching failed
if m.state == csNoMatch:
for t in m.inferredTypes:
if t.len > 1: t.sons.setLen 1
proc argtypeMatches*(c: PContext, f, a: PType, fromHlo = false): bool =
var m: TCandidate
initCandidate(c, m, f)
var m = newCandidate(c, f)
let res = paramTypesMatch(m, f, a, c.graph.emptyNode, nil)
#instantiateGenericConverters(c, res, m)
# XXX this is used by patterns.nim too; I think it's better to not
@ -2583,13 +2578,12 @@ proc argtypeMatches*(c: PContext, f, a: PType, fromHlo = false): bool =
res != nil and m.convMatches == 0 and m.intConvMatches in [0, 256]
proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo;
op: TTypeAttachedOp; col: int): PSym {.procvar.} =
var m: TCandidate
initCandidate(c, m, dc.typ)
op: TTypeAttachedOp; col: int): PSym =
var m = newCandidate(c, dc.typ)
if col >= dc.typ.len:
localError(c.config, info, "cannot instantiate: '" & dc.name.s & "'")
return nil
var f = dc.typ.sons[col]
var f = dc.typ[col]
if op == attachedDeepCopy:
if f.kind in {tyRef, tyPtr}: f = f.lastSon
@ -2632,8 +2626,8 @@ tests:
result = newType(tyArray, dummyOwner)
var n = newNodeI(nkRange, UnknownLineInfo())
addSon(n, newIntNode(nkIntLit, 0))
addSon(n, newIntNode(nkIntLit, x))
n.add newIntNode(nkIntLit, 0)
n.add newIntNode(nkIntLit, x)
let range = newType(tyRange, dummyOwner)
result.rawAddSon(range)
@ -2660,8 +2654,7 @@ tests:
T2.sym.position = 1
setup:
var c: TCandidate
initCandidate(nil, c, nil)
var c = newCandidate(nil, nil)
template yes(x, y) =
test astToStr(x) & " is " & astToStr(y):

View file

@ -79,10 +79,10 @@ proc computeSubObjectAlign(conf: ConfigRef; n: PNode): BiggestInt =
## returns object alignment
case n.kind
of nkRecCase:
assert(n.sons[0].kind == nkSym)
result = computeSubObjectAlign(conf, n.sons[0])
for i in 1 ..< len(n):
let child = n.sons[i]
assert(n[0].kind == nkSym)
result = computeSubObjectAlign(conf, n[0])
for i in 1..<n.len:
let child = n[i]
case child.kind
of nkOfBranch, nkElse:
let align = computeSubObjectAlign(conf, child.lastSon)
@ -94,7 +94,7 @@ proc computeSubObjectAlign(conf: ConfigRef; n: PNode): BiggestInt =
of nkRecList:
result = 1
for i, child in n.sons:
let align = computeSubObjectAlign(conf, n.sons[i])
let align = computeSubObjectAlign(conf, n[i])
if align < 0:
return align
result = max(result, align)
@ -109,7 +109,7 @@ proc setOffsetsToUnknown(n: PNode) =
if n.kind == nkSym and n.sym.kind == skField:
n.sym.offset = szUnknownSize
else:
for i in 0 ..< safeLen(n):
for i in 0..<n.safeLen:
setOffsetsToUnknown(n[i])
proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, accum: var OffsetAccum) =
@ -120,16 +120,16 @@ proc computeObjectOffsetsFoldFunction(conf: ConfigRef; n: PNode, packed: bool, a
raiseIllegalTypeRecursion()
case n.kind
of nkRecCase:
assert(n.sons[0].kind == nkSym)
computeObjectOffsetsFoldFunction(conf, n.sons[0], packed, accum)
assert(n[0].kind == nkSym)
computeObjectOffsetsFoldFunction(conf, n[0], packed, accum)
var maxChildAlign: int = if accum.offset == szUnknownSize: szUnknownSize else: 1
if not packed:
for i in 1 ..< len(n):
let child = n.sons[i]
for i in 1..<n.len:
let child = n[i]
case child.kind
of nkOfBranch, nkElse:
# offset parameter cannot be known yet, it needs to know the alignment first
let align = int(computeSubObjectAlign(conf, n.sons[i].lastSon))
let align = int(computeSubObjectAlign(conf, n[i].lastSon))
maxChildAlign = alignmentMax(maxChildAlign, align)
else:
internalError(conf, "computeObjectOffsetsFoldFunction(record case branch)")
@ -141,9 +141,9 @@ 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 ..< len(n):
for i in 1..<n.len:
var branchAccum = accumRoot
computeObjectOffsetsFoldFunction(conf, n.sons[i].lastSon, packed, branchAccum)
computeObjectOffsetsFoldFunction(conf, n[i].lastSon, packed, branchAccum)
accum.mergeBranch(branchAccum)
of nkRecList:
for i, child in n.sons:
@ -255,14 +255,14 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
typ.size = conf.target.ptrSize
of tyArray:
computeSizeAlign(conf, typ.sons[1])
let elemSize = typ.sons[1].size
computeSizeAlign(conf, typ[1])
let elemSize = typ[1].size
if elemSize < 0:
typ.size = elemSize
typ.align = int16(elemSize)
else:
typ.size = toInt64Checked(lengthOrd(conf, typ.sons[0]) * int32(elemSize), szTooBigSize)
typ.align = typ.sons[1].align
typ.size = toInt64Checked(lengthOrd(conf, typ[0]) * int32(elemSize), szTooBigSize)
typ.align = typ[1].align
of tyUncheckedArray:
let base = typ.lastSon
@ -289,11 +289,11 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
typ.size = 8
typ.align = int16(conf.floatInt64Align)
of tySet:
if typ.sons[0].kind == tyGenericParam:
if typ[0].kind == tyGenericParam:
typ.size = szUncomputedSize
typ.align = szUncomputedSize
else:
let length = toInt64(lengthOrd(conf, typ.sons[0]))
let length = toInt64(lengthOrd(conf, typ[0]))
if length <= 8:
typ.size = 1
typ.align = 1
@ -313,16 +313,16 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
typ.size = align(length, 8) div 8 + 1
typ.align = int16(conf.floatInt64Align)
of tyRange:
computeSizeAlign(conf, typ.sons[0])
typ.size = typ.sons[0].size
typ.align = typ.sons[0].align
typ.paddingAtEnd = typ.sons[0].paddingAtEnd
computeSizeAlign(conf, typ[0])
typ.size = typ[0].size
typ.align = typ[0].align
typ.paddingAtEnd = typ[0].paddingAtEnd
of tyTuple:
try:
var accum = OffsetAccum(maxAlign: 1)
for i in 0 ..< len(typ):
let child = typ.sons[i]
for i in 0..<typ.len:
let child = typ[i]
computeSizeAlign(conf, child)
accum.align(child.align)
if typ.n != nil: # is named tuple (has field symbols)?
@ -340,11 +340,11 @@ proc computeSizeAlign(conf: ConfigRef; typ: PType) =
of tyObject:
try:
var accum =
if typ.sons[0] != nil:
if typ[0] != nil:
# compute header size
var st = typ.sons[0]
var st = typ[0]
while st.kind in skipPtrs:
st = st.sons[^1]
st = st[^1]
computeSizeAlign(conf, st)
if conf.cmd == cmdCompileToCpp:
OffsetAccum(

View file

@ -16,7 +16,7 @@ from trees import getMagic
proc callProc(a: PNode): PNode =
result = newNodeI(nkCall, a.info)
result.add a
result.typ = a.typ.sons[0]
result.typ = a.typ[0]
# we have 4 cases to consider:
# - a void proc --> nothing to do
@ -60,18 +60,18 @@ proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: P
incl(result.flags, sfFromGeneric)
var vpart = newNodeI(nkIdentDefs, varSection.info, 3)
vpart.sons[0] = newSymNode(result)
vpart.sons[1] = newNodeI(nkEmpty, varSection.info)
vpart.sons[2] = if varInit.isNil: v else: vpart[1]
vpart[0] = newSymNode(result)
vpart[1] = newNodeI(nkEmpty, varSection.info)
vpart[2] = if varInit.isNil: v else: vpart[1]
varSection.add vpart
if varInit != nil:
if useShallowCopy and typeNeedsNoDeepCopy(typ) or optTinyRtti in g.config.globalOptions:
varInit.add newFastAsgnStmt(newSymNode(result), v)
else:
let deepCopyCall = newNodeI(nkCall, varInit.info, 3)
deepCopyCall.sons[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy))
deepCopyCall.sons[1] = newSymNode(result)
deepCopyCall.sons[2] = v
deepCopyCall[0] = newSymNode(getSysMagic(g, varSection.info, "deepCopy", mDeepCopy))
deepCopyCall[1] = newSymNode(result)
deepCopyCall[2] = v
varInit.add deepCopyCall
discard """
@ -137,16 +137,16 @@ proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym;
if spawnKind == srByVar:
body.add newAsgnStmt(genDeref(threadLocalProm.newSymNode), call)
elif fv != nil:
let fk = fv.typ.sons[1].flowVarKind
let fk = fv.typ[1].flowVarKind
if fk == fvInvalid:
localError(g.config, f.info, "cannot create a flowVar of type: " &
typeToString(fv.typ.sons[1]))
typeToString(fv.typ[1]))
body.add newAsgnStmt(indirectAccess(threadLocalProm.newSymNode,
if fk == fvGC: "data" else: "blob", fv.info, g.cache), call)
if fk == fvGC:
let incRefCall = newNodeI(nkCall, fv.info, 2)
incRefCall.sons[0] = newSymNode(getSysMagic(g, fv.info, "GCref", mGCref))
incRefCall.sons[1] = indirectAccess(threadLocalProm.newSymNode,
incRefCall[0] = newSymNode(getSysMagic(g, fv.info, "GCref", mGCref))
incRefCall[1] = indirectAccess(threadLocalProm.newSymNode,
"data", fv.info, g.cache)
body.add incRefCall
if barrier == nil:
@ -196,7 +196,7 @@ proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType; scratchOb
varSection, varInit, result: PNode) =
let formals = n[0].typ.n
let tmpName = getIdent(g.cache, genPrefix)
for i in 1 ..< n.len:
for i in 1..<n.len:
# we pick n's type here, which hopefully is 'tyArray' and not
# 'tyOpenArray':
var argType = n[i].typ.skipTypes(abstractInst)
@ -225,11 +225,11 @@ proc getRoot*(n: PNode): PSym =
result = n.sym
of nkDotExpr, nkBracketExpr, nkHiddenDeref, nkDerefExpr,
nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
result = getRoot(n.sons[0])
result = getRoot(n[0])
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = getRoot(n.sons[1])
result = getRoot(n[1])
of nkCallKinds:
if getMagic(n) == mSlice: result = getRoot(n.sons[1])
if getMagic(n) == mSlice: result = getRoot(n[1])
else: discard
proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchObj: PSym;
@ -239,7 +239,7 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchOb
let tmpName = getIdent(g.cache, genPrefix)
# we need to copy the foreign scratch object fields into local variables
# for correctness: These are called 'threadLocal' here.
for i in 1 ..< n.len:
for i in 1..<n.len:
let n = n[i]
let argType = skipTypes(if i < formals.len: formals[i].typ else: n.typ,
abstractInst)
@ -253,8 +253,8 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchOb
# important special case: we always create a zero-copy slice:
let slice = newNodeI(nkCall, n.info, 4)
slice.typ = n.typ
slice.sons[0] = newSymNode(createMagic(g, "slice", mSlice))
slice.sons[0].typ = getSysType(g, n.info, tyInt) # fake type
slice[0] = newSymNode(createMagic(g, "slice", mSlice))
slice[0].typ = getSysType(g, n.info, tyInt) # fake type
var fieldB = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
fieldB.typ = getSysType(g, n.info, tyInt)
objType.addField(fieldB, g.cache)
@ -274,7 +274,7 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchOb
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldA.typ,
indirectAccess(castExpr, fieldA, n.info),
useShallowCopy=true)
slice.sons[2] = threadLocal.newSymNode
slice[2] = threadLocal.newSymNode
else:
let a = genAddrOf(n)
field.typ = a.typ
@ -282,14 +282,14 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType; scratchOb
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), genHigh(g, n))
slice.sons[2] = newIntLit(g, n.info, 0)
slice[2] = newIntLit(g, n.info, 0)
# the array itself does not need to go through a thread local variable:
slice.sons[1] = genDeref(indirectAccess(castExpr, field, n.info))
slice[1] = genDeref(indirectAccess(castExpr, field, n.info))
let threadLocal = addLocalVar(g, varSection,nil, objType.owner, fieldB.typ,
indirectAccess(castExpr, fieldB, n.info),
useShallowCopy=true)
slice.sons[3] = threadLocal.newSymNode
slice[3] = threadLocal.newSymNode
call.add slice
elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and
n.getRoot != nil:
@ -358,7 +358,7 @@ proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: P
result.add varSectionB
var call = newNodeIT(nkCall, n.info, n.typ)
var fn = n.sons[0]
var fn = n[0]
# templates and macros are in fact valid here due to the nature of
# the transformation:
if fn.kind == nkClosure or (fn.typ != nil and fn.typ.callConv == ccClosure):

View file

@ -49,12 +49,12 @@ proc findDocComment(n: PNode): PNode =
if n == nil: return nil
if n.comment.len > 0: return n
if n.kind in {nkStmtList, nkStmtListExpr, nkObjectTy, nkRecList} and n.len > 0:
result = findDocComment(n.sons[0])
result = findDocComment(n[0])
if result != nil: return
if n.len > 1:
result = findDocComment(n.sons[1])
result = findDocComment(n[1])
elif n.kind in {nkAsgn, nkFastAsgn} and n.len == 2:
result = findDocComment(n.sons[1])
result = findDocComment(n[1])
proc extractDocComment(s: PSym): string =
var n = findDocComment(s.ast)
@ -256,7 +256,7 @@ proc suggestField(c: PContext, s: PSym; f: PNode; info: TLineInfo; outputs: var
proc getQuality(s: PSym): range[0..100] =
if s.typ != nil and s.typ.len > 1:
var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
var exp = s.typ[1].skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
if exp.kind == tyVarargs: exp = elemType(exp)
if exp.kind in {tyUntyped, tyTyped, tyGenericParam, tyAnything}: return 50
return 100
@ -275,26 +275,25 @@ 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 ..< len(list):
if list.sons[i].kind == nkSym:
suggestField(c, list.sons[i].sym, f, info, outputs)
for i in 0..<list.len:
if list[i].kind == nkSym:
suggestField(c, list[i].sym, f, info, outputs)
#else: InternalError(list.info, "getSymFromList")
proc suggestObject(c: PContext, n, f: PNode; info: TLineInfo, outputs: var Suggestions) =
case n.kind
of nkRecList:
for i in 0 ..< len(n): suggestObject(c, n.sons[i], f, info, outputs)
for i in 0..<n.len: suggestObject(c, n[i], f, info, outputs)
of nkRecCase:
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)
if n.len > 0:
suggestObject(c, n[0], f, info, outputs)
for i in 1..<n.len: suggestObject(c, lastSon(n[i]), f, info, outputs)
of nkSym: suggestField(c, n.sym, f, info, outputs)
else: discard
proc nameFits(c: PContext, s: PSym, n: PNode): bool =
var op = if n.kind in nkCallKinds: n.sons[0] else: n
if op.kind in {nkOpenSymChoice, nkClosedSymChoice}: op = op.sons[0]
var op = if n.kind in nkCallKinds: n[0] else: n
if op.kind in {nkOpenSymChoice, nkClosedSymChoice}: op = op[0]
var opr: PIdent
case op.kind
of nkSym: opr = op.sym.name
@ -305,8 +304,7 @@ proc nameFits(c: PContext, s: PSym, n: PNode): bool =
proc argsFit(c: PContext, candidate: PSym, n, nOrig: PNode): bool =
case candidate.kind
of OverloadableSyms:
var m: TCandidate
initCandidate(c, m, candidate, nil)
var m = newCandidate(c, candidate, nil)
sigmatch.partialMatch(c, n, nOrig, m)
result = m.state != csNoMatch
else:
@ -322,17 +320,17 @@ proc suggestVar(c: PContext, n: PNode, outputs: var Suggestions) =
wholeSymTab(nameFits(c, it, n), ideCon)
proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} =
if s.typ != nil and len(s.typ) > 1 and s.typ.sons[1] != nil:
if s.typ != nil and s.typ.len > 1 and s.typ[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
let m = s.getModule()
if m != nil and sfSystemModule in m.flags:
if s.kind == skType: return
var exp = s.typ.sons[1].skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
var exp = s.typ[1].skipTypes({tyGenericInst, tyVar, tyLent, tyAlias, tySink})
if exp.kind == tyVarargs: exp = elemType(exp)
if exp.kind in {tyUntyped, tyTyped, tyGenericParam, tyAnything}: return
result = sigmatch.argtypeMatches(c, s.typ.sons[1], firstArg)
result = sigmatch.argtypeMatches(c, s.typ[1], firstArg)
proc suggestOperations(c: PContext, n, f: PNode, typ: PType, outputs: var Suggestions) =
assert typ != nil
@ -395,7 +393,7 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions)
var t = typ
while t != nil:
suggestSymList(c, t.n, field, n.info, outputs)
t = t.sons[0]
t = t[0]
suggestOperations(c, n, field, typ, outputs)
else:
let orig = typ # skipTypes(typ, {tyGenericInst, tyAlias, tySink})
@ -404,8 +402,8 @@ proc suggestFieldAccess(c: PContext, n, field: PNode, outputs: var Suggestions)
var t = typ
while true:
suggestObject(c, t.n, field, n.info, outputs)
if t.sons[0] == nil: break
t = skipTypes(t.sons[0], skipPtrs)
if t[0] == nil: break
t = skipTypes(t[0], skipPtrs)
elif typ.kind == tyTuple and typ.n != nil:
suggestSymList(c, typ.n, field, n.info, outputs)
suggestOperations(c, n, field, orig, outputs)
@ -456,7 +454,7 @@ proc findUsages(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
when defined(nimsuggest):
proc listUsages*(conf: ConfigRef; s: PSym) =
#echo "usages ", len(s.allUsages)
#echo "usages ", s.allUsages.len
for info in s.allUsages:
let x = if info == s.info and info.col == s.info.col: ideDef else: ideUse
suggestResult(conf, symToSuggest(conf, s, isLocal=false, x, info, 100, PrefixMatch.None, false, 0))
@ -571,7 +569,7 @@ proc safeSemExpr*(c: PContext, n: PNode): PNode =
proc sugExpr(c: PContext, n: PNode, outputs: var Suggestions) =
if n.kind == nkDotExpr:
var obj = safeSemExpr(c, n.sons[0])
var obj = safeSemExpr(c, n[0])
# it can happen that errnously we have collected the fieldname
# of the next line, so we check the 'field' is actually on the same
# line as the object to prevent this from happening:
@ -596,14 +594,14 @@ proc suggestExprNoCheck*(c: PContext, n: PNode) =
elif c.config.ideCmd == ideCon:
if n.kind in nkCallKinds:
var a = copyNode(n)
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..len(n)-1:
var x = safeSemExpr(c, n[0])
if x.kind == nkEmpty or x.typ == nil: x = n[0]
a.add x
for i in 1..<n.len:
# use as many typed arguments as possible:
var x = safeSemExpr(c, n.sons[i])
var x = safeSemExpr(c, n[i])
if x.kind == nkEmpty or x.typ == nil: break
addSon(a, x)
a.add x
suggestCall(c, a, n, outputs)
elif n.kind in nkIdentKinds:
var x = safeSemExpr(c, n)

View file

@ -85,20 +85,20 @@ proc parsePipe(filename: AbsoluteFile, inputStream: PLLStream; cache: IdentCache
llStreamClose(s)
proc getFilter(ident: PIdent): TFilterKind =
for i in low(TFilterKind) .. high(TFilterKind):
for i in low(TFilterKind)..high(TFilterKind):
if cmpIgnoreStyle(ident.s, filterNames[i]) == 0:
return i
result = filtNone
proc getParser(conf: ConfigRef; n: PNode; ident: PIdent): TParserKind =
for i in low(TParserKind) .. high(TParserKind):
for i in low(TParserKind)..high(TParserKind):
if cmpIgnoreStyle(ident.s, parserNames[i]) == 0:
return i
localError(conf, n.info, "unknown parser: " & ident.s)
proc getCallee(conf: ConfigRef; n: PNode): PIdent =
if n.kind in nkCallKinds and n.sons[0].kind == nkIdent:
result = n.sons[0].ident
if n.kind in nkCallKinds and n[0].kind == nkIdent:
result = n[0].ident
elif n.kind == nkIdent:
result = n.ident
else:
@ -131,13 +131,13 @@ proc evalPipe(p: var TParsers, n: PNode, filename: AbsoluteFile,
result = start
if n.kind == nkEmpty: return
if n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s == "|":
for i in 1 .. 2:
if n.sons[i].kind == nkInfix:
result = evalPipe(p, n.sons[i], filename, result)
for i in 1..2:
if n[i].kind == nkInfix:
result = evalPipe(p, n[i], filename, result)
else:
result = applyFilter(p, n.sons[i], filename, result)
result = applyFilter(p, n[i], filename, result)
elif n.kind == nkStmtList:
result = evalPipe(p, n.sons[0], filename, result)
result = evalPipe(p, n[0], filename, result)
else:
result = applyFilter(p, n, filename, result)
@ -168,7 +168,7 @@ proc setupParsers*(p: var TParsers; fileIdx: FileIndex; cache: IdentCache;
openParsers(p, fileIdx, llStreamOpen(f), cache, config)
result = true
proc parseFile*(fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): PNode {.procvar.} =
proc parseFile*(fileIdx: FileIndex; cache: IdentCache; config: ConfigRef): PNode =
var p: TParsers
if setupParsers(p, fileIdx, cache, config):
result = parseAll(p)

View file

@ -70,7 +70,7 @@ proc compileCCode*(ccode: string) =
proc run*(args: string) =
var s = @[cstring(gProjectName)] & map(split(args), proc(x: string): cstring = cstring(x))
var err = tinyc.run(gTinyC, cint(len(s)), cast[cstringArray](addr(s[0]))) != 0'i32
var err = tinyc.run(gTinyC, cint(s.len), cast[cstringArray](addr(s[0]))) != 0'i32
closeCCState(gTinyC)
if err: rawMessage(errExecutionOfProgramFailed, "")

File diff suppressed because it is too large Load diff

View file

@ -44,9 +44,9 @@ proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool =
of nkCommentStmt: result = a.comment == b.comment
of nkEmpty, nkNilLit, nkType: result = true
else:
if len(a) == len(b):
for i in 0 ..< len(a):
if not exprStructuralEquivalent(a.sons[i], b.sons[i],
if a.len == b.len:
for i in 0..<a.len:
if not exprStructuralEquivalent(a[i], b[i],
strictSymEquality): return
result = true
@ -68,16 +68,16 @@ proc sameTree*(a, b: PNode): bool =
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
of nkEmpty, nkNilLit, nkType: result = true
else:
if len(a) == len(b):
for i in 0 ..< len(a):
if not sameTree(a.sons[i], b.sons[i]): return
if a.len == b.len:
for i in 0..<a.len:
if not sameTree(a[i], b[i]): return
result = true
proc getMagic*(op: PNode): TMagic =
case op.kind
of nkCallKinds:
case op.sons[0].kind
of nkSym: result = op.sons[0].sym.magic
case op[0].kind
of nkSym: result = op[0].sym.magic
else: result = mNone
else: result = mNone
@ -87,7 +87,7 @@ proc isConstExpr*(n: PNode): bool =
proc isCaseObj*(n: PNode): bool =
if n.kind == nkRecCase: return true
for i in 0..<safeLen(n):
for i in 0..<n.safeLen:
if n[i].isCaseObj: return true
proc isDeepConstExpr*(n: PNode): bool =
@ -95,10 +95,10 @@ proc isDeepConstExpr*(n: PNode): bool =
of nkCharLit..nkNilLit:
result = true
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
result = isDeepConstExpr(n.sons[1])
result = isDeepConstExpr(n[1])
of nkCurly, nkBracket, nkPar, nkTupleConstr, nkObjConstr, nkClosure, nkRange:
for i in ord(n.kind == nkObjConstr) ..< n.len:
if not isDeepConstExpr(n.sons[i]): return false
for i in ord(n.kind == nkObjConstr)..<n.len:
if not isDeepConstExpr(n[i]): return false
if n.typ.isNil: result = true
else:
let t = n.typ.skipTypes({tyGenericInst, tyDistinct, tyAlias, tySink, tyOwned})
@ -117,7 +117,7 @@ proc isRange*(n: PNode): bool {.inline.} =
result = true
proc whichPragma*(n: PNode): TSpecialWord =
let key = if n.kind in nkPragmaCallKinds and n.len > 0: n.sons[0] else: n
let key = if n.kind in nkPragmaCallKinds and n.len > 0: n[0] else: n
if key.kind == nkIdent: result = whichKeyword(key.ident)
proc findPragma*(n: PNode, which: TSpecialWord): PNode =
@ -127,13 +127,13 @@ proc findPragma*(n: PNode, which: TSpecialWord): PNode =
return son
proc effectSpec*(n: PNode, effectType: TSpecialWord): PNode =
for i in 0 ..< len(n):
var it = n.sons[i]
for i in 0..<n.len:
var it = n[i]
if it.kind == nkExprColonExpr and whichPragma(it) == effectType:
result = it.sons[1]
result = it[1]
if result.kind notin {nkCurly, nkBracket}:
result = newNodeI(nkCurly, result.info)
result.add(it.sons[1])
result.add(it[1])
return
proc unnestStmts(n, result: PNode) =
@ -146,8 +146,8 @@ proc flattenStmts*(n: PNode): PNode =
result = newNodeI(nkStmtList, n.info)
unnestStmts(n, result)
if result.len == 1:
result = result.sons[0]
result = result[0]
proc extractRange*(k: TNodeKind, n: PNode, a, b: int): PNode =
result = newNodeI(k, n.info, b-a+1)
for i in 0 .. b-a: result.sons[i] = n.sons[i+a]
for i in 0..b-a: result[i] = n[i+a]

View file

@ -31,8 +31,8 @@ proc hashTree(n: PNode): Hash =
of nkStrLit..nkTripleStrLit:
result = result !& hash(n.strVal)
else:
for i in 0 ..< len(n):
result = result !& hashTree(n.sons[i])
for i in 0..<n.len:
result = result !& hashTree(n[i])
proc treesEquivalent(a, b: PNode): bool =
if a == b:
@ -46,9 +46,9 @@ proc treesEquivalent(a, b: PNode): bool =
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
else:
if len(a) == len(b):
for i in 0 ..< len(a):
if not treesEquivalent(a.sons[i], b.sons[i]): return
if a.len == b.len:
for i in 0..<a.len:
if not treesEquivalent(a[i], b[i]): return
result = true
if result: result = sameTypeOrNil(a.typ, b.typ)
@ -82,9 +82,9 @@ proc nodeTablePut*(t: var TNodeTable, key: PNode, val: int) =
assert(t.data[index].key != nil)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
newSeq(n, len(t.data) * GrowthFactor)
for i in 0 .. high(t.data):
if mustRehash(t.data.len, t.counter):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i].key != nil:
nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val)
swap(t.data, n)
@ -99,9 +99,9 @@ proc nodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int =
assert(t.data[index].key != nil)
result = t.data[index].val
else:
if mustRehash(len(t.data), t.counter):
newSeq(n, len(t.data) * GrowthFactor)
for i in 0 .. high(t.data):
if mustRehash(t.data.len, t.counter):
newSeq(n, t.data.len * GrowthFactor)
for i in 0..high(t.data):
if t.data[i].key != nil:
nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val)
swap(t.data, n)

View file

@ -28,7 +28,7 @@ proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string
template `$`*(typ: PType): string = typeToString(typ)
proc base*(t: PType): PType =
result = t.sons[0]
result = t[0]
# ------------------- type iterator: ----------------------------------------
type
@ -79,8 +79,8 @@ proc invalidGenericInst*(f: PType): bool =
proc isPureObject*(typ: PType): bool =
var t = typ
while t.kind == tyObject and t.sons[0] != nil:
t = t.sons[0].skipTypes(skipPtrs)
while t.kind == tyObject and t[0] != nil:
t = t[0].skipTypes(skipPtrs)
result = t.sym != nil and sfPure in t.sym.flags
proc isUnsigned*(t: PType): bool =
@ -98,7 +98,7 @@ proc getOrdValue*(n: PNode; onError = high(Int128)): Int128 =
toInt128(n.intVal)
of nkNilLit:
int128.Zero
of nkHiddenStdConv: getOrdValue(n.sons[1], onError)
of nkHiddenStdConv: getOrdValue(n[1], onError)
else:
# XXX: The idea behind the introduction of int128 was to finally
# have all calculations numerically far away from any
@ -110,13 +110,13 @@ proc getOrdValue64*(n: PNode): BiggestInt {.deprecated: "use getOrdvalue".} =
case n.kind
of nkCharLit..nkUInt64Lit: n.intVal
of nkNilLit: 0
of nkHiddenStdConv: getOrdValue64(n.sons[1])
of nkHiddenStdConv: getOrdValue64(n[1])
else: high(BiggestInt)
proc getFloatValue*(n: PNode): BiggestFloat =
case n.kind
of nkFloatLiterals: n.floatVal
of nkHiddenStdConv: getFloatValue(n.sons[1])
of nkHiddenStdConv: getFloatValue(n[1])
else: NaN
proc isIntLit*(t: PType): bool {.inline.} =
@ -132,18 +132,18 @@ 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 ..< len(n):
let p = n.sons[i]
for i in 1..<n.len:
let p = n[i]
if p.kind == nkSym:
add(result, p.sym.name.s)
add(result, ": ")
add(result, typeToString(p.sym.typ, prefer))
if i != len(n)-1: add(result, ", ")
result.add(p.sym.name.s)
result.add(": ")
result.add(typeToString(p.sym.typ, prefer))
if i != n.len-1: result.add(", ")
else:
result.add renderTree(p)
add(result, ')')
if n.sons[0].typ != nil:
result.add(": " & typeToString(n.sons[0].typ, prefer))
result.add(')')
if n[0].typ != nil:
result.add(": " & typeToString(n[0].typ, prefer))
if getDeclarationPath:
result.add " [declared in "
result.add(conf$sym.info)
@ -153,7 +153,7 @@ proc elemType*(t: PType): PType =
assert(t != nil)
case t.kind
of tyGenericInst, tyDistinct, tyAlias, tySink: result = elemType(lastSon(t))
of tyArray: result = t.sons[1]
of tyArray: result = t[1]
of tyError: result = t
else: result = t.lastSon
assert(result != nil)
@ -180,8 +180,8 @@ proc iterOverNode(marker: var IntSet, n: PNode, iter: TTypeIter,
# a leaf
result = iterOverTypeAux(marker, n.typ, iter, closure)
else:
for i in 0 ..< len(n):
result = iterOverNode(marker, n.sons[i], iter, closure)
for i in 0..<n.len:
result = iterOverNode(marker, n[i], iter, closure)
if result: return
proc iterOverTypeAux(marker: var IntSet, t: PType, iter: TTypeIter,
@ -195,8 +195,8 @@ 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 ..< len(t):
result = iterOverTypeAux(marker, t.sons[i], iter, closure)
for i in 0..<t.len:
result = iterOverTypeAux(marker, t[i], iter, closure)
if result: return
if t.n != nil and t.kind != tyProc: result = iterOverNode(marker, t.n, iter, closure)
@ -212,17 +212,17 @@ proc searchTypeNodeForAux(n: PNode, p: TTypePredicate,
result = false
case n.kind
of nkRecList:
for i in 0 ..< len(n):
result = searchTypeNodeForAux(n.sons[i], p, marker)
for i in 0..<n.len:
result = searchTypeNodeForAux(n[i], p, marker)
if result: return
of nkRecCase:
assert(n.sons[0].kind == nkSym)
result = searchTypeNodeForAux(n.sons[0], p, marker)
assert(n[0].kind == nkSym)
result = searchTypeNodeForAux(n[0], p, marker)
if result: return
for i in 1 ..< len(n):
case n.sons[i].kind
for i in 1..<n.len:
case n[i].kind
of nkOfBranch, nkElse:
result = searchTypeNodeForAux(lastSon(n.sons[i]), p, marker)
result = searchTypeNodeForAux(lastSon(n[i]), p, marker)
if result: return
else: discard
of nkSym:
@ -239,14 +239,14 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate,
if result: return
case t.kind
of tyObject:
if t.sons[0] != nil:
result = searchTypeForAux(t.sons[0].skipTypes(skipPtrs), predicate, marker)
if t[0] != nil:
result = searchTypeForAux(t[0].skipTypes(skipPtrs), predicate, marker)
if not result: result = searchTypeNodeForAux(t.n, predicate, marker)
of tyGenericInst, tyDistinct, tyAlias, tySink:
result = searchTypeForAux(lastSon(t), predicate, marker)
of tyArray, tySet, tyTuple:
for i in 0 ..< len(t):
result = searchTypeForAux(t.sons[i], predicate, marker)
for i in 0..<t.len:
result = searchTypeForAux(t[i], predicate, marker)
if result: return
else:
discard
@ -262,7 +262,7 @@ proc containsObject*(t: PType): bool =
result = searchTypeFor(t, isObjectPredicate)
proc isObjectWithTypeFieldPredicate(t: PType): bool =
result = t.kind == tyObject and t.sons[0] == nil and
result = t.kind == tyObject and t[0] == nil and
not (t.sym != nil and {sfPure, sfInfixCall} * t.sym.flags != {}) and
tfFinal notin t.flags
@ -282,8 +282,8 @@ proc analyseObjectWithTypeFieldAux(t: PType,
if t.n != nil:
if searchTypeNodeForAux(t.n, isObjectWithTypeFieldPredicate, marker):
return frEmbedded
for i in 0 ..< len(t):
var x = t.sons[i]
for i in 0..<t.len:
var x = t[i]
if x != nil: x = x.skipTypes(skipPtrs)
res = analyseObjectWithTypeFieldAux(x, marker)
if res == frEmbedded:
@ -294,8 +294,8 @@ proc analyseObjectWithTypeFieldAux(t: PType,
of tyGenericInst, tyDistinct, tyAlias, tySink:
result = analyseObjectWithTypeFieldAux(lastSon(t), marker)
of tyArray, tyTuple:
for i in 0 ..< len(t):
res = analyseObjectWithTypeFieldAux(t.sons[i], marker)
for i in 0..<t.len:
res = analyseObjectWithTypeFieldAux(t[i], marker)
if res != frNone:
return frEmbedded
else:
@ -344,8 +344,8 @@ proc canFormAcycleNode(marker: var IntSet, n: PNode, startId: int): bool =
of nkNone..nkNilLit:
discard
else:
for i in 0 ..< len(n):
result = canFormAcycleNode(marker, n.sons[i], startId)
for i in 0..<n.len:
result = canFormAcycleNode(marker, n[i], startId)
if result: return
proc canFormAcycleAux(marker: var IntSet, typ: PType, startId: int): bool =
@ -355,8 +355,8 @@ 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 ..< len(t):
result = canFormAcycleAux(marker, t.sons[i], startId)
for i in 0..<t.len:
result = canFormAcycleAux(marker, t[i], startId)
if result: return
if t.n != nil: result = canFormAcycleNode(marker, t.n, startId)
else:
@ -391,8 +391,8 @@ proc mutateNode(marker: var IntSet, n: PNode, iter: TTypeMutator,
# a leaf
discard
else:
for i in 0 ..< len(n):
addSon(result, mutateNode(marker, n.sons[i], iter, closure))
for i in 0..<n.len:
result.add mutateNode(marker, n[i], iter, closure)
proc mutateTypeAux(marker: var IntSet, t: PType, iter: TTypeMutator,
closure: RootRef): PType =
@ -400,8 +400,8 @@ 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 ..< len(t):
result.sons[i] = mutateTypeAux(marker, result.sons[i], iter, closure)
for i in 0..<t.len:
result[i] = mutateTypeAux(marker, result[i], iter, closure)
if t.n != nil: result.n = mutateNode(marker, t.n, iter, closure)
assert(result != nil)
@ -418,7 +418,7 @@ proc valueToString(a: PNode): string =
proc rangeToStr(n: PNode): string =
assert(n.kind == nkRange)
result = valueToString(n.sons[0]) & ".." & valueToString(n.sons[1])
result = valueToString(n[0]) & ".." & valueToString(n[1])
const
typeToStr: array[TTypeKind, string] = ["None", "bool", "char", "empty",
@ -441,7 +441,7 @@ const preferToResolveSymbols = {preferName, preferTypeName, preferModuleInfo,
preferGenericArg, preferResolved, preferMixed}
template bindConcreteTypeToUserTypeClass*(tc, concrete: PType) =
tc.sons.add concrete
tc.add concrete
tc.flags.incl tfResolved
# TODO: It would be a good idea to kill the special state of a resolved
@ -473,8 +473,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
sfAnon notin t.sym.flags and t.kind != tySequence:
if t.kind == tyInt and isIntLit(t):
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
elif t.kind == tyAlias and t.sons[0].kind != tyAlias:
result = typeToString(t.sons[0])
elif t.kind == tyAlias and t[0].kind != tyAlias:
result = typeToString(t[0])
elif prefer in {preferResolved, preferMixed}:
case t.kind
of IntegralTypes + {tyFloat..tyFloat128} + {tyString, tyCString}:
@ -512,25 +512,25 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
else:
result = "int literal(" & $t.n.intVal & ")"
of tyGenericInst, tyGenericInvocation:
result = typeToString(t.sons[0]) & '['
for i in 1 ..< len(t)-ord(t.kind != tyGenericInvocation):
if i > 1: add(result, ", ")
add(result, typeToString(t.sons[i], preferGenericArg))
add(result, ']')
result = typeToString(t[0]) & '['
for i in 1..<t.len-ord(t.kind != tyGenericInvocation):
if i > 1: result.add(", ")
result.add(typeToString(t[i], preferGenericArg))
result.add(']')
of tyGenericBody:
result = typeToString(t.lastSon) & '['
for i in 0 .. len(t)-2:
if i > 0: add(result, ", ")
add(result, typeToString(t.sons[i], preferTypeName))
add(result, ']')
for i in 0..<t.len-1:
if i > 0: result.add(", ")
result.add(typeToString(t[i], preferTypeName))
result.add(']')
of tyTypeDesc:
if t.sons[0].kind == tyNone: result = "typedesc"
else: result = "type " & typeToString(t.sons[0])
if t[0].kind == tyNone: result = "typedesc"
else: result = "type " & typeToString(t[0])
of tyStatic:
if prefer == preferGenericArg and t.n != nil:
result = t.n.renderTree
else:
result = "static[" & (if t.len > 0: typeToString(t.sons[0]) else: "") & "]"
result = "static[" & (if t.len > 0: typeToString(t[0]) else: "") & "]"
if t.n != nil: result.add "(" & renderTree(t.n) & ")"
of tyUserTypeClass:
if t.sym != nil and t.sym.owner != nil:
@ -560,9 +560,9 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
of tyUserTypeClassInst:
let body = t.base
result = body.sym.name.s & "["
for i in 1 .. len(t) - 2:
if i > 1: add(result, ", ")
add(result, typeToString(t.sons[i]))
for i in 1..<t.len - 1:
if i > 1: result.add(", ")
result.add(typeToString(t[i]))
result.add "]"
of tyAnd:
for i, son in t.sons:
@ -575,7 +575,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
if i < t.sons.high:
result.add(" or ")
of tyNot:
result = "not " & typeToString(t.sons[0])
result = "not " & typeToString(t[0])
of tyUntyped:
#internalAssert t.len == 0
result = "untyped"
@ -585,63 +585,63 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
else:
result = "type(" & renderTree(t.n) & ")"
of tyArray:
if t.sons[0].kind == tyRange:
result = "array[" & rangeToStr(t.sons[0].n) & ", " &
typeToString(t.sons[1]) & ']'
if t[0].kind == tyRange:
result = "array[" & rangeToStr(t[0].n) & ", " &
typeToString(t[1]) & ']'
else:
result = "array[" & typeToString(t.sons[0]) & ", " &
typeToString(t.sons[1]) & ']'
result = "array[" & typeToString(t[0]) & ", " &
typeToString(t[1]) & ']'
of tyUncheckedArray:
result = "UncheckedArray[" & typeToString(t.sons[0]) & ']'
result = "UncheckedArray[" & typeToString(t[0]) & ']'
of tySequence:
result = "seq[" & typeToString(t.sons[0]) & ']'
result = "seq[" & typeToString(t[0]) & ']'
of tyOpt:
result = "opt[" & typeToString(t.sons[0]) & ']'
result = "opt[" & typeToString(t[0]) & ']'
of tyOrdinal:
result = "ordinal[" & typeToString(t.sons[0]) & ']'
result = "ordinal[" & typeToString(t[0]) & ']'
of tySet:
result = "set[" & typeToString(t.sons[0]) & ']'
result = "set[" & typeToString(t[0]) & ']'
of tyOpenArray:
result = "openArray[" & typeToString(t.sons[0]) & ']'
result = "openArray[" & typeToString(t[0]) & ']'
of tyDistinct:
result = "distinct " & typeToString(t.sons[0],
result = "distinct " & typeToString(t[0],
if prefer == preferModuleInfo: preferModuleInfo else: preferTypeName)
of tyTuple:
# we iterate over t.sons here, because t.n may be nil
if t.n != nil:
result = "tuple["
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 < len(t.n) - 1: add(result, ", ")
add(result, ']')
elif len(t) == 0:
assert(t.n.len == t.len)
for i in 0..<t.n.len:
assert(t.n[i].kind == nkSym)
result.add(t.n[i].sym.name.s & ": " & typeToString(t[i]))
if i < t.n.len - 1: result.add(", ")
result.add(']')
elif t.len == 0:
result = "tuple[]"
else:
if prefer == preferTypeName: result = "("
else: result = "tuple of ("
for i in 0 ..< len(t):
add(result, typeToString(t.sons[i]))
if i < len(t) - 1: add(result, ", ")
add(result, ')')
for i in 0..<t.len:
result.add(typeToString(t[i]))
if i < t.len - 1: result.add(", ")
result.add(')')
of tyPtr, tyRef, tyVar, tyLent:
result = typeToStr[t.kind]
if t.len >= 2:
setLen(result, result.len-1)
result.add '['
for i in 0 ..< len(t):
add(result, typeToString(t.sons[i]))
if i < len(t) - 1: add(result, ", ")
for i in 0..<t.len:
result.add(typeToString(t[i]))
if i < t.len - 1: result.add(", ")
result.add ']'
else:
result.add typeToString(t.sons[0])
result.add typeToString(t[0])
of tyRange:
result = "range "
if t.n != nil and t.n.kind == nkRange:
result.add rangeToStr(t.n)
if prefer != preferExported:
result.add("(" & typeToString(t.sons[0]) & ")")
result.add("(" & typeToString(t[0]) & ")")
of tyProc:
result = if tfIterator in t.flags: "iterator "
elif t.owner != nil:
@ -654,31 +654,31 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
"proc "
if tfUnresolved in t.flags: result.add "[*missing parameters*]"
result.add "("
for i in 1 ..< len(t):
for i in 1..<t.len:
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 < len(t) - 1: add(result, ", ")
add(result, ')')
if t.len > 0 and t.sons[0] != nil: add(result, ": " & typeToString(t.sons[0]))
result.add(t.n[i].sym.name.s)
result.add(": ")
result.add(typeToString(t[i]))
if i < t.len - 1: result.add(", ")
result.add(')')
if t.len > 0 and t[0] != nil: result.add(": " & typeToString(t[0]))
var prag = if t.callConv == ccDefault: "" else: CallingConvToStr[t.callConv]
if tfNoSideEffect in t.flags:
addSep(prag)
add(prag, "noSideEffect")
prag.add("noSideEffect")
if tfThread in t.flags:
addSep(prag)
add(prag, "gcsafe")
prag.add("gcsafe")
if t.lockLevel.ord != UnspecifiedLockLevel.ord:
addSep(prag)
add(prag, "locks: " & $t.lockLevel)
if len(prag) != 0: add(result, "{." & prag & ".}")
prag.add("locks: " & $t.lockLevel)
if prag.len != 0: result.add("{." & prag & ".}")
of tyVarargs:
result = typeToStr[t.kind] % typeToString(t.sons[0])
result = typeToStr[t.kind] % typeToString(t[0])
of tySink:
result = "sink " & typeToString(t.sons[0])
result = "sink " & typeToString(t[0])
of tyOwned:
result = "owned " & typeToString(t.sons[0])
result = "owned " & typeToString(t[0])
else:
result = typeToStr[t.kind]
result.addTypeFlags(t)
@ -688,12 +688,12 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
case t.kind
of tyBool, tyChar, tySequence, tyOpenArray, tyString, tyVarargs, tyProxy:
result = Zero
of tySet, tyVar: result = firstOrd(conf, t.sons[0])
of tyArray: result = firstOrd(conf, t.sons[0])
of tySet, tyVar: result = firstOrd(conf, t[0])
of tyArray: result = firstOrd(conf, t[0])
of tyRange:
assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange)
result = getOrdValue(t.n.sons[0])
result = getOrdValue(t.n[0])
of tyInt:
if conf != nil and conf.target.intSize == 4:
result = toInt128(-2147483648)
@ -706,11 +706,11 @@ proc firstOrd*(conf: ConfigRef; t: PType): Int128 =
of tyUInt..tyUInt64: result = Zero
of tyEnum:
# if basetype <> nil then return firstOrd of basetype
if len(t) > 0 and t.sons[0] != nil:
result = firstOrd(conf, t.sons[0])
if t.len > 0 and t[0] != nil:
result = firstOrd(conf, t[0])
else:
assert(t.n.sons[0].kind == nkSym)
result = toInt128(t.n.sons[0].sym.position)
assert(t.n[0].kind == nkSym)
result = toInt128(t.n[0].sym.position)
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink,
tyStatic, tyInferred, tyUserTypeClasses:
result = firstOrd(conf, lastSon(t))
@ -729,8 +729,8 @@ proc firstFloat*(t: PType): BiggestFloat =
of tyRange:
assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange)
getFloatValue(t.n.sons[0])
of tyVar: firstFloat(t.sons[0])
getFloatValue(t.n[0])
of tyVar: firstFloat(t[0])
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink,
tyStatic, tyInferred, tyUserTypeClasses:
firstFloat(lastSon(t))
@ -742,12 +742,12 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
case t.kind
of tyBool: result = toInt128(1'u)
of tyChar: result = toInt128(255'u)
of tySet, tyVar: result = lastOrd(conf, t.sons[0])
of tyArray: result = lastOrd(conf, t.sons[0])
of tySet, tyVar: result = lastOrd(conf, t[0])
of tyArray: result = lastOrd(conf, t[0])
of tyRange:
assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange)
result = getOrdValue(t.n.sons[1])
result = getOrdValue(t.n[1])
of tyInt:
if conf != nil and conf.target.intSize == 4: result = toInt128(0x7FFFFFFF)
else: result = toInt128(0x7FFFFFFFFFFFFFFF'u64)
@ -766,8 +766,8 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
of tyUInt64:
result = toInt128(0xFFFFFFFFFFFFFFFF'u64)
of tyEnum:
assert(t.n.sons[len(t.n) - 1].kind == nkSym)
result = toInt128(t.n.sons[len(t.n) - 1].sym.position)
assert(t.n[^1].kind == nkSym)
result = toInt128(t.n[^1].sym.position)
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink,
tyStatic, tyInferred, tyUserTypeClasses:
result = lastOrd(conf, lastSon(t))
@ -784,11 +784,11 @@ proc lastOrd*(conf: ConfigRef; t: PType): Int128 =
proc lastFloat*(t: PType): BiggestFloat =
case t.kind
of tyFloat..tyFloat128: Inf
of tyVar: lastFloat(t.sons[0])
of tyVar: lastFloat(t[0])
of tyRange:
assert(t.n != nil) # range directly given:
assert(t.n.kind == nkRange)
getFloatValue(t.n.sons[1])
getFloatValue(t.n[1])
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink,
tyStatic, tyInferred, tyUserTypeClasses:
lastFloat(lastSon(t))
@ -799,13 +799,13 @@ proc lastFloat*(t: PType): BiggestFloat =
proc floatRangeCheck*(x: BiggestFloat, t: PType): bool =
case t.kind
# This needs to be special cased since NaN is never
# part of firstFloat(t) .. lastFloat(t)
# part of firstFloat(t)..lastFloat(t)
of tyFloat..tyFloat128:
true
of tyRange:
x in firstFloat(t) .. lastFloat(t)
x in firstFloat(t)..lastFloat(t)
of tyVar:
floatRangeCheck(x, t.sons[0])
floatRangeCheck(x, t[0])
of tyGenericInst, tyDistinct, tyTypeDesc, tyAlias, tySink,
tyStatic, tyInferred, tyUserTypeClasses:
floatRangeCheck(x, lastSon(t))
@ -815,7 +815,7 @@ proc floatRangeCheck*(x: BiggestFloat, t: PType): bool =
proc lengthOrd*(conf: ConfigRef; t: PType): Int128 =
if t.skipTypes(tyUserTypeClasses).kind == tyDistinct:
result = lengthOrd(conf, t.sons[0])
result = lengthOrd(conf, t[0])
else:
let last = lastOrd(conf, t)
let first = firstOrd(conf, t)
@ -897,7 +897,7 @@ proc equalParam(a, b: PSym): TParamsEquality =
proc sameConstraints(a, b: PNode): bool =
if isNil(a) and isNil(b): return true
if a.len != b.len: return false
for i in 1 ..< a.len:
for i in 1..<a.len:
if not exprStructuralEquivalent(a[i].sym.constraint,
b[i].sym.constraint):
return false
@ -905,13 +905,12 @@ proc sameConstraints(a, b: PNode): bool =
proc equalParams(a, b: PNode): TParamsEquality =
result = paramsEqual
var length = len(a)
if length != len(b):
if a.len != b.len:
result = paramsNotEqual
else:
for i in 1 ..< length:
var m = a.sons[i].sym
var n = b.sons[i].sym
for i in 1..<a.len:
var m = a[i].sym
var n = b[i].sym
assert((m.kind == skParam) and (n.kind == skParam))
case equalParam(m, n)
of paramsNotEqual:
@ -936,11 +935,11 @@ 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 len(a) == len(b):
if a.len == b.len:
result = true
for i in 0 ..< len(a):
var x = a.sons[i]
var y = b.sons[i]
for i in 0..<a.len:
var x = a[i]
var y = b[i]
if IgnoreTupleFields in c.flags:
x = skipTypes(x, {tyRange, tyGenericInst, tyAlias})
y = skipTypes(y, {tyRange, tyGenericInst, tyAlias})
@ -948,11 +947,11 @@ 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 ..< len(a.n):
for i in 0..<a.n.len:
# check field names:
if a.n.sons[i].kind == nkSym and b.n.sons[i].kind == nkSym:
var x = a.n.sons[i].sym
var y = b.n.sons[i].sym
if a.n[i].kind == nkSym and b.n[i].kind == nkSym:
var x = a.n[i].sym
var y = b.n[i].sym
result = x.name.id == y.name.id
if not result: break
else:
@ -1011,24 +1010,24 @@ 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 len(a) == len(b):
for i in 0 ..< len(a):
if not sameObjectTree(a.sons[i], b.sons[i], c): return
if a.len == b.len:
for i in 0..<a.len:
if not sameObjectTree(a[i], b[i], c): return
result = true
proc sameObjectStructures(a, b: PType, c: var TSameTypeClosure): bool =
# check base types:
if len(a) != len(b): return
for i in 0 ..< len(a):
if not sameTypeOrNilAux(a.sons[i], b.sons[i], c): return
if a.len != b.len: return
for i in 0..<a.len:
if not sameTypeOrNilAux(a[i], b[i], c): return
if not sameObjectTree(a.n, b.n, c): return
result = true
proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool =
if len(a) != len(b): return false
if a.len != b.len: return false
result = true
for i in 0 ..< len(a):
result = sameTypeOrNilAux(a.sons[i], b.sons[i], c)
for i in 0..<a.len:
result = sameTypeOrNilAux(a[i], b[i], c)
if not result: return
proc isGenericAlias*(t: PType): bool =
@ -1061,11 +1060,11 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
case c.cmp
of dcEq: return false
of dcEqIgnoreDistinct:
while a.kind == tyDistinct: a = a.sons[0]
while b.kind == tyDistinct: b = b.sons[0]
while a.kind == tyDistinct: a = a[0]
while b.kind == tyDistinct: b = b[0]
if a.kind != b.kind: return false
of dcEqOrDistinctOf:
while a.kind == tyDistinct: a = a.sons[0]
while a.kind == tyDistinct: a = a[0]
if a.kind != b.kind: return false
# this is required by tunique_type but makes no sense really:
@ -1075,9 +1074,9 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
rhs = y.skipGenericAlias
if rhs.kind != tyGenericInst or lhs.base != rhs.base:
return false
for i in 1 .. lhs.len - 2:
let ff = rhs.sons[i]
let aa = lhs.sons[i]
for i in 1..<lhs.len - 1:
let ff = rhs[i]
let aa = lhs[i]
if not sameTypeAux(ff, aa, c): return false
return true
@ -1089,7 +1088,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
result = exprStructuralEquivalent(a.n, b.n) and sameFlags(a, b)
if result and a.len == b.len and a.len == 1:
cycleCheck()
result = sameTypeAux(a.sons[0], b.sons[0], c)
result = sameTypeAux(a[0], b[0], c)
of tyObject:
ifFastObjectTypeCheckFailed(a, b):
cycleCheck()
@ -1099,9 +1098,9 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
if c.cmp == dcEq:
if sameFlags(a, b):
ifFastObjectTypeCheckFailed(a, b):
result = sameTypeAux(a.sons[0], b.sons[0], c)
result = sameTypeAux(a[0], b[0], c)
else:
result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b)
result = sameTypeAux(a[0], b[0], c) and sameFlags(a, b)
of tyEnum, tyForward:
# XXX generic enums do not make much sense, but require structural checking
result = a.id == b.id and sameFlags(a, b)
@ -1146,9 +1145,9 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
((ExactConstraints notin c.flags) or sameConstraints(a.n, b.n))
of tyRange:
cycleCheck()
result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
sameValue(a.n.sons[0], b.n.sons[0]) and
sameValue(a.n.sons[1], b.n.sons[1])
result = sameTypeOrNilAux(a[0], b[0], c) and
sameValue(a.n[0], b.n[0]) and
sameValue(a.n[1], b.n[1])
of tyGenericInst, tyAlias, tyInferred:
cycleCheck()
result = sameTypeAux(a.lastSon, b.lastSon, c)
@ -1184,14 +1183,14 @@ proc inheritanceDiff*(a, b: PType): int =
while x != nil:
x = skipTypes(x, skipPtrs)
if sameObjectTypes(x, b): return
x = x.sons[0]
x = x[0]
dec(result)
var y = b
result = 0
while y != nil:
y = skipTypes(y, skipPtrs)
if sameObjectTypes(y, a): return
y = y.sons[0]
y = y[0]
inc(result)
result = high(int)
@ -1208,7 +1207,7 @@ proc commonSuperclass*(a, b: PType): PType =
while x != nil:
x = skipTypes(x, skipPtrs)
ancestors.incl(x.id)
x = x.sons[0]
x = x[0]
var y = b
while y != nil:
var t = y # bug #7818, save type before skip
@ -1217,7 +1216,7 @@ proc commonSuperclass*(a, b: PType): PType =
# bug #7818, defer the previous skipTypes
if t.kind != tyGenericInst: t = y
return t
y = y.sons[0]
y = y[0]
type
TTypeAllowedFlag* = enum
@ -1243,8 +1242,8 @@ 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 ..< len(n):
let it = n.sons[i]
for i in 0..<n.len:
let it = n[i]
result = typeAllowedNode(marker, it, kind, flags)
if result != nil: break
@ -1253,8 +1252,8 @@ 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.len or a.sons[i] == nil: return false
a = a.sons[i]
if i >= a.len or a[i] == nil: return false
a = a[i]
result = a.kind == last
proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
@ -1273,16 +1272,16 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
elif t.kind == tyLent and kind != skResult:
result = t
else:
var t2 = skipTypes(t.sons[0], abstractInst-{tyTypeDesc})
var t2 = skipTypes(t[0], abstractInst-{tyTypeDesc})
case t2.kind
of tyVar, tyLent:
if taHeap notin flags: result = t2 # ``var var`` is illegal on the heap
of tyOpenArray:
if kind != skParam or taIsOpenArray in flags: result = t
else: result = typeAllowedAux(marker, t2.sons[0], kind, flags+{taIsOpenArray})
else: result = typeAllowedAux(marker, t2[0], kind, flags+{taIsOpenArray})
of tyUncheckedArray:
if kind != skParam: result = t
else: result = typeAllowedAux(marker, t2.sons[0], kind, flags)
else: result = typeAllowedAux(marker, t2[0], kind, flags)
else:
if kind notin {skParam, skResult}: result = t
else: result = typeAllowedAux(marker, t2, kind, flags)
@ -1291,11 +1290,11 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
# only closure iterators my be assigned to anything.
result = t
let f = if kind in {skProc, skFunc}: flags+{taNoUntyped} else: flags
for i in 1 ..< len(t):
for i in 1..<t.len:
if result != nil: break
result = typeAllowedAux(marker, t.sons[i], skParam, f-{taIsOpenArray})
if result.isNil and t.sons[0] != nil:
result = typeAllowedAux(marker, t.sons[0], skResult, flags)
result = typeAllowedAux(marker, t[i], skParam, f-{taIsOpenArray})
if result.isNil and t[0] != nil:
result = typeAllowedAux(marker, t[0], skResult, flags)
of tyTypeDesc:
# XXX: This is still a horrible idea...
result = nil
@ -1324,46 +1323,46 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
of tyGenericInst, tyDistinct, tyAlias, tyInferred:
result = typeAllowedAux(marker, lastSon(t), kind, flags)
of tyRange:
if skipTypes(t.sons[0], abstractInst-{tyTypeDesc}).kind notin
if skipTypes(t[0], abstractInst-{tyTypeDesc}).kind notin
{tyChar, tyEnum, tyInt..tyFloat128, tyInt..tyUInt64}: result = t
of tyOpenArray, tyVarargs, tySink:
# you cannot nest openArrays/sinks/etc.
if kind != skParam or taIsOpenArray in flags:
result = t
else:
result = typeAllowedAux(marker, t.sons[0], kind, flags+{taIsOpenArray})
result = typeAllowedAux(marker, t[0], kind, flags+{taIsOpenArray})
of tyUncheckedArray:
if kind != skParam and taHeap notin flags:
result = t
else:
result = typeAllowedAux(marker, lastSon(t), kind, flags-{taHeap})
of tySequence, tyOpt:
if t.sons[0].kind != tyEmpty:
result = typeAllowedAux(marker, t.sons[0], kind, flags+{taHeap})
if t[0].kind != tyEmpty:
result = typeAllowedAux(marker, t[0], kind, flags+{taHeap})
elif kind in {skVar, skLet}:
result = t.sons[0]
result = t[0]
of tyArray:
if t.sons[1].kind != tyEmpty:
result = typeAllowedAux(marker, t.sons[1], kind, flags)
if t[1].kind != tyEmpty:
result = typeAllowedAux(marker, t[1], kind, flags)
elif kind in {skVar, skLet}:
result = t.sons[1]
result = t[1]
of tyRef:
if kind == skConst: result = t
else: result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap})
of tyPtr:
result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap})
of tySet:
for i in 0 ..< len(t):
result = typeAllowedAux(marker, t.sons[i], kind, flags)
for i in 0..<t.len:
result = typeAllowedAux(marker, t[i], kind, flags)
if result != nil: break
of tyObject, tyTuple:
if kind in {skProc, skFunc, skConst} and
t.kind == tyObject and t.sons[0] != nil:
t.kind == tyObject and t[0] != nil:
result = t
else:
let flags = flags+{taField}
for i in 0 ..< len(t):
result = typeAllowedAux(marker, t.sons[i], kind, flags)
for i in 0..<t.len:
result = typeAllowedAux(marker, t[i], kind, flags)
if result != nil: break
if result.isNil and t.n != nil:
result = typeAllowedNode(marker, t.n, kind, flags)
@ -1374,7 +1373,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
# prevent cascading errors:
result = nil
of tyOwned:
if t.len == 1 and t.sons[0].skipTypes(abstractInst).kind in {tyRef, tyPtr, tyProc}:
if t.len == 1 and t[0].skipTypes(abstractInst).kind in {tyRef, tyPtr, tyProc}:
result = typeAllowedAux(marker, t.lastSon, kind, flags+{taHeap})
else:
result = t
@ -1394,7 +1393,7 @@ proc computeSize*(conf: ConfigRef; typ: PType): BiggestInt =
proc getReturnType*(s: PSym): PType =
# Obtains the return type of a iterator/proc/macro/template
assert s.kind in skProcKinds
result = s.typ.sons[0]
result = s.typ[0]
proc getAlign*(conf: ConfigRef; typ: PType): BiggestInt =
computeSizeAlign(conf, typ)
@ -1422,7 +1421,7 @@ proc containsGenericType*(t: PType): bool =
proc baseOfDistinct*(t: PType): PType =
if t.kind == tyDistinct:
result = t.sons[0]
result = t[0]
else:
result = copyType(t, t.owner, false)
var parent: PType = nil
@ -1431,7 +1430,7 @@ proc baseOfDistinct*(t: PType): PType =
parent = it
it = it.lastSon
if it.kind == tyDistinct and parent != nil:
parent.sons[0] = it.sons[0]
parent[0] = it[0]
proc safeInheritanceDiff*(a, b: PType): int =
# same as inheritanceDiff but checks for tyError:
@ -1462,29 +1461,29 @@ type
proc compatibleEffects*(formal, actual: PType): EffectsCompat =
# for proc type compatibility checking:
assert formal.kind == tyProc and actual.kind == tyProc
if formal.n.sons[0].kind != nkEffectList or
actual.n.sons[0].kind != nkEffectList:
if formal.n[0].kind != nkEffectList or
actual.n[0].kind != nkEffectList:
return efTagsUnknown
var spec = formal.n.sons[0]
var spec = formal.n[0]
if spec.len != 0:
var real = actual.n.sons[0]
var real = actual.n[0]
let se = spec.sons[exceptionEffects]
let se = spec[exceptionEffects]
# if 'se.kind == nkArgList' it is no formal type really, but a
# computed effect and as such no spec:
# 'r.msgHandler = if isNil(msgHandler): defaultMsgHandler else: msgHandler'
if not isNil(se) and se.kind != nkArgList:
# spec requires some exception or tag, but we don't know anything:
if real.len == 0: return efRaisesUnknown
let res = compatibleEffectsAux(se, real.sons[exceptionEffects])
let res = compatibleEffectsAux(se, real[exceptionEffects])
if not res: return efRaisesDiffer
let st = spec.sons[tagEffects]
let st = spec[tagEffects]
if not isNil(st) and st.kind != nkArgList:
# spec requires some exception or tag, but we don't know anything:
if real.len == 0: return efTagsUnknown
let res = compatibleEffectsAux(st, real.sons[tagEffects])
let res = compatibleEffectsAux(st, real[tagEffects])
if not res: return efTagsDiffer
if formal.lockLevel.ord < 0 or
actual.lockLevel.ord <= formal.lockLevel.ord:
@ -1497,8 +1496,8 @@ proc isCompileTimeOnly*(t: PType): bool {.inline.} =
proc containsCompileTimeOnly*(t: PType): bool =
if isCompileTimeOnly(t): return true
for i in 0 ..< t.len:
if t.sons[i] != nil and isCompileTimeOnly(t.sons[i]):
for i in 0..<t.len:
if t[i] != nil and isCompileTimeOnly(t[i]):
return true
return false
@ -1523,11 +1522,11 @@ proc skipConv*(n: PNode): PNode =
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
# only skip the conversion if it doesn't lose too important information
# (see bug #1334)
if n.sons[0].typ.classify == n.typ.classify:
result = n.sons[0]
if n[0].typ.classify == n.typ.classify:
result = n[0]
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
if n.sons[1].typ.classify == n.typ.classify:
result = n.sons[1]
if n[1].typ.classify == n.typ.classify:
result = n[1]
else: discard
proc skipHidden*(n: PNode): PNode =
@ -1535,11 +1534,11 @@ proc skipHidden*(n: PNode): PNode =
while true:
case result.kind
of nkHiddenStdConv, nkHiddenSubConv:
if result.sons[1].typ.classify == result.typ.classify:
result = result.sons[1]
if result[1].typ.classify == result.typ.classify:
result = result[1]
else: break
of nkHiddenDeref, nkHiddenAddr:
result = result.sons[0]
result = result[0]
else: break
proc skipConvTakeType*(n: PNode): PNode =
@ -1549,9 +1548,9 @@ proc skipConvTakeType*(n: PNode): PNode =
proc isEmptyContainer*(t: PType): bool =
case t.kind
of tyUntyped, tyNil: result = true
of tyArray: result = t.sons[1].kind == tyEmpty
of tyArray: result = t[1].kind == tyEmpty
of tySet, tySequence, tyOpenArray, tyVarargs:
result = t.sons[0].kind == tyEmpty
result = t[0].kind == tyEmpty
of tyGenericInst, tyAlias, tySink: result = isEmptyContainer(t.lastSon)
else: result = false
@ -1564,7 +1563,7 @@ proc takeType*(formal, arg: PType): PType =
elif formal.kind in {tyOpenArray, tyVarargs, tySequence} and
arg.isEmptyContainer:
let a = copyType(arg.skipTypes({tyGenericInst, tyAlias}), arg.owner, keepId=false)
a.sons[ord(arg.kind == tyArray)] = formal.sons[0]
a[ord(arg.kind == tyArray)] = formal[0]
result = a
elif formal.kind in {tyTuple, tySet} and arg.kind == formal.kind:
result = formal
@ -1576,7 +1575,7 @@ proc skipHiddenSubConv*(n: PNode): PNode =
# param: openArray[string] = []
# [] is an array constructor of length 0 of type string!
let formal = n.typ
result = n.sons[1]
result = n[1]
let arg = result.typ
let dest = takeType(formal, arg)
if dest == arg and formal.kind != tyUntyped:
@ -1640,8 +1639,8 @@ proc isException*(t: PType): bool =
var t = t.skipTypes(abstractInst)
while t.kind == tyObject:
if t.sym != nil and t.sym.magic == mException: return true
if t.sons[0] == nil: break
t = skipTypes(t.sons[0], abstractPtrs)
if t[0] == nil: break
t = skipTypes(t[0], abstractPtrs)
return false
proc isSinkTypeForParam*(t: PType): bool =

Some files were not shown because too many files have changed in this diff Show more