[pypy-svn] r14088 - in pypy/dist/pypy: annotation rpython rpython/test

ludal at codespeak.net ludal at codespeak.net
Sat Jul 2 14:09:14 CEST 2005


Author: ludal
Date: Sat Jul  2 14:09:13 2005
New Revision: 14088

Modified:
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/rstr.py
   pypy/dist/pypy/rpython/test/test_rstr.py
Log:
implements ll rpython string find method


Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Sat Jul  2 14:09:13 2005
@@ -301,6 +301,9 @@
     def method_endswith(str, frag):
         return SomeBool()
 
+    def method_find(str, frag):
+        return SomeInteger()
+
     def method_join(str, s_list):
         getbookkeeper().count("str_join", str)
         s_item = s_list.listdef.read_item()

Modified: pypy/dist/pypy/rpython/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/rstr.py	(original)
+++ pypy/dist/pypy/rpython/rstr.py	Sat Jul  2 14:09:13 2005
@@ -26,6 +26,8 @@
 STR = GcStruct('str', ('hash',  Signed),
                       ('chars', Array(Char)))
 
+SIGNED_ARRAY = GcArray(Signed)
+
 
 class __extend__(annmodel.SomeString):
     def rtyper_makerepr(self, rtyper):
@@ -568,6 +570,47 @@
 
     return True
 
+def ll_find(s1, s2):
+    """Knuth Morris Prath algorithm for substring match"""
+    len1 = len(s1.chars)
+    len2 = len(s2.chars)
+    # Construct the array of possible restarting positions
+    # T = Array_of_ints [-1..len2]
+    # T[-1] = -1 s2.chars[-1] is supposed to be unequal to everything else
+    T = malloc( SIGNED_ARRAY, len2 )
+    i = 0
+    j = -1
+    while i<len2:
+        if j>=0 and s2.chars[i] == s2.chars[j]:
+            j += 1
+            T[i] = j
+            i += 1
+        elif j>0:
+            j = T[j-1]
+        else:
+            T[i] = 0
+            i += 1
+            j = 0
+
+    # Now the find algorithm
+    i = 0
+    m = 0
+    while m+i<len1:
+        if s1.chars[m+i]==s2.chars[i]:
+            i += 1
+            if i==len2:
+                return m
+        else:
+            # mismatch, go back to the last possible starting pos
+            if i==0:
+                e = -1
+            else:
+                e = T[i-1]
+            m = m + i - e
+            if i>0:
+                i = e
+    return -1
+    
 emptystr = string_repr.convert_const("")
 
 def ll_upper(s):

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	Sat Jul  2 14:09:13 2005
@@ -180,6 +180,16 @@
             res = interpret(fn, [i,j])
             assert res is fn(i, j)
 
+def test_find():
+    def fn(i, j):
+        s1 = ['one two three', 'abc abcdab abcdabcdabde']
+        s2 = ['one', 'two', 'abcdab', 'one tou', 'abcdefgh', 'fortytwo']
+        return s1[i].find(s2[j])
+    for i in range(2):
+        for j in range(6):
+            res = interpret(fn, [i,j])
+            assert res == fn(i, j)
+
 def test_upper():
     def fn(i):
         strings = ['', ' ', 'upper', 'UpPeR', ',uppEr,']



More information about the Pypy-commit mailing list