[pygccxml-commit] SF.net SVN: pygccxml: [759] pyplusplus_dev_ft
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-11-27 21:12:54
|
Revision: 759 http://svn.sourceforge.net/pygccxml/?rev=759&view=rev Author: roman_yakovenko Date: 2006-11-27 13:12:53 -0800 (Mon, 27 Nov 2006) Log Message: ----------- adding virtual mem fun controller Modified Paths: -------------- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py pyplusplus_dev_ft/unittests/function_transformations_tester.py Modified: pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/code_creators/__init__.py 2006-11-27 21:12:53 UTC (rev 759) @@ -80,10 +80,9 @@ from calldef_transformed import mem_fun_transformed_wrapper_t from calldef_transformed import free_fun_transformed_t from calldef_transformed import free_fun_transformed_wrapper_t +from calldef_transformed import mem_fun_v_transformed_t +from calldef_transformed import mem_fun_v_transformed_wrapper_t -#~ from calldef_transformed import mem_fun_v_transformed_t -#~ from calldef_transformed import mem_fun_v_transformed_wrapper_t - from global_variable import global_variable_base_t from global_variable import global_variable_t from global_variable import array_gv_t Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_transformed.py 2006-11-27 21:12:53 UTC (rev 759) @@ -21,7 +21,7 @@ def remove_duplicate_linesep( code ): return __REMOVE_DUPLICAET_LINESEP.sub( os.linesep, code ) -class non_virtual_fun_transformed_t( calldef_t ): +class sealed_fun_transformed_t( calldef_t ): def __init__( self, function, wrapper=None ): calldef_t.__init__( self, function=function, wrapper=wrapper ) @@ -53,12 +53,9 @@ return '&%s' % full_name def create_call_policies( self ): - if self.controller.wrapper_call_policies.is_default(): - return '' - else: - return super( non_virtual_fun_transformed_t, self ).create_call_policies() + return '' -class non_virtual_fun_transformed_wrapper_t( calldef_wrapper_t ): +class sealed_fun_transformed_wrapper_t( calldef_wrapper_t ): def __init__( self, function ): calldef_wrapper_t.__init__( self, function=function ) @@ -115,19 +112,19 @@ def _create_impl(self): answer = [ self.create_declaration(self.declaration.alias) + '{' ] - answer.append( '// Transformed wrapper function for "%s"' % self.declaration ) + answer.append( self.indent( '// Transformed wrapper function for "%s"' % self.declaration ) ) body = self.create_body() body = remove_duplicate_linesep( body ) answer.append( self.indent( body ) ) answer.append( '}' ) return os.linesep.join( answer ) -class free_fun_transformed_t( non_virtual_fun_transformed_t ): +class free_fun_transformed_t( sealed_fun_transformed_t ): """Creates code for public non-virtual member functions. """ def __init__( self, function, wrapper=None ): - non_virtual_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) + sealed_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) self.works_on_instance = False def create_def_code( self ): @@ -140,14 +137,14 @@ return arg_utils.keywords_args() -class free_fun_transformed_wrapper_t( non_virtual_fun_transformed_wrapper_t ): +class free_fun_transformed_wrapper_t( sealed_fun_transformed_wrapper_t ): def __init__( self, function ): """Constructor. @param function: Function declaration @type function: calldef_t """ - non_virtual_fun_transformed_wrapper_t .__init__( self, function=function ) + sealed_fun_transformed_wrapper_t .__init__( self, function=function ) def function_type(self): return declarations.free_function_type_t( @@ -180,11 +177,11 @@ return declarations.full_name( self.declaration ) -class mem_fun_transformed_t( non_virtual_fun_transformed_t ): +class mem_fun_transformed_t( sealed_fun_transformed_t ): """Creates code for public non-virtual member functions. """ def __init__( self, function, wrapper=None ): - non_virtual_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) + sealed_fun_transformed_t.__init__( self, function=function, wrapper=wrapper ) def create_keywords_args(self): args = self.controller.wrapper_args[:] @@ -196,14 +193,14 @@ , args ) return arg_utils.keywords_args() -class mem_fun_transformed_wrapper_t( non_virtual_fun_transformed_wrapper_t ): +class mem_fun_transformed_wrapper_t( sealed_fun_transformed_wrapper_t ): def __init__( self, function ): """Constructor. @param function: Function declaration @type function: calldef_t """ - non_virtual_fun_transformed_wrapper_t.__init__( self, function=function ) + sealed_fun_transformed_wrapper_t.__init__( self, function=function ) def __is_global( self ): return not isinstance( self.parent, class_declaration.class_wrapper_t ) @@ -247,3 +244,101 @@ return self.controller.inst_arg.name + '.' + self.declaration.name else: return declarations.full_name( self.declaration ) + +class mem_fun_v_transformed_t( calldef_t ): + def __init__( self, function, wrapper=None ): + calldef_t.__init__( self, function=function, wrapper=wrapper ) + + @property + def ft( self ): #function transformation + return self.declaration.transformations[0] + + @property + def controller( self ): + return self.ft.controller + + def _get_alias_impl( self ): + return self.wrapper.ft.alias + + def create_function_type_alias_code( self, exported_class_alias=None ): + ftype = self.wrapper.function_type() + return 'typedef %s;' % ftype.create_typedef( self.function_type_alias, exported_class_alias ) + + def create_function_ref_code(self, use_function_alias=False): + full_name = self.wrapper.full_name() + + if use_function_alias: + return '%s( &%s )' \ + % ( self.function_type_alias, full_name ) + elif self.declaration.create_with_signature: + func_type = self.wrapper.function_type() + return '(%s)( &%s )' % ( func_type, full_name ) + else: + return '&%s' % full_name + + def create_call_policies( self ): + return '' + +class mem_fun_v_transformed_wrapper_t( calldef_wrapper_t ): + def __init__( self, function ): + calldef_wrapper_t.__init__( self, function=function ) + + @property + def ft( self ): #function transformation + return self.declaration.transformations[0] + + @property + def controller( self ): + return self.ft.controller + + def create_declaration(self, name): + template = 'static %(return_type)s %(name)s( %(args)s )' + + return template % { + 'return_type' : self.controller.wrapper_return_type.decl_string + , 'name' : self.wrapper_name() + , 'args' : self.args_declaration() + } + + def resolve_function_ref( self ): + raise NotImplementedError() + + def create_body(self): + cntrl = self.controller + + make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object' ) + make_tuple = algorithm.create_identifier( self, 'boost::python::make_tuple' ) + + result_var_assign = '' + if not declarations.is_void( self.declaration.return_type ): + result_var_assign = '%(type)s %(name)s = ' \ + % { 'type': cntrl.result_variable.type.decl_string + , 'name' : cntrl.result_variable.name } + + return_stmt_creator = calldef_utils.return_stmt_creator_t( self + , self.controller + , self.controller.result_variable + , self.controller.return_variables ) + + post_call = os.linesep.join( cntrl.post_call ) + if return_stmt_creator.pre_return_code: + post_call = os.linesep.join( [post_call, return_stmt_creator.pre_return_code] ) + + return cntrl.template.substitute({ + 'declare_variables' : os.linesep.join( map( lambda var: var.declare_var_string(), cntrl.variables ) ) + , 'pre_call' : os.linesep.join( cntrl.pre_call ) + , 'post_call' : post_call + , 'save_result' : result_var_assign + , 'function' : self.resolve_function_ref() + , 'arg_expressions' : self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) + , 'return' : return_stmt_creator.statement + }) + + def _create_impl(self): + answer = [ self.create_declaration(self.declaration.alias) + '{' ] + answer.append( self.indent( '// Transformed wrapper function for "%s"' % self.declaration ) ) + body = self.create_body() + body = remove_duplicate_linesep( body ) + answer.append( self.indent( body ) ) + answer.append( '}' ) + return os.linesep.join( answer ) Modified: pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/code_creators/calldef_utils.py 2006-11-27 21:12:53 UTC (rev 759) @@ -123,29 +123,31 @@ def statement( self ): if None is self.__return_stmt: stmt = '' + bpl_object = algorithm.create_identifier( self.__creator, 'boost::python::object' ) make_tuple = algorithm.create_identifier( self.__creator, 'boost::python::make_tuple' ) make_object = algorithm.create_identifier( self.__creator, 'pyplusplus::call_policies::make_object' ) - if self.__return_vars: - if not declarations.is_void( self.__function.return_type ): - if self.__function.call_policies.is_default(): - self.__return_vars.insert( 0, self.__result_var.name ) - else: - self.__return_vars.insert( 0 - , declarations.call_invocation.join( - declarations.templates.join( make_object, [self.__call_policy_alias] ) - , [self.__result_var.name] ) ) - + if not declarations.is_void( self.__function.return_type ): + if self.__function.call_policies.is_default(): + self.__return_vars.insert( 0, self.__result_var.name ) + else: + self.__return_vars.insert( 0 + , declarations.call_invocation.join( + declarations.templates.join( make_object, [self.__call_policy_alias] ) + , [self.__result_var.name] ) ) + + if 0 == len( self.__return_vars ): + pass + elif 1 == len( self.__return_vars ): + stmt = bpl_object + '( %s )' % self.__return_vars[ 0 ] + else: # 1 < stmt = declarations.call_invocation.join( make_tuple, self.__return_vars ) if self.__creator.LINE_LENGTH < len( stmt ): stmt = declarations.call_invocation.join( - make_tuple - , self.__return_vars - , os.linesep + self.__creator.indent( self.__creator.PARAM_SEPARATOR, 6 ) ) - elif not declarations.is_void( self.__function.return_type ): - stmt = self.__result_var.name - else: - pass + make_tuple + , self.__return_vars + , os.linesep + self.__creator.indent( self.__creator.PARAM_SEPARATOR, 6 ) ) + if stmt: stmt = 'return ' + stmt + ';' self.__return_stmt = stmt Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/controllers.py 2006-11-27 21:12:53 UTC (rev 759) @@ -25,18 +25,13 @@ , name=self.name , type=self.type , initialize_expr=self.initialize_expr ) - -class controller_base_t( object ): - def __init__( self, function ): + +class variables_manager_t( object ): + def __init__( self ): object.__init__( self ) - self.__function = function self.__variables = [] #variables - self.__names_in_use = set( map( lambda arg: arg.name, self.function.arguments ) ) + self.__names_in_use = set() - @property - def function( self ): - return self.__function - @property def variables( self ): return self.__variables @@ -46,7 +41,7 @@ self.__variables.append( variable_t( type, unique_name, initialize_expr ) ) return unique_name - def register_variable_name( self, name ): + def register_name( self, name ): return self.__create_unique_var_name( name ) def __create_unique_var_name( self, name ): @@ -60,13 +55,27 @@ self.__names_in_use.add( unique_name ) return unique_name +def create_variables_manager( function ): + vm = variables_manager_t() + map( lambda arg: vm.register_name( arg.name ) , function.arguments ) + return vm + +class controller_base_t( object ): + def __init__( self, function ): + self.__function = function + + @property + def function( self ): + return self.__function + def apply( self, transformations ): raise NotImplementedError() -class non_virtual_fun_controller_t( controller_base_t ): +class sealed_fun_controller_t( controller_base_t ): #base class for free and member function controllers def __init__( self, function ): controller_base_t.__init__( self, function ) + self.__vars_manager = create_variables_manager( function ) self.__wrapper_args = [ arg.clone() for arg in function.arguments ] self.__result_var = variable_t( self.function.return_type , self.register_variable_name( 'result' ) ) @@ -74,7 +83,17 @@ self.__pre_call = [] self.__post_call = [] self.__arg_expressions = [ arg.name for arg in function.arguments ] + + @property + def variables( self ): + return self.__vars_manager.variables + def declare_variable( self, type, name, initialize_expr='' ): + return self.__vars_manager.declare_variable( type, name, initialize_expr) + + def register_variable_name( self, name ): + return self.__vars_manager.register_name( name ) + @property def result_variable( self ): return self.__result_var @@ -103,26 +122,22 @@ def arg_expressions( self ): return self.__arg_expressions - def modify_argument_expression( self, index, expression ): + def modify_arg_expression( self, index, expression ): self.arg_expressions[ index ] = expression @property def wrapper_return_type( self ): - if len( self.return_variables ): + return_vars_count = len( self.return_variables ) + if not declarations.is_void( self.function.return_type ): + return_vars_count += 1 + if 0 == return_vars_count: + return self.function.return_type #return type is void + elif 1 == return_vars_count: + return declarations.dummy_type_t( 'boost::python::object' ) + else: return declarations.dummy_type_t( 'boost::python::tuple' ) - else: - return self.function.return_type - + @property - def wrapper_call_policies( self ): - #prevent recursive import - from pyplusplus import decl_wrappers - if 'boost::python::tuple' == self.wrapper_return_type.decl_string: - return decl_wrappers.default_call_policies() - else: - return self.function.call_policies - - @property def return_variables( self ): return self.__return_variables @@ -143,13 +158,9 @@ def add_post_call_code( self, code ): self.__post_call.append( code ) - def set_input_param( self, index, var_name_or_expr ): - self.__input_params[ index ] = var_name_or_expr - - -class mem_fun_controller_t( non_virtual_fun_controller_t ): +class mem_fun_controller_t( sealed_fun_controller_t ): def __init__( self, function ): - non_virtual_fun_controller_t.__init__( self, function ) + sealed_fun_controller_t.__init__( self, function ) inst_arg_type = declarations.declarated_t( self.function.parent ) if self.function.has_const: @@ -168,10 +179,67 @@ def inst_arg( self ): return self.__inst_arg -class free_fun_controller_t( non_virtual_fun_controller_t ): +class free_fun_controller_t( sealed_fun_controller_t ): def __init__( self, function ): - non_virtual_fun_controller_t.__init__( self, function ) + sealed_fun_controller_t.__init__( self, function ) def apply( self, transformations ): map( lambda t: t.configure_free_fun( self ), transformations ) + +class virtual_mem_fun_controller_t( controller_base_t ): + def __init__( self, function ): + controller_base_t.__init__( self, function ) + self.__py_vars_manager = create_variables_manager( function ) + self.__py_function_var \ + = self.__py_vars_manager.register_name( 'func_' + function.alias ) + self.__py_pre_call = [] + self.__py_post_call = [] + self.__py_result_var = variable_t( declarations.dummy_type_t( 'boost::python::object' ) + , self.register_py_variable_name( 'py_result' ) ) + + self.__py_arg_expressions = [ arg.name for arg in function.arguments ] + + @property + def py_variables( self ): + return self.__py_vars_manager.variables + + def declare_py_variable( self, type, name, initialize_expr='' ): + return self.__py_vars_manager.declare_variable( type, name, initialize_expr) + + def register_py_variable_name( self, name ): + return self.__py_vars_manager.register_name( name ) + + @property + def py_function_var( self ): + return self.__py_function_var + + @property + def py_pre_call( self ): + return self.__py_pre_call + + def add_py_pre_call_code( self, code ): + self.__py_pre_call.append( code ) + + @property + def py_post_call( self ): + return self.__py_post_call + + def add_py_post_call_code( self, code ): + self.__py_post_call.append( code ) + + @property + def py_result_variable( self ): + return self.__py_result_var + + @property + def py_arg_expressions( self ): + return filter( None, self.__py_arg_expressions ) + + def remove_py_arg( self, index ): + self.__py_arg_expressions[ index ] = None + + def modify_py_arg_expression( self, index, expression ): + self.arg_expressions[ index ] = expression + + Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/templates.py 2006-11-27 21:12:53 UTC (rev 759) @@ -30,7 +30,7 @@ , '$return' ])) -class mem_fun_v: +class virtual_mem_fun: override_body = Template( os.linesep.join([ 'if( boost::python::override $py_function_var = this->get_override( "$function_alias" ) ){' , ' $declare_py_variables' Modified: pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py =================================================================== --- pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/pyplusplus/function_transformers/transformers.py 2006-11-27 21:12:53 UTC (rev 759) @@ -74,7 +74,7 @@ #declaring new variable, which will keep result var_name = controller.declare_variable( remove_ref_or_ptr( self.arg.type ), self.arg.name ) #adding just declared variable to the original function call expression - controller.modify_argument_expression( self.arg_index, var_name ) + controller.modify_arg_expression( self.arg_index, var_name ) #adding the variable to return variables list controller.return_variable( var_name ) @@ -84,6 +84,12 @@ def configure_free_fun(self, controller ): self.__configure_non_virtual( controller ) + def configure_virtual_mem_fun( self, controller ): + assert isinstance( controller, controllers.virtual_mem_fun_controller_t ) + #removing arg from the function wrapper definition + controller.remove_py_arg( self.arg_index ) + + # input_t class input_t(transformer.transformer_t): """Handles a single input variable. @@ -216,7 +222,7 @@ controller.add_pre_call_code( seq2arr ) - controller.modify_argument_expression( self.arg_index, native_array ) + controller.modify_arg_expression( self.arg_index, native_array ) def configure_mem_fun( self, controller ): self.__configure_non_virtual( controller ) @@ -272,7 +278,7 @@ , '[%d]' % self.array_size ) #adding just declared variable to the original function call expression - controller.modify_argument_expression( self.arg_index, native_array ) + controller.modify_arg_expression( self.arg_index, native_array ) # Declare a Python list which will receive the output... pylist = controller.declare_variable( declarations.dummy_type_t( "boost::python::list" ) @@ -292,4 +298,3 @@ def configure_free_fun(self, controller ): self.__configure_non_virtual( controller ) - Modified: pyplusplus_dev_ft/unittests/function_transformations_tester.py =================================================================== --- pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-27 10:23:04 UTC (rev 758) +++ pyplusplus_dev_ft/unittests/function_transformations_tester.py 2006-11-27 21:12:53 UTC (rev 759) @@ -95,10 +95,10 @@ point3d = module.point3d_t() result = point3d.initialize( [ 1,2,3 ] ) self.failUnless( result== 1*2*3 and point3d.x == 1 and point3d.y==2 and point3d.z==3 ) - self.failUnless( [1,2,3] == point3d.position()[0] ) - self.failUnless( module.point3d_t.distance( point3d )[0] == math.sqrt( 1*1 + 2*2 + 3*3 ) ) + self.failUnless( [1,2,3] == point3d.position() ) + self.failUnless( module.point3d_t.distance( point3d ) == math.sqrt( 1*1 + 2*2 + 3*3 ) ) - self.failUnless( module.hello_world()[0] == "hello world!" ) + self.failUnless( module.hello_world() == "hello world!" ) #~ img = module.image_t( 2, 6) # Check a method that returns two values by reference This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |