[pypy-svn] r17690 - in pypy/dist/pypy/rpython: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Sep 20 14:21:26 CEST 2005
Author: arigo
Date: Tue Sep 20 14:21:23 2005
New Revision: 17690
Modified:
pypy/dist/pypy/rpython/rstr.py
pypy/dist/pypy/rpython/test/test_rstr.py
Log:
* A version of find/rfind optimized for searching for single characters.
* Implemented ch.isdigit(), isalpha() etc., in addition to isspace() that
we already had.
Next step: fix objspace/std/stringobject.py.
Modified: pypy/dist/pypy/rpython/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/rstr.py (original)
+++ pypy/dist/pypy/rpython/rstr.py Tue Sep 20 14:21:23 2005
@@ -114,7 +114,12 @@
def rtype_method_find(_, hop, reverse=False):
v_str = hop.inputarg(string_repr, arg=0)
- v_value = hop.inputarg(string_repr, arg=1)
+ if hop.args_r[1] == char_repr:
+ v_value = hop.inputarg(char_repr, arg=1)
+ llfn = reverse and ll_rfind_char or ll_find_char
+ else:
+ v_value = hop.inputarg(string_repr, arg=1)
+ llfn = reverse and ll_rfind or ll_find
if hop.nb_args > 2:
v_start = hop.inputarg(Signed, arg=2)
if not hop.args_s[2].nonneg:
@@ -127,10 +132,6 @@
raise TyperError("str.find() end must be proven non-negative")
else:
v_end = hop.gendirectcall(ll_strlen, v_str)
- if reverse:
- llfn = ll_rfind
- else:
- llfn = ll_find
hop.exception_cannot_occur()
return hop.gendirectcall(llfn, v_str, v_value, v_start, v_end)
@@ -408,10 +409,23 @@
vlist = hop.inputargs(char_repr)
return hop.genop('cast_char_to_int', vlist, resulttype=Signed)
- def rtype_method_isspace(_, hop):
+ def _rtype_method_isxxx(_, llfn, hop):
vlist = hop.inputargs(char_repr)
hop.exception_cannot_occur()
- return hop.gendirectcall(ll_char_isspace, vlist[0])
+ return hop.gendirectcall(llfn, vlist[0])
+
+ def rtype_method_isspace(self, hop):
+ return self._rtype_method_isxxx(ll_char_isspace, hop)
+ def rtype_method_isdigit(self, hop):
+ return self._rtype_method_isxxx(ll_char_isdigit, hop)
+ def rtype_method_isalpha(self, hop):
+ return self._rtype_method_isxxx(ll_char_isalpha, hop)
+ def rtype_method_isalnum(self, hop):
+ return self._rtype_method_isxxx(ll_char_isalnum, hop)
+ def rtype_method_isupper(self, hop):
+ return self._rtype_method_isxxx(ll_char_isupper, hop)
+ def rtype_method_islower(self, hop):
+ return self._rtype_method_isxxx(ll_char_islower, hop)
class __extend__(pairtype(CharRepr, IntegerRepr)):
@@ -530,10 +544,37 @@
# get flowed and annotated, mostly with SomePtr.
#
def ll_char_isspace(ch):
- # XXX:
- #return ord(ch) in (9, 10, 11, 12, 13, 32)
c = ord(ch)
- return 9 <= c <= 13 or c == 32
+ return c == 32 or (c <= 13 and c >= 9) # c in (9, 10, 11, 12, 13, 32)
+
+def ll_char_isdigit(ch):
+ c = ord(ch)
+ return c <= 57 and c >= 48
+
+def ll_char_isalpha(ch):
+ c = ord(ch)
+ if c >= 97:
+ return c <= 122
+ else:
+ return 65 <= c <= 90
+
+def ll_char_isalnum(ch):
+ c = ord(ch)
+ if c >= 65:
+ if c >= 97:
+ return c <= 122
+ else:
+ return c <= 90
+ else:
+ return 48 <= c <= 57
+
+def ll_char_isupper(ch):
+ c = ord(ch)
+ return 65 <= c <= 90
+
+def ll_char_islower(ch):
+ c = ord(ch)
+ return 97 <= c <= 122
def ll_char_mul(ch, times):
newstr = malloc(STR, times)
@@ -678,9 +719,27 @@
return True
+def ll_find_char(s, ch, start, end):
+ i = start
+ while i < end:
+ if s.chars[i] == ch:
+ return i
+ i += 1
+ return -1
+
+def ll_rfind_char(s, ch, start, end):
+ i = end
+ while i > start:
+ i -= 1
+ if s.chars[i] == ch:
+ return i
+ return -1
+
def ll_find(s1, s2, start, end):
"""Knuth Morris Prath algorithm for substring match"""
len2 = len(s2.chars)
+ if len2 == 1:
+ return ll_find_char(s1, s2.chars[0], start, end)
if len2 == 0:
return start
# Construct the array of possible restarting positions
@@ -723,6 +782,8 @@
def ll_rfind(s1, s2, start, end):
"""Reversed version of ll_find()"""
len2 = len(s2.chars)
+ if len2 == 1:
+ return ll_rfind_char(s1, s2.chars[0], start, end)
if len2 == 0:
return end
# Construct the array of possible restarting positions
Modified: pypy/dist/pypy/rpython/test/test_rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rstr.py (original)
+++ pypy/dist/pypy/rpython/test/test_rstr.py Tue Sep 20 14:21:23 2005
@@ -109,13 +109,18 @@
assert res.chars[0] == 'x'
assert res.chars[1] == '.'
-def test_char_isspace():
+def test_char_isxxx():
def fn(s):
- return s.isspace()
- res = interpret(fn, ['x'])
- assert res == False
- res = interpret(fn, [' '])
- assert res == True
+ return (s.isspace() |
+ s.isdigit() << 1 |
+ s.isalpha() << 2 |
+ s.isalnum() << 3 |
+ s.isupper() << 4 |
+ s.islower() << 5)
+ for i in range(128):
+ ch = chr(i)
+ res = interpret(fn, [ch])
+ assert res == fn(ch)
def test_char_compare():
res = interpret(lambda c1, c2: c1 == c2, ['a', 'b'])
@@ -248,6 +253,15 @@
res = interpret(fn, [])
assert res == 2 + 2 + 1
+def test_find_char():
+ def fn(ch):
+ pos1 = 'aiuwraz 483'.find(ch)
+ pos2 = 'aiuwraz 483'.rfind(ch)
+ return pos1 + (pos2*100)
+ for ch in 'a ?3':
+ res = interpret(fn, [ch])
+ assert res == fn(ch)
+
def test_upper():
def fn(i):
strings = ['', ' ', 'upper', 'UpPeR', ',uppEr,']
More information about the Pypy-commit
mailing list