[pypy-svn] r43277 - in pypy/branch/pypy-string-formatting: rpython rpython/test translator
arigo at codespeak.net
arigo at codespeak.net
Sat May 12 13:02:30 CEST 2007
Author: arigo
Date: Sat May 12 13:02:29 2007
New Revision: 43277
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 the following combined operations:
lst += string[start:]
lst += string[start:stop]
lst += string[:-1]
Lengthy code, so I wouldn't be surprized if there is a bug somewhere
despite the tests.
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:02:29 2007
@@ -362,6 +362,27 @@
c_strlen, c_stritem)
return v_lst1
+ def rtype_extend_with_str_slice((r_lst1, r_str2), hop):
+ 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)
+ c_stritem = hop.inputconst(Void, string_repr.ll.ll_stritem_nonneg)
+ r_slic = hop.args_r[2]
+ v_lst1, v_str2, v_slice = hop.inputargs(r_lst1, string_repr, r_slic)
+ if r_slic == rs.startonly_slice_repr:
+ hop.gendirectcall(ll_extend_with_str_slice_startonly,
+ v_lst1, v_str2, c_strlen, c_stritem, v_slice)
+ elif r_slic == rs.startstop_slice_repr:
+ hop.gendirectcall(ll_extend_with_str_slice,
+ v_lst1, v_str2, c_strlen, c_stritem, v_slice)
+ elif r_slic == rs.minusone_slice_repr:
+ hop.gendirectcall(ll_extend_with_str_slice_minusone,
+ v_lst1, v_str2, c_strlen, c_stritem)
+ else:
+ raise TyperError('lst += str[:] does not support slices with %r' %
+ (r_slic,))
+ return v_lst1
+
class __extend__(pairtype(AbstractBaseListRepr, AbstractSliceRepr)):
@@ -705,17 +726,54 @@
j += 1
def ll_extend_with_str(lst, s, getstrlen, getstritem):
+ return ll_extend_with_str_slice_startonly(lst, s, getstrlen, getstritem, 0)
+
+def ll_extend_with_str_slice_startonly(lst, s, getstrlen, getstritem, start):
len1 = lst.ll_length()
len2 = getstrlen(s)
- newlength = len1 + len2
+ debug_assert(start >= 0, "unexpectedly negative str slice start")
+ debug_assert(start <= len2, "str slice start larger than str length")
+ newlength = len1 + len2 - start
lst._ll_resize_ge(newlength)
- i = 0
+ i = start
j = len1
while i < len2:
lst.ll_setitem_fast(j, getstritem(s, i))
i += 1
j += 1
+def ll_extend_with_str_slice(lst, s, getstrlen, getstritem, slice):
+ start = slice.start
+ stop = slice.stop
+ len1 = lst.ll_length()
+ len2 = getstrlen(s)
+ debug_assert(start >= 0, "unexpectedly negative str slice start")
+ debug_assert(start <= len2, "str slice start larger than str length")
+ debug_assert(stop >= start, "str slice stop smaller than start")
+ if stop > len2:
+ stop = len2
+ newlength = len1 + stop - start
+ lst._ll_resize_ge(newlength)
+ i = start
+ j = len1
+ while i < stop:
+ lst.ll_setitem_fast(j, getstritem(s, i))
+ i += 1
+ j += 1
+
+def ll_extend_with_str_slice_minusone(lst, s, getstrlen, getstritem):
+ len1 = lst.ll_length()
+ len2m1 = getstrlen(s) - 1
+ debug_assert(len2m1 >= 0, "empty string is sliced with [:-1]")
+ newlength = len1 + len2m1
+ lst._ll_resize_ge(newlength)
+ i = 0
+ j = len1
+ while i < len2m1:
+ lst.ll_setitem_fast(j, getstritem(s, i))
+ i += 1
+ 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:02:29 2007
@@ -576,6 +576,11 @@
def translate_op_alloc_and_set(self, hop):
return rlist.rtype_alloc_and_set(hop)
+ def translate_op_extend_with_str_slice(self, hop):
+ r_arg1 = hop.args_r[0]
+ r_arg2 = hop.args_r[1]
+ return pair(r_arg1, r_arg2).rtype_extend_with_str_slice(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:02:29 2007
@@ -1180,6 +1180,32 @@
res = self.interpret(f, [58])
assert self.ll_to_string(res) == 'abhello58'
+ def f(n, i):
+ s = 'hello%d' % n
+ assert 0 <= i <= len(s)
+ l = ['a', 'b']
+ l += s[i:]
+ return ''.join(l)
+ res = self.interpret(f, [9381701, 3])
+ assert self.ll_to_string(res) == 'ablo9381701'
+
+ def f(n, i, j):
+ s = 'hello%d' % n
+ assert 0 <= i <= j <= len(s)
+ l = ['a', 'b']
+ l += s[i:j]
+ return ''.join(l)
+ res = self.interpret(f, [9381701, 3, 7])
+ assert self.ll_to_string(res) == 'ablo93'
+
+ def f(n):
+ s = 'hello%d' % n
+ l = ['a', 'b']
+ l += s[:-1]
+ return ''.join(l)
+ res = self.interpret(f, [9381701])
+ assert self.ll_to_string(res) == 'abhello938170'
+
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:02:29 2007
@@ -55,6 +55,32 @@
op.result)
block.operations[i] = new_op
+# lst += string[x:y]
+# -->
+# b = getitem(string, slice)
+# c = inplace_add(lst, b)
+# -->
+# c = extend_with_str_slice(lst, string, slice)
+
+def transform_extend_with_str_slice(self, block_subset):
+ """Transforms lst += string[x:y] to extend_with_str_slice"""
+ for block in block_subset:
+ slice_sources = {} # maps b to [string, slice] in the above notation
+ for i in range(len(block.operations)):
+ op = block.operations[i]
+ if (op.opname == 'getitem' and
+ self.gettype(op.args[0]) is str and
+ self.gettype(op.args[1]) is slice):
+ slice_sources[op.result] = op.args
+ elif (op.opname == 'inplace_add' and
+ op.args[1] in slice_sources and
+ self.gettype(op.args[0]) is list):
+ v_string, v_slice = slice_sources[op.args[1]]
+ new_op = SpaceOperation('extend_with_str_slice',
+ [op.args[0], v_string, v_slice],
+ op.result)
+ block.operations[i] = new_op
+
# a[b:c]
# -->
# d = newslice(b, c, None)
@@ -62,22 +88,23 @@
# -->
# e = getslice(a, b, c)
-def transform_slice(self, block_subset):
- """Transforms a[b:c] to getslice(a, b, c)."""
- for block in block_subset:
- operations = block.operations[:]
- n_op = len(operations)
- for i in range(0, n_op-1):
- op1 = operations[i]
- op2 = operations[i+1]
- if (op1.opname == 'newslice' and
- self.gettype(op1.args[2]) is types.NoneType and
- op2.opname == 'getitem' and
- op1.result is op2.args[1]):
- new_op = SpaceOperation('getslice',
- (op2.args[0], op1.args[0], op1.args[1]),
- op2.result)
- block.operations[i+1:i+2] = [new_op]
+##def transform_slice(self, block_subset): -- not used any more --
+## """Transforms a[b:c] to getslice(a, b, c)."""
+## for block in block_subset:
+## operations = block.operations[:]
+## n_op = len(operations)
+## for i in range(0, n_op-1):
+## op1 = operations[i]
+## op2 = operations[i+1]
+## if (op1.opname == 'newslice' and
+## self.gettype(op1.args[2]) is types.NoneType and
+## op2.opname == 'getitem' and
+## op1.result is op2.args[1]):
+## new_op = SpaceOperation('getslice',
+## (op2.args[0], op1.args[0], op1.args[1]),
+## op2.result)
+## block.operations[i+1:i+2] = [new_op]
+
def transform_dead_op_vars(self, block_subset):
# we redo the same simplification from simplify.py,
@@ -215,6 +242,7 @@
default_extra_passes = [
transform_allocate,
+ transform_extend_with_str_slice,
]
def transform_graph(ann, extra_passes=None, block_subset=None):
More information about the Pypy-commit
mailing list