Commit aed0ff79 authored by Stefan Behnel's avatar Stefan Behnel

move extensive node building code for range step calculation into a separate method

parent aec6fcff
...@@ -743,13 +743,44 @@ class IterationTransform(Visitor.EnvTransform): ...@@ -743,13 +743,44 @@ class IterationTransform(Visitor.EnvTransform):
else: else:
# evaluate the same expression as above at runtime # evaluate the same expression as above at runtime
bound2_ref_node = UtilNodes.LetRefNode(bound2) bound2_ref_node = UtilNodes.LetRefNode(bound2)
spanning_type = PyrexTypes.spanning_type(bound1.type, bound2.type) bound1 = self._build_range_step_calculation(
bound1, bound2_ref_node, step, step_value)
if step_value < 0:
step_value = -step_value
step.value = str(step_value)
step.constant_result = step_value
step = step.coerce_to_integer(self.current_env())
if not bound2.is_literal:
# stop bound must be immutable => keep it in a temp var
bound2_is_temp = True
bound2 = bound2_ref_node or UtilNodes.LetRefNode(bound2)
else:
bound2_is_temp = False
for_node = Nodes.ForFromStatNode(
node.pos,
target=node.target,
bound1=bound1, relation1=relation1,
relation2=relation2, bound2=bound2,
step=step, body=node.body,
else_clause=node.else_clause,
from_range=True)
if bound2_is_temp:
for_node = UtilNodes.LetNode(bound2, for_node)
return for_node
def _build_range_step_calculation(self, bound1, bound2_ref_node, step, step_value):
abs_step = abs(step_value)
spanning_type = PyrexTypes.spanning_type(bound1.type, bound2_ref_node.type)
if step.type.is_int and abs_step < 0x7FFF: if step.type.is_int and abs_step < 0x7FFF:
# Avoid loss of integer precision warnings. # Avoid loss of integer precision warnings.
spanning_step_type = PyrexTypes.spanning_type(spanning_type, PyrexTypes.c_int_type) spanning_step_type = PyrexTypes.spanning_type(spanning_type, PyrexTypes.c_int_type)
else: else:
spanning_step_type = PyrexTypes.spanning_type(spanning_type, step.type) spanning_step_type = PyrexTypes.spanning_type(spanning_type, step.type)
if step_value < 0: if step_value < 0:
begin_value = bound2_ref_node begin_value = bound2_ref_node
end_value = bound1 end_value = bound1
...@@ -759,7 +790,7 @@ class IterationTransform(Visitor.EnvTransform): ...@@ -759,7 +790,7 @@ class IterationTransform(Visitor.EnvTransform):
end_value = bound2_ref_node end_value = bound2_ref_node
final_op = '+' final_op = '+'
bound1 = ExprNodes.binop_node( step_calculation_node = ExprNodes.binop_node(
bound1.pos, bound1.pos,
operand1=ExprNodes.binop_node( operand1=ExprNodes.binop_node(
bound1.pos, bound1.pos,
...@@ -804,33 +835,7 @@ class IterationTransform(Visitor.EnvTransform): ...@@ -804,33 +835,7 @@ class IterationTransform(Visitor.EnvTransform):
value='1', value='1',
constant_result=1), constant_result=1),
type=spanning_type) type=spanning_type)
return step_calculation_node
if step_value < 0:
step_value = -step_value
step.value = str(step_value)
step.constant_result = step_value
step = step.coerce_to_integer(self.current_env())
if not bound2.is_literal:
# stop bound must be immutable => keep it in a temp var
bound2_is_temp = True
bound2 = bound2_ref_node or UtilNodes.LetRefNode(bound2)
else:
bound2_is_temp = False
for_node = Nodes.ForFromStatNode(
node.pos,
target=node.target,
bound1=bound1, relation1=relation1,
relation2=relation2, bound2=bound2,
step=step, body=node.body,
else_clause=node.else_clause,
from_range=True)
if bound2_is_temp:
for_node = UtilNodes.LetNode(bound2, for_node)
return for_node
def _transform_dict_iteration(self, node, dict_obj, method, keys, values): def _transform_dict_iteration(self, node, dict_obj, method, keys, values):
temps = [] temps = []
......
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