From 8f8ef4e90b8885232d8631024b6fdf82618db3bc Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Tue, 11 Nov 2008 17:08:47 -0800 Subject: [PATCH] Compile Cython.Compiler.Parsing.py, auto_cpdef, fix bugs in AlignFunctionDefinitions --- Cython/Compiler/Main.py | 2 +- Cython/Compiler/Nodes.py | 72 +++++++++++++++++--------- Cython/Compiler/Options.py | 4 +- Cython/Compiler/ParseTreeTransforms.py | 7 ++- Cython/Compiler/Parsing.py | 7 +-- Cython/Plex/Scanners.pxd | 1 + setup.py | 2 +- 7 files changed, 63 insertions(+), 32 deletions(-) diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py index 54b70a15..6c983c1e 100644 --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py @@ -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), diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 67e67049..423c7a8b 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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() diff --git a/Cython/Compiler/Options.py b/Cython/Compiler/Options.py index fabd6e6d..84b692b0 100644 --- a/Cython/Compiler/Options.py +++ b/Cython/Compiler/Options.py @@ -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): diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index 4834501c..f4b02fde 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -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 diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 960a362a..8bef764a 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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 = {} diff --git a/Cython/Plex/Scanners.pxd b/Cython/Plex/Scanners.pxd index e20b80fa..97c441ad 100644 --- a/Cython/Plex/Scanners.pxd +++ b/Cython/Plex/Scanners.pxd @@ -28,6 +28,7 @@ cdef class Scanner: cdef: long input_state cpdef read(self) + cpdef position(self) cpdef run_machine_inlined(self): cdef: diff --git a/setup.py b/setup.py index 16e1f0c3..a80d60f7 100644 --- 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('.')) -- 2.26.2