def _post_parse_process(the_file): ''' Post process the passed in file. For Objective-C this will perform the following changes: 1: Add local variables for arrays 2: Add arguments for length parameters ''' if the_file.name == 'SGSDK': return logger.info('Post Processing %s for Objective-C wrapper creation', the_file.name) for member in the_file.members: #process all method of the file methods_and_operators = member.methods.items() + member.operators.items() for key, method in methods_and_operators: _post_process_method(method) for key, prop in member.properties.items(): prop.name = prop.name.lower()[0] + prop.name[1:] if prop.getter != None: _post_process_method(prop.getter) if prop.setter != None: _post_process_method(prop.setter)
def create_c_code_for_file(the_file, other): '''This is called by the ... and indicates that the code in the passed in file needs to have some post processing for the C language.''' logger.info('Post Processing %s for C wrapper creation', the_file.name) for member in the_file.members: if member.is_class or member.is_struct or member.is_enum or member.is_type: # Setup the language data member.lang_data['c'] = LangBasicData(member) member.lang_data['cpp'] = LangBasicData(member) _do_create_type_code(member) elif member.is_module or member.is_library: for key, method in member.methods.items(): # Setup the language data method.lang_data['c'] = LangMethodData(method) method.lang_data['cpp'] = LangMethodData(method) if the_file.name == 'SGSDK': _do_create_adapter_code(method) else: # Process parameters - adding length and result parameters to functions/procedures _do_c_parameter_processing(method) # Build method signature and code _do_c_create_method_code(method)
def post_parse_process(the_file): ''' the c modules also wrap array return values and adds length parameters for arrays.''' logger.info('Post Processing %s for Python wrapper creation', the_file.name) for member in the_file.members: for key, method in member.methods.items(): if method.method_called.was_function: #convert string return types result_param = SGParameter('result') result_param.data_type = method.return_type result_param.modifier = 'var' param_list = list(method.params) param_list.append(result_param) method.params = tuple(param_list) arg_list = list(method.args) arg_list.append(result_param) method.args = arg_list method.return_type = None if method.method_called.has_length_params: #add length parameters to this method for param in method.method_called.params: if param.is_length_param: param_list = list(method.params) param_list.append(param) method.params = tuple(param_list) arg_list = list(method.args) arg_list.append(param) method.args = arg_list
def file_visitor(the_file, other): '''Called for each file read in by the parser''' if the_file.name == 'SGSDK': return post_parse_process(the_file) print the_file.name logger.info('Creating Python SwinGame Module %s', the_file.name) write_py_module(the_file)
def _do_c_create_method_code(the_method): '''Add the signature and code for the passed in function or procedure.''' logger.info('VISITING : Method %s', the_method.name) if (the_method.uname != the_method.name) or the_method.has_const_params( ) or the_method.has_var_params() or the_method.has_out_params(): _do_cpp_create_method_code(the_method) method_data = the_method.lang_data['c'] details = the_method.to_keyed_dict(param_visitor, type_visitor, arg_visitor, doc_transform, lang_key='c') # Create signature method_data.signature = '%(return_type)s %(uname_lower)s(%(params)s);' % details if method_data.is_function: details['the_call'] = arg_visitor( '%(calls.name)s(%(calls.args)s)' % details, None, method_data.return_type) method_data.code = c_lib.module_c_function_txt % details else: method_data.code = c_lib.module_c_method_txt % details if method_data.has_const_params(): # Create a version with const parameters passed by value - this avoids having to create const pointers to data in the C SwinGame details = the_method.to_keyed_dict(const_strip_param_visitor, type_visitor, const_strip_arg_visitor, doc_transform, lang_key='c') details['uname'] = details['uname'] + '_byval' details['uname_lower'] = details['uname_lower'] + '_byval' details['name'] = details['uname'] bval_sig = '%(return_type)s %(uname_lower)s(%(params)s);' % details method_data.signature += '\n' + bval_sig #print method_data.signature if method_data.is_function: details['the_call'] = const_strip_arg_visitor( '%(calls.name)s(%(calls.args)s)' % details, None, method_data.return_type) method_data.code += (c_lib.module_c_function_txt % details) else: method_data.code += (c_lib.module_c_method_txt % details)
def _do_cpp_create_method_code(the_method): '''Add the signature and code for the passed in function or procedure.''' logger.info('VISITING : Method %s', the_method.name) method_data = the_method.lang_data['cpp'] details = the_method.to_keyed_dict(cpp_param_visitor, cpp_type_visitor, cpp_arg_visitor, doc_transform, lang_key='cpp') # Create signature method_data.signature = '%(return_type)s %(name_lower)s(%(params)s);' % details if method_data.is_function: details['the_call'] = arg_visitor('%(calls.name)s(%(calls.args)s)' % details, None, method_data.return_type) method_data.code = c_lib.module_cpp_function_txt % details else: method_data.code = c_lib.module_cpp_method_txt % details
def write_pas_code_files(the_file, other): '''Write the code for the Pascal versions''' if the_file.name == 'SGSDK': # skip the library return logger.info('Adding Pascal code for %s', the_file.name) global _my_writer #visit the methods of the library other = dict() other['writer'] = _my_writer other['lang_key'] = 'pas' the_file.members[0].visit_methods(lang_helper.write_method_code, other)
def _do_create_adapter_code(the_method): logger.info('VISITING : SGSDK Method %s', the_method.name) method_data = the_method.lang_data['c'] details = the_method.to_keyed_dict(param_visitor, type_visitor, arg_visitor, doc_transform, lang_key='c') # Create signature method_data.signature = '%(return_type)s %(uname)s(%(params)s);' % details # Create vcpp variable if the_method.is_function: method_data.visual_cpp_variable = '%(return_type)s (*var_%(uname)s)(%(params)s);\n%(return_type)s %(uname)s(%(params)s)\n{\n\treturn var_%(uname)s(%(args)s);\n}' % details else: method_data.visual_cpp_variable = '%(return_type)s (*var_%(uname)s)(%(params)s);\n%(return_type)s %(uname)s(%(params)s)\n{\n\tvar_%(uname)s(%(args)s);\n}' % details method_data.visual_cpp_variable_init = '\t\tvar_%(uname)s = (%(return_type)s (__cdecl *)(%(params)s)) GetProcAddress( LibraryHandle, "%(uname)s" );' % details
def _add_locals_for_pas_library(method): ''' Adds local variables for temporary values between type shifting eg. PChar -> String. This includes local variables for the following cases: * Any parameter that maps the result of a function - these need to be copied to the callers destination (arrays) * Any parameter that is an array * Any string that is returned out (so all var and out string params) ''' logger.info('Post Processing library for Pascal library creation') method_alias = method.alias('pas') for param in method_alias.params: if param.maps_result or param.data_type.wraps_array or (param.modifier in ['var', 'out'] and param.data_type.name.lower() in ['string']): logger.debug('LOCAL VAR: Adding local var of type %s to %s', param.data_type, method.uname) param.lang_data['pas'] = LangParamData(param) local_var = LocalVar() local_var.setup_for_parameter(param, 'pas') method_alias.local_vars.append(local_var)
def _do_cpp_create_method_code(the_method): '''Add the signature and code for the passed in function or procedure.''' logger.info('VISITING : Method %s', the_method.name) method_data = the_method.lang_data['cpp'] details = the_method.to_keyed_dict(cpp_param_visitor, cpp_type_visitor, cpp_arg_visitor, doc_transform, lang_key='cpp') # Create signature method_data.signature = '%(return_type)s %(name_lower)s(%(params)s);' % details if method_data.is_function: details['the_call'] = arg_visitor( '%(calls.name)s(%(calls.args)s)' % details, None, method_data.return_type) method_data.code = c_lib.module_cpp_function_txt % details else: method_data.code = c_lib.module_cpp_method_txt % details
def create_pas_code_for_file(the_file, other): '''This is called by the ... and indicates that the code in the passed in file needs to have some the Pas signatures created.''' logger.info('Post Processing %s for PAS signature creation', the_file.name) for member in the_file.members: if member.is_class or member.is_struct or member.is_enum or member.is_type: # Setup the language data member.lang_data['pas'] = LangBasicData(member) #_do_create_type_code(member) elif member.is_module or member.is_library: for key, method in member.methods.items(): # Setup the language data method.lang_data['pas'] = LangMethodData(method) if the_file.name == 'SGSDK': # skip... pass else: # Build method signature and code _do_create_pas_signature(method, the_file)
def _do_c_create_method_code(the_method): '''Add the signature and code for the passed in function or procedure.''' logger.info('VISITING : Method %s', the_method.name) if (the_method.uname != the_method.name) or the_method.has_const_params() or the_method.has_var_params() or the_method.has_out_params(): _do_cpp_create_method_code(the_method) method_data = the_method.lang_data['c'] details = the_method.to_keyed_dict(param_visitor, type_visitor, arg_visitor, doc_transform, lang_key='c') # Create signature method_data.signature = '%(return_type)s %(uname_lower)s(%(params)s);' % details if method_data.is_function: details['the_call'] = arg_visitor('%(calls.name)s(%(calls.args)s)' % details, None, method_data.return_type) method_data.code = c_lib.module_c_function_txt % details else: method_data.code = c_lib.module_c_method_txt % details if method_data.has_const_params(): # Create a version with const parameters passed by value - this avoids having to create const pointers to data in the C SwinGame details = the_method.to_keyed_dict(const_strip_param_visitor, type_visitor, const_strip_arg_visitor, doc_transform, lang_key='c') details['uname'] = details['uname'] + '_byval' details['uname_lower'] = details['uname_lower'] + '_byval' details['name'] = details['uname'] bval_sig = '%(return_type)s %(uname_lower)s(%(params)s);' % details; method_data.signature += '\n' + bval_sig; #print method_data.signature if method_data.is_function: details['the_call'] = const_strip_arg_visitor('%(calls.name)s(%(calls.args)s)' % details, None, method_data.return_type) method_data.code += (c_lib.module_c_function_txt % details) else: method_data.code += (c_lib.module_c_method_txt % details)
def create_pas_code_for_file(the_file, other): '''This is called by the ... and indicates that the code in the passed in file needs to have some the Pas signatures created.''' logger.info('Post Processing %s for PAS signature creation', the_file.name) for member in the_file.members: if member.is_class or member.is_struct or member.is_enum or member.is_type: # Setup the language data member.lang_data['pas'] = LangBasicData(member) #_do_create_type_code(member) elif member.is_module or member.is_library: for key, method in member.methods.items(): # Setup the language data method.lang_data['pas'] = LangMethodData(method) if the_file.name == 'SGSDK': # Add local variables etc. _add_locals_for_pas_library(method) _do_create_pas_library_code(method) else: # Build method signature and code _do_create_pas_signature(method)
def write_pas_code_files(the_file, other): '''Write the code for the Pascal versions''' if the_file.name == 'Types': logger.info('Writing %s c header', the_file.name) lang_c.write_c_header_for(the_file, out_path='../../Generated/Source/src/') if the_file.name != 'SGSDK': return logger.info('Writing %s c header', the_file.name) lang_c.write_c_header_for(the_file, out_path='../../Generated/Source/src/') logger.info('Writing %s Pascal code', the_file.name) my_writer = FileWriter('../../Generated/Source/src/%s.pas' % the_file.name) my_writer.writeln( pas_lib.header_txt % { 'name': the_file.pascal_name, 'uses': the_file.uses_str(lambda a_file: a_file.pascal_name), 'version': the_file.members[0].version #version from library }) my_writer.indent() #visit the methods of the library other = dict() other['writer'] = my_writer other['lang_key'] = 'pas' the_file.members[0].visit_methods(lang_helper.write_method_code, other) #write out exports my_writer.writeln(pas_lib.exports_header_txt) my_writer.indent() for name in _names: if name == _names[-1]: my_writer.write((pas_lib.export_line_txt % {'name': name})[:-2]) my_writer.write(';') else: my_writer.write(pas_lib.export_line_txt % {'name': name}) my_writer.outdent() my_writer.outdent() my_writer.writeln(pas_lib.footer_txt) my_writer.close()
def write_pas_code_files(the_file, other): '''Write the code for the Pascal versions''' if the_file.name == 'Types': logger.info('Writing %s c header', the_file.name) lang_c.write_c_header_for(the_file, out_path='../../Generated/Source/src/') if the_file.name != 'SGSDK': return logger.info('Writing %s c header', the_file.name) lang_c.write_c_header_for(the_file, out_path='../../Generated/Source/src/') logger.info('Writing %s Pascal code', the_file.name) my_writer = FileWriter('../../Generated/Source/src/%s.pas' % the_file.name) my_writer.writeln(pas_lib.header_txt % { 'name' : the_file.pascal_name, 'uses' : the_file.uses_str(lambda a_file: a_file.pascal_name), 'version' : the_file.members[0].version #version from library }) my_writer.indent(); #visit the methods of the library other = dict() other['writer'] = my_writer other['lang_key'] = 'pas' the_file.members[0].visit_methods(lang_helper.write_method_code, other) #write out exports my_writer.writeln(pas_lib.exports_header_txt) my_writer.indent() for name in _names: if name == _names[-1]: my_writer.write((pas_lib.export_line_txt % {'name': name})[:-2]) my_writer.write(';') else: my_writer.write(pas_lib.export_line_txt % {'name': name}) my_writer.outdent(); my_writer.outdent(); my_writer.writeln(pas_lib.footer_txt) my_writer.close()