[pypy-svn] r27237 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem test

antocuni at codespeak.net antocuni at codespeak.net
Mon May 15 15:29:28 CEST 2006


Author: antocuni
Date: Mon May 15 15:29:19 2006
New Revision: 27237

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rstr.py
   pypy/dist/pypy/rpython/ootypesystem/rstr.py
   pypy/dist/pypy/rpython/rstr.py
   pypy/dist/pypy/rpython/test/test_rstr.py
Log:
Add support for method join to ootypesystem rstr.



Modified: pypy/dist/pypy/rpython/lltypesystem/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rstr.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rstr.py	Mon May 15 15:29:19 2006
@@ -63,6 +63,13 @@
                             # where NULL is always valid: it is chr(0)
 
 
+    def _list_length_items(self, hop, v_lst, LIST):
+        LIST = LIST.TO
+        v_length = hop.gendirectcall(LIST.ll_length, v_lst)
+        v_items = hop.gendirectcall(LIST.ll_items, v_lst)
+        return v_length, v_items
+
+
 class CharRepr(AbstractCharRepr, StringRepr):
     lowleveltype = Char
 

Modified: pypy/dist/pypy/rpython/ootypesystem/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rstr.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rstr.py	Mon May 15 15:29:19 2006
@@ -43,6 +43,14 @@
     def make_iterator_repr(self):
         return string_iterator_repr
 
+    def _list_length_items(self, hop, v_lst, LIST):
+        # ootypesystem list has a different interface that
+        # lltypesystem list, so we don't need to calculate the lenght
+        # here and to pass the 'items' array. Let's pass the list
+        # itself and let LLHelpers.join to manipulate it directly.
+        c_length = hop.inputconst(ootype.Void, None)
+        return c_length, v_lst
+
 
 class CharRepr(AbstractCharRepr, StringRepr):
     lowleveltype = Char
@@ -56,13 +64,13 @@
         return ootype.oostring(ch)
 
     def ll_char_mul(ch, times):
-        builder = ootype.new(ootype.StringBuilder)
-        builder.ll_allocate(times)
+        buf = ootype.new(ootype.StringBuilder)
+        buf.ll_allocate(times)
         i = 0
         while i<times:
-            builder.ll_append_char(ch)
+            buf.ll_append_char(ch)
             i+= 1
-        return builder.ll_build()
+        return buf.ll_build()
 
     def ll_streq(s1, s2):
         if s1 is None:
@@ -76,6 +84,52 @@
             return False
         return s1.ll_strcmp(s2)
 
+    def ll_join(s, length_dummy, lst):
+        length = lst.ll_length()
+        buf = ootype.new(ootype.StringBuilder)
+
+        # TODO: check if it's worth of preallocating the buffer with
+        # the exact length
+##        itemslen = 0
+##        i = 0
+##        while i < length:
+##            itemslen += lst.ll_getitem_fast(i).ll_strlen()
+##            i += 1
+##        resultlen = itemslen + s.ll_strlen()*(length-1)
+##        buf.ll_allocate(resultlen)
+
+        i = 0
+        while i < length-1:
+            item = lst.ll_getitem_fast(i)
+            buf.ll_append(item)
+            buf.ll_append(s)
+            i += 1
+        if length > 0:
+            lastitem = lst.ll_getitem_fast(i)
+            buf.ll_append(lastitem)
+        return buf.ll_build()
+
+    def ll_join_chars(length_dummy, lst):
+        buf = ootype.new(ootype.StringBuilder)
+        length = lst.ll_length()
+        buf.ll_allocate(length)
+        i = 0
+        while i < length:
+            buf.ll_append_char(lst.ll_getitem_fast(i))
+            i += 1
+        return buf.ll_build()
+
+    def ll_join_strs(length_dummy, lst):
+        buf = ootype.new(ootype.StringBuilder)
+        length = lst.ll_length()
+        #buf.ll_allocate(length)
+        i = 0
+        while i < length:
+            buf.ll_append(lst.ll_getitem_fast(i))
+            i += 1
+        return buf.ll_build()
+
+
 def add_helpers():
     dic = {}
     for name, meth in ootype.String._GENERIC_METHODS.iteritems():
@@ -99,6 +153,7 @@
 unichar_repr = UniCharRepr()
 char_repr.ll = LLHelpers
 unichar_repr.ll = LLHelpers
+emptystr = string_repr.convert_const("")
 
 class StringIteratorRepr(AbstractStringIteratorRepr):
     lowleveltype = ootype.Record({'string': string_repr.lowleveltype,

Modified: pypy/dist/pypy/rpython/rstr.py
==============================================================================
--- pypy/dist/pypy/rpython/rstr.py	(original)
+++ pypy/dist/pypy/rpython/rstr.py	Mon May 15 15:29:19 2006
@@ -135,7 +135,12 @@
         v_str, = hop.inputargs(string_repr)
         hop.exception_cannot_occur()
         return hop.gendirectcall(self.ll.ll_lower, v_str)
-        
+
+    def _list_length_items(self, hop, v_lst, LIST):
+        """Return two Variables containing the length and items of a
+        list. Need to be overriden because it is typesystem-specific."""
+        raise NotImplementedError
+
     def rtype_method_join(self, hop):
         hop.exception_cannot_occur()
         rstr = hop.rtyper.type_system.rstr
@@ -145,10 +150,8 @@
         if not isinstance(r_lst, hop.rtyper.type_system.rlist.BaseListRepr):
             raise TyperError("string.join of non-list: %r" % r_lst)
         v_str, v_lst = hop.inputargs(rstr.string_repr, r_lst)
-        LIST = r_lst.lowleveltype.TO
-        v_length = hop.gendirectcall(LIST.ll_length, v_lst)
-        v_items = hop.gendirectcall(LIST.ll_items, v_lst)
-                       
+        v_length, v_items = self._list_length_items(hop, v_lst, r_lst.lowleveltype)
+
         if hop.args_s[0].is_constant() and hop.args_s[0].const == '':
             if r_lst.item_repr == rstr.string_repr:
                 llfn = self.ll.ll_join_strs

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	Mon May 15 15:29:19 2006
@@ -325,37 +325,37 @@
             res = self.interpret(fn, [i])
             assert self.ll_to_string(res) == fn(i)
 
-def test_join():
-    res = interpret(lambda: ''.join([]), [])
-    assert ''.join(res.chars) == ""
-
-    res = interpret(lambda: ''.join(['a', 'b', 'c']), [])
-    assert ''.join(res.chars) == "abc"
-
-    res = interpret(lambda: ''.join(['abc', 'de', 'fghi']), [])
-    assert ''.join(res.chars) == "abcdefghi"
-
-    res = interpret(lambda: '.'.join(['abc', 'def']), [])
-    assert ''.join(res.chars) == 'abc.def'
-    
-    def fn(i, j):
-        s1 = [ '', ',', ' and ']
-        s2 = [ [], ['foo'], ['bar', 'baz', 'bazz']]
-        return s1[i].join(s2[j])
-    for i in range(3):
-        for j in range(3):
-            res = interpret(fn, [i,j])
-            assert ''.join(res.chars) == fn(i, j)
-
-    def fn(i, j):
-        s1 = [ '', ',', ' and ']
-        s2 = [ [], ['foo'], ['bar', 'baz', 'bazz']]
-        s2[1].extend(['x'])
-        return s1[i].join(s2[j])
-    for i in range(3):
-        for j in range(3):
-            res = interpret(fn, [i,j])
-            assert ''.join(res.chars) == fn(i, j)
+    def test_join(self):
+        res = self.interpret(lambda: ''.join([]), [])
+        assert self.ll_to_string(res) == ""
+
+        res = self.interpret(lambda: ''.join(['a', 'b', 'c']), [])
+        assert self.ll_to_string(res) == "abc"
+
+        res = self.interpret(lambda: ''.join(['abc', 'de', 'fghi']), [])
+        assert self.ll_to_string(res) == "abcdefghi"
+
+        res = self.interpret(lambda: '.'.join(['abc', 'def']), [])
+        assert self.ll_to_string(res) == 'abc.def'
+
+        def fn(i, j):
+            s1 = [ '', ',', ' and ']
+            s2 = [ [], ['foo'], ['bar', 'baz', 'bazz']]
+            return s1[i].join(s2[j])
+        for i in range(3):
+            for j in range(3):
+                res = self.interpret(fn, [i,j])
+                assert self.ll_to_string(res) == fn(i, j)
+
+        def fn(i, j):
+            s1 = [ '', ',', ' and ']
+            s2 = [ [], ['foo'], ['bar', 'baz', 'bazz']]
+            s2[1].extend(['x'])
+            return s1[i].join(s2[j])
+        for i in range(3):
+            for j in range(3):
+                res = self.interpret(fn, [i,j])
+                assert self.ll_to_string(res) == fn(i, j)
 
 def test_parse_fmt():
     assert LLHelpers.parse_fmt_string('a') == ['a']



More information about the Pypy-commit mailing list