Compile Cython.Compiler.Parsing.py, auto_cpdef, fix bugs in AlignFunctionDefinitions
authorRobert Bradshaw <robertwb@math.washington.edu>
Wed, 12 Nov 2008 01:08:47 +0000 (17:08 -0800)
committerRobert Bradshaw <robertwb@math.washington.edu>
Wed, 12 Nov 2008 01:08:47 +0000 (17:08 -0800)
Cython/Compiler/Main.py
Cython/Compiler/Nodes.py
Cython/Compiler/Options.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Parsing.py
Cython/Plex/Scanners.pxd
setup.py

index 54b70a15324d08a4799300b1252fedd6cc55cd52..6c983c1e32898cb30f511978309c5bb1792833a1 100644 (file)
@@ -102,8 +102,8 @@ class Context:
             NormalizeTree(self),
             PostParse(self),
             _specific_post_parse,
-            _align_function_definitions,
             InterpretCompilerDirectives(self, self.pragma_overrides),
+            _align_function_definitions,
             FlattenInListTransform(),
             WithTransform(self),
             DecoratorTransform(self),
index 67e670496c11650c6e6b8defb1f0f5a53ab946ab..423c7a8b51f55fa038f686f0da16647d0c247a5c 100644 (file)
@@ -1212,6 +1212,7 @@ class CFuncDefNode(FuncDefNode):
         self.args = declarator.args
         for formal_arg, type_arg in zip(self.args, type.args):
             formal_arg.type = type_arg.type
+            formal_arg.name = type_arg.name
             formal_arg.cname = type_arg.cname
         name = name_declarator.name
         cname = name_declarator.cname
@@ -1466,42 +1467,61 @@ class DefNode(FuncDefNode):
         self.num_required_kw_args = rk
         self.num_required_args = r
         
-    def as_cfunction(self, cfunc):
+    def as_cfunction(self, cfunc=None, scope=None):
         if self.star_arg:
             error(self.star_arg.pos, "cdef function cannot have star argument")
         if self.starstar_arg:
             error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
-        if len(self.args) != len(cfunc.type.args) or cfunc.type.has_varargs:
-            error(self.pos, "wrong number of arguments")
-            error(declarator.pos, "previous declaration here")
-        for formal_arg, type_arg in zip(self.args, cfunc.type.args):
-            name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
-            if type is PyrexTypes.py_object_type or formal_arg.is_self:
-                formal_arg.type = type_arg.type
-                formal_arg.name_declarator = name_declarator
+        if cfunc is None:
+            cfunc_args = []
+            for formal_arg in self.args:
+                name_declarator, type = formal_arg.analyse(scope, nonempty=1)
+                cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
+                                                          cname = None,
+                                                          type = py_object_type,
+                                                          pos = formal_arg.pos))
+            cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
+                                              args = cfunc_args,
+                                              has_varargs = False,
+                                              exception_value = None,
+                                              exception_check = False,
+                                              nogil = False,
+                                              with_gil = False,
+                                              is_overridable = True)
+            cfunc = CVarDefNode(self.pos, type=cfunc_type, pxd_locals=[])
+        else:
+            cfunc_type = cfunc.type
+            if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
+                error(self.pos, "wrong number of arguments")
+                error(declarator.pos, "previous declaration here")
+            for formal_arg, type_arg in zip(self.args, cfunc_type.args):
+                name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
+                if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
+                    formal_arg.type = type_arg.type
+                    formal_arg.name_declarator = name_declarator
         import ExprNodes
-        if cfunc.type.exception_value is None:
+        if cfunc_type.exception_value is None:
             exception_value = None
         else:
-            exception_value = ExprNodes.ConstNode(self.pos, value=cfunc.type.exception_value, type=cfunc.type.return_type)
+            exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
         declarator = CFuncDeclaratorNode(self.pos, 
                                          base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
                                          args = self.args,
                                          has_varargs = False,
-                                         exception_check = cfunc.type.exception_check,
+                                         exception_check = cfunc_type.exception_check,
                                          exception_value = exception_value,
-                                         with_gil = cfunc.type.with_gil,
-                                         nogil = cfunc.type.nogil)
+                                         with_gil = cfunc_type.with_gil,
+                                         nogil = cfunc_type.nogil)
         return CFuncDefNode(self.pos, 
                             modifiers = [],
-                            base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc.type.return_type),
+                            base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
                             declarator = declarator,
                             body = self.body,
                             doc = self.doc,
-                            overridable = cfunc.type.is_overridable,
-                            type = cfunc.type,
-                            with_gil = cfunc.type.with_gil,
-                            nogil = cfunc.type.nogil,
+                            overridable = cfunc_type.is_overridable,
+                            type = cfunc_type,
+                            with_gil = cfunc_type.with_gil,
+                            nogil = cfunc_type.nogil,
                             visibility = 'private',
                             api = False,
                             pxd_locals = cfunc.pxd_locals)
@@ -1513,10 +1533,14 @@ class DefNode(FuncDefNode):
             directive_locals = {}
         self.directive_locals = directive_locals
         for arg in self.args:
-            base_type = arg.base_type.analyse(env)
-            name_declarator, type = \
-                arg.declarator.analyse(base_type, env)
-            arg.name = name_declarator.name
+            if hasattr(arg, 'name'):
+                type = arg.type
+                name_declarator = None
+            else:
+                base_type = arg.base_type.analyse(env)
+                name_declarator, type = \
+                    arg.declarator.analyse(base_type, env)
+                arg.name = name_declarator.name
             if arg.name in directive_locals:
                 type_node = directive_locals[arg.name]
                 other_type = type_node.analyse_as_type(env)
@@ -1528,7 +1552,7 @@ class DefNode(FuncDefNode):
                     error(type_node.pos, "Previous declaration here")
                 else:
                     type = other_type
-            if name_declarator.cname:
+            if name_declarator and name_declarator.cname:
                 error(self.pos,
                     "Python function argument cannot have C name specification")
             arg.type = type.as_argument_type()
index fabd6e6dd8deb8c40a8b237736fa36f8b00e66af..84b692b0885f91b132785ca9cf38ddc81fc982da 100644 (file)
@@ -60,13 +60,15 @@ option_types = {
     'nonecheck' : bool,
     'embedsignature' : bool,
     'locals' : dict,
+    'auto_cpdef': bool,
 }
 
 option_defaults = {
     'boundscheck' : True,
     'nonecheck' : False,
     'embedsignature' : False,
-    'locals' : {}
+    'locals' : {},
+    'auto_cpdef': False,
 }
 
 def parse_option_value(name, value):
index 4834501c458338688ca3eebd37101e9672f2a282..f4b02fdeff257bb6d9efca536039a2db07b77e2b 100644 (file)
@@ -619,6 +619,7 @@ class AlignFunctionDefinitions(CythonTransform):
     
     def visit_ModuleNode(self, node):
         self.scope = node.scope
+        self.directives = node.directives
         self.visitchildren(node)
         return node
     
@@ -631,8 +632,8 @@ class AlignFunctionDefinitions(CythonTransform):
                 error(node.pos, "'%s' redeclared" % node.name)
                 error(pxd_def.pos, "previous declaration here")
                 return None
-        self.visitchildren(node)
-        return node
+        else:
+            return node
         
     def visit_CClassDefNode(self, node, pxd_def=None):
         if pxd_def is None:
@@ -654,6 +655,8 @@ class AlignFunctionDefinitions(CythonTransform):
                 error(node.pos, "'%s' redeclared" % node.name)
                 error(pxd_def.pos, "previous declaration here")
                 return None
+        elif self.scope.is_module_scope and self.directives['auto_cpdef']:
+            node = node.as_cfunction(scope=self.scope)
         # Enable this when internal def functions are allowed. 
         # self.visitchildren(node)
         return node
index 960a362a0109410138ac816f85a9a1e77e91a1b8..8bef764a754800ca0b1ff9e5254af378c1adff53 100644 (file)
@@ -1,3 +1,4 @@
+# cython: auto_cpdef=True
 #
 #   Pyrex Parser
 #
@@ -6,7 +7,7 @@ import os
 import re
 import sys
 from types import ListType, TupleType
-from Scanning import PyrexScanner, FileSourceDescriptor
+from Cython.Compiler.Scanning import PyrexScanner, FileSourceDescriptor
 import Nodes
 import ExprNodes
 import StringEncoding
@@ -1307,7 +1308,7 @@ def p_with_statement(s):
             if not allow_multi and isinstance(target, ExprNodes.TupleNode):
                 s.error("Multiple with statement target values not allowed without paranthesis")
         body = p_suite(s)
-       return Nodes.WithStatNode(pos, manager = manager, 
+    return Nodes.WithStatNode(pos, manager = manager, 
                                       target = target, body = body)
     
 def p_simple_statement(s, first_statement = 0):
@@ -2382,7 +2383,7 @@ def p_code(s, level=None):
             repr(s.sy), repr(s.systring)))
     return body
 
-COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*([a-z]+)\s*=(.*)$")
+COMPILER_DIRECTIVE_COMMENT_RE = re.compile(r"^#\s*cython:\s*([a-z_]+)\s*=(.*)$")
 
 def p_compiler_directive_comments(s):
     result = {}
index e20b80faa6e2344c30f41f6a06d62b02e20c556a..97c441adacfc9074b568653e20b7e697e8219e92 100644 (file)
@@ -28,6 +28,7 @@ cdef class Scanner:
         cdef:
             long input_state
     cpdef read(self)
+    cpdef position(self)
     
     cpdef run_machine_inlined(self):
         cdef:
index 16e1f0c3b3a4a404c2b5bd55eefd323a1bed5918..a80d60f77c7360abf39ab9fa28f7a1e303051b28 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -31,7 +31,7 @@ except ValueError:
     try:
         from Cython.Compiler.Main import compile
         source_root = os.path.dirname(__file__)
-        compiled_modules = ["Cython.Plex.Scanners", "Cython.Compiler.Scanning"]
+        compiled_modules = ["Cython.Plex.Scanners", "Cython.Compiler.Scanning", "Cython.Compiler.Parsing"]
         extensions = []
         for module in compiled_modules:
             source_file = os.path.join(source_root, *module.split('.'))