Commit 8f8ef4e9 authored by Robert Bradshaw's avatar Robert Bradshaw

Compile Cython.Compiler.Parsing.py, auto_cpdef, fix bugs in AlignFunctionDefinitions

parent ecd248ed
......@@ -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),
......
......@@ -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()
......
......@@ -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):
......
......@@ -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
......
# 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 = {}
......
......@@ -28,6 +28,7 @@ cdef class Scanner:
cdef:
long input_state
cpdef read(self)
cpdef position(self)
cpdef run_machine_inlined(self):
cdef:
......
......@@ -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('.'))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment