diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2020-07-17 15:24:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-17 15:24:36 +0200 |
commit | d4984e069adc1984c2f67d073ebb7c42873c4d08 (patch) | |
tree | fec769ace2500b0caa458816c8098ed287eb52d6 /compiler | |
parent | c2f80de1c74c673ab9d3459d1f86fb9fe4366f61 (diff) | |
download | Nim-d4984e069adc1984c2f67d073ebb7c42873c4d08.tar.gz |
arc: cursors for simple for loop variables (#15008)
* arc: cursors for simple for loop variables * merged devel
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/injectdestructors.nim | 2 | ||||
-rw-r--r-- | compiler/transf.nim | 24 |
2 files changed, 23 insertions, 3 deletions
diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 99eefca57..752438180 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -1062,5 +1062,5 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode = if g.config.arcToExpand.hasKey(owner.name.s): echo "--expandArc: ", owner.name.s - echo renderTree(result, {renderIr}) + echo renderTree(result, {renderIr, renderNoComments}) echo "-- end of expandArc ------------------------" diff --git a/compiler/transf.nim b/compiler/transf.nim index be559abb8..7aa18bf52 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -350,7 +350,7 @@ proc transformYield(c: PTransf, n: PNode): PNode = # Choose the right assignment instruction according to the given ``lhs`` # node since it may not be a nkSym (a stack-allocated skForVar) but a # nkDotExpr (a heap-allocated slot into the envP block) - case lhs.kind: + case lhs.kind of nkSym: internalAssert c.graph.config, lhs.sym.kind == skForVar result = newAsgnStmt(c, nkFastAsgn, lhs, rhs) @@ -592,6 +592,22 @@ proc findWrongOwners(c: PTransf, n: PNode) = else: for i in 0..<n.safeLen: findWrongOwners(c, n[i]) +proc isSimpleIteratorVar(iter: PSym): bool = + proc rec(n: PNode; owner: PSym; dangerousYields: var int) = + case n.kind + of nkEmpty..nkNilLit: discard + of nkYieldStmt: + if n[0].kind == nkSym and n[0].sym.owner == owner: + discard "good: yield a single variable that we own" + else: + inc dangerousYields + else: + for c in n: rec(c, owner, dangerousYields) + + var dangerousYields = 0 + rec(iter.ast[bodyPos], iter, dangerousYields) + result = dangerousYields == 0 + proc transformFor(c: PTransf, n: PNode): PNode = # generate access statements for the parameters (unless they are constant) # put mapping from formal parameters to actual parameters @@ -624,18 +640,22 @@ proc transformFor(c: PTransf, n: PNode): PNode = discard c.breakSyms.pop + let iter = call[0].sym + var v = newNodeI(nkVarSection, n.info) for i in 0..<n.len - 2: if n[i].kind == nkVarTuple: for j in 0..<n[i].len-1: addVar(v, copyTree(n[i][j])) # declare new vars else: + if n[i].kind == nkSym and isSimpleIteratorVar(iter): + incl n[i].sym.flags, sfCursor addVar(v, copyTree(n[i])) # declare new vars stmtList.add(v) + # Bugfix: inlined locals belong to the invoking routine, not to the invoked # iterator! - let iter = call[0].sym var newC = newTransCon(getCurrOwner(c)) newC.forStmt = n newC.forLoopBody = loopBody |