Commit bd80e73b authored by root's avatar root

Optimized reversed-range call when constants are inside of the range.

parent a62c801d
...@@ -644,9 +644,6 @@ class IterationTransform(Visitor.EnvTransform): ...@@ -644,9 +644,6 @@ class IterationTransform(Visitor.EnvTransform):
if step_value == 0: if step_value == 0:
# will lead to an error elsewhere # will lead to an error elsewhere
return node return node
if reversed and step_value not in (1, -1):
# FIXME: currently broken - requires calculation of the correct bounds
return node
if not isinstance(step, ExprNodes.IntNode): if not isinstance(step, ExprNodes.IntNode):
step = ExprNodes.IntNode(step_pos, value=str(step_value), step = ExprNodes.IntNode(step_pos, value=str(step_value),
constant_result=step_value) constant_result=step_value)
...@@ -665,6 +662,14 @@ class IterationTransform(Visitor.EnvTransform): ...@@ -665,6 +662,14 @@ class IterationTransform(Visitor.EnvTransform):
bound1, bound2 = bound2, bound1 bound1, bound2 = bound2, bound1
if step_value < 0: if step_value < 0:
step_value = -step_value step_value = -step_value
if step_value != 1:
if isinstance(bound1, ExprNodes.NameNode) or isinstance(bound2, ExprNodes.NameNode):
# FIXME: Optimize when variable is in range (e.g. reversed(range(x, y, 3)))
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,9 +133,88 @@ def reversed_range_step_neg(int a, int b): ...@@ -133,9 +133,88 @@ 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') @cython.test_assert_path_exists('//ForFromStatNode')
def reversed_range_step4():
"""
>>> [ i for i in _reversed(range(-12, -2, 4)) ]
[-4, -8, -12]
>>> reversed_range_step4()
([-4, -8, -12], -12)
"""
cdef int i = 99
result = []
for i in reversed(range(1, 1, 4)):
result.append(i)
assert result == list(reversed(range(1, 1, 4)))
assert i == 99
for i in reversed(range(0, 1, 4)):
result.append(i)
assert result == list(reversed(range(0, 1, 4)))
result = []
for i in reversed(range(1, 8, 4)):
result.append(i)
assert result == list(reversed(range(1, 8, 4)))
result = []
for i in reversed(range(1, 9, 4)):
result.append(i)
assert result == list(reversed(range(1, 9, 4)))
result = []
for i in reversed(range(1, 10, 4)):
result.append(i)
assert result == list(reversed(range(1, 10, 4)))
result = []
for i in reversed(range(1, 11, 4)):
result.append(i)
assert result == list(reversed(range(1, 11, 4)))
result = []
for i in reversed(range(1, 12, 4)):
result.append(i)
assert result == list(reversed(range(1, 12, 4)))
result = []
for i in reversed(range(0, 8, 4)):
result.append(i)
assert result == list(reversed(range(0, 8, 4)))
result = []
for i in reversed(range(0, 9, 4)):
result.append(i)
assert result == list(reversed(range(0, 9, 4)))
result = []
for i in reversed(range(0, 10, 4)):
result.append(i)
assert result == list(reversed(range(0, 10, 4)))
result = []
for i in reversed(range(0, 11, 4)):
result.append(i)
assert result == list(reversed(range(0, 11, 4)))
result = []
for i in reversed(range(0, 12, 4)):
result.append(i)
assert result == list(reversed(range(0, 12, 4)))
result = []
for i in reversed(range(-12, -2, 4)):
result.append(i)
return result, i
#cython.test_assert_path_exists('//ForFromStatNode')
def reversed_range_step3(int a, int b): 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)) ] >>> [ i for i in _reversed(range(0, 5, 3)) ]
[3, 0] [3, 0]
>>> reversed_range_step3(0, 5) >>> reversed_range_step3(0, 5)
......
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