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:
parent
b662842bd0
commit
7e747d11c6
109 changed files with 6115 additions and 6254 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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] =
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 ---------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 "_"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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'"
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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 = ""
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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])
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue