Created
April 3, 2012 04:14
-
-
Save freecnjet/2289265 to your computer and use it in GitHub Desktop.
CodeGenerator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _CPP_HEADER_CODE_GENERATOR_H_ | |
#define _CPP_HEADER_CODE_GENERATOR_H_ | |
#include "CodeGenerator.h" | |
struct CppHeaderGenerator { | |
enum { | |
EAccess_Public = 0x01, | |
EAccess_Protected = 0x02, | |
EAccess_Private = 0x04 | |
}; | |
ModuleDescription* m_ModuleDescription; | |
fstream m_OutputStream; | |
CppHeaderGenerator(ModuleDescription* mod) | |
:m_ModuleDescription(mod) | |
{} | |
int Initial(const char* outfilepath); | |
int Generate(); | |
int Finalize(); | |
void GenerateMethod(std::list<TypeDescription>::iterator& type, int access, bool out_access=true); | |
void GenerateField(std::list<TypeDescription>::iterator& type, int access); | |
}; | |
inline int CppHeaderGenerator::Initial(const char* typefilepath) | |
{ | |
char outfilepath[MAX_OUTPUT_PATH_LEN] = ""; | |
strcpy( outfilepath, typefilepath ); | |
char* ptr = strrchr(outfilepath, '.'); | |
strcpy(ptr, ".h"); | |
m_OutputStream.open(outfilepath, fstream::out); | |
return 0; | |
} | |
inline int CppHeaderGenerator::Finalize() | |
{ | |
m_OutputStream.close(); | |
return 0; | |
} | |
inline void CppHeaderGenerator::GenerateField(std::list<TypeDescription>::iterator& type, int access) | |
{ | |
bool pre_outed = false; | |
for( std::list<FieldDescription>::iterator field = type->m_Fields.begin(); | |
field!=type->m_Fields.end(); ++field ) { | |
int access_flag = 0; | |
if( 0==strcmp(field->m_Access, "public") ) | |
access_flag = EAccess_Public; | |
else if( 0==strcmp(field->m_Access, "protected") ) | |
access_flag = EAccess_Protected; | |
else if( 0==strcmp(field->m_Access, "private") ) | |
access_flag = EAccess_Private; | |
if( 0==(access_flag&access) ) | |
continue; | |
if( !pre_outed ) { | |
if( (access&EAccess_Private) ) | |
m_OutputStream << "private:"; | |
else if( (access&EAccess_Protected) ) | |
m_OutputStream << "protected:"; | |
else if( (access&EAccess_Public) ) | |
m_OutputStream << "public:"; | |
m_OutputStream <<"\n"; | |
pre_outed = true; | |
} | |
m_OutputStream << " "; | |
if(field->m_IsStatic) | |
m_OutputStream << "static "; | |
m_OutputStream << field->m_TypeName << " " << field->m_Name << ";\n"; | |
} | |
} | |
inline void CppHeaderGenerator::GenerateMethod(std::list<TypeDescription>::iterator& type, int access, bool out_access/*=true*/) { | |
bool pre_outed = !out_access; | |
for( std::list<MethodDescription>::iterator method = type->m_Methods.begin(); | |
method!=type->m_Methods.end(); ++method ) { | |
int access_flag = 0; | |
if( 0==strcmp(method->m_Access, "public") ) | |
access_flag = EAccess_Public; | |
else if( 0==strcmp(method->m_Access, "protected") ) | |
access_flag = EAccess_Protected; | |
else if( 0==strcmp(method->m_Access, "private") ) | |
access_flag = EAccess_Private; | |
if( 0==(access_flag&access) ) | |
continue; | |
if( !pre_outed ) { | |
if( (access&EAccess_Private) ) | |
m_OutputStream << "private:"; | |
else if( (access&EAccess_Protected) ) | |
m_OutputStream << "protected:"; | |
else if( (access&EAccess_Public) ) | |
m_OutputStream << "public:"; | |
m_OutputStream <<"\n"; | |
pre_outed = true; | |
} | |
if( method->m_IsStatic && method->m_Virtual ) { | |
printf("Error: method[%s] can't be static and virtual at same time.\n", method->m_Name); | |
} | |
m_OutputStream << " "; | |
if(method->m_IsStatic) | |
m_OutputStream << "static "; | |
if(method->m_Virtual ) | |
m_OutputStream << "virtual "; | |
m_OutputStream << method->m_ReturnTypeName << " " << method->m_Name << "("; | |
for(std::list<ParameterDescription>::iterator parameter = method->m_Parmeters.begin(); | |
parameter!=method->m_Parmeters.end(); ++parameter ) { | |
if(parameter!=method->m_Parmeters.begin()) { | |
m_OutputStream << ", "; | |
} | |
m_OutputStream << parameter->m_TypeName << " " << parameter->m_Name; | |
} | |
m_OutputStream << ")"; | |
if(method->m_MustImplement ) { | |
m_OutputStream << " = 0"; | |
} | |
m_OutputStream << ";\n"; | |
} | |
} | |
inline int CppHeaderGenerator::Generate() | |
{ | |
char import_package[1024]; | |
strcpy( import_package, m_ModuleDescription->m_ImportPackage); | |
char* pch = strtok(import_package, " ,"); | |
if( pch ) { | |
while( pch ) { | |
m_OutputStream << "#include\"" << pch << ".h\"\n"; | |
pch = strtok(0, " ,"); | |
} | |
m_OutputStream << "\n"; | |
} | |
/** | |
* generate header file | |
*/ | |
for( std::list<TypeDescription>::iterator type = m_ModuleDescription->m_Types.begin(); | |
type!=m_ModuleDescription->m_Types.end(); ++ type ) { | |
const char* type_name = type->m_TypeName; | |
/** | |
* enum | |
*/ | |
if( 0==strcmp(type_name, "enum") ) { | |
m_OutputStream << "enum " << type->m_Name << " {\n"; | |
for( std::list<EnumItemDescription>::iterator enum_item = type->m_EnumItems.begin(); | |
enum_item!=type->m_EnumItems.end(); ++enum_item ) { | |
m_OutputStream << " " << enum_item->m_Name; | |
m_OutputStream << " = " << enum_item->m_Value; | |
m_OutputStream << (enum_item!=type->m_EnumItems.end() ? ",\n" : "\n"); | |
} | |
m_OutputStream << "};\n"; | |
m_OutputStream << "extern EnumType* MT" << type->m_Name << ";\n\n"; | |
} else | |
/** | |
* interface | |
*/ | |
if( 0==strcmp(type_name, "interface") ) { | |
m_OutputStream << "struct " << type->m_Name; | |
char extands[256]; | |
strcpy(extands, type->m_Extands); | |
if( 0!=strlen(extands)) { | |
char* pch = strtok(extands, " ,"); | |
if( pch ) { | |
m_OutputStream << " : public "; | |
while( pch!=0 ) { | |
m_OutputStream << pch; | |
pch = strtok(0, " ,"); | |
if( pch!=0 ) { | |
m_OutputStream << ", public "; | |
} | |
} | |
} | |
} | |
m_OutputStream << "{\n"; | |
GenerateMethod(type, EAccess_Public, false); | |
m_OutputStream << "};\n"; | |
m_OutputStream << "extern InterfaceType* MT" << type->m_Name << ";\n\n"; | |
} else | |
/** | |
* class | |
*/ | |
if( 0==strcmp(type_name, "class") || 0==strcmp(type_name, "object") ) { | |
m_OutputStream << "class " << type->m_Name; | |
char extands[256]; | |
strcpy(extands, type->m_Extands); | |
if( 0!=strlen(extands)) { | |
char* pch = strtok(extands, " ,"); | |
if( pch ) { | |
m_OutputStream << " : public "; | |
while( pch!=0 ) { | |
m_OutputStream << pch; | |
pch = strtok(0, " ,"); | |
if( pch!=0 ) { | |
m_OutputStream << ", public "; | |
} | |
} | |
} | |
} else if( 0==strcmp(type_name, "object") ) { | |
m_OutputStream << " : public Object "; | |
} | |
m_OutputStream << "{\n"; | |
GenerateField(type, EAccess_Private); | |
GenerateField(type, EAccess_Protected); | |
GenerateField(type, EAccess_Public); | |
m_OutputStream << "\n"; | |
GenerateMethod(type, EAccess_Private); | |
GenerateMethod(type, EAccess_Protected); | |
GenerateMethod(type, EAccess_Public); | |
m_OutputStream << "};\n"; | |
m_OutputStream << "extern ClassType* MT" << type->m_Name << ";\n\n"; | |
} else | |
/** | |
* valuable type | |
*/ | |
{ | |
if( 0!=strcmp(type->m_Name, type->m_TypeName) ) //define on for redefinition | |
m_OutputStream << "typedef " << type->m_TypeName << " " << type->m_Name << ";\n"; | |
m_OutputStream << "extern Type* MT" << type->m_Name << ";\n\n"; | |
} | |
} | |
return 0; | |
} | |
#endif //_CPP_HEADER_CODE_GENERATOR_H_ | |
#ifndef _CPP_SOURCE_CODE_GENERATOR_H_ | |
#define _CPP_SOURCE_CODE_GENERATOR_H_ | |
#include "CodeGenerator.h" | |
struct CppSourceGenerator { | |
enum { | |
EAccess_Public = 0x01, | |
EAccess_Protected = 0x02, | |
EAccess_Private = 0x04 | |
}; | |
ModuleDescription* m_ModuleDescription; | |
fstream m_OutputStream; | |
char m_HeaderFilePath[MAX_OUTPUT_PATH_LEN]; | |
CppSourceGenerator(ModuleDescription* mod) | |
:m_ModuleDescription(mod) | |
{} | |
int Initial(const char* outfilepath); | |
int Finalize(); | |
int Generate(); | |
}; | |
inline int CppSourceGenerator::Initial(const char* typefilepath) | |
{ | |
char outfilepath[MAX_OUTPUT_PATH_LEN] = ""; | |
strcpy( outfilepath, typefilepath ); | |
char* ptr = strrchr(outfilepath, '.'); | |
strcpy(ptr, ".cpp"); | |
char* ptr_pre0 = strrchr(outfilepath, '/'); | |
char* ptr_pre1 = strrchr(outfilepath, '\\'); | |
if( ptr_pre0 ) { | |
strcpy( m_HeaderFilePath, ptr_pre0+1 ); | |
} else if( ptr_pre1 ){ | |
strcpy( m_HeaderFilePath, ptr_pre1+1 ); | |
} else { | |
strcpy( m_HeaderFilePath, outfilepath ); | |
} | |
ptr = strrchr(m_HeaderFilePath, '.'); | |
strcpy(ptr, ".h"); | |
m_OutputStream.open(outfilepath, fstream::out); | |
return 0; | |
} | |
inline int CppSourceGenerator::Finalize() | |
{ | |
m_OutputStream.close(); | |
return 0; | |
} | |
inline int CppSourceGenerator::Generate() | |
{ | |
m_OutputStream << "#include \"ReflectionSystemImp.h\"\n"; | |
m_OutputStream << "#include \"" << m_HeaderFilePath << "\"\n\n\n"; | |
for( std::list<TypeDescription>::iterator type = m_ModuleDescription->m_Types.begin(); | |
type!=m_ModuleDescription->m_Types.end(); ++type ) { | |
const char* type_name = type->m_TypeName; | |
/** | |
* enum | |
*/ | |
if( 0==strcmp(type_name, "enum") ) { | |
size_t enum_item_count = 0; | |
m_OutputStream << "static EnumItem s_Enum_" << type->m_Name << "_Items[] = {\n"; | |
for( std::list<EnumItemDescription>::iterator enum_item = type->m_EnumItems.begin(); | |
enum_item!=type->m_EnumItems.end(); ++enum_item ) { | |
m_OutputStream << " {\"" << enum_item->m_Name << "\", " << enum_item->m_Value; | |
m_OutputStream << (enum_item!=type->m_EnumItems.end() ? "},\n" : "}\n"); | |
++enum_item_count; | |
} | |
m_OutputStream << "};\n"; | |
m_OutputStream << "EnumTypeImp s_Enum_" << type->m_Name << "_Type(\"" << type->m_Name << "\", " | |
<< "sizeof(" << type->m_Name << "), " << enum_item_count << ", " << "&s_Enum_" | |
<< type->m_Name << "_Items[0]);\n"; | |
m_OutputStream << "EnumType* MT" << type->m_Name << " = &s_Enum_" << type->m_Name << "_Type;\n\n"; | |
} else | |
/** | |
* interface | |
*/ | |
if( 0==strcmp(type_name, "interface") ) { | |
// parameters | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ++method ) { | |
m_OutputStream << "struct {\n"; | |
for(std::list<ParameterDescription>::iterator paramter = method->m_Parmeters.begin(); paramter!=method->m_Parmeters.end(); ++paramter ){ | |
m_OutputStream << " " << paramter->m_TypeName << " " << paramter->m_Name << ";\n"; | |
} | |
m_OutputStream << "} s_" << type->m_Name << "_" << method->m_Name << "_ParamContext;\n"; | |
m_OutputStream << "static ParameterItem s_" << type->m_Name << "_" << method->m_Name << "_Params[] = {\n"; | |
for(std::list<ParameterDescription>::iterator paramter = method->m_Parmeters.begin(); paramter!=method->m_Parmeters.end(); ){ | |
m_OutputStream << " {MT" << paramter->m_TypeName << ", " | |
<< (paramter->m_Optional ? "true" : "false") | |
<< ", \"" << paramter->m_Name << "\"" | |
<< ", &" << "s_" << type->m_Name << "_" << method->m_Name << "_ParamContext." << paramter->m_Name | |
<< ", \"" << paramter->m_DefaultValue << "\""; | |
++paramter; | |
m_OutputStream << (paramter==method->m_Parmeters.end() ? "}\n" : "},\n"); | |
} | |
m_OutputStream << "};\n"; | |
} | |
// method | |
m_OutputStream << "static MethodItem s_" << type->m_Name << "_Methods[] = {\n"; | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ) | |
{ | |
m_OutputStream << " {sizeof(s_" << type->m_Name << "_" << method->m_Name << "_Params)/sizeof(MethodItem)" | |
<< ", &s_" << type->m_Name << "_" << method->m_Name << "_Params"; | |
if( 0==strcmp(method->m_Access, "private") ) { | |
m_OutputStream << ", FLAG_ACCESS_PRIVATE"; | |
} else if( 0==strcmp(method->m_Access, "protected") ) { | |
m_OutputStream << ", FLAG_ACCESS_PROTECTED"; | |
} else { | |
m_OutputStream << ", FLAG_ACCESS_PUBLIC"; | |
} | |
if( method->m_IsConstructor ) { | |
m_OutputStream << "|METHOD_FLAG_CONSTRUCTOR_MASK"; | |
} | |
if( method->m_Virtual ) { | |
m_OutputStream << "|METHOD_FLAG_VIRTUAL_MASK"; | |
} | |
if( method->m_IsStatic ) { | |
m_OutputStream << "|METHOD_FLAG_STATIC_MASK"; | |
} | |
++method; | |
m_OutputStream << (method==type->m_Methods.end() ? "}\n" : "},\n"); | |
} | |
m_OutputStream << "};\n"; | |
// method caller | |
size_t method_item_count = 0; | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ++method ) | |
{ | |
m_OutputStream << "struct " << type->m_Name << "_" << method->m_Name << "_Caller : public MethodInfoImp {\n" | |
<<" " << type->m_Name << "_" << method->m_Name << "_Caller():MethodInfoImp(" << "&s_" << type->m_Name << "_Methods[" << method_item_count << "]) {}\n"; | |
m_OutputStream << " virtual int Invoke(void* obj) {\n " << type->m_Name << "* o = (" << type->m_Name << "*)obj;\n" | |
<< " o->" << method->m_Name << "("; | |
for(std::list<ParameterDescription>::iterator paramter = method->m_Parmeters.begin(); paramter!=method->m_Parmeters.end(); ){ | |
m_OutputStream << "s_" << type->m_Name << "_" << method->m_Name << "_ParamContext." << paramter->m_Name; | |
++paramter; | |
if( paramter!=method->m_Parmeters.end() ) | |
m_OutputStream << ", "; | |
} | |
m_OutputStream << ");\n }\n} s_" << type->m_Name << "_" << method->m_Name << "_Caller;\n"; | |
++method_item_count; | |
} | |
m_OutputStream << "MethodInfo* s_" << type->m_Name << "_Callers[] = {"; | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ) | |
{ | |
m_OutputStream << "&s_" << type->m_Name << "_" << method->m_Name << "_Caller"; | |
++method; | |
if( method!=type->m_Methods.end() ) | |
m_OutputStream << ", "; | |
} | |
m_OutputStream << "};\n"; | |
// base type | |
m_OutputStream << "static Interface* s_" << type->m_Name << "_Bases[] = {"; | |
char extands[256]; | |
int base_count = 0; | |
strcpy(extands, type->m_Extands); | |
if( 0!=strlen(extands)) { | |
char* pch = strtok(extands, " ,"); | |
while( 0!=pch ) { | |
m_OutputStream << "MT" <<pch; | |
++base_count; | |
pch = strtok(0, " ,"); | |
if( 0!=pch ) | |
m_OutputStream << ", "; | |
} | |
} | |
m_OutputStream << "};\n"; | |
m_OutputStream << "struct Interface" << type->m_Name << " : public InterfaceTypeImp {"; | |
m_OutputStream << "};\n"; | |
m_OutputStream << "static InterfaceTypeImp s_Interface_" << type->m_Name << "_Type(" | |
<< type->m_Name << ", " << base_count << ", s_" << type->m_Name << "_Bases&[0], " | |
<< method_item_count << ", &s_" << type->m_Name << "_Callers[0]);\n\n"; | |
} else | |
/** | |
* class | |
*/ | |
if( 0==strcmp(type_name, "class") || 0==strcmp(type_name, "object") ) { | |
// parameters | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ++method ) { | |
m_OutputStream << "struct {\n"; | |
for(std::list<ParameterDescription>::iterator paramter = method->m_Parmeters.begin(); paramter!=method->m_Parmeters.end(); ++paramter ){ | |
m_OutputStream << " " << paramter->m_TypeName << " " << paramter->m_Name << ";\n"; | |
} | |
m_OutputStream << "} s_" << type->m_Name << "_" << method->m_Name << "_ParamContext;\n"; | |
m_OutputStream << "static ParameterItem s_" << type->m_Name << "_" << method->m_Name << "_Params[] = {\n"; | |
for(std::list<ParameterDescription>::iterator paramter = method->m_Parmeters.begin(); paramter!=method->m_Parmeters.end(); ){ | |
m_OutputStream << " {MT" << paramter->m_TypeName << ", " | |
<< (paramter->m_Optional ? "true" : "false") | |
<< ", \"" << paramter->m_Name << "\"" | |
<< ", &" << "s_" << type->m_Name << "_" << method->m_Name << "_ParamContext." << paramter->m_Name | |
<< ", \"" << paramter->m_DefaultValue << "\""; | |
++paramter; | |
m_OutputStream << (paramter==method->m_Parmeters.end() ? "}\n" : "},\n"); | |
} | |
m_OutputStream << "};\n"; | |
} | |
// method | |
m_OutputStream << "static MethodItem s_" << type->m_Name << "_Methods[] = {\n"; | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ) | |
{ | |
m_OutputStream << " {sizeof(s_" << type->m_Name << "_" << method->m_Name << "_Params)/sizeof(MethodItem)" | |
<< ", &s_" << type->m_Name << "_" << method->m_Name << "_Params"; | |
if( 0==strcmp(method->m_Access, "private") ) { | |
m_OutputStream << ", FLAG_ACCESS_PRIVATE"; | |
} else if( 0==strcmp(method->m_Access, "protected") ) { | |
m_OutputStream << ", FLAG_ACCESS_PROTECTED"; | |
} else { | |
m_OutputStream << ", FLAG_ACCESS_PUBLIC"; | |
} | |
if( method->m_IsConstructor ) { | |
m_OutputStream << "|METHOD_FLAG_CONSTRUCTOR_MASK"; | |
} | |
if( method->m_Virtual ) { | |
m_OutputStream << "|METHOD_FLAG_VIRTUAL_MASK"; | |
} | |
if( method->m_IsStatic ) { | |
m_OutputStream << "|METHOD_FLAG_STATIC_MASK"; | |
} | |
++method; | |
m_OutputStream << (method==type->m_Methods.end() ? "}\n" : "},\n"); | |
} | |
m_OutputStream << "};\n"; | |
// method caller | |
size_t method_item_count = 0; | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ++method ) | |
{ | |
m_OutputStream << "struct " << type->m_Name << "_" << method->m_Name << "_Caller : public MethodInfoImp {\n" | |
<<" " << type->m_Name << "_" << method->m_Name << "_Caller():MethodInfoImp(" << "&s_" << type->m_Name << "_Methods[" << method_item_count << "]) {}\n"; | |
m_OutputStream << " virtual int Invoke(void* obj) {\n " << type->m_Name << "* o = (" << type->m_Name << "*)obj;\n" | |
<< " o->" << method->m_Name << "("; | |
for(std::list<ParameterDescription>::iterator paramter = method->m_Parmeters.begin(); paramter!=method->m_Parmeters.end(); ){ | |
m_OutputStream << "s_" << type->m_Name << "_" << method->m_Name << "_ParamContext." << paramter->m_Name; | |
++paramter; | |
if( paramter!=method->m_Parmeters.end() ) | |
m_OutputStream << ", "; | |
} | |
m_OutputStream << ");\n }\n} s_" << type->m_Name << "_" << method->m_Name << "_Caller;\n"; | |
++method_item_count; | |
} | |
m_OutputStream << "MethodInfo* s_" << type->m_Name << "_Callers[] = {"; | |
for(std::list<MethodDescription>::iterator method = type->m_Methods.begin(); method!=type->m_Methods.end(); ) | |
{ | |
m_OutputStream << "&s_" << type->m_Name << "_" << method->m_Name << "_Caller"; | |
++method; | |
if( method!=type->m_Methods.end() ) | |
m_OutputStream << ", "; | |
} | |
m_OutputStream << "};\n"; | |
// field | |
m_OutputStream << "FieldItem s_" << type->m_Name << "_Fields[] = {\n"; | |
for(std::list<FieldDescription>::iterator field = type->m_Fields.begin(); field!=type->m_Fields.end(); ) { | |
m_OutputStream << " {"; | |
if( 0==strcmp(field->m_Access, "private") ) { | |
m_OutputStream << "FLAG_ACCESS_PRIVATE"; | |
} else if( 0==strcmp(field->m_Access, "protected") ) { | |
m_OutputStream << "FLAG_ACCESS_PROTECTED"; | |
} else { | |
m_OutputStream << "FLAG_ACCESS_PUBLIC"; | |
} | |
if( field->m_CanWrite ) { | |
m_OutputStream << "|FIELD_FLAG_WRITE_MASK"; | |
} | |
if( field->m_CanRead ) { | |
m_OutputStream << "|FIELD_FLAG_READ_MASK"; | |
} | |
if( field->m_IsStatic ) { | |
m_OutputStream << "|FIELD_FLAG_STATIC_MASK"; | |
} | |
m_OutputStream << ", MT" << field->m_TypeName | |
<< ", " << field->m_Name | |
<< ", " << field->m_DefaultValue; | |
if( 0==strcmp(field->m_Access, "public") ) | |
m_OutputStream << ", offsetof(" << type->m_Name << ", " << field->m_Name << ")"; | |
else | |
m_OutputStream << ", INVALID_OFFSET"; | |
++field; | |
m_OutputStream << (field!=type->m_Fields.end() ? "},\n" : "}\n"); | |
} | |
m_OutputStream << "};\n"; | |
// base type | |
m_OutputStream << "static Interface* s_" << type->m_Name << "_Bases[] = {"; | |
char extands[256]; | |
int base_count = 0; | |
strcpy(extands, type->m_Extands); | |
if( 0!=strlen(extands)) { | |
char* pch = strtok(extands, " ,"); | |
while( 0!=pch ) { | |
m_OutputStream << "MT" <<pch; | |
++base_count; | |
pch = strtok(0, " ,"); | |
if( 0!=pch ) | |
m_OutputStream << ", "; | |
} | |
} | |
m_OutputStream << "};\n"; | |
m_OutputStream << "struct Interface" << type->m_Name << " : public ClassTypeImp {"; | |
m_OutputStream << "};\n"; | |
m_OutputStream << "static ClassTypeImp s_Class_" << type->m_Name << "_Type(" | |
<< type->m_Name << ", " << base_count << ", s_" << type->m_Name << "_Bases&[0], " | |
<< method_item_count << ", &s_" << type->m_Name << "_Callers[0]);\n\n"; | |
} else | |
/** | |
* valuable type | |
*/ | |
{ | |
m_OutputStream << "ValueType s_" << type->m_Name << "_Type(\"" << type->m_Name << "\", Type::REDEFINE, sizeof(" << type->m_Name << ");\n\n"; | |
} | |
} | |
///** | |
//* generate stub source file | |
//*/ | |
//for( xml_node type = m_Types.first_child(); type; type=type.next_sibling() ) | |
//{ | |
// const char* type_name = type.attribute("type").value(); | |
// /** | |
// * enum | |
// */ | |
// if( 0==strcmp(type_name, "enum") ) { | |
// size_t enum_item_count = 0; | |
// m_OutputStream << "static EnumItem s_Enum_" << type.name() << "_Items[] = {\n"; | |
// int current_value = 0; | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// if( item.attribute("value") ) { | |
// current_value = atoi(item.attribute("value").value()); | |
// } | |
// m_OutputStream << " {\"" << item.name() << "\", " << current_value; | |
// m_OutputStream << (item.next_sibling()? "},\n" : "}\n"); | |
// | |
// ++current_value; | |
// ++enum_item_count; | |
// } | |
// m_OutputStream << "};\n"; | |
// m_OutputStream << "EnumTypeInfo s_Enum_" << type.name() << "_Info(\"" << type.name() << "\", " << "sizeof(" << type.name() << "), " << enum_item_count << ", " << "&s_Enum_" << type.name() << "_Items[0]);\n\n"; | |
// } else | |
// /** | |
// * struct | |
// */ | |
// if( 0==strcmp(type_name, "struct") ) { | |
// size_t struct_item_count = 0; | |
// m_OutputStream << "static StructItem s_Struct_" << type.name() << "_Items[] = {\n"; | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// m_OutputStream << " {\"" << item.name() << "\", \"" << item.attribute("type").value() << "\""; | |
// m_OutputStream << (item.next_sibling()? "},\n" : "}\n"); | |
// ++struct_item_count; | |
// } | |
// m_OutputStream << "};\n"; | |
// m_OutputStream << "StructTypeInfo s_Struct_" << type.name() << "_Info(\"" << type.name() << "\", " << "sizeof(" << type.name() << "), " << struct_item_count << ", " << "&s_Struct_" << type.name() << "_Items[0]);\n\n"; | |
// } else | |
// /** | |
// * class | |
// */ | |
// if( 0==strcmp(type_name, "class") ) { | |
// // method param | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// if( 0==strcmp(item.attribute("type").value(), "function") ) | |
// { | |
// m_OutputStream << "static MethodParam s_Class_" << type.name() << "_" << item.name() << "_Params[] = {\n"; | |
// for( xml_node param = item.first_child(); param; param=param.next_sibling() ) { | |
// m_OutputStream << " {\"" << param.name() << "\", \"" << param.attribute("type").value() << "\""; | |
// m_OutputStream << (param.next_sibling()? "},\n" : "}\n"); | |
// } | |
// m_OutputStream << "};\n"; | |
// } | |
// } | |
// // method | |
// size_t method_item_count = 0; | |
// m_OutputStream << "static MethodItem s_Class_" << type.name() << "_Methods[] = {\n"; | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// if( 0==strcmp(item.attribute("type").value(), "function") ) { | |
// m_OutputStream << " {\"" << item.name() << "\", \"" << item.attribute("return").value() << "\"" | |
// << ", sizeof(" << "s_Class_" << type.name() << "_" << item.name() << "_Params" << ")/sizeof(MethodParam)," | |
// << " &s_Class_" << type.name() << "_" << item.name() << "_Params[0]"; | |
// m_OutputStream << (item.next_sibling()? "},\n" : "}\n"); | |
// ++method_item_count; | |
// } | |
// } | |
// m_OutputStream << "};\n"; | |
// // property | |
// size_t property_item_count = 0; | |
// m_OutputStream << "static PropertyItem s_Class_" << type.name() << "_Propertys[] = {\n"; | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// if( 0!=strcmp(item.attribute("type").value(), "function") ) { // member function | |
// m_OutputStream << " {\"" << item.name() << "\", \"" << item.attribute("type").value() << "\""; | |
// m_OutputStream << (item.next_sibling()? "},\n" : "}\n"); | |
// ++property_item_count; | |
// } | |
// } | |
// m_OutputStream << "};\n"; | |
// m_OutputStream << "ClassTypeInfo s_Class_" << type.name() << "_Info(\"" << type.name() << "\", " << "sizeof(" << type.name() << "), " << property_item_count << ", " << "&s_Class_" << type.name() << "_Propertys[0]," | |
// << method_item_count << ", &s_Class_" << type.name() << "_Methods[0] );\n\n"; | |
// } else | |
// /** | |
// * runtime class | |
// */ | |
// if( 0==strcmp(type_name, "rtclass") ) { | |
// // method param | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// if( 0==strcmp(item.attribute("type").value(), "function") ) | |
// { | |
// m_OutputStream << "static MethodParam s_Class_" << type.name() << "_" << item.name() << "_Params[] = {\n"; | |
// for( xml_node param = item.first_child(); param; param=param.next_sibling() ) { | |
// m_OutputStream << " {\"" << param.name() << "\", \"" << param.attribute("type").value() << "\""; | |
// m_OutputStream << (param.next_sibling()? "},\n" : "}\n"); | |
// } | |
// m_OutputStream << "};\n"; | |
// } | |
// } | |
// // method | |
// size_t method_item_count = 0; | |
// m_OutputStream << "static MethodItem s_Class_" << type.name() << "_Methods[] = {\n"; | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// if( 0==strcmp(item.attribute("type").value(), "function") ) { | |
// m_OutputStream << " {\"" << item.name() << "\", \"" << item.attribute("return").value() << "\"" | |
// << ", sizeof(" << "s_Class_" << type.name() << "_" << item.name() << "_Params" << ")/sizeof(MethodParam)," | |
// << " &s_Class_" << type.name() << "_" << item.name() << "_Params[0]"; | |
// m_OutputStream << (item.next_sibling()? "},\n" : "}\n"); | |
// ++method_item_count; | |
// } | |
// } | |
// m_OutputStream << "};\n"; | |
// // property | |
// size_t property_item_count = 0; | |
// m_OutputStream << "static PropertyItem s_Class_" << type.name() << "_Propertys[] = {\n"; | |
// for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
// { | |
// if( 0!=strcmp(item.attribute("type").value(), "function") ) { // member function | |
// m_OutputStream << " {\"" << item.name() << "\", \"" << item.attribute("type").value() << "\""; | |
// m_OutputStream << (item.next_sibling()? "},\n" : "}\n"); | |
// ++property_item_count; | |
// } | |
// } | |
// m_OutputStream << "};\n"; | |
// m_OutputStream << "RTClassTypeInfo s_RTClass_" << type.name() << "_Info(\"" << type.name() << "\", " << "sizeof(" << type.name() << "), " << property_item_count << ", " << "&s_Class_" << type.name() << "_Propertys[0]," | |
// << method_item_count << ", &s_Class_" << type.name() << "_Methods[0] );\n\n"; | |
// } else | |
// /** | |
// * basic type | |
// */ | |
// { | |
// m_OutputStream << "BasicTypeInfo s_Basic_" << type.name() << "_Info(\"" << type.name() << "\", " << "sizeof(" << type.name() << "), \"" << type.attribute("type").value() << "\");\n\n"; | |
// } | |
//} | |
return 0; | |
} | |
#endif | |
#pragma once | |
#include <list> | |
#include <cstring> | |
#include <iostream> | |
#include <fstream> | |
#include <cstdarg> | |
#include <cstdio> | |
using namespace std; | |
#include "pugixml.hpp" | |
using namespace pugi; | |
struct ValueTypeDescription { | |
const char* m_Name; | |
const char* m_TypeName; | |
}; | |
struct EnumItemDescription { | |
const char* m_Name; | |
int m_Value; | |
}; | |
struct FieldDescription { | |
const char* m_Name; | |
const char* m_TypeName; | |
const char* m_Access; | |
bool m_IsStatic; | |
bool m_CanRead; | |
bool m_CanWrite; | |
const char* m_DefaultValue; | |
}; | |
struct ParameterDescription { | |
const char* m_Name; | |
const char* m_TypeName; | |
bool m_Optional; | |
const char* m_DefaultValue; | |
}; | |
struct MethodDescription { | |
const char* m_Name; | |
const char* m_Access; | |
bool m_IsStatic; | |
bool m_IsConstructor; | |
bool m_Virtual; | |
bool m_MustImplement; | |
const char* m_ReturnTypeName; | |
std::list<ParameterDescription> m_Parmeters; | |
}; | |
struct TypeDescription { | |
const char* m_Name; | |
const char* m_TypeName; | |
const char* m_Extands; | |
const char* m_Implements; | |
int m_ArrayBound; | |
std::list<EnumItemDescription> m_EnumItems; | |
std::list<FieldDescription> m_Fields; | |
std::list<MethodDescription> m_Methods; | |
}; | |
struct ModuleDescription { | |
const char* m_Name; | |
const char* m_Description; | |
const char* m_Activator; | |
const char* m_Version; | |
const char* m_ImportPackage; | |
const char* m_ExportPackage; | |
std::list<TypeDescription> m_Types; | |
int ParserModule(xml_node &node); | |
}; | |
#include "GrammarTree.h" | |
int ParserValueType(xml_node &node, TypeDescription &type_desc); | |
int ParserEnum(xml_node &node, TypeDescription &type_desc); | |
int ParserInterface(xml_node &node, TypeDescription &type_desc); | |
int ParserClass(xml_node &node, TypeDescription &type_desc); | |
int ParserObject(xml_node &node, TypeDescription &type_desc); | |
int ModuleDescription::ParserModule(xml_node &node) | |
{ | |
m_Name = node.name(); | |
m_Description = node.attribute("description").value(); | |
m_Activator = node.attribute("activator").value(); | |
m_Version = node.attribute("version").value(); | |
m_ImportPackage = node.attribute("import_package").value(); | |
m_ExportPackage = node.attribute("export_package").value(); | |
for( xml_node type = node.first_child(); type; type=type.next_sibling() ) | |
{ | |
int error = 0; | |
TypeDescription type_desc; | |
type_desc.m_Name = type.name(); | |
const char* type_name = type.attribute("type").value(); | |
type_desc.m_TypeName = type_name; | |
/** | |
* enum | |
*/ | |
if( 0==strcmp(type_name, "enum") ) { | |
error = ParserEnum(type, type_desc); | |
} else | |
/** | |
* interface | |
*/ | |
if( 0==strcmp(type_name, "interface") ) { | |
error = ParserInterface(type, type_desc); | |
} else | |
/** | |
* class | |
*/ | |
if( 0==strcmp(type_name, "class") ) { | |
error = ParserClass(type, type_desc); | |
} else | |
/** | |
* object class | |
*/ | |
if( 0==strcmp(type_name, "object") ) { | |
error = ParserObject(type, type_desc); | |
} else | |
/** | |
* value type | |
*/ | |
{ | |
error = ParserValueType(type, type_desc); | |
} | |
if( 0!=error ) | |
return error; | |
m_Types.push_back(type_desc); | |
} | |
return 0; | |
} | |
int ParserValueType(xml_node &node, TypeDescription &type_desc) | |
{ | |
// no need other operation | |
return 0; | |
} | |
int ParserEnum(xml_node &type, TypeDescription &type_desc) | |
{ | |
EnumItemDescription enum_item; | |
int current_item_value = 0; | |
for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
{ | |
enum_item.m_Name = item.name(); | |
if( item.attribute("value") ) { | |
current_item_value = atoi(item.attribute("value").value()); | |
} | |
enum_item.m_Value = current_item_value++; | |
type_desc.m_EnumItems.push_back(enum_item); | |
} | |
return 0; | |
} | |
int ParserInterface(xml_node &type, TypeDescription &type_desc) | |
{ | |
ParameterDescription param; | |
MethodDescription method; | |
type_desc.m_Extands = type.attribute("extands") ? type.attribute("extands").value() : ""; | |
type_desc.m_Implements = ""; | |
for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
{ | |
if( 0==strcmp(item.attribute("type").value(), "function") ) { // method | |
method.m_Name = item.name(); | |
method.m_Access = "public"; | |
method.m_IsConstructor = false; | |
method.m_ReturnTypeName = !method.m_IsConstructor ? item.attribute("return").value() : ""; | |
method.m_IsStatic = false; | |
method.m_Virtual = true; | |
method.m_MustImplement = true; | |
method.m_Parmeters.clear(); | |
for(xml_node param_node=item.first_child(); param_node; param_node=param_node.next_sibling() ) { | |
param.m_Name = param_node.name(); | |
param.m_TypeName = param_node.attribute("type").value(); | |
param.m_Optional = false; | |
param.m_DefaultValue = ""; | |
method.m_Parmeters.push_back(param); | |
} | |
type_desc.m_Methods.push_back(method); | |
} | |
} | |
return 0; | |
} | |
int ParserClass(xml_node &type, TypeDescription &type_desc) | |
{ | |
ParameterDescription param; | |
MethodDescription method; | |
FieldDescription field; | |
type_desc.m_Extands = type.attribute("extands") ? type.attribute("extands").value() : ""; | |
type_desc.m_Implements = type.attribute("implements") ? type.attribute("implements").value() : ""; | |
for(xml_node item=type.first_child(); item; item=item.next_sibling() ) | |
{ | |
if( 0==strcmp(item.attribute("type").value(), "function") ) { // method | |
method.m_Name = item.name(); | |
method.m_Access = item.attribute("access") ? item.attribute("access").value() : "public"; | |
method.m_IsConstructor = (0==strcmp(type_desc.m_Name, method.m_Name)); | |
method.m_ReturnTypeName = !method.m_IsConstructor ? item.attribute("return").value() : ""; | |
method.m_IsStatic = item.attribute("static") ? true : false; | |
method.m_Virtual = item.attribute("virtual") ? true : false; | |
method.m_MustImplement = item.attribute("pure") ? true :false; | |
method.m_Parmeters.clear(); | |
for(xml_node param_node=item.first_child(); param_node; param_node=param_node.next_sibling() ) { | |
param.m_Name = param_node.name(); | |
param.m_TypeName = param_node.attribute("type").value(); | |
param.m_Optional = param_node.attribute("optional") ? true : false; | |
param.m_DefaultValue = param.m_Optional ? param_node.attribute("default").value() : ""; | |
method.m_Parmeters.push_back(param); | |
} | |
type_desc.m_Methods.push_back(method); | |
} else { // field | |
field.m_Name = item.name(); | |
field.m_TypeName = item.attribute("type").value(); | |
field.m_Access = item.attribute("access") ? item.attribute("access").value() : "public"; | |
field.m_IsStatic = item.attribute("static") ? true : false; | |
field.m_CanRead = item.attribute("noread") ? false : true; | |
field.m_CanWrite = item.attribute("nowrite") ? false : true; | |
field.m_DefaultValue = item.attribute("default").value(); | |
type_desc.m_Fields.push_back(field); | |
} | |
} | |
return 0; | |
} | |
int ParserObject(xml_node &node, TypeDescription &type_desc) | |
{ | |
ParserClass(node, type_desc); | |
return 0; | |
} | |
#pragma warning(disable:4996) | |
#include "CppHeaderCodeGenerator.h" | |
#include "CppSourceCodeGenerator.h" | |
int main( int argc, char* argv[] ) | |
{ | |
/** | |
* parser typedef file | |
*/ | |
xml_document doc; | |
xml_parse_result result = doc.load_file(argv[1]); | |
if( result ) { | |
cout << "Type file[" << argv[1] << "] parsed with no errors." << endl; | |
}else { | |
cout << "Type file[" << argv[1] << "] parsed with error, attr value: [" << doc.child("node").attribute("attr").value() << "]\n"; | |
cout << "Error description: " << result.description() << "\n"; | |
return -1; | |
} | |
xml_node module_node = doc.root().first_child(); | |
/** | |
* parser grammar tree | |
*/ | |
ModuleDescription module; | |
module.ParserModule(module_node); | |
/** | |
* generate header files and stub source file | |
*/ | |
int ret = 0; | |
while( true ) | |
{ | |
cout << "Generate c++ header file." << endl; | |
CppHeaderGenerator headerGen(&module); | |
if( 0==headerGen.Initial(argv[1]) ) { | |
if( 0!=headerGen.Generate() ) | |
ret = -2; | |
if( 0!=headerGen.Finalize() ) | |
ret = -2; | |
} else { | |
ret = -2; | |
} | |
if( 0!=ret ) { | |
cout << "Failed to generate c++ header file." << endl; | |
break; | |
} | |
cout << "Generate c++ source file." << endl; | |
CppSourceGenerator sourceGen(&module); | |
if( 0==sourceGen.Initial(argv[1]) ) { | |
if( 0!=sourceGen.Generate() ) | |
ret = -3; | |
if( 0!=sourceGen.Finalize() ) | |
ret = -3; | |
} else { | |
ret = -3; | |
} | |
if( 0!=ret ) { | |
cout << "Failed to generate c++ source file." << endl; | |
break; | |
} | |
cout << "Generate complete with no error." << endl; | |
break; | |
} | |
#if 0 | |
::system("pause"); | |
#endif | |
return ret; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment