[pypy-svn] r54572 - in pypy/branch/io-improvements/pypy/rpython: . lltypesystem ootypesystem test

fijal at codespeak.net fijal at codespeak.net
Thu May 8 20:37:42 CEST 2008


Author: fijal
Date: Thu May  8 20:37:41 2008
New Revision: 54572

Added:
   pypy/branch/io-improvements/pypy/rpython/lltypesystem/rbuilder.py   (contents, props changed)
   pypy/branch/io-improvements/pypy/rpython/ootypesystem/rbuilder.py   (contents, props changed)
   pypy/branch/io-improvements/pypy/rpython/rbuilder.py   (contents, props changed)
   pypy/branch/io-improvements/pypy/rpython/test/test_rbuilder.py   (contents, props changed)
Modified:
   pypy/branch/io-improvements/pypy/rpython/typesystem.py
Log:
String builder implementation. Still needs more tests (like backend ones)


Added: pypy/branch/io-improvements/pypy/rpython/lltypesystem/rbuilder.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-improvements/pypy/rpython/lltypesystem/rbuilder.py	Thu May  8 20:37:41 2008
@@ -0,0 +1,56 @@
+
+from pypy.rpython.rbuilder import AbstractStringBuilderRepr
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem.rstr import STR
+from pypy.rpython.annlowlevel import llstr
+from pypy.rlib import rgc
+
+STRINGBUILDER = lltype.GcStruct('stringbuilder',
+                              ('allocated', lltype.Signed),
+                              ('used', lltype.Signed),
+                              ('buf', lltype.Ptr(STR)))
+
+class StringBuilderRepr(AbstractStringBuilderRepr):
+    lowleveltype = lltype.Ptr(STRINGBUILDER)
+
+    @staticmethod
+    def ll_new(init_size):
+        ll_builder = lltype.malloc(STRINGBUILDER)
+        ll_builder.allocated = init_size
+        ll_builder.used = 0
+        ll_builder.buf = rgc.resizable_buffer_of_shape(STR, init_size)
+        return ll_builder
+
+    @staticmethod
+    def ll_append(ll_builder, str):
+        ll_str = llstr(str)
+        used = ll_builder.used
+        lgt = len(ll_str.chars)
+        allocated = ll_builder.allocated
+        needed = lgt + used
+        if needed >= allocated:
+            # XXX tune overallocation scheme
+            new_allocated = needed + 100
+            ll_builder.buf = rgc.resize_buffer(ll_builder.buf, used,
+                                               new_allocated)
+            ll_builder.allocated = new_allocated
+        ll_str.copy_contents(ll_str, ll_builder.buf, 0, used, lgt)
+        ll_builder.used = used + lgt
+    
+    @staticmethod
+    def ll_append_char(ll_builder, char):
+        if ll_builder.used == ll_builder.allocated:
+            # XXX tune overallocation scheme
+            new_allocated = ll_builder.allocated + 100
+            ll_builder.buf = rgc.resize_buffer(ll_builder.buf, ll_builder.used,
+                                               new_allocated)
+            ll_builder.allocated = new_allocated
+        ll_builder.buf.chars[ll_builder.used] = char
+        ll_builder.used += 1
+
+    @staticmethod
+    def ll_build(ll_builder):
+        final_size = ll_builder.used
+        return rgc.finish_building_buffer(ll_builder.buf, final_size)
+
+stringbuilder_repr = StringBuilderRepr()

Added: pypy/branch/io-improvements/pypy/rpython/ootypesystem/rbuilder.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-improvements/pypy/rpython/ootypesystem/rbuilder.py	Thu May  8 20:37:41 2008
@@ -0,0 +1,24 @@
+
+from pypy.rpython.rbuilder import AbstractStringBuilderRepr
+from pypy.rpython.ootypesystem import ootype
+
+class StringBuilderRepr(AbstractStringBuilderRepr):
+    lowleveltype = ootype.StringBuilder
+
+    @staticmethod
+    def ll_new(init_size):
+        return ootype.new(ootype.StringBuilder)
+
+    @staticmethod
+    def ll_append_char(builder, char):
+        builder.ll_append_char(char)
+
+    @staticmethod
+    def ll_append(builder, string):
+        builder.ll_append(string)
+
+    @staticmethod
+    def ll_build(builder):
+        return builder.ll_build()
+
+stringbuilder_repr = StringBuilderRepr()

Added: pypy/branch/io-improvements/pypy/rpython/rbuilder.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-improvements/pypy/rpython/rbuilder.py	Thu May  8 20:37:41 2008
@@ -0,0 +1,40 @@
+
+from pypy.annotation.model import SomeObject, SomeString, s_None,\
+     SomeChar, SomeInteger
+from pypy.rpython.rmodel import Repr
+from pypy.rpython.annlowlevel import llhelper
+from pypy.rpython.lltypesystem import lltype
+
+class SomeStringBuilder(SomeObject):
+    def __init__(self, init_size):
+        self.init_size = init_size
+
+    def method_append(self, s_str):
+        assert isinstance(s_str, (SomeString, SomeChar))
+        return s_None
+
+    def method_build(self):
+        return SomeString()
+    
+    def rtyper_makerepr(self, rtyper):
+        return rtyper.type_system.rbuilder.stringbuilder_repr
+
+class AbstractStringBuilderRepr(Repr):
+    def rtyper_new(self, hop):
+        repr = hop.r_result
+        if len(hop.args_v) == 0:
+            v_arg = hop.inputconst(lltype.Signed, hop.s_result.init_size)
+        else:
+            v_arg = hop.inputarg(lltype.Signed, 0)
+        return hop.gendirectcall(self.ll_new, v_arg)
+
+    def rtype_method_append(self, hop):
+        vlist = hop.inputargs(*hop.args_r)
+        if isinstance(hop.args_s[1], SomeChar):
+            return hop.gendirectcall(self.ll_append_char, *vlist)
+        return hop.gendirectcall(self.ll_append, *vlist)
+
+    def rtype_method_build(self, hop):
+        vlist = hop.inputargs(*hop.args_r)
+        return hop.gendirectcall(self.ll_build, *vlist)
+

Added: pypy/branch/io-improvements/pypy/rpython/test/test_rbuilder.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-improvements/pypy/rpython/test/test_rbuilder.py	Thu May  8 20:37:41 2008
@@ -0,0 +1,29 @@
+
+from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+from pypy.rlib.rstring import StringBuilder
+
+class BaseTestStringBuilder(BaseRtypingTest):
+    def test_simple(self):
+        def func():
+            s = StringBuilder()
+            s.append("a")
+            s.append("abc")
+            return s.build()
+        res = self.ll_to_string(self.interpret(func, []))
+        assert res == "aabc"
+
+    def test_overallocation(self):
+        def func():
+            s = StringBuilder(4)
+            s.append("abcd")
+            s.append("defg")
+            s.append("rty")
+            return s.build()
+        res = self.ll_to_string(self.interpret(func, []))
+        assert res == "abcddefgrty"
+
+class TestLLtype(BaseTestStringBuilder, LLRtypeMixin):
+    pass
+
+class TestOOtype(BaseTestStringBuilder, OORtypeMixin):
+    pass

Modified: pypy/branch/io-improvements/pypy/rpython/typesystem.py
==============================================================================
--- pypy/branch/io-improvements/pypy/rpython/typesystem.py	(original)
+++ pypy/branch/io-improvements/pypy/rpython/typesystem.py	Thu May  8 20:37:41 2008
@@ -22,7 +22,7 @@
                 return None
         if name in ('rclass', 'rpbc', 'rbuiltin', 'rtuple', 'rlist',
                     'rslice', 'rdict', 'rrange', 'rstr', 'rgeneric',
-                    'll_str', 'exceptiondata'):
+                    'll_str', 'rbuilder', 'exceptiondata'):
             mod = load(name)
             if mod is not None:
                 setattr(self, name, mod)



More information about the Pypy-commit mailing list