fix templating, actually works
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 16 Aug 2009 00:06:04 +0000 (17:06 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 16 Aug 2009 00:06:04 +0000 (17:06 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py
Cython/Includes/python_ref.pxd

index 9077fd6952050b6a64f74b1b301f86bca7cad321..1134cdce1e9af4fce497fb322296a4f61e5887c3 100755 (executable)
@@ -1078,19 +1078,28 @@ class ImagNode(AtomicNewTempExprNode):
         
 
 class NewExprNode(AtomicExprNode):
+
+    # C++ new statement
+    #
+    # cppclass              string               c++ class to create
+    # template_parameters   None or [ExprNode]   temlate parameters, if any
     
     def analyse_types(self, env):
-        print self.cppclass
         entry = env.lookup(self.cppclass)
         if entry is None or not entry.is_cpp_class:
             error(self.pos, "new operator can only be applied to a C++ class")
             return
+        if self.template_parameters is not None:
+            template_types = [v.analyse_as_type(env) for v in self.template_parameters]
+            type = entry.type.specialize_here(self.pos, template_types)
+        else:
+            type = entry.type
  
-        constructor = entry.type.scope.lookup(u'__init__')
+        constructor = type.scope.lookup(u'__init__')
         if constructor is None:
             print "no constructor declared"
-            # create one
-        self.class_entry = entry
+            # TODO(danilo): create one
+        self.class_type = type
         self.entry = constructor
         self.type = constructor.type
    
@@ -1098,7 +1107,7 @@ class NewExprNode(AtomicExprNode):
         pass
    
     def calculate_result_code(self):
-        return "new " + self.class_entry.cname
+        return "new " + self.class_type.declaration_code("")
 
 
 class NameNode(AtomicExprNode):
@@ -2442,7 +2451,7 @@ class SimpleCallNode(CallNode):
                     "Python object cannot be passed as a varargs parameter")
         # Calc result type and code fragment
         if isinstance(self.function, NewExprNode):
-            self.type = PyrexTypes.CPtrType(self.function.class_entry.type)
+            self.type = PyrexTypes.CPtrType(self.function.class_type)
         else:
             self.type = func_type.return_type
         if self.type.is_pyobject:
index 721b3d5b6b22c97ea2aac475cdcd422f1b13d10e..173133a309669d3f3f28aa3da9915005cb16727b 100644 (file)
@@ -297,7 +297,13 @@ def p_new_expr(s):
     pos = s.position()
     s.next()
     name = p_ident(s)
-    return p_call(s, ExprNodes.NewExprNode(pos, cppclass = name))
+    if s.sy == '[':
+        s.next()
+        template_parameters = p_simple_expr_list(s)
+        s.expect(']')        
+    else:
+        template_parameters = None
+    return p_call(s, ExprNodes.NewExprNode(pos, cppclass = name, template_parameters = template_parameters))
 
 #trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
 
index 735a07033395da4d59cc2cb2f5eb31c0b5d81b06..017e7010772fae1cbd8b7e20392b83172440955c 100755 (executable)
@@ -1423,7 +1423,7 @@ class CppClassType(CType):
             name = self.name
         else:
             name = self.cname
-        return "%s %s%s" % (name, entity_code, templates)
+        return "%s%s %s" % (name, templates, entity_code)
 
     def is_subclass(self, other_type):
         # TODO(danilo): Handle templates.
index 7e0a313d7a8bd8cd6bc56cf481dd7ccc00b0a9f9..9fc15ef37cf5d6d22102d46b91dda0b15c5d8307 100644 (file)
@@ -393,6 +393,7 @@ class Scope(object):
                     entry.type.scope = scope
                     self.type_entries.append(entry)
         if not scope and not entry.type.scope:
+            print pos
             self.check_for_illegal_incomplete_ctypedef(typedef_flag, pos)
         return entry
     
index e9b17411a49a63946eca1de1465db5bbe9c1ed69..f9ef4015454c152d6c9e54d5c826a9f99965c0d4 100644 (file)
@@ -3,7 +3,8 @@ cdef extern from "Python.h":
     ctypedef struct PyObject:
         Py_ssize_t ob_refcnt
         PyTypeObject *ob_type
-    ctypedef struct FILE    
+    ctypedef struct FILE:
+        pass
 
 
     #####################################################################