[pypy-svn] r17436 - in pypy/dist/pypy: rpython rpython/test translator/c/test
tismer at codespeak.net
tismer at codespeak.net
Sat Sep 10 01:10:41 CEST 2005
Author: tismer
Date: Sat Sep 10 01:10:39 2005
New Revision: 17436
Modified:
pypy/dist/pypy/rpython/rlist.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 specialization for index checking to (x)range.
reversed dependencies of imports.
Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py (original)
+++ pypy/dist/pypy/rpython/rlist.py Sat Sep 10 01:10:39 2005
@@ -3,7 +3,6 @@
from pypy.objspace.flow.model import Constant
from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst
from pypy.rpython.rmodel import IteratorRepr
-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
@@ -29,6 +28,7 @@
class __extend__(annmodel.SomeList):
def rtyper_makerepr(self, rtyper):
+ from pypy.rpython import rrange
listitem = self.listdef.listitem
s_value = listitem.s_value
if listitem.range_step and not listitem.mutated:
Modified: pypy/dist/pypy/rpython/rrange.py
==============================================================================
--- pypy/dist/pypy/rpython/rrange.py (original)
+++ pypy/dist/pypy/rpython/rrange.py Sat Sep 10 01:10:39 2005
@@ -3,6 +3,7 @@
from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, IteratorRepr
from pypy.rpython.lltype import Ptr, GcStruct, Signed, malloc, Void
from pypy.objspace.flow.model import Constant
+from pypy.rpython.rlist import ll_newlist, dum_nocheck, dum_checkidx
# ____________________________________________________________
#
@@ -34,9 +35,12 @@
class __extend__(pairtype(RangeRepr, IntegerRepr)):
def rtype_getitem((r_rng, r_int), hop):
+ from pypy.rpython.rlist import dum_nocheck, dum_checkidx
if hop.has_implicit_exception(IndexError):
- s = "getitem on range with try, except: block not supported."
- raise TyperError, s
+ spec = dum_checkidx
+ else:
+ spec = dum_nocheck
+ v_func = hop.inputconst(Void, spec)
v_lst, v_index = hop.inputargs(r_rng, Signed)
cstep = hop.inputconst(Signed, r_rng.step)
if hop.args_s[1].nonneg:
@@ -44,12 +48,17 @@
else:
llfn = ll_rangeitem
hop.exception_is_here()
- return hop.gendirectcall(llfn, v_lst, v_index, cstep)
+ return hop.gendirectcall(llfn, v_func, v_lst, v_index, cstep)
# ____________________________________________________________
#
# Low-level methods.
+# XXX I think range could be simplified and generalized by storing the
+# range length and a current index, but no stop value at all.
+# The iterator would always use indexing, which implies a multiplication
+# in the range, but that's low cost.
+
def _ll_rangelen(start, stop, step):
if step > 0:
result = (stop - start + (step-1)) // step
@@ -62,14 +71,23 @@
def ll_rangelen(l, step):
return _ll_rangelen(l.start, l.stop, step)
-def ll_rangeitem_nonneg(l, i, step):
- return l.start + i*step
-
-def ll_rangeitem(l, i, step):
- if i < 0:
- length = ll_rangelen(l, step)
- i += length
- return l.start + i*step
+def ll_rangeitem_nonneg(func, l, index, step):
+ if func is dum_checkidx and index >= _ll_rangelen(l.start, l.stop, step):
+ raise IndexError
+ return l.start + index * step
+
+def ll_rangeitem(func, l, index, step):
+ if func is dum_checkidx:
+ length = _ll_rangelen(l.start, l.stop, step)
+ if index < 0:
+ index += length
+ if index < 0 or index >= length:
+ raise IndexError
+ else:
+ if index < 0:
+ length = _ll_rangelen(l.start, l.stop, step)
+ index += length
+ return l.start + index * step
# ____________________________________________________________
#
@@ -103,7 +121,6 @@
rtype_builtin_xrange = rtype_builtin_range
def ll_range2list(LISTPTR, start, stop, step):
- from pypy.rpython.rlist import ll_newlist
length = _ll_rangelen(start, stop, step)
l = ll_newlist(LISTPTR, length)
idx = 0
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 Sat Sep 10 01:10:39 2005
@@ -8,11 +8,11 @@
length = len(expected)
l = ll_newrange(start, stop)
assert ll_rangelen(l, step) == length
- lst = [ll_rangeitem(l, i, step) for i in range(length)]
+ lst = [ll_rangeitem(dum_nocheck, l, i, step) for i in range(length)]
assert lst == expected
- lst = [ll_rangeitem_nonneg(l, i, step) for i in range(length)]
+ lst = [ll_rangeitem_nonneg(dum_nocheck, l, i, step) for i in range(length)]
assert lst == expected
- lst = [ll_rangeitem(l, i-length, step) for i in range(length)]
+ lst = [ll_rangeitem(dum_nocheck, l, i-length, step) for i in range(length)]
assert lst == expected
for start in (-10, 0, 1, 10):
@@ -74,6 +74,5 @@
r.reverse()
return r[0]
start, stop = 10, 17
- res = interpret(dummyfn, [start, stop])#, view=True)
+ res = interpret(dummyfn, [start, stop]))
assert res == dummyfn(start, stop)
-
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 Sat Sep 10 01:10:39 2005
@@ -357,3 +357,14 @@
return r[0]
f = self.getcompiled(fn)
assert f() == fn()
+
+ def test_range_idx(self):
+ def fn(idx=int):
+ r = range(10, 37, 4)
+ try:
+ return r[idx]
+ except: raise
+ f = self.getcompiled(fn)
+ assert f(0) == fn(0)
+ assert f(-1) == fn(-1)
+ raises(IndexError, f, 42)
\ No newline at end of file
More information about the Pypy-commit
mailing list