mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
split the inline and closure iterators into different symbol kinds for easier discrimination between them
This commit is contained in:
@@ -469,7 +469,8 @@ type
|
||||
skResult, # special 'result' variable
|
||||
skProc, # a proc
|
||||
skMethod, # a method
|
||||
skIterator, # an iterator
|
||||
skIterator, # an inline iterator
|
||||
skClosureIterator, # a resumable closure iterator
|
||||
skConverter, # a type converter
|
||||
skMacro, # a macro
|
||||
skTemplate, # a template; currently also misused for user-defined
|
||||
@@ -485,8 +486,8 @@ type
|
||||
TSymKinds* = set[TSymKind]
|
||||
|
||||
const
|
||||
routineKinds* = {skProc, skMethod, skIterator, skConverter,
|
||||
skMacro, skTemplate}
|
||||
routineKinds* = {skProc, skMethod, skIterator, skClosureIterator,
|
||||
skConverter, skMacro, skTemplate}
|
||||
tfIncompleteStruct* = tfVarargs
|
||||
skError* = skUnknown
|
||||
|
||||
@@ -820,8 +821,8 @@ type
|
||||
# the poor naming choices in the standard library.
|
||||
|
||||
const
|
||||
OverloadableSyms* = {skProc, skMethod, skIterator, skConverter,
|
||||
skModule, skTemplate, skMacro}
|
||||
OverloadableSyms* = {skProc, skMethod, skIterator, skClosureIterator,
|
||||
skConverter, skModule, skTemplate, skMacro}
|
||||
|
||||
GenericTypes*: TTypeKinds = {tyGenericInvokation, tyGenericBody,
|
||||
tyGenericParam}
|
||||
@@ -843,7 +844,8 @@ const
|
||||
tyTuple, tySequence}
|
||||
NilableTypes*: TTypeKinds = {tyPointer, tyCString, tyRef, tyPtr, tySequence,
|
||||
tyProc, tyString, tyError}
|
||||
ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType, skIterator,
|
||||
ExportableSymKinds* = {skVar, skConst, skProc, skMethod, skType,
|
||||
skIterator, skClosureIterator,
|
||||
skMacro, skTemplate, skConverter, skEnumField, skLet, skStub}
|
||||
PersistentNodeFlags*: TNodeFlags = {nfBase2, nfBase8, nfBase16,
|
||||
nfDotSetter, nfDotField,
|
||||
@@ -869,7 +871,10 @@ const
|
||||
nkStrKinds* = {nkStrLit..nkTripleStrLit}
|
||||
|
||||
skLocalVars* = {skVar, skLet, skForVar, skParam, skResult}
|
||||
skProcKinds* = {skProc, skTemplate, skMacro, skIterator, skMethod, skConverter}
|
||||
skProcKinds* = {skProc, skTemplate, skMacro, skIterator, skClosureIterator,
|
||||
skMethod, skConverter}
|
||||
|
||||
skIterators* = {skIterator, skClosureIterator}
|
||||
|
||||
lfFullExternalName* = lfParamCopy # \
|
||||
# only used when 'gCmd == cmdPretty': Indicates that the symbol has been
|
||||
@@ -1479,8 +1484,7 @@ proc originatingModule*(s: PSym): PSym =
|
||||
while result.kind != skModule: result = result.owner
|
||||
|
||||
proc isRoutine*(s: PSym): bool {.inline.} =
|
||||
result = s.kind in {skProc, skTemplate, skMacro, skIterator, skMethod,
|
||||
skConverter}
|
||||
result = s.kind in skProcKinds
|
||||
|
||||
proc hasPattern*(s: PSym): bool {.inline.} =
|
||||
result = isRoutine(s) and s.ast.sons[patternPos].kind != nkEmpty
|
||||
|
||||
@@ -1803,7 +1803,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||
else:
|
||||
genProc(p.module, sym)
|
||||
putLocIntoDest(p, d, sym.loc)
|
||||
of skProc, skConverter, skIterator:
|
||||
of skProc, skConverter, skIterators:
|
||||
genProc(p.module, sym)
|
||||
if sym.loc.r == nil or sym.loc.t == nil:
|
||||
internalError(n.info, "expr: proc not init " & sym.name.s)
|
||||
|
||||
@@ -863,7 +863,7 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope =
|
||||
res.add(t.sons[i].strVal)
|
||||
of nkSym:
|
||||
var sym = t.sons[i].sym
|
||||
if sym.kind in {skProc, skIterator, skMethod}:
|
||||
if sym.kind in {skProc, skIterator, skClosureIterator, skMethod}:
|
||||
var a: TLoc
|
||||
initLocExpr(p, t.sons[i], a)
|
||||
res.add(rdLoc(a).ropeToStr)
|
||||
|
||||
@@ -69,7 +69,7 @@ proc mangleName(s: PSym): PRope =
|
||||
if result == nil:
|
||||
if gCmd == cmdCompileToLLVM:
|
||||
case s.kind
|
||||
of skProc, skMethod, skConverter, skConst, skIterator:
|
||||
of skProc, skMethod, skConverter, skConst, skIterators:
|
||||
result = ~"@"
|
||||
of skVar, skForVar, skResult, skLet:
|
||||
if sfGlobal in s.flags: result = ~"@"
|
||||
|
||||
@@ -705,7 +705,7 @@ proc cgsym(m: BModule, name: string): PRope =
|
||||
var sym = magicsys.getCompilerProc(name)
|
||||
if sym != nil:
|
||||
case sym.kind
|
||||
of skProc, skMethod, skConverter, skIterator: genProc(m, sym)
|
||||
of skProc, skMethod, skConverter, skIterators: genProc(m, sym)
|
||||
of skVar, skResult, skLet: genVarPrototype(m, sym)
|
||||
of skType: discard getTypeDesc(m, sym.typ)
|
||||
else: internalError("cgsym: " & name)
|
||||
|
||||
@@ -366,7 +366,7 @@ proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode =
|
||||
proc genSection(d: PDoc, kind: TSymKind) =
|
||||
const sectionNames: array[skModule..skTemplate, string] = [
|
||||
"Imports", "Types", "Vars", "Lets", "Consts", "Vars", "Procs", "Methods",
|
||||
"Iterators", "Converters", "Macros", "Templates"
|
||||
"Iterators", "Iterators", "Converters", "Macros", "Templates"
|
||||
]
|
||||
if d.section[kind] == nil: return
|
||||
var title = sectionNames[kind].toRope
|
||||
|
||||
@@ -103,7 +103,7 @@ proc importSymbol(c: PContext, n: PNode, fromMod: PSym) =
|
||||
internalError(n.info, "importSymbol: 2")
|
||||
# for an enumeration we have to add all identifiers
|
||||
case s.kind
|
||||
of skProc, skMethod, skIterator, skMacro, skTemplate, skConverter:
|
||||
of skProcKinds:
|
||||
# for a overloadable syms add all overloaded routines
|
||||
var it: TIdentIter
|
||||
var e = initIdentIter(it, fromMod.tab, s.name)
|
||||
|
||||
@@ -1154,7 +1154,7 @@ proc createVar(p: PProc, typ: PType, indirect: bool): PRope =
|
||||
|
||||
proc isIndirect(v: PSym): bool =
|
||||
result = (sfAddrTaken in v.flags) and (mapType(v.typ) != etyObject) and
|
||||
v.kind notin {skProc, skConverter, skMethod, skIterator}
|
||||
v.kind notin {skProc, skConverter, skMethod, skIterator, skClosureIterator}
|
||||
|
||||
proc genVarInit(p: PProc, v: PSym, n: PNode) =
|
||||
var
|
||||
|
||||
@@ -232,9 +232,9 @@ proc newOuterContext(fn: PSym, up: POuterContext = nil): POuterContext =
|
||||
initIdNodeTable(result.localsToAccess)
|
||||
initIdTable(result.localsToEnv)
|
||||
initIdTable(result.lambdasToEnv)
|
||||
result.isIter = fn.kind == skIterator and fn.typ.callConv == ccClosure
|
||||
result.isIter = fn.kind == skClosureIterator
|
||||
if result.isIter: initIterContext(result, fn)
|
||||
|
||||
|
||||
proc newInnerContext(fn: PSym): PInnerContext =
|
||||
new(result)
|
||||
result.fn = fn
|
||||
@@ -292,8 +292,7 @@ proc newCall(a, b: PSym): PNode =
|
||||
result.add newSymNode(b)
|
||||
|
||||
proc isInnerProc(s, outerProc: PSym): bool {.inline.} =
|
||||
result = (s.kind in {skProc, skMethod, skConverter} or
|
||||
s.kind == skIterator and s.typ.callConv == ccClosure) and
|
||||
result = s.kind in {skProc, skMethod, skConverter, skClosureIterator} and
|
||||
s.skipGenericOwner == outerProc
|
||||
#s.typ.callConv == ccClosure
|
||||
|
||||
@@ -653,7 +652,7 @@ proc outerProcSons(o: POuterContext, n: PNode) =
|
||||
proc liftIterSym*(n: PNode): PNode =
|
||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||
let iter = n.sym
|
||||
assert iter.kind == skIterator
|
||||
assert iter.kind == skClosureIterator
|
||||
|
||||
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
|
||||
|
||||
@@ -679,7 +678,7 @@ proc transformOuterProc(o: POuterContext, n: PNode): PNode =
|
||||
|
||||
var closure = PEnv(idTableGet(o.lambdasToEnv, local))
|
||||
|
||||
if local.kind == skIterator and local.typ.callConv == ccClosure:
|
||||
if local.kind == skClosureIterator:
|
||||
# consider: [i1, i2, i1] Since we merged the iterator's closure
|
||||
# with the captured owning variables, we need to generate the
|
||||
# closure generation code again:
|
||||
@@ -843,10 +842,10 @@ proc liftForLoop*(body: PNode): PNode =
|
||||
|
||||
# static binding?
|
||||
var env: PSym
|
||||
if call[0].kind == nkSym and call[0].sym.kind == skIterator:
|
||||
if call[0].kind == nkSym and call[0].sym.kind == skClosureIterator:
|
||||
# createClosure()
|
||||
let iter = call[0].sym
|
||||
assert iter.kind == skIterator
|
||||
assert iter.kind == skClosureIterator
|
||||
env = copySym(getHiddenParam(iter))
|
||||
|
||||
var v = newNodeI(nkVarSection, body.info)
|
||||
|
||||
@@ -109,7 +109,7 @@ type
|
||||
|
||||
proc getSymRepr*(s: PSym): string =
|
||||
case s.kind
|
||||
of skProc, skMethod, skConverter, skIterator: result = getProcHeader(s)
|
||||
of skProc, skMethod, skConverter, skIterators: result = getProcHeader(s)
|
||||
else: result = s.name.s
|
||||
|
||||
proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
|
||||
|
||||
@@ -772,6 +772,17 @@ proc implictPragmas*(c: PContext, sym: PSym, n: PNode,
|
||||
addToLib(lib, sym)
|
||||
if sym.loc.r == nil: sym.loc.r = toRope(sym.name.s)
|
||||
|
||||
proc hasPragma*(n: PNode, pragma: TSpecialWord): bool =
|
||||
if n == nil or n.sons == nil:
|
||||
return false
|
||||
|
||||
for p in n.sons:
|
||||
var key = if p.kind == nkExprColonExpr: p[0] else: p
|
||||
if key.kind == nkIdent and whichKeyword(key.ident) == pragma:
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
proc pragma(c: PContext, sym: PSym, n: PNode, validPragmas: TSpecialWords) =
|
||||
if n == nil: return
|
||||
for i in countup(0, sonsLen(n) - 1):
|
||||
|
||||
@@ -64,7 +64,7 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
|
||||
errors[errors.len - 1].add("\n " & err)
|
||||
if z.state == csMatch:
|
||||
# little hack so that iterators are preferred over everything else:
|
||||
if sym.kind == skIterator: inc(z.exactMatches, 200)
|
||||
if sym.kind in skIterators: inc(z.exactMatches, 200)
|
||||
case best.state
|
||||
of csEmpty, csNoMatch: best = z
|
||||
of csMatch:
|
||||
@@ -289,8 +289,9 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
|
||||
result = newNodeI(a.kind, n.info)
|
||||
for i in countup(0, len(a)-1):
|
||||
var candidate = a.sons[i].sym
|
||||
if candidate.kind in {skProc, skMethod, skConverter, skIterator}:
|
||||
# if suffices that the candidate has the proper number of generic
|
||||
if candidate.kind in {skProc, skMethod, skConverter,
|
||||
skIterator, skClosureIterator}:
|
||||
# it suffices that the candidate has the proper number of generic
|
||||
# type parameters:
|
||||
if safeLen(candidate.ast.sons[genericParamsPos]) == n.len-1:
|
||||
result.add(explicitGenericSym(c, n, candidate))
|
||||
|
||||
@@ -274,7 +274,7 @@ proc makeRangeType*(c: PContext; first, last: BiggestInt;
|
||||
addSonSkipIntLit(result, intType) # basetype of range
|
||||
|
||||
proc markIndirect*(c: PContext, s: PSym) {.inline.} =
|
||||
if s.kind in {skProc, skConverter, skMethod, skIterator}:
|
||||
if s.kind in {skProc, skConverter, skMethod, skIterator, skClosureIterator}:
|
||||
incl(s.flags, sfAddrTaken)
|
||||
# XXX add to 'c' for global analysis
|
||||
|
||||
|
||||
@@ -662,11 +662,11 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||
flags: TExprFlags): PNode =
|
||||
if flags*{efInTypeof, efWantIterator} != {}:
|
||||
# consider: 'for x in pReturningArray()' --> we don't want the restriction
|
||||
# to 'skIterator' anymore; skIterator is preferred in sigmatch already for
|
||||
# typeof support.
|
||||
# to 'skIterators' anymore; skIterators are preferred in sigmatch already
|
||||
# for typeof support.
|
||||
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
|
||||
result = semOverloadedCall(c, n, nOrig,
|
||||
{skProc, skMethod, skConverter, skMacro, skTemplate, skIterator})
|
||||
{skProc, skMethod, skConverter, skMacro, skTemplate}+skIterators)
|
||||
else:
|
||||
result = semOverloadedCall(c, n, nOrig,
|
||||
{skProc, skMethod, skConverter, skMacro, skTemplate})
|
||||
@@ -679,7 +679,7 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
|
||||
case callee.kind
|
||||
of skMacro, skTemplate: discard
|
||||
else:
|
||||
if (callee.kind == skIterator) and (callee.id == c.p.owner.id):
|
||||
if (callee.kind in skIterators) and (callee.id == c.p.owner.id):
|
||||
localError(n.info, errRecursiveDependencyX, callee.name.s)
|
||||
if sfNoSideEffect notin callee.flags:
|
||||
if {sfImportc, sfSideEffect} * callee.flags != {}:
|
||||
@@ -1193,7 +1193,7 @@ proc semReturn(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkSonsLen(n, 1)
|
||||
if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro} or
|
||||
(c.p.owner.kind == skIterator and c.p.owner.typ.callConv == ccClosure):
|
||||
c.p.owner.kind == skClosureIterator:
|
||||
if n.sons[0].kind != nkEmpty:
|
||||
# transform ``return expr`` to ``result = expr; return``
|
||||
if c.p.resultSym != nil:
|
||||
@@ -1258,7 +1258,7 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
|
||||
proc semYield(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
checkSonsLen(n, 1)
|
||||
if c.p.owner == nil or c.p.owner.kind != skIterator:
|
||||
if c.p.owner == nil or c.p.owner.kind notin skIterators:
|
||||
localError(n.info, errYieldNotAllowedHere)
|
||||
elif c.p.inTryStmt > 0 and c.p.owner.typ.callConv != ccInline:
|
||||
localError(n.info, errYieldNotAllowedInTryStmt)
|
||||
@@ -1266,9 +1266,11 @@ proc semYield(c: PContext, n: PNode): PNode =
|
||||
n.sons[0] = semExprWithType(c, n.sons[0]) # check for type compatibility:
|
||||
var restype = c.p.owner.typ.sons[0]
|
||||
if restype != nil:
|
||||
n.sons[0] = fitNode(c, restype.base, n.sons[0])
|
||||
let adjustedRes = if c.p.owner.kind == skIterator: restype.base
|
||||
else: restype
|
||||
n.sons[0] = fitNode(c, adjustedRes, n.sons[0])
|
||||
if n.sons[0].typ == nil: internalError(n.info, "semYield")
|
||||
semYieldVarResult(c, n, restype)
|
||||
semYieldVarResult(c, n, adjustedRes)
|
||||
else:
|
||||
localError(n.info, errCannotReturnExpr)
|
||||
elif c.p.owner.typ.sons[0] != nil:
|
||||
@@ -1828,7 +1830,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
var s = lookUp(c, n)
|
||||
semCaptureSym(s, c.p.owner)
|
||||
result = semSym(c, n, s, flags)
|
||||
if s.kind in {skProc, skMethod, skIterator, skConverter}:
|
||||
if s.kind in {skProc, skMethod, skConverter}+skIterators:
|
||||
#performProcvarCheck(c, n, s)
|
||||
result = symChoice(c, n, s, scClosed)
|
||||
if result.kind == nkSym:
|
||||
@@ -1918,7 +1920,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
localError(n.info, errUseQualifier, s.name.s)
|
||||
elif s.magic == mNone: result = semDirectOp(c, n, flags)
|
||||
else: result = semMagic(c, n, s, flags)
|
||||
of skProc, skMethod, skConverter, skIterator:
|
||||
of skProc, skMethod, skConverter, skIterators:
|
||||
if s.magic == mNone: result = semDirectOp(c, n, flags)
|
||||
else: result = semMagic(c, n, s, flags)
|
||||
else:
|
||||
@@ -1942,7 +1944,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||
of nkBracketExpr:
|
||||
checkMinSonsLen(n, 1)
|
||||
var s = qualifiedLookUp(c, n.sons[0], {checkUndeclared})
|
||||
if s != nil and s.kind in {skProc, skMethod, skConverter, skIterator}:
|
||||
if s != nil and s.kind in {skProc, skMethod, skConverter}+skIterators:
|
||||
# type parameters: partial generic specialization
|
||||
n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s)
|
||||
result = explicitGenericInstantiation(c, n, s)
|
||||
|
||||
@@ -42,7 +42,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
|
||||
of skUnknown:
|
||||
# Introduced in this pass! Leave it as an identifier.
|
||||
result = n
|
||||
of skProc, skMethod, skIterator, skConverter:
|
||||
of skProc, skMethod, skIterators, skConverter:
|
||||
result = symChoice(c, n, s, scOpen)
|
||||
of skTemplate:
|
||||
if macroToExpand(s):
|
||||
@@ -141,7 +141,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||
# symbol lookup ...
|
||||
of skUnknown, skParam:
|
||||
# Leave it as an identifier.
|
||||
of skProc, skMethod, skIterator, skConverter:
|
||||
of skProc, skMethod, skIterators, skConverter:
|
||||
result.sons[0] = symChoice(c, n.sons[0], s, scOption)
|
||||
first = 1
|
||||
of skGenericParam:
|
||||
|
||||
@@ -76,8 +76,8 @@ proc performProcvarCheck(c: PContext, n: PNode, s: PSym) =
|
||||
|
||||
proc semProcvarCheck(c: PContext, n: PNode) =
|
||||
let n = n.skipConv
|
||||
if n.kind == nkSym and n.sym.kind in {skProc, skMethod, skIterator,
|
||||
skConverter}:
|
||||
if n.kind == nkSym and n.sym.kind in {skProc, skMethod, skConverter,
|
||||
skIterator, skClosureIterator}:
|
||||
performProcvarCheck(c, n, n.sym)
|
||||
|
||||
proc semProc(c: PContext, n: PNode): PNode
|
||||
@@ -665,7 +665,7 @@ proc semFor(c: PContext, n: PNode): PNode =
|
||||
# first class iterator:
|
||||
result = semForVars(c, n)
|
||||
elif call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
|
||||
call.sons[0].sym.kind != skIterator:
|
||||
call.sons[0].sym.kind notin skIterators:
|
||||
if length == 3:
|
||||
n.sons[length-2] = implicitIterator(c, "items", n.sons[length-2])
|
||||
elif length == 4:
|
||||
@@ -998,8 +998,7 @@ proc activate(c: PContext, n: PNode) =
|
||||
discard
|
||||
|
||||
proc maybeAddResult(c: PContext, s: PSym, n: PNode) =
|
||||
if s.typ.sons[0] != nil and
|
||||
(s.kind != skIterator or s.typ.callConv == ccClosure):
|
||||
if s.typ.sons[0] != nil and s.kind != skIterator:
|
||||
addResult(c, s.typ.sons[0], n.info, s.kind)
|
||||
addResultNode(c, n)
|
||||
|
||||
@@ -1074,12 +1073,12 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
rawAddSon(s.typ, nil)
|
||||
if n.sons[patternPos].kind != nkEmpty:
|
||||
n.sons[patternPos] = semPattern(c, n.sons[patternPos])
|
||||
if s.kind == skIterator:
|
||||
if s.kind in skIterators:
|
||||
s.typ.flags.incl(tfIterator)
|
||||
|
||||
var proto = searchForProc(c, s.scope, s)
|
||||
if proto == nil:
|
||||
if s.kind == skIterator and isAnon: s.typ.callConv = ccClosure
|
||||
if proto == nil:
|
||||
if s.kind == skClosureIterator: s.typ.callConv = ccClosure
|
||||
else: s.typ.callConv = lastOptionEntry(c).defaultCC
|
||||
# add it here, so that recursive procs are possible:
|
||||
if sfGenSym in s.flags: discard
|
||||
@@ -1139,7 +1138,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
||||
n.sons[bodyPos] = transformBody(c.module, semBody, s)
|
||||
popProcCon(c)
|
||||
else:
|
||||
if s.typ.sons[0] != nil and kind != skIterator:
|
||||
if s.typ.sons[0] != nil and kind notin skIterators:
|
||||
addDecl(c, newSym(skUnknown, getIdent"result", nil, n.info))
|
||||
var toBind = initIntSet()
|
||||
n.sons[bodyPos] = semGenericStmtScope(c, n.sons[bodyPos], {}, toBind)
|
||||
@@ -1166,7 +1165,10 @@ proc determineType(c: PContext, s: PSym) =
|
||||
discard semProcAux(c, s.ast, s.kind, {}, stepDetermineType)
|
||||
|
||||
proc semIterator(c: PContext, n: PNode): PNode =
|
||||
result = semProcAux(c, n, skIterator, iteratorPragmas)
|
||||
let kind = if hasPragma(n[pragmasPos], wClosure) or
|
||||
n[namePos].kind == nkEmpty: skClosureIterator
|
||||
else: skIterator
|
||||
result = semProcAux(c, n, kind, iteratorPragmas)
|
||||
var s = result.sons[namePos].sym
|
||||
var t = s.typ
|
||||
if t.sons[0] == nil and s.typ.callConv != ccClosure:
|
||||
|
||||
@@ -171,7 +171,7 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym): PNode =
|
||||
of skUnknown:
|
||||
# Introduced in this pass! Leave it as an identifier.
|
||||
result = n
|
||||
of skProc, skMethod, skIterator, skConverter, skTemplate, skMacro:
|
||||
of OverloadableSyms:
|
||||
result = symChoice(c, n, s, scOpen)
|
||||
of skGenericParam:
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
@@ -348,7 +348,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||
of nkMethodDef:
|
||||
result = semRoutineInTemplBody(c, n, skMethod)
|
||||
of nkIteratorDef:
|
||||
result = semRoutineInTemplBody(c, n, skIterator)
|
||||
result = semRoutineInTemplBody(c, n, n[namePos].sym.kind)
|
||||
of nkTemplateDef:
|
||||
result = semRoutineInTemplBody(c, n, skTemplate)
|
||||
of nkMacroDef:
|
||||
|
||||
@@ -953,6 +953,23 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
||||
let typ = semTypeNode(c, n, nil)
|
||||
result.sons.safeAdd(typ)
|
||||
|
||||
proc semProcTypeWithScope(c: PContext, n: PNode,
|
||||
prev: PType, kind: TSymKind): PType =
|
||||
checkSonsLen(n, 2)
|
||||
openScope(c)
|
||||
result = semProcTypeNode(c, n.sons[0], nil, prev, kind)
|
||||
# dummy symbol for `pragma`:
|
||||
var s = newSymS(kind, newIdentNode(getIdent("dummy"), n.info), c)
|
||||
s.typ = result
|
||||
if n.sons[1].kind == nkEmpty or n.sons[1].len == 0:
|
||||
if result.callConv == ccDefault:
|
||||
result.callConv = ccClosure
|
||||
#Message(n.info, warnImplicitClosure, renderTree(n))
|
||||
else:
|
||||
pragma(c, s, n.sons[1], procTypePragmas)
|
||||
when useEffectSystem: setEffectsForProcType(result, n.sons[1])
|
||||
closeScope(c)
|
||||
|
||||
proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
result = nil
|
||||
if gCmd == cmdIdeTools: suggestExpr(c, n)
|
||||
@@ -1075,27 +1092,18 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||
var base = semTypeNode(c, n.sons[0], nil)
|
||||
result.rawAddSon(base)
|
||||
result.flags.incl tfHasStatic
|
||||
of nkProcTy, nkIteratorTy:
|
||||
of nkIteratorTy:
|
||||
if n.sonsLen == 0:
|
||||
result = newConstraint(c, tyIter)
|
||||
else:
|
||||
result = semProcTypeWithScope(c, n, prev, skClosureIterator)
|
||||
result.flags.incl(tfIterator)
|
||||
result.callConv = ccClosure
|
||||
of nkProcTy:
|
||||
if n.sonsLen == 0:
|
||||
result = newConstraint(c, tyProc)
|
||||
else:
|
||||
checkSonsLen(n, 2)
|
||||
openScope(c)
|
||||
result = semProcTypeNode(c, n.sons[0], nil, prev, skProc)
|
||||
# dummy symbol for `pragma`:
|
||||
var s = newSymS(skProc, newIdentNode(getIdent("dummy"), n.info), c)
|
||||
s.typ = result
|
||||
if n.sons[1].kind == nkEmpty or n.sons[1].len == 0:
|
||||
if result.callConv == ccDefault:
|
||||
result.callConv = ccClosure
|
||||
#Message(n.info, warnImplicitClosure, renderTree(n))
|
||||
else:
|
||||
pragma(c, s, n.sons[1], procTypePragmas)
|
||||
when useEffectSystem: setEffectsForProcType(result, n.sons[1])
|
||||
closeScope(c)
|
||||
if n.kind == nkIteratorTy:
|
||||
result.flags.incl(tfIterator)
|
||||
result.callConv = ccClosure
|
||||
result = semProcTypeWithScope(c, n, prev, skProc)
|
||||
of nkEnumTy: result = semEnum(c, n, prev)
|
||||
of nkType: result = n.typ
|
||||
of nkStmtListType: result = semStmtListType(c, n, prev)
|
||||
|
||||
@@ -1142,7 +1142,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType,
|
||||
z.calleeSym = m.calleeSym
|
||||
var best = -1
|
||||
for i in countup(0, sonsLen(arg) - 1):
|
||||
if arg.sons[i].sym.kind in {skProc, skIterator, skMethod, skConverter}:
|
||||
if arg.sons[i].sym.kind in {skProc, skMethod, skConverter}+skIterators:
|
||||
copyCandidate(z, m)
|
||||
var r = typeRel(z, f, arg.sons[i].typ)
|
||||
if r != isNone:
|
||||
|
||||
@@ -113,7 +113,7 @@ proc newAsgnStmt(c: PTransf, le: PNode, ri: PTransNode): PTransNode =
|
||||
result[1] = ri
|
||||
|
||||
proc transformSymAux(c: PTransf, n: PNode): PNode =
|
||||
#if n.sym.kind == skIterator and n.sym.typ.callConv == ccClosure:
|
||||
#if n.sym.kind == skClosureIterator:
|
||||
# return liftIterSym(n)
|
||||
var b: PNode
|
||||
var tc = c.transCon
|
||||
@@ -434,7 +434,6 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||
var length = sonsLen(n)
|
||||
var call = n.sons[length - 2]
|
||||
if call.kind notin nkCallKinds or call.sons[0].kind != nkSym or
|
||||
call.sons[0].typ.callConv == ccClosure or
|
||||
call.sons[0].sym.kind != skIterator:
|
||||
n.sons[length-1] = transformLoopBody(c, n.sons[length-1]).PNode
|
||||
return lambdalifting.liftForLoop(n).PTransNode
|
||||
@@ -454,7 +453,7 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
|
||||
var newC = newTransCon(getCurrOwner(c))
|
||||
newC.forStmt = n
|
||||
newC.forLoopBody = loopBody
|
||||
if iter.kind != skIterator: internalError(call.info, "transformFor")
|
||||
internalAssert iter.kind == skIterator
|
||||
# generate access statements for the parameters (unless they are constant)
|
||||
pushTransCon(c, newC)
|
||||
for i in countup(1, sonsLen(call) - 1):
|
||||
@@ -741,7 +740,7 @@ proc transformBody*(module: PSym, n: PNode, prc: PSym): PNode =
|
||||
var c = openTransf(module, "")
|
||||
result = processTransf(c, n, prc)
|
||||
result = liftLambdas(prc, result)
|
||||
#if prc.kind == skIterator and prc.typ.callConv == ccClosure:
|
||||
#if prc.kind == skClosureIterator:
|
||||
# result = lambdalifting.liftIterator(prc, result)
|
||||
incl(result.flags, nfTransf)
|
||||
when useEffectSystem: trackProc(prc, result)
|
||||
|
||||
@@ -1247,7 +1247,7 @@ proc computeSize(typ: PType): BiggestInt =
|
||||
|
||||
proc getReturnType*(s: PSym): PType =
|
||||
# Obtains the return type of a iterator/proc/macro/template
|
||||
assert s.kind in {skProc, skTemplate, skMacro, skIterator}
|
||||
assert s.kind in skProcKinds
|
||||
result = s.typ.sons[0]
|
||||
|
||||
proc getSize(typ: PType): BiggestInt =
|
||||
|
||||
@@ -1311,7 +1311,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags = {}) =
|
||||
case s.kind
|
||||
of skVar, skForVar, skTemp, skLet, skParam, skResult:
|
||||
genRdVar(c, n, dest, flags)
|
||||
of skProc, skConverter, skMacro, skTemplate, skMethod, skIterator:
|
||||
of skProc, skConverter, skMacro, skTemplate, skMethod, skIterators:
|
||||
# 'skTemplate' is only allowed for 'getAst' support:
|
||||
if sfImportc in s.flags: c.importcSym(n.info, s)
|
||||
genLit(c, n, dest)
|
||||
|
||||
@@ -279,8 +279,8 @@ skForVar
|
||||
col 7: ""
|
||||
|
||||
|
||||
skIterator
|
||||
----------
|
||||
skIterator, skClosureIterator
|
||||
-----------------------------
|
||||
|
||||
The fourth column will be the empty string if the iterator is being
|
||||
defined, since at that point in the file the parser hasn't processed
|
||||
|
||||
@@ -88,7 +88,7 @@ type
|
||||
nskUnknown, nskConditional, nskDynLib, nskParam,
|
||||
nskGenericParam, nskTemp, nskModule, nskType, nskVar, nskLet,
|
||||
nskConst, nskResult,
|
||||
nskProc, nskMethod, nskIterator,
|
||||
nskProc, nskMethod, nskIterator, nskClosureIterator,
|
||||
nskConverter, nskMacro, nskTemplate, nskField,
|
||||
nskEnumField, nskForVar, nskLabel,
|
||||
nskStub
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
discard """
|
||||
line: 10
|
||||
errormsg: "value returned by statement has to be discarded"
|
||||
errormsg: "value of type 'string' has to be discarded"
|
||||
"""
|
||||
|
||||
# bug #578
|
||||
|
||||
@@ -8,7 +8,7 @@ discard """
|
||||
"""
|
||||
|
||||
proc factory(a, b: int): iterator (): int =
|
||||
iterator foo(): int =
|
||||
iterator foo(): int {.closure.} =
|
||||
var x = a
|
||||
while x <= b:
|
||||
yield x
|
||||
|
||||
Reference in New Issue
Block a user