From e994a8b7d945de650dc07cb47abd393c87a8e79a Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Sat, 19 Jul 2008 22:40:11 +0200 Subject: [PATCH] Assignments on cdef variables are transformed into singleassignments --- Cython/Compiler/Nodes.py | 10 +++------- Cython/Compiler/ParseTreeTransforms.py | 21 ++++++++++++++++++++- tests/run/bufaccess.pyx | 16 ++++++++++++---- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index fb2b8060..8fdaae42 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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 diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 070e1f6f..4cf5e356 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -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 diff --git a/tests/run/bufaccess.pyx b/tests/run/bufaccess.pyx index 6c7cb544..14981d9e 100644 --- a/tests/run/bufaccess.pyx +++ b/tests/run/bufaccess.pyx @@ -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 -- 2.26.2