more flexable declare
authorRobert Bradshaw <robertwb@math.washington.edu>
Tue, 7 Oct 2008 18:05:58 +0000 (11:05 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Tue, 7 Oct 2008 18:05:58 +0000 (11:05 -0700)
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Shadow.py

index 136dbedf23ccc8d3c3cd09f2d1f01fab0f0185ae..80ccfe6e1aa1a3f972431a72ceb940883bee956c 100644 (file)
@@ -2549,6 +2549,22 @@ class ExprStatNode(StatNode):
 
     child_attrs = ["expr"]
     
+    def analyse_declarations(self, env):
+        import ExprNodes
+        if isinstance(self.expr, ExprNodes.GeneralCallNode):
+            func = self.expr.function.as_cython_attribute()
+            if func == u'declare':
+                args, kwds = self.expr.explicit_args_kwds()
+                if len(args):
+                    error(self.expr.pos, "Variable names must be specified.")
+                for var, type_node in kwds.key_value_pairs:
+                    type = type_node.analyse_as_type(env)
+                    if type is None:
+                        error(type_node.pos, "Unknown type")
+                    else:
+                        env.declare_var(var.value, type, var.pos, is_cdef = True)
+                self.__class__ = PassStatNode
+    
     def analyse_expressions(self, env):
         self.expr.analyse_expressions(env)
         self.expr.release_temp(env)
@@ -2609,8 +2625,7 @@ class SingleAssignmentNode(AssignmentNode):
                 args, kwds = self.rhs.explicit_args_kwds()
                 
                 if func_name in ['declare', 'typedef']:
-                    self.declaration_only = True
-                    if len(args) != 1 or kwds is not None:
+                    if len(args) > 2 or kwds is not None:
                         error(rhs.pos, "Can only declare one type at a time.")
                         return
                     type = args[0].analyse_as_type(env)
@@ -2628,7 +2643,13 @@ class SingleAssignmentNode(AssignmentNode):
                             return
                         for var, pos in vars:
                             env.declare_var(var, type, pos, is_cdef = True)
+                        if len(args) == 2:
+                            # we have a value
+                            self.rhs = args[1]
+                        else:
+                            self.declaration_only = True
                     else:
+                        self.declaration_only = True
                         if not isinstance(lhs, ExprNodes.NameNode):
                             error(lhs.pos, "Invalid declaration.")
                         env.declare_typedef(lhs.name, type, self.pos, 'private')
index d8d97f07281a0a4a9d15976dc47ed236c73ec0f3..254a421873a657aa23fc41cc17c0151cc9a0e988 100644 (file)
@@ -719,12 +719,12 @@ class TransformBuiltinMethods(EnvTransform):
             if attribute == u'compiled':
                 node = BoolNode(node.pos, value=True)
             else:
-                error(node.pos, u"'%s' not a valid cython attribute" % attribute)
+                error(node.pos, u"'%s' not a valid cython attribute or is being used incorrectly" % attribute)
         return node
 
     def visit_SimpleCallNode(self, node):
 
-        # locals
+        # locals builtin
         if isinstance(node.function, ExprNodes.NameNode):
             if node.function.name == 'locals':
                 pos = node.pos
index b0cba9e9732afd73670713277532c92877682169..6e6c750807d851a0e48368e08a60de4d55052251 100644 (file)
@@ -21,11 +21,14 @@ def sizeof(arg):
 def address(arg):
     return pointer(type(arg))([arg])
     
-def declare(type):
-    if callable(type):
-        return type()
+def declare(type=None, value=None, **kwds):
+    if type and callable(type):
+        if value:
+            return type(value)
+        else:
+            return type()
     else:
-        return None
+        return value
 
 # Emulated types