summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-08-21 12:31:55 +0200
committerAraq <rumpf_a@web.de>2015-08-21 21:34:14 +0200
commitbfd2fd67f948f6a5ee8815ee866d55d147f53c73 (patch)
treed03fdbac18566c26c4a9dffd74c270949889a8c9 /compiler
parent2733c508ef2681fe8eddfe9c73419ef3226e479d (diff)
downloadNim-bfd2fd67f948f6a5ee8815ee866d55d147f53c73.tar.gz
tuple unpacking works in a non-var/let context
Diffstat (limited to 'compiler')
-rw-r--r--compiler/lowerings.nim26
-rw-r--r--compiler/semexprs.nim8
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