From: Robert Bradshaw Date: Sun, 16 Aug 2009 00:06:04 +0000 (-0700) Subject: fix templating, actually works X-Git-Tag: 0.13.beta0~353^2~48 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=fee03687b5c32dd20fa8c7009d0dff4727306e68;p=cython.git fix templating, actually works --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 9077fd69..1134cdce 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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: diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 721b3d5b..173133a3 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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 diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 735a0703..017e7010 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -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. diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 7e0a313d..9fc15ef3 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -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 diff --git a/Cython/Includes/python_ref.pxd b/Cython/Includes/python_ref.pxd index e9b17411..f9ef4015 100644 --- a/Cython/Includes/python_ref.pxd +++ b/Cython/Includes/python_ref.pxd @@ -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 #####################################################################