Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: 
Changeset: r68567:2f143b453556
Date: 2013-12-29 10:57 +0200
http://bitbucket.org/pypy/pypy/changeset/2f143b453556/

Log:    implement rsplit and fix the annotation

diff --git a/rpython/rtyper/lltypesystem/rstr.py 
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -638,8 +638,7 @@
 
         return LLHelpers.ll_search(s1, s2, start, end, FAST_FIND)
 
-    @classmethod
-    def ll_rfind(cls, s1, s2, start, end):
+    def ll_rfind(s1, s2, start, end):
         if start < 0:
             start = 0
         if end > len(s1.chars):
@@ -649,9 +648,9 @@
 
         m = len(s2.chars)
         if m == 1:
-            return cls.ll_rfind_char(s1, s2.chars[0], start, end)
+            return LLHelpers.ll_rfind_char(s1, s2.chars[0], start, end)
 
-        return cls.ll_search(s1, s2, start, end, FAST_RFIND)
+        return LLHelpers.ll_search(s1, s2, start, end, FAST_RFIND)
 
     @classmethod
     def ll_count(cls, s1, s2, start, end):
@@ -899,7 +898,7 @@
         prev_pos = 0
         if pos < 0:
             items[0] = s
-            return items
+            return res
         while pos >= 0 and count < max:
             item = items[count] = s.malloc(pos - prev_pos)
             item.copy_contents(s, item, prev_pos, 0, pos -
@@ -909,7 +908,7 @@
             pos = s.find(c, pos + markerlen, last)
         item = items[count] = s.malloc(last - prev_pos)
         item.copy_contents(s, item, prev_pos, 0, last - prev_pos)
-        return items
+        return res
 
     def ll_rsplit_chr(LIST, s, c, max):
         chars = s.chars
@@ -946,6 +945,37 @@
         item.copy_contents(s, item, j, 0, i - j)
         return res
 
+    def ll_rsplit(LIST, s, c, max):
+        count = 1
+        if max == -1:
+            max = len(s.chars)
+        pos = len(s.chars)
+        markerlen = len(c.chars)
+        pos = s.rfind(c, 0, pos)
+        while pos >= 0 and count <= max:
+            pos = s.rfind(c, 0, pos - markerlen)
+            count += 1
+        res = LIST.ll_newlist(count)
+        items = res.ll_items()
+        pos = 0
+        pos = len(s.chars)
+        prev_pos = pos
+        pos = s.rfind(c, 0, pos)
+        if pos < 0:
+            items[0] = s
+            return res
+        count -= 1
+        while pos >= 0 and count > 0:
+            item = items[count] = s.malloc(prev_pos - pos - markerlen)
+            item.copy_contents(s, item, pos + markerlen, 0,
+                               prev_pos - pos - markerlen)
+            count -= 1
+            prev_pos = pos
+            pos = s.rfind(c, 0, pos)
+        item = items[count] = s.malloc(prev_pos)
+        item.copy_contents(s, item, 0, 0, prev_pos)
+        return res
+
     @jit.elidable
     def ll_replace_chr_chr(s, c1, c2):
         length = len(s.chars)
@@ -1125,7 +1155,8 @@
                               'copy_contents_from_str' : 
staticAdtMethod(copy_string_contents),
                               'gethash': LLHelpers.ll_strhash,
                               'length': LLHelpers.ll_length,
-                              'find': LLHelpers.ll_find}))
+                              'find': LLHelpers.ll_find,
+                              'rfind': LLHelpers.ll_rfind}))
 UNICODE.become(GcStruct('rpy_unicode', ('hash', Signed),
                         ('chars', Array(UniChar, hints={'immutable': True})),
                         adtmeths={'malloc' : staticAdtMethod(mallocunicode),
diff --git a/rpython/rtyper/rstr.py b/rpython/rtyper/rstr.py
--- a/rpython/rtyper/rstr.py
+++ b/rpython/rtyper/rstr.py
@@ -357,10 +357,16 @@
 
     def rtype_method_rsplit(self, hop):
         rstr = hop.args_r[0].repr
+        v_str = hop.inputarg(rstr.repr, 0)
+        if isinstance(hop.args_s[1], annmodel.SomeString):
+            v_chr = hop.inputarg(rstr.repr, 1)
+            fn = self.ll.ll_rsplit
+        else:
+            v_chr = hop.inputarg(rstr.char_repr, 1)
+            fn = self.ll.ll_rsplit_chr
         if hop.nb_args == 3:
-            v_str, v_chr, v_max = hop.inputargs(rstr.repr, rstr.char_repr, 
Signed)
+            v_max = hop.inputarg(Signed, 2)
         else:
-            v_str, v_chr = hop.inputargs(rstr.repr, rstr.char_repr)
             v_max = hop.inputconst(Signed, -1)
         try:
             list_type = hop.r_result.lowleveltype.TO
@@ -368,7 +374,7 @@
             list_type = hop.r_result.lowleveltype
         cLIST = hop.inputconst(Void, list_type)
         hop.exception_cannot_occur()
-        return hop.gendirectcall(self.ll.ll_rsplit_chr, cLIST, v_str, v_chr, 
v_max)
+        return hop.gendirectcall(fn, cLIST, v_str, v_chr, v_max)
 
     def rtype_method_replace(self, hop):
         rstr = hop.args_r[0].repr
diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py
--- a/rpython/rtyper/test/test_rstr.py
+++ b/rpython/rtyper/test/test_rstr.py
@@ -744,6 +744,19 @@
             res = self.interpret(f, [i])
             assert res == True
 
+    def test_rsplit_multichar(self):
+        l = ["abc::z", "abc", "abc::def:::x"]
+        exp = [["abc", "z"], ["abc"], ["abc", "def:", "x"]]
+        exp2 = [["abc", "z"], ["abc"], ["abc::def:", "x"]]
+
+        def f(i):
+            s = l[i]
+            return s.rsplit("::") == exp[i] and s.rsplit("::", 1) == exp2[i]
+
+        for i in range(3):
+            res = self.interpret(f, [i])
+            assert res == True
+
     def test_rsplit(self):
         fn = self._make_split_test('rsplit')
         for i in range(5):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to