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