[pypy-svn] r43283 - in pypy/branch/pypy-string-formatting: rpython rpython/test translator
arigo at codespeak.net
arigo at codespeak.net
Sat May 12 13:43:42 CEST 2007
Author: arigo
Date: Sat May 12 13:43:41 2007
New Revision: 43283
Modified:
pypy/branch/pypy-string-formatting/rpython/rlist.py
pypy/branch/pypy-string-formatting/rpython/rtyper.py
pypy/branch/pypy-string-formatting/rpython/test/test_rlist.py
pypy/branch/pypy-string-formatting/translator/transform.py
Log:
Direct support for
lst += char * count
lst += count * char
Also check that 'lst' is really a list of chars, and complain clearly
if it something else like a list of strings.
Modified: pypy/branch/pypy-string-formatting/rpython/rlist.py
==============================================================================
--- pypy/branch/pypy-string-formatting/rpython/rlist.py (original)
+++ pypy/branch/pypy-string-formatting/rpython/rlist.py Sat May 12 13:43:41 2007
@@ -4,7 +4,7 @@
from pypy.rpython.error import TyperError
from pypy.rpython.rmodel import Repr, IteratorRepr, IntegerRepr, inputconst
from pypy.rpython.rslice import AbstractSliceRepr
-from pypy.rpython.rstr import AbstractStringRepr
+from pypy.rpython.rstr import AbstractStringRepr, AbstractCharRepr
from pypy.rpython.lltypesystem.lltype import typeOf, Ptr, Void, Signed, Bool
from pypy.rpython.lltypesystem.lltype import nullptr, Char, UniChar
from pypy.rpython import robject
@@ -354,6 +354,9 @@
class __extend__(pairtype(AbstractListRepr, AbstractStringRepr)):
def rtype_inplace_add((r_lst1, r_str2), hop):
+ if r_lst1.item_repr.lowleveltype != Char:
+ raise TyperError('"lst += string" only supported with a list '
+ 'of chars')
string_repr = r_lst1.rtyper.type_system.rstr.string_repr
v_lst1, v_str2 = hop.inputargs(r_lst1, string_repr)
c_strlen = hop.inputconst(Void, string_repr.ll.ll_strlen)
@@ -363,6 +366,9 @@
return v_lst1
def rtype_extend_with_str_slice((r_lst1, r_str2), hop):
+ if r_lst1.item_repr.lowleveltype != Char:
+ raise TyperError('"lst += string" only supported with a list '
+ 'of chars')
rs = r_lst1.rtyper.type_system.rslice
string_repr = r_lst1.rtyper.type_system.rstr.string_repr
c_strlen = hop.inputconst(Void, string_repr.ll.ll_strlen)
@@ -383,6 +389,17 @@
(r_slic,))
return v_lst1
+class __extend__(pairtype(AbstractListRepr, AbstractCharRepr)):
+
+ def rtype_extend_with_char_count((r_lst1, r_chr2), hop):
+ if r_lst1.item_repr.lowleveltype != Char:
+ raise TyperError('"lst += string" only supported with a list '
+ 'of chars')
+ char_repr = r_lst1.rtyper.type_system.rstr.char_repr
+ v_lst1, v_chr, v_count = hop.inputargs(r_lst1, char_repr, Signed)
+ hop.gendirectcall(ll_extend_with_char_count, v_lst1, v_chr, v_count)
+ return v_lst1
+
class __extend__(pairtype(AbstractBaseListRepr, AbstractSliceRepr)):
@@ -774,6 +791,17 @@
i += 1
j += 1
+def ll_extend_with_char_count(lst, char, count):
+ if count <= 0:
+ return
+ len1 = lst.ll_length()
+ newlength = len1 + count
+ lst._ll_resize_ge(newlength)
+ j = len1
+ while j < newlength:
+ lst.ll_setitem_fast(j, char)
+ j += 1
+
def ll_listslice_startonly(RESLIST, l1, start):
len1 = l1.ll_length()
debug_assert(start >= 0, "unexpectedly negative list slice start")
Modified: pypy/branch/pypy-string-formatting/rpython/rtyper.py
==============================================================================
--- pypy/branch/pypy-string-formatting/rpython/rtyper.py (original)
+++ pypy/branch/pypy-string-formatting/rpython/rtyper.py Sat May 12 13:43:41 2007
@@ -581,6 +581,11 @@
r_arg2 = hop.args_r[1]
return pair(r_arg1, r_arg2).rtype_extend_with_str_slice(hop)
+ def translate_op_extend_with_char_count(self, hop):
+ r_arg1 = hop.args_r[0]
+ r_arg2 = hop.args_r[1]
+ return pair(r_arg1, r_arg2).rtype_extend_with_char_count(hop)
+
def translate_op_newtuple(self, hop):
return self.type_system.rtuple.rtype_newtuple(hop)
Modified: pypy/branch/pypy-string-formatting/rpython/test/test_rlist.py
==============================================================================
--- pypy/branch/pypy-string-formatting/rpython/test/test_rlist.py (original)
+++ pypy/branch/pypy-string-formatting/rpython/test/test_rlist.py Sat May 12 13:43:41 2007
@@ -1,5 +1,6 @@
import sys
from pypy.translator.translator import TranslationContext
+from pypy.rpython.error import TyperError
from pypy.rpython.lltypesystem.lltype import *
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.rlist import *
@@ -1171,7 +1172,7 @@
else:
assert False
- def test_charlist_extensions(self):
+ def test_charlist_extension_1(self):
def f(n):
s = 'hello%d' % n
l = ['a', 'b']
@@ -1180,6 +1181,15 @@
res = self.interpret(f, [58])
assert self.ll_to_string(res) == 'abhello58'
+ def test_extend_a_non_char_list_1(self):
+ def f(n):
+ s = 'hello%d' % n
+ l = ['foo', 'bar']
+ l += s # NOT SUPPORTED for now if l is not a list of chars
+ return ''.join(l)
+ py.test.raises(TyperError, self.interpret, f, [58])
+
+ def test_charlist_extension_2(self):
def f(n, i):
s = 'hello%d' % n
assert 0 <= i <= len(s)
@@ -1189,6 +1199,16 @@
res = self.interpret(f, [9381701, 3])
assert self.ll_to_string(res) == 'ablo9381701'
+ def test_extend_a_non_char_list_2(self):
+ def f(n, i):
+ s = 'hello%d' % n
+ assert 0 <= i <= len(s)
+ l = ['foo', 'bar']
+ l += s[i:] # NOT SUPPORTED for now if l is not a list of chars
+ return ''.join(l)
+ py.test.raises(TyperError, self.interpret, f, [9381701, 3])
+
+ def test_charlist_extension_3(self):
def f(n, i, j):
s = 'hello%d' % n
assert 0 <= i <= j <= len(s)
@@ -1198,6 +1218,7 @@
res = self.interpret(f, [9381701, 3, 7])
assert self.ll_to_string(res) == 'ablo93'
+ def test_charlist_extension_4(self):
def f(n):
s = 'hello%d' % n
l = ['a', 'b']
@@ -1206,6 +1227,34 @@
res = self.interpret(f, [9381701])
assert self.ll_to_string(res) == 'abhello938170'
+ def test_charlist_extension_5(self):
+ def f(count):
+ l = ['a', 'b']
+ l += '.' * count # char * count
+ return ''.join(l)
+ res = self.interpret(f, [7])
+ assert self.ll_to_string(res) == 'ab.......'
+ res = self.interpret(f, [0])
+ assert self.ll_to_string(res) == 'ab'
+
+ def test_charlist_extension_6(self):
+ def f(count):
+ l = ['a', 'b']
+ l += count * '.' # count * char
+ return ''.join(l)
+ res = self.interpret(f, [7])
+ assert self.ll_to_string(res) == 'ab.......'
+ res = self.interpret(f, [0])
+ assert self.ll_to_string(res) == 'ab'
+
+ def test_extend_a_non_char_list_6(self):
+ def f(count):
+ l = ['foo', 'bar']
+ # NOT SUPPORTED for now if l is not a list of chars
+ l += count * '.'
+ return ''.join(l)
+ py.test.raises(TyperError, self.interpret, f, [5])
+
class TestLLtype(BaseTestRlist, LLRtypeMixin):
rlist = ll_rlist
Modified: pypy/branch/pypy-string-formatting/translator/transform.py
==============================================================================
--- pypy/branch/pypy-string-formatting/translator/transform.py (original)
+++ pypy/branch/pypy-string-formatting/translator/transform.py Sat May 12 13:43:41 2007
@@ -81,6 +81,37 @@
op.result)
block.operations[i] = new_op
+# lst += char*count [or count*char]
+# -->
+# b = mul(char, count) [or count, char]
+# c = inplace_add(lst, b)
+# -->
+# c = extend_with_char_count(lst, char, count)
+
+def transform_extend_with_char_count(self, block_subset):
+ """Transforms lst += char*count to extend_with_char_count"""
+ for block in block_subset:
+ mul_sources = {} # maps b to (char, count) in the above notation
+ for i in range(len(block.operations)):
+ op = block.operations[i]
+ if op.opname == 'mul':
+ s0 = self.binding(op.args[0], None)
+ s1 = self.binding(op.args[1], None)
+ if (isinstance(s0, annmodel.SomeChar) and
+ isinstance(s1, annmodel.SomeInteger)):
+ mul_sources[op.result] = op.args[0], op.args[1]
+ elif (isinstance(s1, annmodel.SomeChar) and
+ isinstance(s0, annmodel.SomeInteger)):
+ mul_sources[op.result] = op.args[1], op.args[0]
+ elif (op.opname == 'inplace_add' and
+ op.args[1] in mul_sources and
+ self.gettype(op.args[0]) is list):
+ v_char, v_count = mul_sources[op.args[1]]
+ new_op = SpaceOperation('extend_with_char_count',
+ [op.args[0], v_char, v_count],
+ op.result)
+ block.operations[i] = new_op
+
# a[b:c]
# -->
# d = newslice(b, c, None)
@@ -243,6 +274,7 @@
default_extra_passes = [
transform_allocate,
transform_extend_with_str_slice,
+ transform_extend_with_char_count,
]
def transform_graph(ann, extra_passes=None, block_subset=None):
More information about the Pypy-commit
mailing list