| 1 | # HG changeset patch |
|---|
| 2 | # User Magnus Lie Hetland <magnus@hetland.org> |
|---|
| 3 | # Date 1233323896 -3600 |
|---|
| 4 | # Node ID 8ec1acab2e2236e48dede5f44b066a6ca0460daf |
|---|
| 5 | # Parent 41ac022ba25ce119cbd22455de2a8291c7281d5a |
|---|
| 6 | Fixed #196 |
|---|
| 7 | |
|---|
| 8 | diff -r 41ac022ba25c -r 8ec1acab2e22 Cython/Compiler/Nodes.py |
|---|
| 9 | --- a/Cython/Compiler/Nodes.py Fri Jan 30 10:54:11 2009 +0100 |
|---|
| 10 | +++ b/Cython/Compiler/Nodes.py Fri Jan 30 14:58:16 2009 +0100 |
|---|
| 11 | @@ -3904,9 +3904,15 @@ |
|---|
| 12 | self.bound1.generate_evaluation_code(code) |
|---|
| 13 | self.bound2.generate_evaluation_code(code) |
|---|
| 14 | offset, incop = self.relation_table[self.relation1] |
|---|
| 15 | + if incop == "++": |
|---|
| 16 | + decop = "--" |
|---|
| 17 | + else: |
|---|
| 18 | + decop = "++" |
|---|
| 19 | if self.step is not None: |
|---|
| 20 | self.step.generate_evaluation_code(code) |
|---|
| 21 | - incop = "%s=%s" % (incop[0], self.step.result()) |
|---|
| 22 | + step = self.step.result() |
|---|
| 23 | + incop = "%s=%s" % (incop[0], step) |
|---|
| 24 | + decop = "%s=%s" % (decop[0], step) |
|---|
| 25 | loopvar_name = self.loopvar_node.result() |
|---|
| 26 | code.putln( |
|---|
| 27 | "for (%s = %s%s; %s %s %s; %s%s) {" % ( |
|---|
| 28 | @@ -3919,7 +3925,11 @@ |
|---|
| 29 | self.target.generate_assignment_code(self.py_loopvar_node, code) |
|---|
| 30 | self.body.generate_execution_code(code) |
|---|
| 31 | code.put_label(code.continue_label) |
|---|
| 32 | - code.putln("}") |
|---|
| 33 | + if getattr(self, "from_range", False): |
|---|
| 34 | + # Undo last increment to maintain Python semantics: |
|---|
| 35 | + code.putln("} %s%s;" % (loopvar_name, decop)) |
|---|
| 36 | + else: |
|---|
| 37 | + code.putln("}") |
|---|
| 38 | break_label = code.break_label |
|---|
| 39 | code.set_loop_labels(old_loop_labels) |
|---|
| 40 | if self.else_clause: |
|---|
| 41 | diff -r 41ac022ba25c -r 8ec1acab2e22 Cython/Compiler/Optimize.py |
|---|
| 42 | --- a/Cython/Compiler/Optimize.py Fri Jan 30 10:54:11 2009 +0100 |
|---|
| 43 | +++ b/Cython/Compiler/Optimize.py Fri Jan 30 14:58:16 2009 +0100 |
|---|
| 44 | @@ -144,7 +144,8 @@ |
|---|
| 45 | relation2=relation2, bound2=bound2, |
|---|
| 46 | step=step, body=node.body, |
|---|
| 47 | else_clause=node.else_clause, |
|---|
| 48 | - loopvar_node=node.target) |
|---|
| 49 | + loopvar_node=node.target, |
|---|
| 50 | + from_range=True) |
|---|
| 51 | return for_node |
|---|
| 52 | |
|---|
| 53 | def _transform_dict_iteration(self, node, dict_obj, keys, values): |
|---|
| 54 | diff -r 41ac022ba25c -r 8ec1acab2e22 tests/run/for_decrement.pyx |
|---|
| 55 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
|---|
| 56 | +++ b/tests/run/for_decrement.pyx Fri Jan 30 14:58:16 2009 +0100 |
|---|
| 57 | @@ -0,0 +1,43 @@ |
|---|
| 58 | +""" |
|---|
| 59 | +>>> range_loop_indices() |
|---|
| 60 | +** Calculating step ** |
|---|
| 61 | +(9, 9, 8, 1, 2) |
|---|
| 62 | +>>> from_loop_indices() |
|---|
| 63 | +** Calculating step ** |
|---|
| 64 | +** Calculating step ** |
|---|
| 65 | +** Calculating step ** |
|---|
| 66 | +** Calculating step ** |
|---|
| 67 | +** Calculating step ** |
|---|
| 68 | +(10, 10, 0) |
|---|
| 69 | +""" |
|---|
| 70 | + |
|---|
| 71 | +cdef int get_step(): |
|---|
| 72 | + """ |
|---|
| 73 | + This should only be called once, when used in range(). |
|---|
| 74 | + """ |
|---|
| 75 | + print "** Calculating step **" |
|---|
| 76 | + return 2 |
|---|
| 77 | + |
|---|
| 78 | +def range_loop_indices(): |
|---|
| 79 | + """ |
|---|
| 80 | + Optimized integer for loops using range() should follow Python behavior, |
|---|
| 81 | + and leave the index variable with the last value of the range. |
|---|
| 82 | + """ |
|---|
| 83 | + cdef int i, j, k, l, m |
|---|
| 84 | + for i in range(10): pass |
|---|
| 85 | + for j in range(2,10): pass |
|---|
| 86 | + for k in range(0,10,get_step()): pass |
|---|
| 87 | + for l in range(10,0,-1): pass |
|---|
| 88 | + for m in range(10,0,-2): pass |
|---|
| 89 | + return i, j, k, l, m |
|---|
| 90 | + |
|---|
| 91 | +def from_loop_indices(): |
|---|
| 92 | + """ |
|---|
| 93 | + for-from-loops should follow C behavior, and leave the index variable |
|---|
| 94 | + incremented one step after the last iteration. |
|---|
| 95 | + """ |
|---|
| 96 | + cdef int i, j, k |
|---|
| 97 | + for i from 0 <= i < 10 by get_step(): pass |
|---|
| 98 | + for j from 0 <= j < 10: pass |
|---|
| 99 | + for k from 10 > k > 0: pass |
|---|
| 100 | + return i, j, k |
|---|
| 101 | \ No newline at end of file |
|---|