summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-06-15 10:15:32 +0200
committerAraq <rumpf_a@web.de>2011-06-15 10:15:32 +0200
commita15475f582e18a684c1015544b908b195f436d6d (patch)
treed3f364add28442d2627bb6aa85ccfda9f275a7c0
parent4fa80956b89c2ee06d8940018101240efec7dc02 (diff)
downloadNim-a15475f582e18a684c1015544b908b195f436d6d.tar.gz
tuple unpacking is not enforced in for loops anymore
-rwxr-xr-xcompiler/semstmts.nim6
-rwxr-xr-xcompiler/transf.nim5
-rw-r--r--tests/accept/compile/tgenericmatcher2.nim18
-rw-r--r--tests/accept/compile/titer_no_tuple_unpack.nim13
-rwxr-xr-xtodo.txt1
-rwxr-xr-xweb/news.txt1
6 files changed, 40 insertions, 4 deletions
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index f074a00cd..62eb52ac1 100755
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -447,14 +447,16 @@ proc semFor(c: PContext, n: PNode): PNode =
     result = semForFields(c, n, call.sons[0].sym.magic)
   else:
     var iter = skipTypes(n.sons[length-2].typ, {tyGenericInst})
-    if iter.kind != tyTuple: 
+    # length == 3 means that there is one for loop variable
+    # and thus no tuple unpacking:
+    if iter.kind != tyTuple or length == 3: 
       if length != 3: GlobalError(n.info, errWrongNumberOfVariables)
       var v = newSymS(skForVar, n.sons[0], c)
       v.typ = iter
       n.sons[0] = newSymNode(v)
       addDecl(c, v)
     else: 
-      if length-2 != sonsLen(iter): 
+      if length-2 != sonsLen(iter):
         GlobalError(n.info, errWrongNumberOfVariables)
       for i in countup(0, length - 3): 
         var v = newSymS(skForVar, n.sons[i], c)
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 15deb266d..f301a3717 100755
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -305,7 +305,10 @@ proc introduceNewLocalVars(c: PTransf, n: PNode): PTransNode =
 proc transformYield(c: PTransf, n: PNode): PTransNode = 
   result = newTransNode(nkStmtList, n.info, 0)
   var e = n.sons[0]
-  if skipTypes(e.typ, {tyGenericInst}).kind == tyTuple: 
+  # c.transCon.forStmt.len == 3 means that there is one for loop variable
+  # and thus no tuple unpacking:
+  if skipTypes(e.typ, {tyGenericInst}).kind == tyTuple and
+      c.transCon.forStmt.len != 3:
     e = skipConv(e)
     if e.kind == nkPar: 
       for i in countup(0, sonsLen(e) - 1): 
diff --git a/tests/accept/compile/tgenericmatcher2.nim b/tests/accept/compile/tgenericmatcher2.nim
new file mode 100644
index 000000000..aa2f9dbb3
--- /dev/null
+++ b/tests/accept/compile/tgenericmatcher2.nim
@@ -0,0 +1,18 @@
+
+type
+  TMatcherKind = enum
+    mkTerminal, mkSequence, mkAlternation, mkRepeat
+  TMatcher[T] = object
+    case kind: TMatcherKind
+    of mkTerminal:
+      value: T
+    of mkSequence, mkAlternation:
+      matchers: seq[TMatcher[T]]
+    of mkRepeat:
+      matcher: ref TMatcher[T]
+      min, max: int
+
+var 
+  m: ref TMatcher[int]
+
+
diff --git a/tests/accept/compile/titer_no_tuple_unpack.nim b/tests/accept/compile/titer_no_tuple_unpack.nim
new file mode 100644
index 000000000..da5e1bc46
--- /dev/null
+++ b/tests/accept/compile/titer_no_tuple_unpack.nim
@@ -0,0 +1,13 @@
+

+iterator xrange(fromm, to: int, step = 1): tuple[x, y: int] =

+  var a = fromm

+  while a <= to:

+    yield (a, a+1)

+    inc(a, step)

+
+for a, b in xrange(3, 7):
+  echo a, " ", b
+  
+for tup in xrange(3, 7):
+  echo tup
+
diff --git a/todo.txt b/todo.txt
index 5d928ab88..2208925e4 100755
--- a/todo.txt
+++ b/todo.txt
@@ -3,7 +3,6 @@ High priority (version 0.8.12)
 * implement message passing built-ins
 
 * add --deadlock_prevention:on|off switch? timeout for locks?
-* iterators should not always be destructive!
 * real types for template results
 * built-in serialization
 
diff --git a/web/news.txt b/web/news.txt
index c6039a0eb..321550dfe 100755
--- a/web/news.txt
+++ b/web/news.txt
@@ -83,6 +83,7 @@ Additions
   returns a ``TFile`` and raises an exception in case of an error.
 - The compiler now might use hashing for string case statements depending
   on the number of string literals in the case statement.
+- Tuple unpacking is not enforced in ``for`` loops anymore.
 - Added a wrapper for ``redis``.
 - Added a wrapper for ``0mq`` via the ``zmq`` module.
 - Added a wrapper for ``sphinx``.