iterators now return tyIter(T);

tyIter(T) represents an "iteration yielding values of type T"

I'm planning to use that in the context of the `is` operator
supporting predicates such as `C.items is iterator` and also
in the upcoming support for higher-order inline iterators.
This commit is contained in:
Zahary Karadjov
2014-03-05 01:14:37 +02:00
parent 016492375f
commit 5324c9ebba
6 changed files with 18 additions and 11 deletions

View File

@@ -1192,7 +1192,7 @@ proc nullify[T](arr: var T) =
for i in low(arr)..high(arr):
arr[i] = nil
proc resetModule*(m: var BModule) =
proc resetModule*(m: BModule) =
# between two compilations in CAAS mode, we can throw
# away all the data that was written to disk
initLinkedList(m.headerFiles)

View File

@@ -146,7 +146,7 @@ proc newProc*(prc: PSym, module: BModule): BProc =
result.nestedTryStmts = @[]
result.finallySafePoints = @[]
iterator cgenModules*: var BModule =
iterator cgenModules*: BModule =
for i in 0..high(gModules):
# ultimately, we are iterating over the file ids here.
# some "files" won't have an associated cgen module (like stdin)

View File

@@ -1266,7 +1266,7 @@ 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, n.sons[0])
n.sons[0] = fitNode(c, restype.base, n.sons[0])
if n.sons[0].typ == nil: internalError(n.info, "semYield")
semYieldVarResult(c, n, restype)
else:
@@ -1884,7 +1884,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
message(n.info, warnDeprecated, "bind")
result = semExpr(c, n.sons[0], flags)
of nkTypeOfExpr, nkTupleTy, nkRefTy..nkEnumTy, nkStaticTy:
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc})
var typ = semTypeNode(c, n, nil).skipTypes({tyTypeDesc, tyIter})
result.typ = makeTypeDesc(c, typ)
#result = symNodeFromType(c, typ, n.info)
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit:

View File

@@ -616,7 +616,8 @@ proc symForVar(c: PContext, n: PNode): PSym =
proc semForVars(c: PContext, n: PNode): PNode =
result = n
var length = sonsLen(n)
var iter = skipTypes(n.sons[length-2].typ, {tyGenericInst})
let iterBase = n.sons[length-2].typ.skipTypes({tyIter})
var iter = skipTypes(iterBase, {tyGenericInst})
# length == 3 means that there is one for loop variable
# and thus no tuple unpacking:
if iter.kind != tyTuple or length == 3:
@@ -626,7 +627,7 @@ proc semForVars(c: PContext, n: PNode): PNode =
# BUGFIX: don't use `iter` here as that would strip away
# the ``tyGenericInst``! See ``tests/compile/tgeneric.nim``
# for an example:
v.typ = n.sons[length-2].typ
v.typ = iterBase
n.sons[0] = newSymNode(v)
if sfGenSym notin v.flags: addForVarDecl(c, v)
else:

View File

@@ -845,8 +845,10 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
n.sons[0].info)
if lifted != nil: r = lifted
r.flags.incl tfRetType
result.sons[0] = skipIntLit(r)
res.typ = result.sons[0]
r = skipIntLit(r)
if kind == skIterator: r = newTypeWithSons(c, tyIter, @[r])
result.sons[0] = r
res.typ = r
proc semStmtListType(c: PContext, n: PNode, prev: PType): PType =
checkMinSonsLen(n, 1)
@@ -959,7 +961,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
of nkTypeOfExpr:
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
checkSonsLen(n, 1)
result = semExprWithType(c, n.sons[0], {efInTypeof}).typ
result = semExprWithType(c, n.sons[0], {efInTypeof}).typ.skipTypes({tyIter})
of nkPar:
if sonsLen(n) == 1: result = semTypeNode(c, n.sons[0], prev)
else:

View File

@@ -921,14 +921,18 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
result = typeRel(c, prev.base, a.base)
else:
result = isNone
of tyIter:
if a.kind == f.kind: result = typeRel(c, f.base, a.base)
else: result = isNone
of tyStmt:
result = isGeneric
of tyProxy:
result = isEqual
else: internalError("typeRel: " & $f.kind)
else: internalAssert false
proc cmpTypes*(c: PContext, f, a: PType): TTypeRelation =
var m: TCandidate