[pypy-commit] pypy numpy-multidim: better support for slices

fijal noreply at buildbot.pypy.org
Fri Oct 28 20:39:46 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-multidim
Changeset: r48585:a2490f74710a
Date: 2011-10-28 20:38 +0200
http://bitbucket.org/pypy/pypy/changeset/a2490f74710a/

Log:	better support for slices

diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -56,7 +56,15 @@
         if isinstance(w_idx, IntObject):
             return (self.int_w(w_idx), 0, 0, 1)
         else:
-            return (0, size, 1, size)
+            assert isinstance(w_idx, SliceObject)
+            start, stop, step = w_idx.start, w_idx.stop, w_idx.step
+            if step == 0:
+                return (0, size, 1, size)
+            if start < 0:
+                start += size
+            if stop < 0:
+                stop += size
+            return (start, stop, step, size//step)
 
     @specialize.argtype(1)
     def wrap(self, obj):
@@ -143,6 +151,10 @@
 
 class SliceObject(W_Root):
     tp = FakeSpace.w_slice
+    def __init__(self, start, stop, step):
+        self.start = start
+        self.stop = stop
+        self.step = step
 
 class InterpreterState(object):
     def __init__(self, code):
@@ -294,14 +306,17 @@
         return "[" + ", ".join([repr(item) for item in self.items]) + "]"
 
 class SliceConstant(Node):
-    def __init__(self):
-        pass
+    def __init__(self, start, stop, step):
+        # no negative support for now
+        self.start = start
+        self.stop = stop
+        self.step = step
 
     def wrap(self, space):
-        return SliceObject()
+        return SliceObject(self.start, self.stop, self.step)
 
     def __repr__(self):
-        return 'slice()'
+        return 'slice(%s,%s,%s)' % (self.start, self.stop, self.step)
 
 class Execute(Node):
     def __init__(self, expr):
@@ -392,8 +407,31 @@
         assert lgt >= 0
         if ':' in v:
             # a slice
-            assert v == ':'
-            return SliceConstant()
+            if v == ':':
+                return SliceConstant(0, 0, 0)
+            else:
+                l = v.split(':')
+                if len(l) == 2:
+                    one = l[0]
+                    two = l[1]
+                    if not one:
+                        one = 0
+                    else:
+                        one = int(one)
+                    return SliceConstant(int(l[0]), int(l[1]), 1)
+                else:
+                    three = int(l[2])
+                    # all can be empty
+                    if l[0]:
+                        one = int(l[0])
+                    else:
+                        one = 0
+                    if l[1]:
+                        two = int(l[1])
+                    else:
+                        two = -1
+                    return SliceConstant(one, two, three)
+                
         if v[0] == '[':
             return ArrayConstant([self.parse_constant(elem)
                                   for elem in v[1:lgt].split(",")])
diff --git a/pypy/module/micronumpy/test/test_compile.py b/pypy/module/micronumpy/test/test_compile.py
--- a/pypy/module/micronumpy/test/test_compile.py
+++ b/pypy/module/micronumpy/test/test_compile.py
@@ -167,3 +167,12 @@
         b -> 3
         """)
         assert interp.results[0].value.val == 4
+
+    def test_slice_step(self):
+        interp = self.run("""
+        a = |30|
+        b = a -> ::2
+        b -> 3
+        """)
+        assert interp.results[0].value.val == 6
+        


More information about the pypy-commit mailing list