Commit 2d146971 authored by root's avatar root

Functioning with Nodes which do not have a constant value that is a long or int.

parent db4001fa
......@@ -663,20 +663,64 @@ class IterationTransform(Visitor.EnvTransform):
if abs_step != 1:
if not (isinstance(bound1.constant_result, (int, long)) and
isinstance(bound2.constant_result, (int, long))):
# FIXME: calculate final bounds at runtime
return node
if step_value < 0:
begin_value = bound2.constant_result
end_value = bound1.constant_result
bound1_value = begin_value - abs_step * ((begin_value - end_value - 1) // abs_step) - 1
spanning_type = PyrexTypes.spanning_type(bound1.type, bound2.type)
spanning_step_type = PyrexTypes.spanning_type(spanning_type, step.type)
if step_value < 0:
begin_value = bound2
end_value = bound1
final_op = '-'
final_node = ExprNodes.SubNode
else:
begin_value = bound1
end_value = bound2
final_op = '+'
final_node = ExprNodes.AddNode
beg_sub_end = ExprNodes.SubNode(bound1.pos,
operand1=begin_value,
operator='-',
operand2=end_value,
type=spanning_type)
one_node = ExprNodes.IntNode(bound1.pos, value='1', constant_result=1)
beg_sub_end_sub_1 = ExprNodes.SubNode(bound1.pos,
operand1=beg_sub_end,
operator='-',
operand2=one_node,
type=spanning_step_type)
abs_step_node = ExprNodes.IntNode(bound1.pos, value=str(abs_step), constant_value=abs_step)
div_val_node = ExprNodes.DivNode(bound1.pos,
operand1=beg_sub_end_sub_1,
operator='//',
operand2=abs_step_node,
type=spanning_step_type)
delta_node = ExprNodes.MulNode(bound1.pos,
operand1=abs_step_node,
operator='*',
operand2=div_val_node,
type=spanning_step_type)
beg_func_delta = final_node(bound1.pos,
operand1=bound2,
operator=final_op,
operand2=delta_node,
type=spanning_step_type)
bound1 = final_node(bound1.pos,
operand1=beg_func_delta,
operator=final_op,
operand2=one_node,
type=spanning_type)
else:
begin_value = bound1.constant_result
end_value = bound2.constant_result
bound1_value = end_value + abs_step * ((begin_value - end_value - 1) // abs_step) + 1
bound1 = ExprNodes.IntNode(
bound1.pos, value=str(bound1_value), constant_result=bound1_value,
type=PyrexTypes.spanning_type(bound1.type, bound2.type))
if step_value < 0:
begin_value = bound2.constant_result
end_value = bound1.constant_result
bound1_value = begin_value - abs_step * ((begin_value - end_value - 1) // abs_step) - 1
else:
begin_value = bound1.constant_result
end_value = bound2.constant_result
bound1_value = end_value + abs_step * ((begin_value - end_value - 1) // abs_step) + 1
bound1 = ExprNodes.IntNode(
bound1.pos, value=str(bound1_value), constant_result=bound1_value,
type=PyrexTypes.spanning_type(bound1.type, bound2.type))
if step_value < 0:
step_value = -step_value
......
......@@ -134,7 +134,8 @@ def reversed_range_step_neg(int a, int b):
return result, i
#cython.test_assert_path_exists('//ForFromStatNode')
@cython.test_assert_path_exists('//ForFromStatNode')
@cython.test_fail_if_path_exists('//ForInStatNode')
def reversed_range_step3(int a, int b):
"""
>>> [ i for i in _reversed(range(-5, 0, 3)) ]
......@@ -159,6 +160,32 @@ def reversed_range_step3(int a, int b):
return result, i
@cython.test_assert_path_exists('//ForFromStatNode')
@cython.test_fail_if_path_exists('//ForInStatNode')
def reversed_range_step3_neg(int a, int b):
"""
>>> [ i for i in _reversed(range(0, -5, -3)) ]
[-3, 0]
>>> reversed_range_step3_neg(0, -5)
([-3, 0], 0)
>>> [ i for i in _reversed(range(5, 0, -3)) ]
[2, 5]
>>> reversed_range_step3_neg(5, 0)
([2, 5], 5)
>>> [ i for i in _reversed(range(0, 5, -3)) ]
[]
>>> reversed_range_step3_neg(0, 5)
([], 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_fail_if_path_exists('//ForInStatNode')
def reversed_range_constant():
......
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