From: Danilo Freitas Date: Thu, 2 Jul 2009 02:43:21 +0000 (-0300) Subject: Working with 'new' operator X-Git-Tag: 0.13.beta0~353^2~77 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=286018341767ee683364cd1097b8dfabd5ff603b;p=cython.git Working with 'new' operator --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 3364b69f..056e89c8 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1080,13 +1080,11 @@ class ImagNode(AtomicNewTempExprNode): class NewExprNode(AtomicExprNode): type = PyrexTypes.cpp_class_type - subexpr = ['arg'] + subexpr = ['args'] def analyse_types(self, env): - entry = env.lookup(self.arg.name) - if not entry: - self.type = PyrexTypes.error_type - return + for arg in self.args: + arg.analyse_types(env) def coerce_to(self, type, env): return self @@ -1095,7 +1093,7 @@ class NewExprNode(AtomicExprNode): pass def calculate_result_code(self): - pass + return "" class NameNode(AtomicExprNode): @@ -1247,7 +1245,8 @@ class NameNode(AtomicExprNode): entry = self.entry #entry.used = 1 if not (entry.is_const or entry.is_variable - or entry.is_builtin or entry.is_cfunction): + or entry.is_builtin or entry.is_cfunction + or entry.is_cpp_class): if self.entry.as_variable: self.entry = self.entry.as_variable else: @@ -2375,6 +2374,15 @@ class SimpleCallNode(CallNode): self.type = py_object_type self.gil_check(env) self.is_temp = 1 + if func_type.is_cpp_class: + for arg in self.args: + arg.analyse_types(env) + entry = env.lookup(self.function.name) + self.type = entry.type + self.function.type = PyrexTypes.CppMethodType(self.function.name, + PyrexTypes.CppClassType(self.function.name, "cppclass", + entry.scope, 0, entry.cname, []), self.args) + self.analyse_c_function_call(env) else: for arg in self.args: arg.analyse_types(env) @@ -2398,7 +2406,7 @@ class SimpleCallNode(CallNode): def analyse_c_function_call(self, env): func_type = self.function_type() # Check function type - if not func_type.is_cfunction: + if not func_type.is_cfunction and not func_type.is_cpp_method: if not func_type.is_error: error(self.pos, "Calling non-function type '%s'" % func_type) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 233a9ae2..7763479c 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -931,6 +931,7 @@ class CppClassNode(CStructOrUnionDefNode): self.entry = env.declare_cpp_class( self.name, "cppclass", scope, 0, self.pos, self.cname, base_class_types, visibility = self.visibility) + self.entry.is_cpp_class = 1 if self.attributes is not None: if self.in_pxd and not env.in_cinclude: self.entry.defined_in_pxd = 1 diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 8fa08b8f..2fdd1175 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -296,7 +296,7 @@ def p_new_expr(s): pos = s.position() s.next() args = p_simple_expr_list(s) - return ExprNodes.NewExprNode(pos, arg = args[0]) + return ExprNodes.NewExprNode(pos, args = args) #trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index caf258ce..af3adf57 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -39,6 +39,7 @@ class PyrexType(BaseType): # is_ptr boolean Is a C pointer type # is_null_ptr boolean Is the type of NULL # is_cfunction boolean Is a C function type + # is_cpp_method boolean Is a C++ method type # is_struct_or_union boolean Is a C struct or union type # is_struct boolean Is a C struct type # is_enum boolean Is a C enum type @@ -90,6 +91,7 @@ class PyrexType(BaseType): is_ptr = 0 is_null_ptr = 0 is_cfunction = 0 + is_cpp_method = 0 is_struct_or_union = 0 is_cpp_class = 0 is_struct = 0 @@ -1228,6 +1230,28 @@ class CFuncType(CType): s = self.declaration_code("(*)", with_calling_convention=False) return '(%s)' % s +class CppMethodType(CFuncType): + + # return_type CppClassType + + is_cpp_method = 1 + + def __init__(self, class_name, return_type, args, has_varargs = 0, + exception_value = None, exception_check = 0, calling_convention = "", + nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0): + self.class_name = class_name + self.return_type = return_type + self.args = args + self.has_varargs = has_varargs + self.exception_value = exception_value + self.exception_check = exception_check + self.calling_convention = calling_convention + self.nogil = nogil + self.with_gil = with_gil + self.is_overridable = is_overridable + self.optional_arg_count = optional_arg_count + + class CFuncTypeArg(object): # name string diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 236f3d0c..c1863113 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -74,6 +74,7 @@ class Entry(object): # is_unbound_cmethod boolean Is an unbound C method of an extension type # is_type boolean Is a type definition # is_cclass boolean Is an extension class + # is_cpp_class boolean Is a C++ class # is_const boolean Is a constant # is_property boolean Is a property of an extension type: # doc_cname string or None C const holding the docstring @@ -131,6 +132,7 @@ class Entry(object): is_unbound_cmethod = 0 is_type = 0 is_cclass = 0 + is_cpp_class = 0 is_const = 0 is_property = 0 doc_cname = None