Commits

Maciej Fijalkowski  committed 2f143b4

implement rsplit and fix the annotation

  • Participants
  • Parent commits 376eb89

Comments (0)

Files changed (3)

File rpython/rtyper/lltypesystem/rstr.py

 
         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):
 
         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):
         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 -
             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
         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)
                               '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),

File rpython/rtyper/rstr.py

 
     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
             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

File rpython/rtyper/test/test_rstr.py

             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):