[pypy-svn] r17490 - in pypy/dist/pypy: annotation rpython rpython/test translator/c/test

tismer at codespeak.net tismer at codespeak.net
Mon Sep 12 11:03:43 CEST 2005


Author: tismer
Date: Mon Sep 12 11:03:41 2005
New Revision: 17490

Modified:
   pypy/dist/pypy/annotation/listdef.py
   pypy/dist/pypy/rpython/rrange.py
   pypy/dist/pypy/rpython/test/test_rrange.py
   pypy/dist/pypy/translator/c/test/test_typed.py
Log:
added the missing pieces to unify different ranges, plus some tests.

There is anyway a little problem:
We don't handle large ranges correctly which needs an unsigned len result.
Given that, range is still not absolutely compatible. No idea yet,
what we want to do about it.

Modified: pypy/dist/pypy/annotation/listdef.py
==============================================================================
--- pypy/dist/pypy/annotation/listdef.py	(original)
+++ pypy/dist/pypy/annotation/listdef.py	Mon Sep 12 11:03:41 2005
@@ -7,6 +7,15 @@
     resized = False    # True for lists resized after creation
     range_step = None  # the step -- only for lists only created by a range()
 
+    # what to do if range_step is different in merge.
+    # - if one is a list (range_step is None), unify to a list.
+    # - if both have a step, unify to use a variable step (indicated by 0)
+    _step_map = {
+        (type(None), int): None,
+        (int, type(None)): None,
+        (int, int)       : 0,
+        }
+
     def __init__(self, bookkeeper, s_value):
         self.s_value = s_value
         self.bookkeeper = bookkeeper
@@ -20,7 +29,8 @@
             self.mutated |= other.mutated
             self.resized |= other.resized
             if other.range_step != self.range_step:
-                self.range_step = None
+                self.range_step = self._step_map[type(self.range_step),
+                                                 type(other.range_step)]
             self.itemof.update(other.itemof)
             read_locations = self.read_locations.copy()
             other_read_locations = other.read_locations.copy()

Modified: pypy/dist/pypy/rpython/rrange.py
==============================================================================
--- pypy/dist/pypy/rpython/rrange.py	(original)
+++ pypy/dist/pypy/rpython/rrange.py	Mon Sep 12 11:03:41 2005
@@ -130,12 +130,11 @@
         vstart, vstop = hop.inputargs(Signed, Signed)
     else:
         vstart, vstop, vstep = hop.inputargs(Signed, Signed, Signed)
-    const_step = isinstance(vstep, Constant)
-    if const_step and vstep.value == 0:
-        # not really needed, annotator catches it. Just in case...
-        raise TyperError("range cannot have a const step of zero")
+        if isinstance(vstep, Constant) and vstep.value == 0:
+            # not really needed, annotator catches it. Just in case...
+            raise TyperError("range cannot have a const step of zero")
     if isinstance(hop.r_result, RangeRepr):
-        if const_step:
+        if hop.r_result.step != 0:
             return hop.gendirectcall(ll_newrange, vstart, vstop)
         else:
             return hop.gendirectcall(ll_newrangest, vstart, vstop, vstep)

Modified: pypy/dist/pypy/rpython/test/test_rrange.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rrange.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rrange.py	Mon Sep 12 11:03:41 2005
@@ -1,6 +1,7 @@
 from pypy.translator.translator import Translator
 from pypy.rpython.rrange import *
 from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.rarithmetic import intmask
 
 def test_rlist_range():
     def test1(start, stop, step, varstep):
@@ -118,30 +119,6 @@
         for i in r:
             res = res * 51 + i
         return res
-    res = interpret(fn, [2, 7, 1])#, view=True)
-    # XXX not finished, stunned
-
-# XXX the above test works, but it always turns the range into a list!!!
-#
-# here another test that show that this even happens in a simple case.
-# I think this is an annotator problem
-
-def test_range_funny():
-    # this is just an example.
-    # making start/stop different is ok
-    def fn(start, stop):
-        if stop >= start:
-            r = range(start, stop, 1)
-        else:
-            r = range(start, stop-1, 1)
-        return r[-2]
-    # making step different turns the range into a list!
-    # I think, we should instead either specialize the blocks,
-    # or morph the whole thing into the variable step case???
-    def fn(start, stop):
-        if stop >= start:
-            r = range(start, stop, 1)
-        else:
-            r = range(start, stop, -1)
-        return r[-2]
-    res = interpret(fn, [2, 7])#, view=True)
+    for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
+        res = interpret(fn, args)#, view=True)
+        assert res == intmask(fn(*args))

Modified: pypy/dist/pypy/translator/c/test/test_typed.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_typed.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_typed.py	Mon Sep 12 11:03:41 2005
@@ -4,7 +4,7 @@
 from pypy.translator.translator import Translator
 from pypy.translator.test import snippet 
 from pypy.translator.tool.cbuild import skip_missing_compiler
-from pypy.rpython.rarithmetic import r_uint
+from pypy.rpython.rarithmetic import r_uint, intmask
 
 from pypy.translator.c.test.test_annotated import TestAnnotatedTestCase as _TestAnnotatedTestCase
 
@@ -380,3 +380,20 @@
         assert f(1) == fn(1)
         assert f(3) == fn(3)
         raises(ValueError, f, 0)
+
+    def test_range_iter(self):
+        def fn(start=int, stop=int, step=int):
+            res = 0
+            if step == 0:
+                if stop >= start:
+                    r = range(start, stop, 1)
+                else:
+                    r = range(start, stop, -1)
+            else:
+                r = range(start, stop, step)
+            for i in r:
+                res = res * 51 + i
+            return res
+        f = self.getcompiled(fn)
+        for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
+            assert f(*args) == intmask(fn(*args))



More information about the Pypy-commit mailing list