mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 22:10:33 +00:00
added system.finished for first class iterators
This commit is contained in:
@@ -344,7 +344,7 @@ type
|
||||
nfSem # node has been checked for semantics
|
||||
|
||||
TNodeFlags* = set[TNodeFlag]
|
||||
TTypeFlag* = enum # keep below 15 for efficiency reasons (now: 14)
|
||||
TTypeFlag* = enum # keep below 17 for efficiency reasons (now: 16)
|
||||
tfVarargs, # procedure has C styled varargs
|
||||
tfNoSideEffect, # procedure type does not allow side effects
|
||||
tfFinal, # is the object final?
|
||||
|
||||
@@ -692,13 +692,6 @@ proc liftIterator*(iter: PSym, body: PNode): PNode =
|
||||
stateAsgnStmt.add(newIntTypeNode(nkIntLit, -1, getSysType(tyInt)))
|
||||
result.add(stateAsgnStmt)
|
||||
|
||||
# TODO:
|
||||
# - nested iterators
|
||||
# - arglist as a type
|
||||
# - tyIterator everywhere
|
||||
# - 'finished' builtin
|
||||
# - 'start' builtin (XXX copy Lua's terminology?)
|
||||
|
||||
proc liftIterSym*(n: PNode): PNode =
|
||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
|
||||
|
||||
@@ -1473,7 +1473,7 @@ proc simpleStmt(p: var TParser): PNode =
|
||||
case p.tok.tokType
|
||||
of tkReturn: result = parseReturnOrRaise(p, nkReturnStmt)
|
||||
of tkRaise: result = parseReturnOrRaise(p, nkRaiseStmt)
|
||||
of tkYield: result = parseYieldOrDiscard(p, nkYieldStmt)
|
||||
of tkYield: result = parseReturnOrRaise(p, nkYieldStmt)
|
||||
of tkDiscard: result = parseReturnOrRaise(p, nkDiscardStmt)
|
||||
of tkBreak: result = parseBreakOrContinue(p, nkBreakStmt)
|
||||
of tkContinue: result = parseBreakOrContinue(p, nkContinueStmt)
|
||||
|
||||
@@ -1173,6 +1173,8 @@ proc SemYield(c: PContext, n: PNode): PNode =
|
||||
SemYieldVarResult(c, n, restype)
|
||||
else:
|
||||
localError(n.info, errCannotReturnExpr)
|
||||
elif c.p.owner.typ.sons[0] != nil:
|
||||
localError(n.info, errGenerated, "yield statement must yield a value")
|
||||
|
||||
proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym =
|
||||
if onlyCurrentScope:
|
||||
|
||||
@@ -818,7 +818,7 @@ proc semIterator(c: PContext, n: PNode): PNode =
|
||||
result = semProcAux(c, n, skIterator, iteratorPragmas)
|
||||
var s = result.sons[namePos].sym
|
||||
var t = s.typ
|
||||
if t.sons[0] == nil:
|
||||
if t.sons[0] == nil and s.typ.callConv != ccClosure:
|
||||
LocalError(n.info, errXNeedsReturnType, "iterator")
|
||||
# iterators are either 'inline' or 'closure'; for backwards compatibility,
|
||||
# we require first class iterators to be marked with 'closure' explicitly
|
||||
|
||||
@@ -2096,6 +2096,12 @@ when not defined(EcmaScript) and not defined(NimrodVM):
|
||||
`result` = `x`.ClEnv;
|
||||
""".}
|
||||
|
||||
proc finished*[T: proc](x: T): bool {.noSideEffect, inline.} =
|
||||
## can be used to determine if a first class iterator has finished.
|
||||
{.emit: """
|
||||
`result` = *((NI*) `x`.ClEnv) < 0;
|
||||
""".}
|
||||
|
||||
elif defined(ecmaScript) or defined(NimrodVM):
|
||||
# Stubs:
|
||||
proc GC_disable() = nil
|
||||
|
||||
@@ -14,7 +14,14 @@ ta da1 1
|
||||
3 3
|
||||
0
|
||||
1
|
||||
2'''
|
||||
2
|
||||
a1: A
|
||||
a2: A
|
||||
a1: B
|
||||
a2: B
|
||||
a1: C
|
||||
a2: C
|
||||
a1: D'''
|
||||
"""
|
||||
# Test first class iterator:
|
||||
|
||||
@@ -77,3 +84,34 @@ proc invoke(iter: proc(): int {.closure.}) =
|
||||
|
||||
invoke(count0)
|
||||
invoke(count2)
|
||||
|
||||
|
||||
# simple tasking:
|
||||
type
|
||||
TTask = proc (ticker: int) {.closure.}
|
||||
|
||||
iterator a1(ticker: int) {.closure.} =
|
||||
echo "a1: A"
|
||||
yield
|
||||
echo "a1: B"
|
||||
yield
|
||||
echo "a1: C"
|
||||
yield
|
||||
echo "a1: D"
|
||||
|
||||
iterator a2(ticker: int) {.closure.} =
|
||||
echo "a2: A"
|
||||
yield
|
||||
echo "a2: B"
|
||||
yield
|
||||
echo "a2: C"
|
||||
|
||||
proc runTasks(t: varargs[TTask]) =
|
||||
var ticker = 0
|
||||
while true:
|
||||
let x = t[ticker mod t.len]
|
||||
if finished(x): break
|
||||
x(ticker)
|
||||
inc ticker
|
||||
|
||||
runTasks(a1, a2)
|
||||
|
||||
6
todo.txt
6
todo.txt
@@ -1,7 +1,11 @@
|
||||
version 0.9.2
|
||||
=============
|
||||
|
||||
- test&finish first class iterators
|
||||
- test&finish first class iterators:
|
||||
* nested iterators
|
||||
* arglist as a type?
|
||||
* tyIterator?
|
||||
|
||||
- fix closure bug finally
|
||||
- overloading based on ASTs: 'constraint' should not be in PType but for the
|
||||
parameter *symbol*
|
||||
|
||||
Reference in New Issue
Block a user