Commit ff852bac authored by Stefan Behnel's avatar Stefan Behnel

refactor and make reversed(range()) optimisation apply only to known bounds, not any non-NameNode

parent b1f82f65
...@@ -663,13 +663,16 @@ class IterationTransform(Visitor.EnvTransform): ...@@ -663,13 +663,16 @@ class IterationTransform(Visitor.EnvTransform):
if step_value < 0: if step_value < 0:
step_value = -step_value step_value = -step_value
if step_value != 1: if step_value != 1:
if isinstance(bound1, ExprNodes.NameNode) or isinstance(bound2, ExprNodes.NameNode): begin_value = bound1.constant_result
end_value = bound2.constant_result
if isinstance(begin_value, (int, long)) and isinstance(end_value, (int, long)):
bound1_value = step_value * ((begin_value - end_value - 1) // step_value) + end_value + 1
bound1 = ExprNodes.IntNode(
bound1.pos, value=str(bound1_value), constant_result=bound1_value,
type=PyrexTypes.widest_numeric_type(bound1.type, bound2.type))
else:
# FIXME: Optimize when variable is in range (e.g. reversed(range(x, y, 3))) # FIXME: Optimize when variable is in range (e.g. reversed(range(x, y, 3)))
return node return node
else:
end_value = int(bound2.value)
begin_value = int(bound1.value)
bound1.value = str(step_value*((begin_value-end_value-1) // step_value) + end_value+1)
else: else:
if step_value < 0: if step_value < 0:
step_value = -step_value step_value = -step_value
......
...@@ -133,12 +133,39 @@ def reversed_range_step_neg(int a, int b): ...@@ -133,12 +133,39 @@ def reversed_range_step_neg(int a, int b):
result.append(i) result.append(i)
return result, i return result, i
#cython.test_assert_path_exists('//ForFromStatNode')
def reversed_range_step3(int a, int b):
"""
>>> [ i for i in _reversed(range(-5, 0, 3)) ]
[-2, -5]
>>> reversed_range_step3(-5, 0)
([-2, -5], -5)
>>> [ i for i in _reversed(range(0, 5, 3)) ]
[3, 0]
>>> reversed_range_step3(0, 5)
([3, 0], 0)
>>> [ i for i in _reversed(range(5, 0, 3)) ]
[]
>>> reversed_range_step3(5, 0)
([], 99)
"""
cdef int i = 99
result = []
for i in reversed(range(a, b, 3)):
result.append(i)
return result, i
@cython.test_assert_path_exists('//ForFromStatNode') @cython.test_assert_path_exists('//ForFromStatNode')
def reversed_range_step4(): @cython.test_fail_if_path_exists('//ForInStatNode')
def reversed_range_constant():
""" """
>>> [ i for i in _reversed(range(-12, -2, 4)) ] >>> [ i for i in _reversed(range(-12, -2, 4)) ]
[-4, -8, -12] [-4, -8, -12]
>>> reversed_range_step4() >>> reversed_range_constant()
([-4, -8, -12], -12) ([-4, -8, -12], -12)
""" """
cdef int i = 99 cdef int i = 99
...@@ -207,29 +234,6 @@ def reversed_range_step4(): ...@@ -207,29 +234,6 @@ def reversed_range_step4():
result.append(i) result.append(i)
return result, i return result, i
#cython.test_assert_path_exists('//ForFromStatNode')
def reversed_range_step3(int a, int b):
"""
>>> [ i for i in _reversed(range(-5, 0, 3)) ]
[-2, -5]
>>> reversed_range_step3(-5, 0)
([-2, -5], -5)
>>> [ i for i in _reversed(range(0, 5, 3)) ]
[3, 0]
>>> reversed_range_step3(0, 5)
([3, 0], 0)
>>> [ i for i in _reversed(range(5, 0, 3)) ]
[]
>>> reversed_range_step3(5, 0)
([], 99)
"""
cdef int i = 99
result = []
for i in reversed(range(a, b, 3)):
result.append(i)
return result, i
unicode_string = u"abcDEF" unicode_string = u"abcDEF"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment