[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