next steps for first class iterators

This commit is contained in:
Araq
2012-11-26 02:43:32 +01:00
parent 538699a281
commit dd9ad9e497
7 changed files with 16 additions and 7 deletions

View File

@@ -888,7 +888,13 @@ proc evalIsOp*(n: PNode): PNode =
of "closure":
let t = skipTypes(t1, abstractRange)
result = newIntNode(nkIntLit, ord(t.kind == tyProc and
t.callConv == ccClosure))
t.callConv == ccClosure and
tfIterator notin t.flags))
of "iterator":
let t = skipTypes(t1, abstractRange)
result = newIntNode(nkIntLit, ord(t.kind == tyProc and
t.callConv == ccClosure and
tfIterator in t.flags))
else:
let t2 = n[2].typ
var match = if t2.kind == tyTypeClass: matchTypeClass(t2, t1)

View File

@@ -738,7 +738,7 @@ proc isExprStart(p: TParser): bool =
of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf,
tkProc, tkIterator, tkBind,
tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
tkTuple, tkType, tkWhen, tkCase:
tkTuple, tkType, tkWhen, tkCase, tkShared:
result = true
else: result = false
@@ -788,6 +788,7 @@ proc primary(p: var TParser, mode: TPrimaryMode): PNode =
of tkVar: result = parseTypeDescKAux(p, nkVarTy, mode)
of tkRef: result = parseTypeDescKAux(p, nkRefTy, mode)
of tkPtr: result = parseTypeDescKAux(p, nkPtrTy, mode)
of tkShared: result = parseTypeDescKAux(p, nkSharedTy, mode)
of tkType: result = parseTypeDescKAux(p, nkTypeOfExpr, mode)
of tkTuple: result = parseTuple(p)
of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef})

View File

@@ -744,11 +744,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: s.typ.flags.incl(tfIterator)
var proto = SearchForProc(c, s, c.tab.tos-2) # -2 because we have a scope
# open for parameters
if proto == nil:
s.typ.callConv = lastOptionEntry(c).defaultCC
s.typ.callConv = lastOptionEntry(c).defaultCC
# add it here, so that recursive procs are possible:
# -2 because we have a scope open for parameters
if sfGenSym in s.flags: nil

View File

@@ -911,6 +911,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
closeScope(c.tab)
if n.kind == nkIteratorTy:
result.flags.incl(tfIterator)
result.callConv = ccClosure
of nkEnumTy: result = semEnum(c, n, prev)
of nkType: result = n.typ
of nkStmtListType: result = semStmtListType(c, n, prev)

View File

@@ -293,6 +293,8 @@ proc procTypeRel(c: var TCandidate, f, a: PType): TTypeRelation =
elif tfThread in f.flags and a.flags * {tfThread, tfNoSideEffect} == {}:
# noSideEffect implies ``tfThread``! XXX really?
return isNone
elif f.flags * {tfIterator} != a.flags * {tfIterator}:
return isNone
elif f.callconv != a.callconv:
# valid to pass a 'nimcall' thingie to 'closure':
if f.callconv == ccClosure and a.callconv == ccDefault:

View File

@@ -79,7 +79,7 @@ iterator count2(): int {.closure.} =
# a first class iterator has the type 'proc {.closure.}', but maybe
# it shouldn't:
proc invoke(iter: proc(): int {.closure.}) =
proc invoke(iter: iterator(): int {.closure.}) =
for x in iter(): echo x
invoke(count0)
@@ -88,7 +88,7 @@ invoke(count2)
# simple tasking:
type
TTask = proc (ticker: int) {.closure.}
TTask = iterator (ticker: int)
iterator a1(ticker: int) {.closure.} =
echo "a1: A"

View File

@@ -2,7 +2,6 @@ version 0.9.2
=============
- test&finish first class iterators:
* tyIterator: implement nkIteratorTy, nkSharedTy
* allow return in first class iterators
* nested iterators
* arglist as a type?
@@ -34,7 +33,6 @@ Bugs
- bug: the parser is not strict enough with newlines: 'echo "a" echo "b"'
compiles
- bug: blocks can "export" an identifier but the CCG generates {} for them ...
- bug: what if we pass an iterator to a proc var? iterators use tyProc too ...
version 0.9.XX