Tuple unpacking now works for for vars (#10152)

* Tuple unpacking now works for `for` vars
* Give error if length of tuple vars != length of tuple
* Fix error message showing wrong tuple length
* unpacking now works now for mutable items
* Update changelog
This commit is contained in:
Neelesh Chandola 2019-02-23 18:31:34 +05:30 • committed by Andreas Rumpf
commit 9884129058
7 changed files with 156 additions and 45 deletions

View file

@ -378,9 +378,15 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
for i in countup(0, sonsLen(e) - 1):
var v = e.sons[i]
if v.kind == nkExprColonExpr: v = v.sons[1]
let lhs = c.transCon.forStmt.sons[i]
let rhs = transform(c, v)
add(result, asgnTo(lhs, rhs))
if c.transCon.forStmt[i].kind == nkVarTuple:
for j in 0 ..< sonsLen(c.transCon.forStmt[i])-1:
let lhs = c.transCon.forStmt[i][j]
let rhs = transform(c, newTupleAccess(c.graph, v, j))
add(result, asgnTo(lhs, rhs))
else:
let lhs = c.transCon.forStmt.sons[i]
let rhs = transform(c, v)
add(result, asgnTo(lhs, rhs))
else:
# Unpack the tuple into the loop variables
# XXX: BUG: what if `n` is an expression with side-effects?
@ -389,9 +395,15 @@ proc transformYield(c: PTransf, n: PNode): PTransNode =
let rhs = transform(c, newTupleAccess(c.graph, e, i))
add(result, asgnTo(lhs, rhs))
else:
let lhs = c.transCon.forStmt.sons[0]
let rhs = transform(c, e)
add(result, asgnTo(lhs, rhs))
if c.transCon.forStmt.sons[0].kind == nkVarTuple:
for i in 0 ..< sonsLen(c.transCon.forStmt[0])-1:
let lhs = c.transCon.forStmt[0][i]
let rhs = transform(c, newTupleAccess(c.graph, e, i))
add(result, asgnTo(lhs, rhs))
else:
let lhs = c.transCon.forStmt.sons[0]
let rhs = transform(c, e)
add(result, asgnTo(lhs, rhs))
inc(c.transCon.yieldStmts)
if c.transCon.yieldStmts <= 1:
@ -609,7 +621,11 @@ proc transformFor(c: PTransf, n: PNode): PTransNode =
var v = newNodeI(nkVarSection, n.info)
for i in countup(0, length - 3):
addVar(v, copyTree(n.sons[i])) # declare new vars
if n[i].kind == nkVarTuple:
for j in 0 ..< sonsLen(n[i])-1:
addVar(v, copyTree(n[i][j])) # declare new vars
else:
addVar(v, copyTree(n.sons[i])) # declare new vars
add(stmtList, v.PTransNode)
# Bugfix: inlined locals belong to the invoking routine, not to the invoked