Commit 3bad2267 authored by Magnus Lie Hetland's avatar Magnus Lie Hetland

Fix for #196

parent 1fdb965c
...@@ -3904,9 +3904,15 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -3904,9 +3904,15 @@ class ForFromStatNode(LoopNode, StatNode):
self.bound1.generate_evaluation_code(code) self.bound1.generate_evaluation_code(code)
self.bound2.generate_evaluation_code(code) self.bound2.generate_evaluation_code(code)
offset, incop = self.relation_table[self.relation1] offset, incop = self.relation_table[self.relation1]
if incop == "++":
decop = "--"
else:
decop = "++"
if self.step is not None: if self.step is not None:
self.step.generate_evaluation_code(code) self.step.generate_evaluation_code(code)
incop = "%s=%s" % (incop[0], self.step.result()) step = self.step.result()
incop = "%s=%s" % (incop[0], step)
decop = "%s=%s" % (decop[0], step)
loopvar_name = self.loopvar_node.result() loopvar_name = self.loopvar_node.result()
code.putln( code.putln(
"for (%s = %s%s; %s %s %s; %s%s) {" % ( "for (%s = %s%s; %s %s %s; %s%s) {" % (
...@@ -3919,6 +3925,10 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -3919,6 +3925,10 @@ class ForFromStatNode(LoopNode, StatNode):
self.target.generate_assignment_code(self.py_loopvar_node, code) self.target.generate_assignment_code(self.py_loopvar_node, code)
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.put_label(code.continue_label) code.put_label(code.continue_label)
if getattr(self, "from_range", False):
# Undo last increment to maintain Python semantics:
code.putln("} %s%s;" % (loopvar_name, decop))
else:
code.putln("}") code.putln("}")
break_label = code.break_label break_label = code.break_label
code.set_loop_labels(old_loop_labels) code.set_loop_labels(old_loop_labels)
......
...@@ -144,7 +144,8 @@ class IterationTransform(Visitor.VisitorTransform): ...@@ -144,7 +144,8 @@ class IterationTransform(Visitor.VisitorTransform):
relation2=relation2, bound2=bound2, relation2=relation2, bound2=bound2,
step=step, body=node.body, step=step, body=node.body,
else_clause=node.else_clause, else_clause=node.else_clause,
loopvar_node=node.target) loopvar_node=node.target,
from_range=True)
return for_node return for_node
def _transform_dict_iteration(self, node, dict_obj, keys, values): def _transform_dict_iteration(self, node, dict_obj, keys, values):
......
"""
>>> range_loop_indices()
** Calculating step **
(9, 9, 8, 1, 2)
>>> from_loop_indices()
** Calculating step **
** Calculating step **
** Calculating step **
** Calculating step **
** Calculating step **
(10, 10, 0)
"""
cdef int get_step():
"""
This should only be called once, when used in range().
"""
print "** Calculating step **"
return 2
def range_loop_indices():
"""
Optimized integer for loops using range() should follow Python behavior,
and leave the index variable with the last value of the range.
"""
cdef int i, j, k, l, m
for i in range(10): pass
for j in range(2,10): pass
for k in range(0,10,get_step()): pass
for l in range(10,0,-1): pass
for m in range(10,0,-2): pass
return i, j, k, l, m
def from_loop_indices():
"""
for-from-loops should follow C behavior, and leave the index variable
incremented one step after the last iteration.
"""
cdef int i, j, k
for i from 0 <= i < 10 by get_step(): pass
for j from 0 <= j < 10: pass
for k from 10 > k > 0: pass
return i, j, k
\ No newline at end of file
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