From df6713cca6767d2be02fea643d6782111ea985a6 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw Date: Thu, 3 Apr 2008 00:23:51 -0700 Subject: [PATCH] Transformation fixes --- Cython/Compiler/CmdLine.py | 3 +- Cython/Compiler/ExprNodes.py | 74 +++++++++++++++++++------------- Cython/Compiler/Nodes.py | 5 ++- Cython/Compiler/Parsing.py | 16 ++++--- Cython/Distutils/extension.py | 79 +++++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+), 35 deletions(-) create mode 100644 Cython/Distutils/extension.py diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py index abf8eeab..05a607a4 100644 --- a/Cython/Compiler/CmdLine.py +++ b/Cython/Compiler/CmdLine.py @@ -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) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index ab3d891b..9ebb2815 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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): diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 564ff97a..557a75fe 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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: diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 0b403f9b..9b5775f2 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -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 index 00000000..5c35557a --- /dev/null +++ b/Cython/Distutils/extension.py @@ -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 -- 2.26.2