Transformation fixes
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 3 Apr 2008 07:23:51 +0000 (00:23 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 3 Apr 2008 07:23:51 +0000 (00:23 -0700)
Cython/Compiler/CmdLine.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/Nodes.py
Cython/Compiler/Parsing.py
Cython/Distutils/extension.py [new file with mode: 0644]

index abf8eeab62d02561ed4ed340f817e5b9f5b4c99b..05a607a4a3e4a5b400ddede0320e912a52ccb1e5 100644 (file)
@@ -30,7 +30,8 @@ Options:
   -D, --no-docstrings            Remove docstrings.
   -a, --annotate                 Produce an colorized version of the source.
   --convert-range                Convert for loops using range() function to for...from loops. 
-"""  
+  --cplus                        Output a c++ rather than c file.
+"""
 #The following experimental options are supported only on MacOSX:
 #  -C, --compile    Compile generated .c file to .o file
 #  -X, --link       Link .o file to produce extension module (implies -C)
index ab3d891b4e35b627e3d169f2d1193a5c6471a4de..9ebb2815b17fc7209ce5aeb5fe129f796e428862 100644 (file)
@@ -169,9 +169,9 @@ class ExprNode(Node):
     def get_child_attrs(self):
         """Automatically provide the contents of subexprs as children, unless child_attr
         has been declared. See Nodes.Node.get_child_accessors."""
-        if self.child_attrs != None:
-            return self.child_attr
-        elif self.subexprs != None:
+        if self.child_attrs is not None:
+            return self.child_attrs
+        elif self.subexprs is not None:
             return self.subexprs
         
     def not_implemented(self, method_name):
@@ -870,6 +870,8 @@ class NameNode(AtomicExprNode):
     def check_identifier_kind(self):
         #print "NameNode.check_identifier_kind:", self.entry.name ###
         #print self.entry.__dict__ ###
+        print self
+        print self.pos, self.name
         entry = self.entry
         #entry.used = 1
         if not (entry.is_const or entry.is_variable 
@@ -2364,22 +2366,16 @@ class DictNode(ExprNode):
     #  key_value_pairs  [(ExprNode, ExprNode)]
     
     def compile_time_value(self, denv):
-        pairs = [(key.compile_time_value(denv), value.compile_time_value(denv))
-            for (key, value) in self.key_value_pairs]
+        pairs = [(item.key.compile_time_value(denv), item.value.compile_time_value(denv))
+            for item in self.key_value_pairs]
         try:
             return dict(pairs)
         except Exception, e:
             self.compile_time_value_error(e)
     
     def analyse_types(self, env):
-        new_pairs = []
-        for key, value in self.key_value_pairs:
-            key.analyse_types(env)
-            value.analyse_types(env)
-            key = key.coerce_to_pyobject(env)
-            value = value.coerce_to_pyobject(env)
-            new_pairs.append((key, value))
-        self.key_value_pairs = new_pairs
+        for item in self.key_value_pairs:
+            item.analyse_types(env)
         self.type = py_object_type
         self.is_temp = 1
     
@@ -2387,11 +2383,11 @@ class DictNode(ExprNode):
         #  Custom method used here because key-value
         #  pairs are evaluated and used one at a time.
         self.allocate_temp(env, result)
-        for key, value in self.key_value_pairs:
-            key.allocate_temps(env)
-            value.allocate_temps(env)
-            key.release_temp(env)
-            value.release_temp(env)
+        for item in self.key_value_pairs:
+            item.key.allocate_temps(env)
+            item.value.allocate_temps(env)
+            item.key.release_temp(env)
+            item.value.release_temp(env)
     
     def generate_evaluation_code(self, code):
         #  Custom method used here because key-value
@@ -2400,21 +2396,39 @@ class DictNode(ExprNode):
             "%s = PyDict_New(); %s" % (
                 self.result_code,
                 code.error_goto_if_null(self.result_code, self.pos)))
-        for key, value in self.key_value_pairs:
-            key.generate_evaluation_code(code)
-            value.generate_evaluation_code(code)
+        for item in self.key_value_pairs:
+            item.generate_evaluation_code(code)
             code.put_error_if_neg(self.pos, 
                 "PyDict_SetItem(%s, %s, %s)" % (
                     self.result_code,
-                    key.py_result(),
-                    value.py_result()))
-            key.generate_disposal_code(code)
-            value.generate_disposal_code(code)
+                    item.key.py_result(),
+                    item.value.py_result()))
+            item.generate_disposal_code(code)
             
     def annotate(self, code):
-        for key, value in self.key_value_pairs:
-            key.annotate(code)
-            value.annotate(code)
+        for item in self.key_value_pairs:
+            item.annotate(code)
+            
+class DictItemNode(ExprNode):
+    # Represents a single item in a DictNode
+    #
+    # key          ExprNode
+    # value        ExprNode
+    subexprs = ['key', 'value']
+            
+    def analyse_types(self, env):
+        self.key.analyse_types(env)
+        self.value.analyse_types(env)
+        self.key = self.key.coerce_to_pyobject(env)
+        self.value = self.value.coerce_to_pyobject(env)
+        
+    def generate_evaluation_code(self, code):
+        self.key.generate_evaluation_code(code)
+        self.value.generate_evaluation_code(code)
+        
+    def generate_disposal_code(self, code):
+        self.key.generate_disposal_code(code)
+        self.value.generate_disposal_code(code)
 
 class ClassNode(ExprNode):
     #  Helper class used in the implementation of Python
@@ -3411,6 +3425,8 @@ class PrimaryCmpNode(ExprNode, CmpNode):
     #  Instead, we override all the framework methods
     #  which use it.
     
+    child_attrs = ['operand1', 'operand2', 'cascade']
+    
     cascade = None
     
     def compile_time_value(self, denv):
@@ -3530,6 +3546,8 @@ class CascadedCmpNode(Node, CmpNode):
     #  operand2      ExprNode
     #  cascade       CascadedCmpNode
 
+    child_attrs = ['operand2', 'cascade']
+
     cascade = None
     
     def analyse_types(self, env, operand1):
index 564ff97afa20d763c38e6ca2ddbc13a0865408b1..557a75fe1e49424881e56593971bdd50cf5ca996 100644 (file)
@@ -477,7 +477,8 @@ class CFuncDeclaratorNode(CDeclaratorNode):
         exc_val = None
         exc_check = 0
         if return_type.is_pyobject \
-            and (self.exception_value or self.exception_check):
+            and (self.exception_value or self.exception_check) \
+            and self.exception_check != '+':
                 error(self.pos,
                     "Exception clause not allowed for function returning Python object")
         else:
@@ -1841,6 +1842,8 @@ class OverrideCheckNode(StatNode):
     #  func_temp
     #  body
     
+    child_attrs = ['body']
+
     def analyse_expressions(self, env):
         self.args = env.arg_entries
         if self.py_func.is_module_scope:
index 0b403f9b4f7ca840ef2c7f26b01b36f2e8877d90..9b5775f261a36d978c3e59f1f417454eda2c53a4 100644 (file)
@@ -702,15 +702,18 @@ def p_dict_maker(s):
     s.next()
     items = []
     while s.sy != '}':
-        key = p_simple_expr(s)
-        s.expect(':')
-        value = p_simple_expr(s)
-        items.append((key, value))
+        items.append(p_dict_item(s))
         if s.sy != ',':
             break
         s.next()
     s.expect('}')
     return ExprNodes.DictNode(pos, key_value_pairs = items)
+    
+def p_dict_item(s):
+    key = p_simple_expr(s)
+    s.expect(':')
+    value = p_simple_expr(s)
+    return ExprNodes.DictItemNode(key.pos, key=key, value=value)
 
 def p_backquote_expr(s):
     # s.sy == '`'
@@ -1743,8 +1746,11 @@ def p_cdef_statement(s, level, visibility = 'private', api = 0,
     if api:
         if visibility not in ('private', 'public'):
             error(pos, "Cannot combine 'api' with '%s'" % visibility)
-    if visibility == 'extern' and s.sy == 'from':
+    if (visibility == 'extern') and s.sy == 'from':
             return p_cdef_extern_block(s, level, pos)
+    elif s.sy == 'import':
+        s.next()
+        return p_cdef_extern_block(s, level, pos)
     elif s.sy == ':':
         return p_cdef_block(s, level, visibility, api)
     elif s.sy == 'class':
diff --git a/Cython/Distutils/extension.py b/Cython/Distutils/extension.py
new file mode 100644 (file)
index 0000000..5c35557
--- /dev/null
@@ -0,0 +1,79 @@
+"""Pyrex.Distutils.extension
+
+Provides a modified Extension class, that understands hou to describe
+Pyrex extension modules in setup scripts."""
+
+__revision__ = "$Id:$"
+
+import os, string, sys
+from types import *
+import distutils.extension as _Extension
+
+try:
+    import warnings
+except ImportError:
+    warnings = None
+
+class Extension(_Extension.Extension):
+    _Extension.Extension.__doc__ + \
+    """pyrex_include_dirs : [string]
+        list of directories to search for Pyrex header files (.pxd) (in
+        Unix form for portability)
+    pyrex_create_listing_file : boolean
+        write pyrex error messages to a listing (.lis) file.
+    pyrex_cplus : boolean
+        use the C++ compiler for compiling and linking.
+    pyrex_c_in_temp : boolean
+        put generated C files in temp directory.
+    pyrex_gen_pxi : boolean
+        generate .pxi file for public declarations
+    """
+
+    # When adding arguments to this constructor, be sure to update
+    # user_options.extend in build_ext.py.
+    def __init__ (self, name, sources,
+            include_dirs = None,
+            define_macros = None,
+            undef_macros = None,
+            library_dirs = None,
+            libraries = None,
+            runtime_library_dirs = None,
+            extra_objects = None,
+            extra_compile_args = None,
+            extra_link_args = None,
+            export_symbols = None,
+            #swig_opts = None,
+            depends = None,
+            language = None,
+            pyrex_include_dirs = None,
+            pyrex_create_listing = 0,
+            pyrex_cplus = 0,
+            pyrex_c_in_temp = 0,
+            pyrex_gen_pxi = 0,
+            **kw):
+
+        _Extension.Extension.__init__(self, name, sources,
+            include_dirs = include_dirs,
+            define_macros = define_macros,
+            undef_macros = undef_macros,
+            library_dirs = library_dirs,
+            libraries = libraries,
+            runtime_library_dirs = runtime_library_dirs,
+            extra_objects = extra_objects,
+            extra_compile_args = extra_compile_args,
+            extra_link_args = extra_link_args,
+            export_symbols = export_symbols,
+            #swig_opts = swig_opts,
+            depends = depends,
+            language = language,
+            **kw)
+
+        self.pyrex_include_dirs = pyrex_include_dirs or []
+        self.pyrex_create_listing = pyrex_create_listing
+        self.pyrex_cplus = pyrex_cplus
+        self.pyrex_c_in_temp = pyrex_c_in_temp
+        self.pyrex_gen_pxi = pyrex_gen_pxi
+
+# class Extension
+
+read_setup_file = _Extension.read_setup_file