Working with 'new' operator
authorDanilo Freitas <dsurviver@gmail.com>
Thu, 2 Jul 2009 02:43:21 +0000 (23:43 -0300)
committerDanilo Freitas <dsurviver@gmail.com>
Thu, 2 Jul 2009 02:43:21 +0000 (23:43 -0300)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py

index 3364b69fc5a2351d565cb7d83f666962b837cd43..056e89c8219203a1d55bb847c8622d8562fefd7d 100644 (file)
@@ -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)
index 233a9ae25f49bc497d767110866dd33deeaa5902..7763479cebe4d7528849426df11a36330f873f42 100644 (file)
@@ -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
index 8fa08b8f156542c10a33b7c4bf6c7c64d6a2918b..2fdd11752d9f3048b6f61c8426b105d201a9e6e2 100644 (file)
@@ -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
index caf258cef24b570588fab11e6ebf11d3ee22be52..af3adf57238f8b5f79ea2d3d822b013fc40c9dcc 100644 (file)
@@ -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
index 236f3d0c2fa48f5135f7418e8987537b633e9f84..c186311384bb743d34a42619150d3c1c119d4a59 100644 (file)
@@ -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