improvements for first class iterators
This commit is contained in:
parent
e4211230e8
commit
1fada12a5f
3 changed files with 35 additions and 6 deletions
|
|
@ -115,6 +115,11 @@ proc genGotoState(p: BProc, n: PNode) =
|
||||||
proc genBreakState(p: BProc, n: PNode) =
|
proc genBreakState(p: BProc, n: PNode) =
|
||||||
var a: TLoc
|
var a: TLoc
|
||||||
initLocExpr(p, n.sons[0], a)
|
initLocExpr(p, n.sons[0], a)
|
||||||
|
if n.sons[0].kind == nkClosure:
|
||||||
|
# XXX this produces quite inefficient code!
|
||||||
|
# the environment is guaranteed to contain the 'state' field at offset 0:
|
||||||
|
lineF(p, cpsStmts, "if ((((NI*) $1.ClEnv)[0]) < 0) break;$n", [rdLoc(a)])
|
||||||
|
else:
|
||||||
lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)])
|
lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)])
|
||||||
|
|
||||||
proc genSingleVar(p: BProc, a: PNode) =
|
proc genSingleVar(p: BProc, a: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -693,7 +693,7 @@ proc liftIterator*(iter: PSym, body: PNode): PNode =
|
||||||
result.add(stateAsgnStmt)
|
result.add(stateAsgnStmt)
|
||||||
|
|
||||||
proc liftForLoop*(body: PNode): PNode =
|
proc liftForLoop*(body: PNode): PNode =
|
||||||
# BIG problem ahead: the iterator could be invoked indirectly, but then
|
# problem ahead: the iterator could be invoked indirectly, but then
|
||||||
# we don't know what environment to create here:
|
# we don't know what environment to create here:
|
||||||
#
|
#
|
||||||
# iterator count(): int =
|
# iterator count(): int =
|
||||||
|
|
@ -750,7 +750,10 @@ proc liftForLoop*(body: PNode): PNode =
|
||||||
# gather vars in a tuple:
|
# gather vars in a tuple:
|
||||||
var v2 = newNodeI(nkLetSection, body.info)
|
var v2 = newNodeI(nkLetSection, body.info)
|
||||||
var vpart = newNodeI(if L == 3: nkIdentDefs else: nkVarTuple, body.info)
|
var vpart = newNodeI(if L == 3: nkIdentDefs else: nkVarTuple, body.info)
|
||||||
for i in 0 .. L-3: addSon(vpart, body[i])
|
for i in 0 .. L-3:
|
||||||
|
assert body[i].kind == nkSym
|
||||||
|
body[i].sym.kind = skLet
|
||||||
|
addSon(vpart, body[i])
|
||||||
|
|
||||||
addSon(vpart, ast.emptyNode) # no explicit type
|
addSon(vpart, ast.emptyNode) # no explicit type
|
||||||
if not env.isnil:
|
if not env.isnil:
|
||||||
|
|
@ -760,7 +763,10 @@ proc liftForLoop*(body: PNode): PNode =
|
||||||
|
|
||||||
loopBody.sons[0] = v2
|
loopBody.sons[0] = v2
|
||||||
var bs = newNodeI(nkBreakState, body.info)
|
var bs = newNodeI(nkBreakState, body.info)
|
||||||
|
if not env.isNil:
|
||||||
bs.addSon(indirectAccess(env,
|
bs.addSon(indirectAccess(env,
|
||||||
newSym(skField, getIdent(":state"), env, env.info), body.info))
|
newSym(skField, getIdent":state", env, env.info), body.info))
|
||||||
|
else:
|
||||||
|
bs.addSon(call.sons[0])
|
||||||
loopBody.sons[1] = bs
|
loopBody.sons[1] = bs
|
||||||
loopBody.sons[2] = body[L-1]
|
loopBody.sons[2] = body[L-1]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''tada
|
output: '''tada
|
||||||
ta da'''
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
ta da1
|
||||||
|
2
|
||||||
|
3'''
|
||||||
"""
|
"""
|
||||||
# Test first class iterator:
|
# Test first class iterator:
|
||||||
|
|
||||||
|
|
@ -21,13 +26,26 @@ iterator tokenize2(s: string, seps: set[char] = Whitespace): tuple[
|
||||||
yield (substr(s, i, j-1), false)
|
yield (substr(s, i, j-1), false)
|
||||||
i = j
|
i = j
|
||||||
|
|
||||||
|
iterator count3(): int {.closure.} =
|
||||||
|
yield 1
|
||||||
|
yield 2
|
||||||
|
yield 3
|
||||||
|
|
||||||
for word, isSep in tokenize2("ta da", whiteSpace):
|
for word, isSep in tokenize2("ta da", whiteSpace):
|
||||||
if not isSep:
|
if not isSep:
|
||||||
stdout.write(word)
|
stdout.write(word)
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
proc inProc() =
|
proc inProc() =
|
||||||
|
for c in count3():
|
||||||
|
echo c
|
||||||
|
|
||||||
for word, isSep in tokenize2("ta da", whiteSpace):
|
for word, isSep in tokenize2("ta da", whiteSpace):
|
||||||
stdout.write(word)
|
stdout.write(word)
|
||||||
|
|
||||||
|
for c in count3():
|
||||||
|
echo c
|
||||||
|
|
||||||
|
|
||||||
inProc()
|
inProc()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue