2009/3/21 Lisandro Dalcin <[email protected]>

> On Sat, Mar 21, 2009 at 9:24 AM, Stefan Behnel <[email protected]>
> wrote:
> >>>>>
> >>>>> for i from 0 <= i < 10:
> >>>>>      print i
> >>>>>      i += 5
> >
> > So I'm +1 for officially allowing the above and making it exit early.
> > Letting Cython basically ignore the "i += 5" would be a bug.
> >
>
> Me too, +1.
>
>
>
> --
> Lisandro Dalcín
> ---------------
> Centro Internacional de Métodos Computacionales en Ingeniería (CIMEC)
> Instituto de Desarrollo Tecnológico para la Industria Química (INTEC)
> Consejo Nacional de Investigaciones Científicas y Técnicas (CONICET)
> PTLC - Güemes 3450, (3000) Santa Fe, Argentina
> Tel/Fax: +54-(0)342-451.1594
> _______________________________________________
> Cython-dev mailing list
> [email protected]
> http://codespeak.net/mailman/listinfo/cython-dev
>

I looked at a range optimization example

cdef int g():
    print "g called"
    return 10

def f():
    cdef int i
    for i in range(0, g(), 2):
        print i
        i += 2

This gives the following output -

>>>
g called
0
4
8

Is this the output we are expecting?  I for one expected i to hold the next
value from the list supplied by range every time it iterates over the loop,
inspite of i being defined as a cdef int type.

I created a temp variable inside Nodes.py.  Every time i enter the loop, i
assign the loop counter var to the temp.  Inside the loop, there on I can
modify the loop counter, but at the end of the loop i reassign the temp back
to the loop counter var.

This is the code change i made

diff -r 651a88137be7 Cython/Compiler/Nodes.py
--- a/Cython/Compiler/Nodes.py  Fri Mar 20 17:51:46 2009 +0100
+++ b/Cython/Compiler/Nodes.py  Sun Mar 22 21:05:41 2009 +0530
@@ -3968,6 +3968,7 @@
         loopvar_name = self.loopvar_node.result()
         if from_range:
             range_bound = code.funcstate.allocate_temp(self.bound2.type,
manage_ref=False)
+            temp_loop_counter =
code.funcstate.allocate_temp(self.loopvar_node.type, manage_ref=False)
             code.putln("%s = %s;" % (range_bound, self.bound2.result()))
             # Skip the loop entirely (and avoid assigning to the loopvar)
if
             # the loop is empty:
@@ -3976,18 +3977,22 @@
                 ))
         else:
             range_bound = self.bound2.result()
         code.putln(
             "for (%s = %s%s; %s %s %s; %s%s) {" % (
                 loopvar_name,
                 self.bound1.result(), offset,
                 loopvar_name, self.relation2, range_bound,
                 loopvar_name, incop))
+        if from_range:
+            code.putln("%s = %s;" % (temp_loop_counter, loopvar_name))
         if self.py_loopvar_node:
             self.py_loopvar_node.generate_evaluation_code(code)
             self.target.generate_assignment_code(self.py_loopvar_node,
code)
         self.body.generate_execution_code(code)
         code.put_label(code.continue_label)
         if from_range:
+            code.putln("%s = %s;" % (loopvar_name, temp_loop_counter))
             # Undo last increment to maintain Python semantics:
             code.putln("} %s%s;" % (loopvar_name, decop))
             # End the outer if statement:

With that I get the following output-
g called
0
2
4
6
8

Shouldn't this be the expected output?

-- 
Regards,
Anoop S.
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to