[pypy-svn] r13665 - in pypy/dist/pypy: rpython rpython/test translator/c/test

ac at codespeak.net ac at codespeak.net
Tue Jun 21 19:34:57 CEST 2005


Author: ac
Date: Tue Jun 21 19:34:56 2005
New Revision: 13665

Modified:
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/rstr.py
   pypy/dist/pypy/rpython/test/test_rstr.py
   pypy/dist/pypy/translator/c/test/test_typed.py
Log:
Added <, <=, >=, > and iteration for rstrings.

Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Tue Jun 21 19:34:56 2005
@@ -247,6 +247,10 @@
         assert type(b) is bool
         return not b
     
+    def op_cast_char_to_int(self, b):
+        assert type(b) is str and len(b) == 1
+        return ord(b)
+
 # __________________________________________________________
 # primitive operations
 from pypy.objspace.flow.operation import FunctionByName

Modified: pypy/dist/pypy/rpython/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/rstr.py	(original)
+++ pypy/dist/pypy/rpython/rstr.py	Tue Jun 21 19:34:56 2005
@@ -98,6 +98,9 @@
         v_str, v_lst = hop.inputargs(string_repr, r_lst)
         return hop.gendirectcall(ll_join, v_str, v_lst)
         
+    def make_iterator_repr(self):
+        return string_iterator_repr
+
 class __extend__(pairtype(StringRepr, IntegerRepr)):
     def rtype_getitem(_, hop):
         v_str, v_index = hop.inputargs(string_repr, Signed)
@@ -122,7 +125,31 @@
         v_str1, v_str2 = hop.inputargs(string_repr, string_repr)
         vres = hop.gendirectcall(ll_streq, v_str1, v_str2)
         return hop.genop('bool_not', [vres], resulttype=Bool)
-    
+
+    def rtype_lt(_, hop):
+        v_str1, v_str2 = hop.inputargs(string_repr, string_repr)
+        vres = hop.gendirectcall(ll_strcmp, v_str1, v_str2)
+        return hop.genop('int_lt', [vres, hop.inputconst(Signed, 0)],
+                         resulttype=Bool)
+
+    def rtype_le(_, hop):
+        v_str1, v_str2 = hop.inputargs(string_repr, string_repr)
+        vres = hop.gendirectcall(ll_strcmp, v_str1, v_str2)
+        return hop.genop('int_le', [vres, hop.inputconst(Signed, 0)],
+                         resulttype=Bool)
+
+    def rtype_ge(_, hop):
+        v_str1, v_str2 = hop.inputargs(string_repr, string_repr)
+        vres = hop.gendirectcall(ll_strcmp, v_str1, v_str2)
+        return hop.genop('int_ge', [vres, hop.inputconst(Signed, 0)],
+                         resulttype=Bool)
+
+    def rtype_gt(_, hop):
+        v_str1, v_str2 = hop.inputargs(string_repr, string_repr)
+        vres = hop.gendirectcall(ll_strcmp, v_str1, v_str2)
+        return hop.genop('int_gt', [vres, hop.inputconst(Signed, 0)],
+                         resulttype=Bool)
+
 class __extend__(CharRepr):
 
     def convert_const(self, value):
@@ -258,6 +285,24 @@
         j += 1
     return newstr
 
+def ll_strcmp(s1, s2):
+    chars1 = s1.chars
+    chars2 = s2.chars
+    len1 = len(chars1)
+    len2 = len(chars2)
+
+    if len1 < len2:
+        cmplen = len1
+    else:
+        cmplen = len2
+    i = 0
+    while i < cmplen:
+        diff = ord(chars1[i]) - ord(chars2[i])
+        if diff != 0:
+            return diff
+        i += 1
+    return len1 - len2
+
 def ll_streq(s1, s2):
     len1 = len(s1.chars)
     len2 = len(s2.chars)
@@ -346,3 +391,35 @@
             res_index += 1
         i += 1
     return result
+
+# ____________________________________________________________
+#
+#  Iteration.
+
+class StringIteratorRepr(Repr):
+    lowleveltype = Ptr(GcStruct('stringiter',
+                                ('string', string_repr.lowleveltype),
+                                ('index', Signed)))
+    def newiter(self, hop):
+        v_str, = hop.inputargs(string_repr)
+        return hop.gendirectcall(ll_striter, v_str)
+
+    def rtype_next(self, hop):
+        v_iter, = hop.inputargs(self)
+        return hop.gendirectcall(ll_strnext, v_iter)
+
+string_iterator_repr = StringIteratorRepr()
+
+def ll_striter(string):
+    iter = malloc(string_iterator_repr.lowleveltype.TO)
+    iter.string = string
+    iter.index = 0
+    return iter
+
+def ll_strnext(iter):
+    chars = iter.string.chars
+    index = iter.index
+    if index >= len(chars):
+        raise StopIteration
+    iter.index = index + 1
+    return chars[index]

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 Jun 21 19:34:56 2005
@@ -53,6 +53,23 @@
             res = ev_fn(i, j)
             assert ''.join(res.chars) == fn(i, j)
 
+def test_iter():
+    def fn(i):
+        s = ['', 'a', 'hello'][i]
+        i = 0
+        for c in s:
+            if c != s[i]:
+                return False
+            i += 1
+        if i == len(s):
+            return True
+        return False
+
+    ev_fn = make_interpreter(fn, [0])    
+    for i in range(3):
+        res = ev_fn(i)
+        assert res is True
+        
 def test_char_constant():
     def fn(s):
         return s + '.'
@@ -90,6 +107,47 @@
             res = ev_fn(i, j)
             assert res is fn(i, j)
 
+    def fn(i, j):
+        s1 = ['one', 'two']
+        s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+        return s1[i] < s2[j]
+    ev_fn = make_interpreter(fn, [0,0])    
+    for i in range(2):
+        for j in range(6):
+            res = ev_fn(i, j)
+            assert res is fn(i, j)
+
+    def fn(i, j):
+        s1 = ['one', 'two']
+        s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+        return s1[i] <= s2[j]
+    ev_fn = make_interpreter(fn, [0,0])    
+    for i in range(2):
+        for j in range(6):
+            res = ev_fn(i, j)
+            assert res is fn(i, j)
+
+    def fn(i, j):
+        s1 = ['one', 'two']
+        s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+        return s1[i] >= s2[j]
+    ev_fn = make_interpreter(fn, [0,0])    
+    for i in range(2):
+        for j in range(6):
+            res = ev_fn(i, j)
+            assert res is fn(i, j)
+
+    def fn(i, j):
+        s1 = ['one', 'two']
+        s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+        return s1[i] > s2[j]
+    ev_fn = make_interpreter(fn, [0,0])    
+    for i in range(2):
+        for j in range(6):
+            res = ev_fn(i, j)
+            assert res is fn(i, j)
+
+
 def test_startswith():
     def fn(i, j):
         s1 = ['one', 'two']

Modified: pypy/dist/pypy/translator/c/test/test_typed.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_typed.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_typed.py	Tue Jun 21 19:34:56 2005
@@ -88,6 +88,7 @@
             for j in range(6):
                 res = fn(i, j)
                 assert res is testfn(i, j)
+
         def testfn(i=int, j=int):
             s1 = ['one', 'two']
             s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
@@ -98,6 +99,46 @@
                 res = fn(i, j)
                 assert res is testfn(i, j)
                 
+        def testfn(i=int, j=int):
+            s1 = ['one', 'two']
+            s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+            return s1[i] < s2[j]
+        fn = self.getcompiled(testfn)
+        for i in range(2):
+            for j in range(6):
+                res = fn(i, j)
+                assert res is testfn(i, j)
+                
+        def testfn(i=int, j=int):
+            s1 = ['one', 'two']
+            s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+            return s1[i] <= s2[j]
+        fn = self.getcompiled(testfn)
+        for i in range(2):
+            for j in range(6):
+                res = fn(i, j)
+                assert res is testfn(i, j)
+                
+        def testfn(i=int, j=int):
+            s1 = ['one', 'two']
+            s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+            return s1[i] > s2[j]
+        fn = self.getcompiled(testfn)
+        for i in range(2):
+            for j in range(6):
+                res = fn(i, j)
+                assert res is testfn(i, j)
+                
+        def testfn(i=int, j=int):
+            s1 = ['one', 'two']
+            s2 = ['one', 'two', 'o', 'on', 'twos', 'foobar']
+            return s1[i] >= s2[j]
+        fn = self.getcompiled(testfn)
+        for i in range(2):
+            for j in range(6):
+                res = fn(i, j)
+                assert res is testfn(i, j)
+                
     def test_str_methods(self):
         def testfn(i=int, j=int):
             s1 = ['one', 'two']



More information about the Pypy-commit mailing list