Skip to content

Instantly share code, notes, and snippets.

@freecnjet
Created April 3, 2012 04:14
Show Gist options
  • Save freecnjet/2289265 to your computer and use it in GitHub Desktop.
Save freecnjet/2289265 to your computer and use it in GitHub Desktop.
CodeGenerator
#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