Author: Maciej Fijalkowski <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit