diff options
author | Araq <rumpf_a@web.de> | 2012-11-26 02:43:32 +0100 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-11-26 02:43:32 +0100 |
commit | dd9ad9e49730cec954e9113f0136053c5020aafd (patch) | |
tree | 09cce2a19da1d7688a021b3c5fd6e603656c599b | |
parent | 538699a2810017981b4cb8b6994c0da0afeb0452 (diff) | |
download | Nim-dd9ad9e49730cec954e9113f0136053c5020aafd.tar.gz |
next steps for first class iterators
-rwxr-xr-x | compiler/evals.nim | 8 | ||||
-rwxr-xr-x | compiler/parser.nim | 3 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 3 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 1 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 2 | ||||
-rw-r--r-- | tests/run/titer8.nim | 4 | ||||
-rwxr-xr-x | todo.txt | 2 |
7 files changed, 16 insertions, 7 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim index 0d960c952..20d354aaf 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -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) diff --git a/compiler/parser.nim b/compiler/parser.nim index e31f2752c..077fc52f4 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -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}) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 52d922b2d..37ffe2889 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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 diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 530e803a3..f644683f5 100755 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 03fb9a075..799622355 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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: diff --git a/tests/run/titer8.nim b/tests/run/titer8.nim index 34067c414..af0e643f1 100644 --- a/tests/run/titer8.nim +++ b/tests/run/titer8.nim @@ -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" diff --git a/todo.txt b/todo.txt index 9ee49b4f2..7d8a3809d 100755 --- a/todo.txt +++ b/todo.txt @@ -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 |