Assignments on cdef variables are transformed into singleassignments
authorDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Sat, 19 Jul 2008 20:40:11 +0000 (22:40 +0200)
committerDag Sverre Seljebotn <dagss@student.matnat.uio.no>
Sat, 19 Jul 2008 20:40:11 +0000 (22:40 +0200)
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py
tests/run/bufaccess.pyx

index fb2b80604aa74702d7b0deb8a127373e0e53f801..8fdaae427cb2c73d0a6d8b172d8162c37ef83e69 100644 (file)
@@ -388,13 +388,9 @@ class CNameDeclaratorNode(CDeclaratorNode):
             self.default.release_temp(env)
 
     def generate_execution_code(self, code):
-        if self.default is not None:
-            self.default.generate_evaluation_code(code)
-            if self.type.is_pyobject:
-                self.default.make_owned_reference(code)
-            code.putln('%s = %s;' % (self.entry.cname, self.default.result_as(self.entry.type)))
-            self.default.generate_post_assignment_code(code)
-            code.putln()
+        assert self.default is None
+        # PostParse creates assignment statements for any
+        # default values
 
 class CPtrDeclaratorNode(CDeclaratorNode):
     # base     CDeclaratorNode
index 070e1f6f0a0097e704a33d5bb5af621231e1a4ce..4cf5e356ba0b5fd6c49198dbbff4d7504af9c4d0 100644 (file)
@@ -91,6 +91,8 @@ class PostParse(CythonTransform):
     as such).
 
     Specifically:
+    - Default values to cdef assignments are turned into single
+    assignments following the declaration.
     - CBufferAccessTypeNode has its options interpreted:
     Any first positional argument goes into the "dtype" attribute,
     any "ndim" keyword argument goes into the "ndim" attribute and
@@ -101,6 +103,23 @@ class PostParse(CythonTransform):
     if a more pure Abstract Syntax Tree is wanted.
     """
 
+    def visit_CVarDefNode(self, node):
+        # This assumes only plain names and pointers are assignable on
+        # declaration.
+        self.visitchildren(node)
+        stats = [node]
+        for decl in node.declarators:
+            while isinstance(decl, CPtrDeclaratorNode):
+                decl = decl.base
+            if isinstance(decl, CNameDeclaratorNode):
+                if decl.default is not None:
+                    stats.append(SingleAssignmentNode(node.pos,
+                        lhs=NameNode(node.pos, name=decl.name),
+                        rhs=decl.default))
+                    decl.default = None
+        return stats
+            
+
     buffer_options = ("dtype", "ndim") # ordered!
     def visit_CBufferAccessTypeNode(self, node):
         options = {}
@@ -263,7 +282,7 @@ class AnalyseExpressionsTransform(CythonTransform):
         node.body.analyse_expressions(node.local_scope)
         self.visitchildren(node)
         return node
-        
+
 class MarkClosureVisitor(CythonTransform):
     
     needs_closure = False
index 6c7cb5445b89ba45008b94cf454110d289031918..14981d9eb4bc0c7d069c1a73968c81d84017612a 100644 (file)
@@ -34,6 +34,12 @@ __doc__ = u"""
     acquired
     0 1 2 3 4 5
     released
+
+    >>> cdef_assignment(A, 6)
+    acquired A
+    0 1 2 3 4 5
+    released A
+    
     >>> printbuf_float(MockBuffer("f", [1.0, 1.25, 0.75, 1.0]), (4,))
     acquired
     1.0 1.25 0.75 1.0
@@ -86,11 +92,13 @@ def as_argument_defval(object[int] bufarg=MockBuffer('i', range(6)), int n=6):
         print bufarg[i],
     print
 
+def cdef_assignment(obj, n):
+    cdef object[int] buf = obj
+    cdef int i
+    for i in range(n):
+        print buf[i],
+    print
 
-
-# default values
-# 
-    
 def printbuf_float(o, shape):
     # should make shape builtin
     cdef object[float] buf