diff --git a/project/auxillary/vis_ast/update_deps.ps1 b/project/auxillary/vis_ast/update_deps.ps1 index b8eef86..4b72e9f 100644 --- a/project/auxillary/vis_ast/update_deps.ps1 +++ b/project/auxillary/vis_ast/update_deps.ps1 @@ -249,6 +249,8 @@ function setup-raylib { foreach ($header in $raylib_headers) { Copy-Item -Path $header -Destination (join-path $path_raylib_inc (split-path $header -Leaf)) } - remove-item -path $path_temp -Recurse + + # Don't want to remove as it hampers debugging. + # remove-item -path $path_temp -Recurse } setup-raylib diff --git a/project/bootstrap.cpp b/project/bootstrap.cpp index ad7f698..1571db3 100644 --- a/project/bootstrap.cpp +++ b/project/bootstrap.cpp @@ -181,17 +181,18 @@ int gen_main() // gen.cpp { - Code src_start = scan_file( "components/src_start.cpp" ); - Code static_data = scan_file( "components/static_data.cpp" ); - Code ast_case_macros = scan_file( "components/ast_case_macros.cpp" ); - Code ast = scan_file( "components/ast.cpp" ); - Code interface = scan_file( "components/interface.cpp" ); - Code upfront = scan_file( "components/interface.upfront.cpp" ); - Code parsing = scan_file( "components/interface.parsing.cpp" ); - Code untyped = scan_file( "components/interface.untyped.cpp" ); + Code src_start = scan_file( "components/src_start.cpp" ); + Code static_data = scan_file( "components/static_data.cpp" ); + Code ast_case_macros = scan_file( "components/ast_case_macros.cpp" ); + Code ast = scan_file( "components/ast.cpp" ); + Code code_serialization = scan_file( "components/code_serialization.cpp" ); + Code interface = scan_file( "components/interface.cpp" ); + Code upfront = scan_file( "components/interface.upfront.cpp" ); + Code parsing = scan_file( "components/interface.parsing.cpp" ); + Code untyped = scan_file( "components/interface.untyped.cpp" ); CodeBody etoktype = gen_etoktype( "enums/ETokType.csv", "enums/AttributeTokens.csv" ); - CodeNS nspaced_etoktype = def_namespace( name(Parser), def_namespace_body( args(etoktype)) ); + CodeNS nspaced_etoktype = def_namespace( name(parser), def_namespace_body( args(etoktype)) ); Builder src = Builder::open( "gen/gen.cpp" ); @@ -205,6 +206,7 @@ int gen_main() src.print_fmt( "\n#pragma region AST\n\n" ); src.print( ast_case_macros ); src.print( ast ); + src.print( code ); src.print_fmt( "\n#pragma endregion AST\n" ); src.print_fmt( "\n#pragma region Interface\n" ); diff --git a/project/components/ast.cpp b/project/components/ast.cpp index 764ffba..63fd070 100644 --- a/project/components/ast.cpp +++ b/project/components/ast.cpp @@ -371,13 +371,17 @@ AST* AST::duplicate() } String AST::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void AST::to_string( String& result ) { local_persist thread_local char SerializationLevel = 0; - - // TODO : Need to refactor so that intermeidate strings are freed conviently. - String result = String::make( GlobalAllocator, "" ); - + switch ( Type ) { using namespace ECode; @@ -406,994 +410,171 @@ String AST::to_string() case Access_Public: result.append( Name ); break; - + case Class: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - result.append( "class " ); - - if ( Attributes ) - { - result.append_fmt( "%S ", Attributes->to_string() ); - } - - if ( ParentType ) - { - char const* access_level = to_str( ParentAccess ); - - result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - - CodeType interface = ParentType->Next->cast< CodeType >(); - if ( interface ) - result.append( "\n" ); - - while ( interface ) - { - result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; - } - } - else if ( Name ) - { - result.append( Name ); - } - - if ( InlineCmt ) - { - result.append_fmt( " // %S", InlineCmt->Content ); - } - - result.append_fmt( "\n{\n%S\n}", Body->to_string() ); - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - result.append(";\n"); - } + cast().to_string_def( result ); break; case Class_Fwd: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes ) - result.append_fmt( "class %S %S", Attributes->to_string(), Name ); - - else result.append_fmt( "class %S", Name ); - - // Check if it can have an end-statement - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - { - if ( InlineCmt ) - result.append_fmt( "; // %S\n", InlineCmt->Content ); - else - result.append(";\n"); - } - } + cast().to_string_fwd( result ); break; case Constructor: - { - result.append( Parent->Name ); - - if ( Params ) - result.append_fmt( "( %S )", Params->to_string() ); - else - result.append( "(void)" ); - - if ( InitializerList ) - result.append_fmt( " : %S", InitializerList->to_string() ); - - if ( InlineCmt ) - result.append_fmt( " // %S", InlineCmt->Content ); - - result.append_fmt( "\n{\n%S\n}\n", Body->to_string() ); - } + cast().to_string_def( result ); break; case Constructor_Fwd: - { - result.append( Parent->Name ); - - if ( Params ) - result.append_fmt( "( %S )", Params->to_string() ); - else - { - if ( InlineCmt ) - result.append_fmt( "(void); // %S\n", InlineCmt->Content ); - else - result.append( "(void);\n" ); - } - } + cast().to_string_fwd( result ); break; case Destructor: - { - if ( Specs ) - { - CodeSpecifiers specs = Specs->cast(); - - if ( specs.has( ESpecifier::Virtual ) ) - result.append_fmt( "virtual ~%S()", Parent->Name ); - else - result.append_fmt( "~%S()", Parent->Name ); - } - else - result.append_fmt( "~%S()", Parent->Name ); - - result.append_fmt( "\n{\n%S\n}\n", Body->to_string() ); - } + cast().to_string_def( result ); break; case Destructor_Fwd: - { - if ( Specs ) - { - CodeSpecifiers specs = Specs->cast(); - - if ( specs.has( ESpecifier::Virtual ) ) - result.append_fmt( "virtual ~%S();\n", Parent->Name ); - else - result.append_fmt( "~%S()", Parent->Name ); - - if ( specs.has( ESpecifier::Pure ) ) - result.append( " = 0;" ); - } - else - result.append_fmt( "~%S();", Parent->Name ); - - if ( InlineCmt ) - result.append_fmt( " %S", InlineCmt->Content ); - else - result.append("\n"); - } + cast().to_string_fwd( result ); break; case Enum: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes || UnderlyingType ) - { - result.append( "enum " ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - if ( UnderlyingType ) - result.append_fmt( "%S : %S\n{\n%S\n}" - , Name - , UnderlyingType->to_string() - , Body->to_string() - ); - - else result.append_fmt( "%S\n{\n%S\n}", Name, Body->to_string() ); - } - else result.append_fmt( "enum %S\n{\n%S\n}", Name, Body->to_string() ); - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - result.append(";\n"); - } + cast().to_string_def( result ); break; case Enum_Fwd: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - result.append_fmt( "enum %S : %S", Name, UnderlyingType->to_string() ); - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - { - if ( InlineCmt ) - result.append_fmt("; %S", InlineCmt->Content ); - else - result.append(";\n"); - } - } + cast().to_string_fwd( result ); break; case Enum_Class: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes || UnderlyingType ) - { - result.append( "enum class " ); - - if ( Attributes ) - { - result.append_fmt( "%S ", Attributes->to_string() ); - } - - if ( UnderlyingType ) - { - result.append_fmt( "%S : %S\n{\n%S\n}", Name, UnderlyingType->to_string(), Body->to_string() ); - } - else - { - result.append_fmt( "%S\n{\n%S\n}", Name, Body->to_string() ); - } - } - else - { - result.append_fmt( "enum class %S\n{\n%S\n}", Body->to_string() ); - } - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - result.append(";\n"); - } + cast().to_string_class_def( result ); break; case Enum_Class_Fwd: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - result.append( "enum class " ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - result.append_fmt( "%S : %S", Name, UnderlyingType->to_string() ); - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - { - if ( InlineCmt ) - result.append_fmt("; %S", InlineCmt->Content ); - else - result.append(";\n"); - } - } + cast().to_string_class_fwd( result ); break; case Export_Body: - { - result.append_fmt( "export\n{\n" ); - - Code curr = { this }; - s32 left = NumEntries; - while ( left-- ) - { - result.append_fmt( "%S", curr.to_string() ); - ++curr; - } - - result.append_fmt( "};\n" ); - } + cast().to_string_export( result ); break; case Extern_Linkage: - result.append_fmt( "extern \"%S\"\n{\n%S\n}\n", Name, Body->to_string() ); + cast().to_string( result ); break; case Friend: - result.append_fmt( "friend %S", Declaration->to_string() ); - - if ( result[ result.length() -1 ] != ';' ) - { - result.append( ";" ); - } - - if ( InlineCmt ) - result.append_fmt(" %S", InlineCmt->Content ); - else - result.append("\n"); + cast().to_string( result ); break; case Function: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export" ); - - if ( Attributes ) - result.append_fmt( " %S ", Attributes->to_string() ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ! ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - if ( Attributes || Specs ) - result.append( "\n" ); - - if ( ReturnType ) - result.append_fmt( "%S %S(", ReturnType->to_string(), Name ); - - else - result.append_fmt( "%S(", Name ); - - if ( Params ) - result.append_fmt( "%S)", Params->to_string() ); - - else - result.append( ")" ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - result.append_fmt( "\n{\n%S\n}\n", Body->to_string() ); - } + cast().to_string_def( result ); break; case Function_Fwd: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ! ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - if ( Attributes || Specs ) - { - result.append("\n" ); - } - - if ( ReturnType ) - result.append_fmt( "%S %S(", ReturnType->to_string(), Name ); - - else - result.append_fmt( "%S(", Name ); - - if ( Params ) - result.append_fmt( "%S)", Params->to_string() ); - - else - result.append( ")" ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - if ( InlineCmt ) - result.append_fmt( "; %S", InlineCmt->Content ); - else - result.append( ";\n" ); - } + cast().to_string_fwd( result ); break; case Module: - if (((u32(ModuleFlag::Export) & u32(ModuleFlags)) == u32(ModuleFlag::Export))) - result.append("export "); - - if (((u32(ModuleFlag::Import) & u32(ModuleFlags)) == u32(ModuleFlag::Import))) - result.append("import "); - - result.append_fmt( "%S;\n", Name ); - break; + cast().to_string( result ); + break; case Namespace: - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - result.append_fmt( "namespace %S\n{\n%S\n}\n", Name , Body->to_string() ); + cast().to_string( result ); break; case Operator: case Operator_Member: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ! ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - if ( Attributes || Specs ) - { - result.append("\n" ); - } - - if ( ReturnType ) - result.append_fmt( "%S %S (", ReturnType->to_string(), Name ); - - if ( Params ) - result.append_fmt( "%S)", Params->to_string() ); - - else - result.append( ")" ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - result.append_fmt( "\n{\n%S\n}\n" - , Body->to_string() - ); - } + cast().to_string_def( result ); break; case Operator_Fwd: case Operator_Member_Fwd: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes ) - result.append_fmt( "%S\n", Attributes->to_string() ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ! ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - if ( Attributes || Specs ) - { - result.append("\n" ); - } - - result.append_fmt( "%S %S (", ReturnType->to_string(), Name ); - - if ( Params ) - result.append_fmt( "%S)", Params->to_string() ); - - else - result.append_fmt( ")" ); - - if ( Specs ) - { - for ( SpecifierT spec : Specs->cast() ) - { - if ( ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - } - - if ( InlineCmt ) - result.append_fmt( "; %S", InlineCmt->Content ); - else - result.append( ";\n" ); - } + cast().to_string_fwd( result ); break; case Operator_Cast: - { - if ( Specs ) - { - // TODO : Add support for specifies before the operator keyword - - if ( Name && Name.length() ) - result.append_fmt( "%Soperator %S()", Name, ValueType->to_string() ); - else - result.append_fmt( "operator %S()", ValueType->to_string() ); - - for ( SpecifierT spec : Specs->cast() ) - { - if ( ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); - } - } - - result.append_fmt( "\n{\n%S\n}\n", Body->to_string() ); - break; - } - - if ( Name && Name.length() ) - result.append_fmt("%Soperator %S()\n{\n%S\n}\n", Name, ValueType->to_string(), Body->to_string() ); - else - result.append_fmt("operator %S()\n{\n%S\n}\n", ValueType->to_string(), Body->to_string() ); - } + cast().to_string_def( result ); break; case Operator_Cast_Fwd: - if ( Specs ) - { - // TODO : Add support for specifies before the operator keyword - - result.append_fmt( "operator %S()", ValueType->to_string() ); - - for ( SpecifierT spec : Specs->cast() ) - { - if ( ESpecifier::is_trailing( spec ) ) - { - StrC spec_str = ESpecifier::to_str( spec ); - result.append_fmt( " %*s", spec_str.Len, spec_str.Ptr ); - } - } - - if ( InlineCmt ) - result.append_fmt( "; %S", InlineCmt->Content ); - else - result.append( ";\n" ); - break; - } - - if ( InlineCmt ) - result.append_fmt("operator %S(); %S", ValueType->to_string() ); - else - result.append_fmt("operator %S();\n", ValueType->to_string() ); + cast().to_string_fwd( result ); break; case Parameters: - { - if ( ValueType == nullptr ) - { - result.append_fmt( "%S", Name ); - break; - } - - if ( Name ) - result.append_fmt( "%S %S", ValueType->to_string(), Name ); - - else - result.append_fmt( "%S", ValueType->to_string() ); - - if ( Value ) - result.append_fmt( "= %S", Value->to_string() ); - - if ( NumEntries - 1 > 0) - { - for ( CodeParam param : CodeParam { (AST_Param*) Next } ) - { - result.append_fmt( ", %S", param.to_string() ); - } - } - } + cast().to_string( result ); break; + case Preprocess_Define: - result.append_fmt( "#define %S %S\n", Name, Content ); + cast().to_string( result ); break; case Preprocess_If: - result.append_fmt( "#if %S\n", Content ); + cast().to_string_if( result ); break; case Preprocess_IfDef: - result.append_fmt( "#ifdef %S\n", Content ); + cast().to_string_ifdef( result ); break; case Preprocess_IfNotDef: - result.append_fmt( "#ifndef %S\n", Content ); + cast().to_string_ifndef( result ); break; case Preprocess_Include: - result.append_fmt( "#include %S\n", Content ); + cast().to_string( result ); break; case Preprocess_ElIf: - result.append_fmt( "#elif %S\n", Content ); + cast().to_string_elif( result ); break; case Preprocess_Else: - result.append_fmt( "#else\n" ); + cast().to_string_else( result ); break; case Preprocess_EndIf: - result.append_fmt( "#endif\n" ); + cast().to_string_endif( result ); break; case Preprocess_Pragma: - result.append_fmt( "#pragma %S\n", Content ); + cast().to_string( result ); break; case Specifiers: - { - s32 idx = 0; - s32 left = NumEntries; - while ( left-- ) - { - StrC spec = ESpecifier::to_str( ArrSpecs[idx] ); - result.append_fmt( "%.*s ", spec.Len, spec.Ptr ); - idx++; - } - } + cast().to_string( result ); break; case Struct: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - result.append( "struct " ); - - if ( Attributes ) - { - result.append_fmt( "%S ", Attributes->to_string() ); - } - - if ( ParentType ) - { - char const* access_level = to_str( ParentAccess ); - - result.append_fmt( "%S : %s %S", Name, access_level, ParentType ); - - CodeType interface = ParentType->Next->cast< CodeType >(); - if ( interface ) - result.append( "\n" ); - - while ( interface ) - { - result.append_fmt( ", %S", interface.to_string() ); - interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; - } - } - else if ( Name ) - { - result.append( Name ); - } - - if ( InlineCmt ) - { - result.append_fmt( " // %S", InlineCmt->Content ); - } - - result.append_fmt( "\n{\n%S\n}", Body->to_string() ); - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - result.append(";\n"); - } + cast().to_string_def( result ); break; case Struct_Fwd: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes ) - result.append_fmt( "struct %S %S", Attributes->to_string(), Name ); - - else result.append_fmt( "struct %S", Name ); - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - { - if ( InlineCmt ) - result.append_fmt("; %S", InlineCmt->Content ); - else - result.append(";\n"); - } - } + cast().to_string_fwd( result ); break; case Template: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Params ) - result.append_fmt( "template< %S >\n%S", Params->to_string(), Declaration->to_string() ); - else - result.append_fmt( "template<>\n%S", Declaration->to_string() ); - } + cast().to_string( result ); break; case Typedef: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - result.append( "typedef "); - - // Determines if the typedef is a function typename - if ( UnderlyingType->ReturnType ) - result.append( UnderlyingType->to_string() ); - else - result.append_fmt( "%S %S", UnderlyingType->to_string(), Name ); - - if ( UnderlyingType->Type == Typename && UnderlyingType->ArrExpr ) - { - result.append_fmt( "[ %S ];", UnderlyingType->ArrExpr->to_string() ); - - AST* next_arr_expr = UnderlyingType->ArrExpr->Next; - while ( next_arr_expr ) - { - result.append_fmt( "[ %S ];", next_arr_expr->to_string() ); - next_arr_expr = next_arr_expr->Next; - } - } - else - { - result.append( ";" ); - } - - if ( InlineCmt ) - result.append_fmt(" %S", InlineCmt->Content); - else - result.append("\n"); - } + cast().to_string( result ); break; case Typename: - { - #if GEN_USE_NEW_TYPENAME_PARSING - if ( ReturnType && Params ) - { - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - else - { - if ( Specs ) - result.append_fmt( "%S ( %S ) ( %S ) %S", ReturnType->to_string(), Name, Params->to_string(), Specs->to_string() ); - else - result.append_fmt( "%S ( %S ) ( %S )", ReturnType->to_string(), Name, Params->to_string() ); - } - - break; - } - #else - if ( ReturnType && Params ) - { - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - else - { - if ( Specs ) - result.append_fmt( "%S %S ( %S ) %S", ReturnType->to_string(), Name, Params->to_string(), Specs->to_string() ); - else - result.append_fmt( "%S %S ( %S )", ReturnType->to_string(), Name, Params->to_string() ); - } - - break; - } - #endif - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - if ( Specs ) - result.append_fmt( "%S %S", Name, Specs->to_string() ); - else - result.append_fmt( "%S", Name ); - - if ( IsParamPack ) - result.append("..."); - } + cast().to_string( result ); break; case Union: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - result.append( "union " ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - if ( Name ) - { - result.append_fmt( "%S\n{\n%S\n}" - , Name - , Body->to_string() - ); - } - else - { - // Anonymous union - result.append_fmt( "\n{\n%S\n}" - , Body->to_string() - ); - } - - if ( Parent == nullptr || ( Parent->Type != ECode::Typedef && Parent->Type != ECode::Variable ) ) - result.append(";\n"); - } + cast().to_string( result ); break; case Using: - { - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes ) - result.append_fmt( "%S ", Attributes->to_string() ); - - if ( UnderlyingType ) - { - result.append_fmt( "using %S = %S", Name, UnderlyingType->to_string() ); - - if ( UnderlyingType->ArrExpr ) - { - result.append_fmt( "[ %S ]", UnderlyingType->ArrExpr->to_string() ); - - AST* next_arr_expr = UnderlyingType->ArrExpr->Next; - while ( next_arr_expr ) - { - result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); - next_arr_expr = next_arr_expr->Next; - } - } - - result.append( ";" ); - } - else - result.append_fmt( "using %S;", Name ); - - if ( InlineCmt ) - result.append_fmt(" %S\n", InlineCmt->Content ); - else - result.append("\n"); - } + cast().to_string( result ); break; case Using_Namespace: - if ( InlineCmt ) - result.append_fmt( "using namespace $S; %S", Name, InlineCmt->Content ); - else - result.append_fmt( "using namespace %s;\n", Name ); + cast().to_string_ns( result ); break; case Variable: - { - if ( Parent && Parent->Type == Variable ) - { - // Its a comma-separated variable ( a NextVar ) - - if ( Specs ) - result.append_fmt( "%S ", Specs->to_string() ); - - result.append( Name ); - - if ( ArrExpr ) - { - result.append_fmt( "[ %S ]", ArrExpr->to_string() ); - - AST* next_arr_expr = ArrExpr->Next; - while ( next_arr_expr ) - { - result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); - next_arr_expr = next_arr_expr->Next; - } - } - - if ( Value ) - result.append_fmt( " = %S", Value->to_string() ); - - // Keep the chain going... - if ( NextVar ) - result.append_fmt( ", %S", NextVar->to_string() ); - - break; - } - - if ( bitfield_is_equal( u32, ModuleFlags, ModuleFlag::Export )) - result.append( "export " ); - - if ( Attributes || Specs ) - { - if ( Attributes ) - result.append_fmt( "%S ", Specs->to_string() ); - - if ( Specs ) - result.append_fmt( "%S\n", Specs->to_string() ); - - result.append_fmt( "%S %S", ValueType->to_string(), Name ); - - if ( ValueType->ArrExpr ) - { - result.append_fmt( "[ %S ]", ValueType->ArrExpr->to_string() ); - - AST* next_arr_expr = ValueType->ArrExpr->Next; - while ( next_arr_expr ) - { - result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); - next_arr_expr = next_arr_expr->Next; - } - } - - if ( BitfieldSize ) - result.append_fmt( " : %S", BitfieldSize->to_string() ); - - if ( Value ) - result.append_fmt( " = %S", Value->to_string() ); - - if ( NextVar ) - result.append_fmt( ", %S", NextVar->to_string() ); - - if ( InlineCmt ) - result.append_fmt("; %S", InlineCmt->Content); - else - result.append( ";\n" ); - - break; - } - - if ( BitfieldSize ) - result.append_fmt( "%S %S : %S", ValueType->to_string(), Name, BitfieldSize->to_string() ); - - else if ( ValueType->ArrExpr ) - { - result.append_fmt( "%S %S[ %S ]", ValueType->to_string(), Name, ValueType->ArrExpr->to_string() ); - - AST* next_arr_expr = ValueType->ArrExpr->Next; - while ( next_arr_expr ) - { - result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); - next_arr_expr = next_arr_expr->Next; - } - } - - else - result.append_fmt( "%S %S", ValueType->to_string(), Name ); - - if ( Value ) - result.append_fmt( " = %S", Value->to_string() ); - - if ( NextVar ) - result.append_fmt( ", %S", NextVar->to_string() ); - - result.append( ";" ); - - if ( InlineCmt ) - result.append_fmt(" %S", InlineCmt->Content); - else - result.append("\n"); - } + cast().to_string( result ); break; case Enum_Body: @@ -1404,19 +585,9 @@ String AST::to_string() case Namespace_Body: case Struct_Body: case Union_Body: - { - Code curr = Front->cast(); - s32 left = NumEntries; - while ( left -- ) - { - result.append_fmt( "%S", curr.to_string() ); - ++curr; - } - } + cast().to_string( result ); break; } - - return result; } bool AST::is_equal( AST* other ) diff --git a/project/components/ast.hpp b/project/components/ast.hpp index ea06500..1c64b31 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -103,7 +103,7 @@ struct Code Using_Code( Code ); template< class Type > - Type cast() + forceinline Type cast() { return * rcast( Type*, this ); } @@ -113,10 +113,13 @@ struct Code return ast; } Code& operator ++(); - auto& operator*() - { - return *this; - } + + + // TODO(Ed) : Remove this overload. +// auto& operator*() +// { +// return *this; +// } AST* ast; @@ -182,7 +185,7 @@ struct AST neverinline String to_string(); template< class Type > - Type cast() + forceinline Type cast() { return * this; } @@ -263,7 +266,7 @@ struct AST StringCached Content; // Attributes, Comment, Execution, Include struct { SpecifierT ArrSpecs[ArrSpecs_Cap]; // Specifiers - AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. + AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. }; }; union { @@ -350,7 +353,7 @@ struct AST_POD struct test { SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers - AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. + AST* NextSpecs; // Specifiers; If ArrSpecs is full, then NextSpecs is used. }; constexpr int pls = sizeof(test); @@ -385,6 +388,8 @@ struct CodeBody { return rcast( AST*, ast )->has_entries(); } + void to_string( String& result ); + void to_string_export( String& result ); AST* raw() { return rcast( AST*, ast ); @@ -419,6 +424,9 @@ struct CodeClass Using_Code( CodeClass ); void add_interface( CodeType interface ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); AST* raw() { @@ -448,6 +456,7 @@ struct CodeParam CodeParam get( s32 idx ); bool has_entries(); + void to_string( String& result ); AST* raw() { return rcast( AST*, ast ); @@ -520,6 +529,7 @@ struct CodeSpecifiers return -1; } + void to_string( String& result ); AST* raw() { return rcast( AST*, ast ); @@ -559,6 +569,9 @@ struct CodeStruct Using_Code( CodeStruct ); void add_interface( CodeType interface ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); AST* raw() { @@ -592,27 +605,260 @@ struct CodeStruct Define_CodeType( Attributes ); Define_CodeType( Comment ); -Define_CodeType( Constructor ); -Define_CodeType( Define ); -Define_CodeType( Destructor ); -Define_CodeType( Enum ); + +struct CodeConstructor +{ + Using_Code( CodeConstructor ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); + + AST* raw(); + operator Code(); + AST_Constructor* operator->(); + AST_Constructor* ast; +}; + +struct CodeDefine +{ + Using_Code( CodeDefine ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Define* operator->(); + AST_Define* ast; +}; + +struct CodeDestructor +{ + Using_Code( CodeDestructor ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); + + AST* raw(); + operator Code(); + AST_Destructor* operator->(); + AST_Destructor* ast; +}; + +struct CodeEnum +{ + Using_Code( CodeEnum ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); + + AST* raw(); + operator Code(); + AST_Enum* operator->(); + AST_Enum* ast; +}; + Define_CodeType( Exec ); -Define_CodeType( Extern ); -Define_CodeType( Include ); -Define_CodeType( Friend ); -Define_CodeType( Fn ); -Define_CodeType( Module ); -Define_CodeType( NS ); -Define_CodeType( Operator ); -Define_CodeType( OpCast ); -Define_CodeType( Pragma ); -Define_CodeType( PreprocessCond ); -Define_CodeType( Template ); -Define_CodeType( Type ); -Define_CodeType( Typedef ); -Define_CodeType( Union ); -Define_CodeType( Using ); -Define_CodeType( Var ); + +struct CodeExtern +{ + Using_Code( CodeExtern ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Extern* operator->(); + AST_Extern* ast; +}; + +struct CodeInclude +{ + Using_Code( CodeInclude ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Include* operator->(); + AST_Include* ast; +}; + +struct CodeFriend +{ + Using_Code( CodeFriend ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Friend* operator->(); + AST_Friend* ast; +}; + +struct CodeFn +{ + Using_Code( CodeFriend ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); + + AST* raw(); + operator Code(); + AST_Fn* operator->(); + AST_Fn* ast; +}; + +struct CodeModule +{ + Using_Code( CodeModule ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Module* operator->(); + AST_Module* ast; +}; + +struct CodeNS +{ + Using_Code( CodeNS ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_NS* operator->(); + AST_NS* ast; +}; + +struct CodeOperator +{ + Using_Code( CodeOperator ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); + + AST* raw(); + operator Code(); + AST_Operator* operator->(); + AST_Operator* ast; +}; + +struct CodeOpCast +{ + Using_Code( CodeOpCast ); + + void to_string_def( String& result ); + void to_string_fwd( String& result ); + + AST* raw(); + operator Code(); + AST_OpCast* operator->(); + AST_OpCast* ast; +}; + +struct CodePragma +{ + Using_Code( CodePragma ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Pragma* operator->(); + AST_Pragma* ast; +}; + +struct CodePreprocessCond +{ + Using_Code( CodePreprocessCond ); + + void to_string_if( String& result ); + void to_string_ifdef( String& result ); + void to_string_ifndef( String& result ); + void to_string_elif( String& result ); + void to_string_else( String& result ); + void to_string_endif( String& result ); + + AST* raw(); + operator Code(); + AST_PreprocessCond* operator->(); + AST_PreprocessCond* ast; +}; + +struct CodeTemplate +{ + Using_Code( CodeTemplate ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Template* operator->(); + AST_Template* ast; +}; + +struct CodeType +{ + Using_Code( CodeType ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Type* operator->(); + AST_Type* ast; +}; + +struct CodeTypedef +{ + Using_Code( CodeTypedef ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Typedef* operator->(); + AST_Typedef* ast; +}; + +struct CodeUnion +{ + Using_Code( CodeUnion ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Union* operator->(); + AST_Union* ast; +}; + +struct CodeUsing +{ + Using_Code( CodeUsing ); + + void to_string( String& result ); + void to_string_ns( String& result ); + + AST* raw(); + operator Code(); + AST_Using* operator->(); + AST_Using* ast; +}; + +struct CodeVar +{ + Using_Code( CodeVar ); + + void to_string( String& result ); + + AST* raw(); + operator Code(); + AST_Var* operator->(); + AST_Var* ast; +}; #undef Define_CodeType #undef Using_Code diff --git a/project/components/code_serialization.cpp b/project/components/code_serialization.cpp new file mode 100644 index 0000000..274a53d --- /dev/null +++ b/project/components/code_serialization.cpp @@ -0,0 +1,1314 @@ +#if GEN_INTELLISENSE_DIRECTIVES +#pragma once +#include "ast.cpp" +#endif + +String Code::to_string() +{ + if ( ast == nullptr ) + { + log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); + return { nullptr }; + } + return rcast( AST*, ast )->to_string(); +} + +String CodeAttributes::to_string() +{ + return ast->Content.duplicate( GlobalAllocator ); +} + +String CodeBody::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Enum_Body: + case Class_Body: + case Extern_Linkage_Body: + case Function_Body: + case Global_Body: + case Namespace_Body: + case Struct_Body: + case Union_Body: + to_string( result ); + break; + + case Export_Body: + to_string_export( result ); + break; + } + return result; +} + +void CodeBody::to_string( String& result ) +{ + Code curr = ast->Front; + s32 left = ast->NumEntries; + while ( left -- ) + { + result.append_fmt( "%S", curr.to_string() ); + ++curr; + } +} + +void CodeBody::to_string_export( String& result ) +{ + result.append_fmt( "export\n{\n" ); + + Code curr = { this }; + s32 left = ast->NumEntries; + while ( left-- ) + { + result.append_fmt( "%S", curr.to_string() ); + ++curr; + } + + result.append_fmt( "};\n" ); +} + +String CodeComment::to_string() +{ + return ast->Content.duplicate( GlobalAllocator ); +} + +String CodeConstructor::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch (ast->Type) + { + using namespace ECode; + case Constructor: + to_string_def( result ); + break; + case Constructor_Fwd: + to_string_fwd( result ); + break; + } + return result; +} + +void CodeConstructor::to_string_def( String& result ) +{ + result.append( ast->Parent->name ); + + if ( ast->Params ) + result.append_fmt( "( %S )", ast->Params.to_string() ); + else + result.append( "(void)" ); + + if ( ast->InitializerList ) + result.append_fmt( " : %S", ast->InitializerList.to_string() ); + + if ( ast->InlineCmt ) + result.append_fmt( " // %S", ast->InlineCmt->Content ); + + result.append_fmt( "\n{\n%S\n}\n", ast->Body.to_string() ); +} + +void CodeConstructor::to_string_fwd( String& result ) +{ + result.append( ast->Parent->Name ); + + if ( ast->Params ) + result.append_fmt( "( %S )", ast->Params.to_string() ); + else + { + if ( ast->InlineCmt ) + result.append_fmt( "(void); // %S\n", ast->InlineCmt->Content ); + else + result.append( "(void);\n" ); + } +} + +String CodeClass::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Class: + to_string_def( result ); + break; + case Class_Fwd: + to_string_fwd( result ); + break; + } + return result; +} + +void CodeClass::to_string_def( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + result.append( "class " ); + + if ( ast->Attributes ) + { + result.append_fmt( "%S ", ast->Attributes.to_string() ); + } + + if ( ast->ParentType ) + { + char const* access_level = to_str( ast->ParentAccess ); + + result.append_fmt( "%S : %s %S", ast->Name, access_level, ast->ParentType ); + + CodeType interface = ast->ParentType->Next->cast< CodeType >(); + if ( interface ) + result.append( "\n" ); + + while ( interface ) + { + result.append_fmt( ", %S", interface.to_string() ); + interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; + } + } + else if ( ast->Name ) + { + result.append( ast->Name ); + } + + if ( ast->InlineCmt ) + { + result.append_fmt( " // %S", ast->InlineCmt->Content ); + } + + result.append_fmt( "\n{\n%S\n}", ast->Body.to_string() ); + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + result.append(";\n"); +} + +void CodeClass::to_string_fwd( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes ) + result.append_fmt( "class %S %S", ast->Attributes.to_string(), ast->Name ); + + else result.append_fmt( "class %S", ast->Name ); + + // Check if it can have an end-statement + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + { + if ( ast->InlineCmt ) + result.append_fmt( "; // %S\n", ast->InlineCmt->Content ); + else + result.append(";\n"); + } +} + +String CodeDefine::to_string() +{ + return String::fmt_buf( GlobalAllocator, "#define %S %S\n", ast->Name, ast->Content ); +} + +void CodeDefine::to_string( String& result ) +{ + return result.append_fmt( "#define %S %S\n", ast->Name, ast->Content ); +} + +String CodeDestructor::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Destructor: + to_string_def( result ); + break; + case Destructor_Fwd: + to_string_fwd( result ); + break; + } + return result; +} + +void CodeDestructor::to_string_def( String& result ) +{ + if ( ast->Specs ) + { + if ( ast->Specs.has( ESpecifier::Virtual ) ) + result.append_fmt( "virtual ~%S()", ast->Parent->Name ); + else + result.append_fmt( "~%S()", ast->Parent->Name ); + } + else + result.append_fmt( "~%S()", ast->Parent->Name ); + + result.append_fmt( "\n{\n%S\n}\n", ast->Body.to_string() ); +} + +void CodeDestructor::to_string_fwd( String& result ) +{ + if ( ast->Specs ) + { + if ( ast->Specs.has( ESpecifier::Virtual ) ) + result.append_fmt( "virtual ~%S();\n", ast->Parent->Name ); + else + result.append_fmt( "~%S()", ast->Parent->Name ); + + if ( ast->Specs.has( ESpecifier::Pure ) ) + result.append( " = 0;" ); + } + else + result.append_fmt( "~%S();", ast->Parent->Name ); + + if ( ast->InlineCmt ) + result.append_fmt( " %S", ast->InlineCmt->Content ); + else + result.append("\n"); +} + +String CodeEnum::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Enum: + to_string_def( result ); + break; + case Enum_Fwd: + to_string_fwd( result ); + break; + case Enum_Class: + to_string_class_def( result ); + break; + case Enum_Class_Fwd: + to_string_class_fwd( result ); + break; + } + return result; +} + +void CodeEnum::to_string_def( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes || ast->UnderlyingType ) + { + result.append( "enum " ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + if ( UnderlyingType ) + result.append_fmt( "%S : %S\n{\n%S\n}" + , ast->Name + , ast->UnderlyingType.to_string() + , ast->Body.to_string() + ); + + else result.append_fmt( "%S\n{\n%S\n}", ast->Name, ast->Body.to_string() ); + } + else result.append_fmt( "enum %S\n{\n%S\n}", ast->Name, ast->Body.to_string() ); + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + result.append(";\n"); +} + +void CodeEnum::to_string_fwd( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + result.append_fmt( "enum %S : %S", ast->Name, ast->UnderlyingType.to_string() ); + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + { + if ( ast->InlineCmt ) + result.append_fmt("; %S", ast->InlineCmt->Content ); + else + result.append(";\n"); + } +} + +void CodeEnum::to_string_class_def( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes || ast->UnderlyingType ) + { + result.append( "enum class " ); + + if ( ast->Attributes ) + { + result.append_fmt( "%S ", ast->Attributes.to_string() ); + } + + if ( ast->UnderlyingType ) + { + result.append_fmt( "%S : %S\n{\n%S\n}", ast->Name, ast->UnderlyingType.to_string(), ast->Body.to_string() ); + } + else + { + result.append_fmt( "%S\n{\n%S\n}", ast->Name, ast->Body.to_string() ); + } + } + else + { + result.append_fmt( "enum class %S\n{\n%S\n}", ast->Body.to_string() ); + } + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + result.append(";\n"); +} + +void CodeEnum::to_string_class_fwd( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + result.append( "enum class " ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + result.append_fmt( "%S : %S", ast->Name, ast->UnderlyingType.to_string() ); + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + { + if ( ast->InlineCmt ) + result.append_fmt("; %S", ast->InlineCmt->Content ); + else + result.append(";\n"); + } +} + +String CodeExec::to_string() +{ + return ast->Content.duplicate( GlobalAllocator ); +} + +String CodeExtern::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeExtern::to_string( String& result ) +{ + if ( ast->Body ) + result.append_fmt( "extern \"%S\"\n{\n%S\n}\n", ast->Name, ast->Body.to_string() ); + else + result.append_fmt( "extern \"%S\"\n{}\n", ast->Name ); +} + +String CodeInclude::to_string() +{ + return String::fmt( GlobalAllocator, "#include %S\n", ast->Content ); +} + +void CodeInclude::to_string( String& result ) +{ + result.append_fmt( "#include %S\n", ast->Content ); +} + +String CodeFriend::to_string( String& result ) +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeFriend::to_string( String& result ) +{ + result.append_fmt( "friend %S", ast->Declaration->to_string() ); + + if ( result[ result.length() -1 ] != ';' ) + { + result.append( ";" ); + } + + if ( ast->InlineCmt ) + result.append_fmt(" %S", ast->InlineCmt->Content ); + else + result.append("\n"); +} + +String CodeFn::to_string( String& result ) +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Function: + to_string_def( result ); + break; + case Function_Fwd: + to_string_fwd( result ); + break; + } + return result; +} + +void CodeFn::to_string_def( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export" ); + + if ( ast->Attributes ) + result.append_fmt( " %S ", ast->Attributes.to_string() ); + + if ( ast->Specs ) + { + for ( SpecifierT spec : ast->Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( ast->Attributes || ast->Specs ) + result.append( "\n" ); + + if ( ast->ReturnType ) + result.append_fmt( "%S %S(", ast->ReturnType.to_string(), ast->Name ); + + else + result.append_fmt( "%S(", ast->Name ); + + if ( Params ) + result.append_fmt( "%S)", ast->Params.to_string() ); + + else + result.append( ")" ); + + if ( ast->Specs ) + { + for ( SpecifierT spec : ast->Specs ) + { + if ( ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + result.append_fmt( "\n{\n%S\n}\n", ast->Body.to_string() ); +} + +void CodeFn::to_string_fwd( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + if ( Specs ) + { + for ( SpecifierT spec : Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( ast->Attributes || ast->Specs ) + { + result.append("\n" ); + } + + if ( ast->ReturnType ) + result.append_fmt( "%S %S(", ast->ReturnType.to_string(), ast->Name ); + + else + result.append_fmt( "%S(", ast->Name ); + + if ( ast->Params ) + result.append_fmt( "%S)", ast->Params.to_string() ); + + else + result.append( ")" ); + + if ( ast->Specs ) + { + for ( SpecifierT spec : Specs ) + { + if ( ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( ast->InlineCmt ) + result.append_fmt( "; %S", ast->InlineCmt->Content ); + else + result.append( ";\n" ); +} + +String CodeModule::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeModule::to_string( String& result ) +{ + if (((u32(ModuleFlag::Export) & u32(ast->ModuleFlags)) == u32(ModuleFlag::Export))) + result.append("export "); + + if (((u32(ModuleFlag::Import) & u32(ast->ModuleFlags)) == u32(ModuleFlag::Import))) + result.append("import "); + + result.append_fmt( "%S;\n", ast->Name ); +} + +String CodeNS::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeNS::to_string( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + result.append_fmt( "namespace %S\n{\n%S\n}\n", ast->Name , ast->Body.to_string() ); +} + +String CodeOperator::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Operator: + case Operator_Member: + to_string_def( result ); + break; + case Operator_Fwd: + case Operator_Member_Fwd: + to_string_fwd( result ); + break; + } + return result; +} + +void CodeOperator::to_string_def( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + if ( ast->Specs ) + { + for ( SpecifierT spec : ast->Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( ast->Attributes || ast->Specs ) + { + result.append("\n" ); + } + + if ( ast->ReturnType ) + result.append_fmt( "%S %S (", ast->ReturnType.to_string(), ast->Name ); + + if ( ast->Params ) + result.append_fmt( "%S)", ast->Params.to_string() ); + + else + result.append( ")" ); + + if ( ast->Specs ) + { + for ( SpecifierT spec : ast->Specs ) + { + if ( ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + result.append_fmt( "\n{\n%S\n}\n" + , ast->Body.to_string() + ); +} + +void CodeOperator::to_string_fwd( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes ) + result.append_fmt( "%S\n", ast->Attributes.to_string() ); + + if ( ast->Specs ) + { + for ( SpecifierT spec : Specs ) + { + if ( ! ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( ast->Attributes || ast->Specs ) + { + result.append("\n" ); + } + + result.append_fmt( "%S %S (", ast->ReturnType.to_string(), ast->Name ); + + if ( ast->Params ) + result.append_fmt( "%S)", ast->Params.to_string() ); + + else + result.append_fmt( ")" ); + + if ( ast->Specs ) + { + for ( SpecifierT spec : Specs ) + { + if ( ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + } + + if ( ast->InlineCmt ) + result.append_fmt( "; %S", ast->InlineCmt->Content ); + else + result.append( ";\n" ); +} + +String CodeOpCast::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Operator_Cast: + to_string_def( result ); + break; + case Operator_Cast_Fwd: + to_string_fwd( result ); + break; + } + return result; +} + +void CodeOpCast::to_string_def( String& result ) +{ + if ( ast->Specs ) + { + // TODO : Add support for specifies before the operator keyword + + if ( ast->Name && ast->Name.length() ) + result.append_fmt( "%Soperator %S()", ast->Name, ast->ValueType.to_string() ); + else + result.append_fmt( "operator %S()", ast->ValueType.to_string() ); + + for ( SpecifierT spec : Specs ) + { + if ( ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); + } + } + + result.append_fmt( "\n{\n%S\n}\n", ast->Body.to_string() ); + break; + } + + if ( ast->Name && ast->Name.length() ) + result.append_fmt("%Soperator %S()\n{\n%S\n}\n", ast->Name, ast->ValueType.to_string(), ast->Body.to_string() ); + else + result.append_fmt("operator %S()\n{\n%S\n}\n", ast->ValueType.to_string(), ast->Body.to_string() ); +} + +void CodeOpCast::to_string_fwd( String& result ) +{ + if ( ast->Specs ) + { + // TODO : Add support for specifies before the operator keyword + + result.append_fmt( "operator %S()", ast->ValueType.to_string() ); + + for ( SpecifierT spec : Specs ) + { + if ( ESpecifier::is_trailing( spec ) ) + { + StrC spec_str = ESpecifier::to_str( spec ); + result.append_fmt( " %*s", spec_str.Len, spec_str.Ptr ); + } + } + + if ( ast->InlineCmt ) + result.append_fmt( "; %S", ast->InlineCmt->Content ); + else + result.append( ";\n" ); + break; + } + + if ( ast->InlineCmt ) + result.append_fmt("operator %S(); %S", ast->ValueType.to_string() ); + else + result.append_fmt("operator %S();\n", ast->ValueType.to_string() ); +} + +String CodeParam::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeParam::to_string( String& result ) +{ + if ( ast->ValueType == nullptr ) + { + result.append_fmt( "%S", ast->Name ); + break; + } + + if ( ast->Name ) + result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name ); + + else + result.append_fmt( "%S", ast->ValueType.to_string() ); + + if ( ast->Value ) + result.append_fmt( "= %S", ast->Value.to_string() ); + + if ( ast->NumEntries - 1 > 0) + { + for ( CodeParam param : ast->Next ) + { + result.append_fmt( ", %S", param.to_string() ); + } + } +} + +String CodePreprocessCond::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Preprocess_If: + to_string_if( result ); + break; + case Preprocess_IfDef: + to_string_ifdef( result ); + break; + case Preprocess_IfNotDef + to_string_ifndef( result ); + break; + case Preprocess_ElIf: + to_string_elif( result ); + break; + case Preprocess_Else: + to_string_else( result ); + break; + case Preprocess_EndIf: + to_string_endif( result ); + break; + } + return result; +} + +void CodePreprocessCond::to_string_if( String& result ) +{ + result.append_fmt( "#if %S\n", ast->Content ); +} + +void CodePreprocessCond::to_string_ifdef( String& result ) +{ + result.append_fmt( "#ifdef %S\n", ast->Content ); +} + +void CodePreprocessCond::to_string_ifndef( String& result ) +{ + result.append_fmt( "#ifndef %S\n", ast->Content ); +} + +void CodePreprocessCond::to_string_elif( String& result ) +{ + result.append_fmt( "#elif %S\n", ast->Content ); +} + +void CodePreprocessCond::to_string_else( String& result ) +{ + result.append_fmt( "#else\n" ); +} + +void CodePreprocessCond::to_string_endif( String& result ) +{ + result.append_fmt( "#endif\n" ); +} + +String CodePragma::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodePragma::to_string( String& result ) +{ + result.append_fmt( "#pragma %S\n", ast->Content ); +} + +String CodeSpecifiers::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeSpecifiers::to_string( String& result ) +{ + s32 idx = 0; + s32 left = ast->NumEntries; + while ( left-- ) + { + StrC spec = ESpecifier::to_str( ast->ArrSpecs[idx] ); + result.append_fmt( "%.*s ", spec.Len, spec.Ptr ); + idx++; + } +} + +String CodeStruct::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Struct: + to_string_def( result ); + break; + case Struct_Fwd: + to_string_fwd( result ); + break; + } + return result; +} + +void CodeStruct::to_string_def( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + result.append( "struct " ); + + if ( ast->Attributes ) + { + result.append_fmt( "%S ", ast->Attributes.to_string() ); + } + + if ( ast->ParentType ) + { + char const* access_level = to_str( ast->ParentAccess ); + + result.append_fmt( "%S : %s %S", ast->Name, access_level, ast->ParentType ); + + CodeType interface = ast->ParentType->Next->cast< CodeType >(); + if ( interface ) + result.append( "\n" ); + + while ( interface ) + { + result.append_fmt( ", %S", interface.to_string() ); + interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; + } + } + else if ( ast->Name ) + { + result.append( ast->Name ); + } + + if ( ast->InlineCmt ) + { + result.append_fmt( " // %S", ast->InlineCmt->Content ); + } + + result.append_fmt( "\n{\n%S\n}", ast->Body.to_string() ); + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + result.append(";\n"); +} + +void CodeStruct::to_string_fwd( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes ) + result.append_fmt( "struct %S %S", ast->Attributes.to_string(), ast->Name ); + + else result.append_fmt( "struct %S", ast->Name ); + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + { + if ( ast->InlineCmt ) + result.append_fmt("; %S", ast->InlineCmt->Content ); + else + result.append(";\n"); + } +} + +String CodeTemplate::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeTemplate::to_string( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Params ) + result.append_fmt( "template< %S >\n%S", ast->Params.to_string(), ast->Declaration.to_string() ); + else + result.append_fmt( "template<>\n%S", ast->Declaration.to_string() ); +} + +String CodeTypedef::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeTypedef::to_string( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + result.append( "typedef "); + + // Determines if the typedef is a function typename + if ( ast->UnderlyingType->ReturnType ) + result.append( ast->UnderlyingType.to_string() ); + else + result.append_fmt( "%S %S", ast->UnderlyingType.to_string(), ast->Name ); + + if ( ast->UnderlyingType->Type == Typename && ast->UnderlyingType->ArrExpr ) + { + result.append_fmt( "[ %S ];", ast->UnderlyingType->ArrExpr->to_string() ); + + AST* next_arr_expr = ast->UnderlyingType->ArrExpr->Next; + while ( next_arr_expr ) + { + result.append_fmt( "[ %S ];", next_arr_expr.to_string() ); + next_arr_expr = next_arr_expr->Next; + } + } + else + { + result.append( ";" ); + } + + if ( ast->InlineCmt ) + result.append_fmt(" %S", ast->InlineCmt->Content); + else + result.append("\n"); +} + +String CodeType::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeType::to_string( String& result ) +{ + #if GEN_USE_NEW_TYPENAME_PARSING + if ( ast->ReturnType && ast->Params ) + { + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + else + { + if ( ast->Specs ) + result.append_fmt( "%S ( %S ) ( %S ) %S", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string(), ast->Specs.to_string() ); + else + result.append_fmt( "%S ( %S ) ( %S )", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string() ); + } + + break; + } + #else + if ( ast->ReturnType && ast->Params ) + { + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + else + { + if ( Specs ) + result.append_fmt( "%S %S ( %S ) %S", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string(), ast->Specs.to_string() ); + else + result.append_fmt( "%S %S ( %S )", ast->ReturnType.to_string(), ast->Name, ast->Params.to_string() ); + } + + break; + } + #endif + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + if ( ast->Specs ) + result.append_fmt( "%S %S", ast->Name, ast->Specs.to_string() ); + else + result.append_fmt( "%S", ast->Name ); + + if ( ast->IsParamPack ) + result.append("..."); +} + +String CodeUnion::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeUnion::to_string( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + result.append( "union " ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + if ( ast->Name ) + { + result.append_fmt( "%S\n{\n%S\n}" + , ast->Name + , ast->Body.to_string() + ); + } + else + { + // Anonymous union + result.append_fmt( "\n{\n%S\n}" + , ast->Body.to_string() + ); + } + + if ( ast->Parent == nullptr || ( ast->Parent->Type != ECode::Typedef && ast->Parent->Type != ECode::Variable ) ) + result.append(";\n"); +} + +String CodeUsing::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + switch ( ast->Type ) + { + using namespace ECode; + case Using: + to_string( result ); + break; + case Using_Namespace: + to_string_ns( result ); + break; + } + return result; +} + +void CodeUsing::to_string( String& result ) +{ + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Attributes.to_string() ); + + if ( ast->UnderlyingType ) + { + result.append_fmt( "using %S = %S", ast->Name, ast->UnderlyingType.to_string() ); + + if ( ast->UnderlyingType->ArrExpr ) + { + result.append_fmt( "[ %S ]", ast->UnderlyingType->ArrExpr.to_string() ); + + AST* next_arr_expr = ast->UnderlyingType->ArrExpr->Next; + while ( next_arr_expr ) + { + result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); + next_arr_expr = next_arr_expr->Next; + } + } + + result.append( ";" ); + } + else + result.append_fmt( "using %S;", ast->Name ); + + if ( ast->InlineCmt ) + result.append_fmt(" %S\n", ast->InlineCmt->Content ); + else + result.append("\n"); +} + +void CodeUsing::to_string_ns( String& result ) +{ + if ( ast->InlineCmt ) + result.append_fmt( "using namespace $S; %S", ast->Name, ast->InlineCmt->Content ); + else + result.append_fmt( "using namespace %s;\n", ast->Name ); +} + +String CodeVar::to_string() +{ + String result = String::make( GlobalAllocator, "" ); + to_string( result ); + return result; +} + +void CodeVar::to_string( String& result ) +{ + if ( ast->Parent && ast->Parent->Type == ECode::Variable ) + { + // Its a comma-separated variable ( a NextVar ) + + if ( ast->Specs ) + result.append_fmt( "%S ", ast->Specs.to_string() ); + + result.append( ast->Name ); + + if ( ast->ValueType->ArrExpr ) + { + result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() ); + + AST* next_arr_expr = ast->ValueType->ArrExpr->Next; + while ( next_arr_expr ) + { + result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); + next_arr_expr = next_arr_expr->Next; + } + } + + if ( ast->Value ) + result.append_fmt( " = %S", ast->Value.to_string() ); + + // Keep the chain going... + if ( ast->NextVar ) + result.append_fmt( ", %S", ast->NextVar.to_string() ); + + break; + } + + if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) + result.append( "export " ); + + if ( ast->Attributes || ast->Specs ) + { + if ( ast->Attributes ) + result.append_fmt( "%S ", ast->Specs.to_string() ); + + if ( ast->Specs ) + result.append_fmt( "%S\n", ast->Specs.to_string() ); + + result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name ); + + if ( ast->ValueType->ArrExpr ) + { + result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() ); + + AST* next_arr_expr = ast->ValueType->ArrExpr->Next; + while ( next_arr_expr ) + { + result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); + next_arr_expr = next_arr_expr->Next; + } + } + + if ( ast->BitfieldSize ) + result.append_fmt( " : %S", ast->BitfieldSize.to_string() ); + + if ( ast->Value ) + result.append_fmt( " = %S", ast->Value.to_string() ); + + if ( ast->NextVar ) + result.append_fmt( ", %S", ast->NextVar.to_string() ); + + if ( ast->InlineCmt ) + result.append_fmt("; %S", ast->InlineCmt->Content); + else + result.append( ";\n" ); + + break; + } + + if ( ast->BitfieldSize ) + result.append_fmt( "%S %S : %S", ast->ValueType.to_string(), ast->Name, ast->BitfieldSize.to_string() ); + + else if ( ValueType->ArrExpr ) + { + result.append_fmt( "%S %S[ %S ]", ast->ValueType.to_string(), ast->Name, ast->ValueType->ArrExpr.to_string() ); + + AST* next_arr_expr = ast->ValueType->ArrExpr->Next; + while ( next_arr_expr ) + { + result.append_fmt( "[ %S ]", next_arr_expr->to_string() ); + next_arr_expr = next_arr_expr->Next; + } + } + + else + result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name ); + + if ( Value ) + result.append_fmt( " = %S", ast->Value.to_string() ); + + if ( NextVar ) + result.append_fmt( ", %S", ast->NextVar.to_string() ); + + result.append( ";" ); + + if ( InlineCmt ) + result.append_fmt(" %S", ast->InlineCmt->Content); + else + result.append("\n"); +} diff --git a/project/components/gen/ast_inlines.hpp b/project/components/gen/ast_inlines.hpp index a7ff8c0..d2fc4fd 100644 --- a/project/components/gen/ast_inlines.hpp +++ b/project/components/gen/ast_inlines.hpp @@ -49,16 +49,6 @@ void Code::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String Code::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - Code& Code::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -127,16 +117,6 @@ void CodeBody::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeBody::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeBody& CodeBody::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -205,16 +185,6 @@ void CodeAttributes::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeAttributes::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeAttributes& CodeAttributes::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -303,16 +273,6 @@ void CodeComment::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeComment::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeComment& CodeComment::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -401,16 +361,6 @@ void CodeConstructor::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeConstructor::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeConstructor& CodeConstructor::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -499,16 +449,6 @@ void CodeClass::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeClass::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeClass& CodeClass::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -577,16 +517,6 @@ void CodeDefine::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeDefine::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeDefine& CodeDefine::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -675,16 +605,6 @@ void CodeDestructor::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeDestructor::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeDestructor& CodeDestructor::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -773,16 +693,6 @@ void CodeEnum::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeEnum::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeEnum& CodeEnum::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -871,16 +781,6 @@ void CodeExec::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeExec::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeExec& CodeExec::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1067,16 +967,6 @@ void CodeFriend::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeFriend::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeFriend& CodeFriend::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1165,16 +1055,6 @@ void CodeFn::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeFn::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeFn& CodeFn::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1263,16 +1143,6 @@ void CodeInclude::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeInclude::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeInclude& CodeInclude::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1361,16 +1231,6 @@ void CodeModule::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeModule::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeModule& CodeModule::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1459,16 +1319,6 @@ void CodeNS::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeNS::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeNS& CodeNS::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1557,16 +1407,6 @@ void CodeOperator::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeOperator::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeOperator& CodeOperator::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1655,16 +1495,6 @@ void CodeOpCast::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeOpCast::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeOpCast& CodeOpCast::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1753,16 +1583,6 @@ void CodeParam::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeParam::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeParam& CodeParam::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1831,16 +1651,6 @@ void CodePragma::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodePragma::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodePragma& CodePragma::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -1929,16 +1739,6 @@ void CodePreprocessCond::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodePreprocessCond::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodePreprocessCond& CodePreprocessCond::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2027,16 +1827,6 @@ void CodeSpecifiers::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeSpecifiers::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeSpecifiers& CodeSpecifiers::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2105,16 +1895,6 @@ void CodeStruct::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeStruct::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeStruct& CodeStruct::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2183,16 +1963,6 @@ void CodeTemplate::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeTemplate::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeTemplate& CodeTemplate::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2281,16 +2051,6 @@ void CodeType::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeType::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeType& CodeType::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2379,16 +2139,6 @@ void CodeTypedef::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeTypedef::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeTypedef& CodeTypedef::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2477,16 +2227,6 @@ void CodeUnion::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeUnion::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeUnion& CodeUnion::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2575,16 +2315,6 @@ void CodeUsing::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeUsing::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeUsing& CodeUsing::operator=( Code other ) { if ( other.ast && other->Parent ) @@ -2673,16 +2403,6 @@ void CodeVar::set_global() rcast( AST*, ast )->Parent = Code::Global.ast; } -String CodeVar::to_string() -{ - if ( ast == nullptr ) - { - log_failure( "Code::to_string: Cannot convert code to string, AST is null!" ); - return { nullptr }; - } - return rcast( AST*, ast )->to_string(); -} - CodeVar& CodeVar::operator=( Code other ) { if ( other.ast && other->Parent ) diff --git a/project/components/interface.cpp b/project/components/interface.cpp index c6fdfd2..f926de0 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -1,6 +1,6 @@ #ifdef GEN_INTELLISENSE_DIRECTIVES #pragma once -#include "ast.cpp" +#include "code_serialization.cpp" #endif internal void init_parser(); diff --git a/project/gen.cpp b/project/gen.cpp index 8a494aa..e253cd6 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -20,6 +20,7 @@ GEN_NS_BEGIN #include "components/ast_case_macros.cpp" #include "components/ast.cpp" +#include "components/code_serialization.cpp" #include "components/interface.cpp" #include "components/interface.upfront.cpp" diff --git a/project/helpers/helper.hpp b/project/helpers/helper.hpp index 49fb4fb..ad478db 100644 --- a/project/helpers/helper.hpp +++ b/project/helpers/helper.hpp @@ -379,16 +379,16 @@ CodeBody gen_ast_inlines() rcast(AST*, ast)->Parent = Code::Global.ast; } - String ::to_string() - { - if ( ast == nullptr ) - { - log_failure("Code::to_string: Cannot convert code to string, AST is null!"); - return { nullptr }; - } - - return rcast(AST*, ast)->to_string(); - } +// String ::to_string() +// { +// if ( ast == nullptr ) +// { +// log_failure("Code::to_string: Cannot convert code to string, AST is null!"); +// return { nullptr }; +// } +// +// return rcast(AST*, ast)->to_string(); +// } & ::operator =( Code other ) { if ( other.ast && other->Parent ) diff --git a/singleheader/singleheader.cpp b/singleheader/singleheader.cpp index 8590b70..d6d9b6d 100644 --- a/singleheader/singleheader.cpp +++ b/singleheader/singleheader.cpp @@ -198,6 +198,7 @@ int gen_main() Code static_data = scan_file( project_dir "components/static_data.cpp" ); Code ast_case_macros = scan_file( project_dir "components/ast_case_macros.cpp" ); Code ast = scan_file( project_dir "components/ast.cpp" ); + Code code = scan_file( project_dir "components/code_serialization.cpp" ); Code interface = scan_file( project_dir "components/interface.cpp" ); Code upfront = scan_file( project_dir "components/interface.upfront.cpp" ); Code parsing = scan_file( project_dir "components/interface.parsing.cpp" ); @@ -212,6 +213,7 @@ int gen_main() header.print_fmt( "#pragma region AST\n\n" ); header.print( ast_case_macros ); header.print( ast ); + header.print( code ); header.print_fmt( "#pragma endregion AST\n\n" ); header.print_fmt( "#pragma region Interface\n" );