[pypy-svn] r14606 - in pypy/dist/pypy/rpython: . test

arigo at codespeak.net arigo at codespeak.net
Wed Jul 13 02:06:39 CEST 2005


Author: arigo
Date: Wed Jul 13 02:06:36 2005
New Revision: 14606

Modified:
   pypy/dist/pypy/rpython/rtuple.py
   pypy/dist/pypy/rpython/test/test_rtuple.py
Log:
Iteration over tuples of length 1 (!).  This is needed by os.path.join()...



Modified: pypy/dist/pypy/rpython/rtuple.py
==============================================================================
--- pypy/dist/pypy/rpython/rtuple.py	(original)
+++ pypy/dist/pypy/rpython/rtuple.py	Wed Jul 13 02:06:36 2005
@@ -4,6 +4,7 @@
 from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
 from pypy.rpython.lltype import Ptr, GcStruct, Void, Signed, malloc
+from pypy.rpython.lltype import typeOf, nullptr
 
 # ____________________________________________________________
 #
@@ -64,6 +65,11 @@
             hop.gendirectcall(rlist.ll_setitem_nonneg, vlist, cindex, vitem)
         return vlist
 
+    def make_iterator_repr(self):
+        if len(self.items_r) == 1:
+            return Length1TupleIteratorRepr(self)
+        raise TyperError("can only iterate over tuples of length 1 for now")
+
 class __extend__(pairtype(TupleRepr, Repr)): 
     def rtype_contains((r_tup, r_item), hop): 
         v_tup = hop.args_v[0] 
@@ -155,3 +161,37 @@
             llops.gencapicall('PyTuple_SetItem_WithIncref', [v_result, ci,
                                                              v_converted])
         return v_result
+
+# ____________________________________________________________
+#
+#  Iteration.
+
+class Length1TupleIteratorRepr(Repr):
+
+    def __init__(self, r_tuple):
+        self.r_tuple = r_tuple
+        self.lowleveltype = Ptr(GcStruct('tuple1iter',
+                                         ('tuple', r_tuple.lowleveltype)))
+
+    def newiter(self, hop):
+        v_tuple, = hop.inputargs(self.r_tuple)
+        citerptr = hop.inputconst(Void, self.lowleveltype)
+        return hop.gendirectcall(ll_tupleiter, citerptr, v_tuple)
+
+    def rtype_next(self, hop):
+        v_iter, = hop.inputargs(self)
+        return hop.gendirectcall(ll_tuplenext, v_iter)
+
+def ll_tupleiter(ITERPTR, tuple):
+    iter = malloc(ITERPTR.TO)
+    iter.tuple = tuple
+    return iter
+
+def ll_tuplenext(iter):
+    # for iterating over length 1 tuples only!
+    t = iter.tuple
+    if t:
+        iter.tuple = nullptr(typeOf(t).TO)
+        return t.item0
+    else:
+        raise StopIteration

Modified: pypy/dist/pypy/rpython/test/test_rtuple.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rtuple.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rtuple.py	Wed Jul 13 02:06:36 2005
@@ -77,3 +77,12 @@
     assert res is True 
     res = interpret(f, [0])
     assert res is False 
+
+def test_tuple_iterator_length1():
+    def f(i):
+        total = 0
+        for x in (i,):
+            total += x
+        return total
+    res = interpret(f, [93813])
+    assert res == 93813



More information about the Pypy-commit mailing list