cython-devel
changeset 1673:5730e9a933ef
Fix for #196
| author | Magnus Lie Hetland |
|---|---|
| date | Fri Jan 30 15:53:16 2009 +0100 (3 years ago) |
| parents | 41ac022ba25c |
| children | 55c8d03e36e1 |
| files | Cython/Compiler/Nodes.py Cython/Compiler/Optimize.py tests/run/for_decrement.pyx |
line diff
1.1 --- a/Cython/Compiler/Nodes.py Fri Jan 30 10:54:11 2009 +0100
1.2 +++ b/Cython/Compiler/Nodes.py Fri Jan 30 15:53:16 2009 +0100
1.3 @@ -3904,9 +3904,15 @@
1.4 self.bound1.generate_evaluation_code(code)
1.5 self.bound2.generate_evaluation_code(code)
1.6 offset, incop = self.relation_table[self.relation1]
1.7 + if incop == "++":
1.8 + decop = "--"
1.9 + else:
1.10 + decop = "++"
1.11 if self.step is not None:
1.12 self.step.generate_evaluation_code(code)
1.13 - incop = "%s=%s" % (incop[0], self.step.result())
1.14 + step = self.step.result()
1.15 + incop = "%s=%s" % (incop[0], step)
1.16 + decop = "%s=%s" % (decop[0], step)
1.17 loopvar_name = self.loopvar_node.result()
1.18 code.putln(
1.19 "for (%s = %s%s; %s %s %s; %s%s) {" % (
1.20 @@ -3919,7 +3925,11 @@
1.21 self.target.generate_assignment_code(self.py_loopvar_node, code)
1.22 self.body.generate_execution_code(code)
1.23 code.put_label(code.continue_label)
1.24 - code.putln("}")
1.25 + if getattr(self, "from_range", False):
1.26 + # Undo last increment to maintain Python semantics:
1.27 + code.putln("} %s%s;" % (loopvar_name, decop))
1.28 + else:
1.29 + code.putln("}")
1.30 break_label = code.break_label
1.31 code.set_loop_labels(old_loop_labels)
1.32 if self.else_clause:
2.1 --- a/Cython/Compiler/Optimize.py Fri Jan 30 10:54:11 2009 +0100
2.2 +++ b/Cython/Compiler/Optimize.py Fri Jan 30 15:53:16 2009 +0100
2.3 @@ -144,7 +144,8 @@
2.4 relation2=relation2, bound2=bound2,
2.5 step=step, body=node.body,
2.6 else_clause=node.else_clause,
2.7 - loopvar_node=node.target)
2.8 + loopvar_node=node.target,
2.9 + from_range=True)
2.10 return for_node
2.11
2.12 def _transform_dict_iteration(self, node, dict_obj, keys, values):
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/tests/run/for_decrement.pyx Fri Jan 30 15:53:16 2009 +0100
3.3 @@ -0,0 +1,43 @@
3.4 +"""
3.5 +>>> range_loop_indices()
3.6 +** Calculating step **
3.7 +(9, 9, 8, 1, 2)
3.8 +>>> from_loop_indices()
3.9 +** Calculating step **
3.10 +** Calculating step **
3.11 +** Calculating step **
3.12 +** Calculating step **
3.13 +** Calculating step **
3.14 +(10, 10, 0)
3.15 +"""
3.16 +
3.17 +cdef int get_step():
3.18 + """
3.19 + This should only be called once, when used in range().
3.20 + """
3.21 + print "** Calculating step **"
3.22 + return 2
3.23 +
3.24 +def range_loop_indices():
3.25 + """
3.26 + Optimized integer for loops using range() should follow Python behavior,
3.27 + and leave the index variable with the last value of the range.
3.28 + """
3.29 + cdef int i, j, k, l, m
3.30 + for i in range(10): pass
3.31 + for j in range(2,10): pass
3.32 + for k in range(0,10,get_step()): pass
3.33 + for l in range(10,0,-1): pass
3.34 + for m in range(10,0,-2): pass
3.35 + return i, j, k, l, m
3.36 +
3.37 +def from_loop_indices():
3.38 + """
3.39 + for-from-loops should follow C behavior, and leave the index variable
3.40 + incremented one step after the last iteration.
3.41 + """
3.42 + cdef int i, j, k
3.43 + for i from 0 <= i < 10 by get_step(): pass
3.44 + for j from 0 <= j < 10: pass
3.45 + for k from 10 > k > 0: pass
3.46 + return i, j, k
3.47 \ No newline at end of file
