[pypy-svn] r14605 - in pypy/dist/pypy: rpython rpython/test translator/goal

arigo at codespeak.net arigo at codespeak.net
Wed Jul 13 01:58:25 CEST 2005


Author: arigo
Date: Wed Jul 13 01:58:21 2005
New Revision: 14605

Modified:
   pypy/dist/pypy/rpython/rlist.py
   pypy/dist/pypy/rpython/rslice.py
   pypy/dist/pypy/rpython/test/test_rlist.py
   pypy/dist/pypy/translator/goal/ISSUES.txt
Log:
Support for [:-1] in getitem for lists.


Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py	(original)
+++ pypy/dist/pypy/rpython/rlist.py	Wed Jul 13 01:58:21 2005
@@ -5,6 +5,7 @@
 from pypy.rpython import rrange
 from pypy.rpython.rslice import SliceRepr
 from pypy.rpython.rslice import startstop_slice_repr, startonly_slice_repr
+from pypy.rpython.rslice import minusone_slice_repr
 from pypy.rpython.rclass import InstanceRepr
 from pypy.rpython.lltype import GcForwardReference, Ptr, GcArray, GcStruct
 from pypy.rpython.lltype import Void, Signed, malloc, typeOf, Primitive
@@ -205,6 +206,9 @@
         if r_slic == startstop_slice_repr:
             v_lst, v_slice = hop.inputargs(r_lst, startstop_slice_repr)
             return hop.gendirectcall(ll_listslice, v_lst, v_slice)
+        if r_slic == minusone_slice_repr:
+            v_lst, v_ignored = hop.inputargs(r_lst, minusone_slice_repr)
+            return hop.gendirectcall(ll_listslice_minusone, v_lst)
         raise TyperError(r_slic)
 
     def rtype_delitem((r_lst, r_slic), hop):
@@ -445,6 +449,18 @@
     l.items = newitems
     return l
 
+def ll_listslice_minusone(l1):
+    newlen = len(l1.items) - 1
+    assert newlen >= 0
+    newitems = malloc(typeOf(l1).TO.items.TO, newlen)
+    j = 0
+    while j < newlen:
+        newitems[j] = l1.items[j]
+        j += 1
+    l = malloc(typeOf(l1).TO)
+    l.items = newitems
+    return l
+
 def ll_listdelslice_startonly(l1, start):
     newitems = malloc(typeOf(l1).TO.items.TO, start)
     j = 0

Modified: pypy/dist/pypy/rpython/rslice.py
==============================================================================
--- pypy/dist/pypy/rpython/rslice.py	(original)
+++ pypy/dist/pypy/rpython/rslice.py	Wed Jul 13 01:58:21 2005
@@ -25,6 +25,9 @@
     def rtyper_makerepr(self, rtyper):
         if not self.step.is_constant() or self.step.const not in (None, 1):
             raise TyperError("only supports slices with step 1")
+        if (self.start.is_constant() and self.start.const in (None, 0) and
+            self.stop.is_constant() and self.stop.const == -1):
+            return minusone_slice_repr    # [:-1]
         if isinstance(self.start, annmodel.SomeInteger):
             if not self.start.nonneg:
                 raise TyperError("slice start must be proved non-negative")
@@ -36,7 +39,9 @@
         else:
             return startstop_slice_repr
     def rtyper_makekey(self):
-        return self.stop.rtyper_makekey(), self.step.rtyper_makekey()
+        return (self.start.rtyper_makekey(),
+                self.stop.rtyper_makekey(),
+                self.step.rtyper_makekey())
 
 
 class SliceRepr(Repr):
@@ -46,6 +51,8 @@
 startstop_slice_repr.lowleveltype = Ptr(SLICE)
 startonly_slice_repr = SliceRepr()
 startonly_slice_repr.lowleveltype = Signed
+minusone_slice_repr = SliceRepr()
+minusone_slice_repr.lowleveltype = Void    # only for [:-1]
 
 # ____________________________________________________________
 
@@ -66,6 +73,10 @@
     assert isinstance(v_step, Constant) and v_step.value in (None, 1)
     if isinstance(v_start, Constant) and v_start.value is None:
         v_start = hop.inputconst(Signed, 0)
+    if (isinstance(v_start, Constant) and v_start.value == 0 and
+        isinstance(v_stop, Constant) and v_stop.value == -1):
+        # [:-1] slice
+        return hop.inputconst(Void, slice(None,-1))
     if isinstance(v_stop, Constant) and v_stop.value is None:
         # start-only slice
         # NB. cannot just return v_start in case it is a constant

Modified: pypy/dist/pypy/rpython/test/test_rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rlist.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rlist.py	Wed Jul 13 01:58:21 2005
@@ -332,3 +332,11 @@
     assert res == 0
     res = interpret(fn, [2])
     assert res == 1
+
+def test_list_slice_minusone():
+    def fn(i):
+        lst = [i, i+1, i+2]
+        lst2 = lst[:-1]
+        return lst[-1] * lst2[-1]
+    res = interpret(fn, [5])
+    assert res == 42

Modified: pypy/dist/pypy/translator/goal/ISSUES.txt
==============================================================================
--- pypy/dist/pypy/translator/goal/ISSUES.txt	(original)
+++ pypy/dist/pypy/translator/goal/ISSUES.txt	Wed Jul 13 01:58:21 2005
@@ -4,8 +4,6 @@
 Let's list and update here the issues that will show up, or have shown up
 already sometime ago, while running translate_pypy::
 
-  * we need slicing of the form [:-1].
-
   * the PBCReprs generally lack a convert_from_to() to convert from a small PBC
     set to a larger one.
 



More information about the Pypy-commit mailing list