diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/lowerings.nim | 26 | ||||
-rw-r--r-- | compiler/semexprs.nim | 8 |
2 files changed, 34 insertions, 0 deletions
diff --git a/compiler/lowerings.nim b/compiler/lowerings.nim index 647ea59d6..20800b809 100644 --- a/compiler/lowerings.nim +++ b/compiler/lowerings.nim @@ -63,6 +63,32 @@ proc lowerTupleUnpacking*(n: PNode; owner: PSym): PNode = if n.sons[i].kind == nkSym: v.addVar(n.sons[i]) result.add newAsgnStmt(n.sons[i], newTupleAccess(tempAsNode, i)) +proc newTupleAccessRaw*(tup: PNode, i: int): PNode = + result = newNodeI(nkBracketExpr, tup.info) + addSon(result, copyTree(tup)) + var lit = newNodeI(nkIntLit, tup.info) + lit.intVal = i + addSon(result, lit) + +proc lowerTupleUnpackingForAsgn*(n: PNode; owner: PSym): PNode = + let value = n.lastSon + result = newNodeI(nkStmtList, n.info) + + var temp = newSym(skTemp, getIdent(genPrefix), owner, value.info) + var v = newNodeI(nkLetSection, value.info) + let tempAsNode = newIdentNode(getIdent(genPrefix & $temp.id), value.info) + + var vpart = newNodeI(nkIdentDefs, tempAsNode.info, 3) + vpart.sons[0] = tempAsNode + vpart.sons[1] = ast.emptyNode + vpart.sons[2] = value + addSon(v, vpart) + result.add(v) + + let lhs = n.sons[0] + for i in 0 .. lhs.len-1: + result.add newAsgnStmt(lhs.sons[i], newTupleAccessRaw(tempAsNode, i)) + proc lowerSwap*(n: PNode; owner: PSym): PNode = result = newNodeI(nkStmtList, n.info) # note: cannot use 'skTemp' here cause we really need the copy for the VM :-( diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index bb3ec9df0..d6f6e3a2c 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1282,6 +1282,14 @@ proc semAsgn(c: PContext, n: PNode): PNode = result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=") add(result, n[1]) return semExprNoType(c, result) + of nkPar: + if a.len >= 2: + # unfortunately we need to rewrite ``(x, y) = foo()`` already here so + # that overloading of the assignment operator still works. Usually we + # prefer to do these rewritings in transf.nim: + return semStmt(c, lowerTupleUnpackingForAsgn(n, c.p.owner)) + else: + a = semExprWithType(c, a, {efLValue}) else: a = semExprWithType(c, a, {efLValue}) n.sons[0] = a |