diff options
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ccgstmts.nim | 7 | ||||
-rw-r--r-- | compiler/lambdalifting.nim | 14 |
2 files changed, 16 insertions, 5 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 9c9b61088..5e3504cd9 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -115,7 +115,12 @@ proc genGotoState(p: BProc, n: PNode) = proc genBreakState(p: BProc, n: PNode) = var a: TLoc initLocExpr(p, n.sons[0], a) - lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(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)]) proc genSingleVar(p: BProc, a: PNode) = var v = a.sons[0].sym diff --git a/compiler/lambdalifting.nim b/compiler/lambdalifting.nim index ada14edf2..9d7e0e961 100644 --- a/compiler/lambdalifting.nim +++ b/compiler/lambdalifting.nim @@ -693,7 +693,7 @@ proc liftIterator*(iter: PSym, body: PNode): PNode = result.add(stateAsgnStmt) 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: # # iterator count(): int = @@ -750,7 +750,10 @@ proc liftForLoop*(body: PNode): PNode = # gather vars in a tuple: var v2 = newNodeI(nkLetSection, 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 if not env.isnil: @@ -760,7 +763,10 @@ proc liftForLoop*(body: PNode): PNode = loopBody.sons[0] = v2 var bs = newNodeI(nkBreakState, body.info) - bs.addSon(indirectAccess(env, - newSym(skField, getIdent(":state"), env, env.info), body.info)) + if not env.isNil: + bs.addSon(indirectAccess(env, + newSym(skField, getIdent":state", env, env.info), body.info)) + else: + bs.addSon(call.sons[0]) loopBody.sons[1] = bs loopBody.sons[2] = body[L-1] |