diff --git a/project/gen.cpp b/project/gen.cpp index 3cc9a88..388e6e7 100644 --- a/project/gen.cpp +++ b/project/gen.cpp @@ -1708,14 +1708,12 @@ namespace gen namespace StaticData { global Array< Pool > CodePools = { nullptr }; - global Array< Arena > CodeEntriesArenas = { nullptr }; global Array< Arena > StringArenas = { nullptr }; global StringTable StringCache; global AllocatorInfo Allocator_DataArrays = heap(); global AllocatorInfo Allocator_CodePool = heap(); - global AllocatorInfo Allocator_CodeEntriesArena = heap(); global AllocatorInfo Allocator_StringArena = heap(); global AllocatorInfo Allocator_StringTable = heap(); global AllocatorInfo Allocator_TypeTable = heap(); @@ -1781,7 +1779,7 @@ namespace gen #pragma region AST Body Case Macros # define AST_BODY_CLASS_UNALLOWED_TYPES \ - case Attributes: \ + case PlatformAttributes: \ case Class_Body: \ case Enum_Body: \ case Extern_Linkage: \ @@ -1801,7 +1799,7 @@ namespace gen case Access_Public: \ case Access_Protected: \ case Access_Private: \ - case Attributes: \ + case PlatformAttributes: \ case Class_Body: \ case Enum_Body: \ case Extern_Linkage: \ @@ -1824,7 +1822,7 @@ namespace gen case Access_Public: \ case Access_Protected: \ case Access_Private: \ - case Attributes: \ + case PlatformAttributes: \ case Class_Body: \ case Enum_Body: \ case Execution: \ @@ -1854,91 +1852,11 @@ namespace gen { using namespace ECode; - Code - result = make_code(); - result->Parent = Parent; - result->Name = Name; - result->Type = Type; - result->Op = Op; + Code result = make_code(); - switch ( Type ) - { - case Invalid: - log_failure( "AST::duplicate: Cannot duplicate an invalid AST." ); - return nullptr; + mem_copy( (AST*)result, this, sizeof( AST ) ); - case Access_Public: - case Access_Protected: - case Access_Private: - case Attributes: - case Comment: - case Execution: - case Module: - case Preprocessor_Include: - case Untyped: - // Can just be the same, as its a cached string. - result->Content = Content; - return result; - - case Specifiers: - // Need to memcpy the specifiers. - mem_copy( result->ArrSpecs, ArrSpecs, sizeof( ArrSpecs ) ); - result->StaticIndex = StaticIndex; - return result; - - // The main purpose of this is to make sure entires in the AST are unique, - // So that we can assign the new parent without corrupting the existing AST. - case Class: - case Class_Fwd: - case Class_Body: - case Enum: - case Enum_Fwd: - case Enum_Body: - case Enum_Class: - case Enum_Class_Fwd: - case Export_Body: - case Extern_Linkage: - case Extern_Linkage_Body: - case Friend: - case Function: - case Function_Fwd: - case Function_Body: - case Global_Body: - case Namespace: - case Namespace_Body: - case Operator: - case Operator_Fwd: - case Operator_Cast: - case Operator_Cast_Fwd: - case Operator_Member: - case Operator_Member_Fwd: - case Parameters: - case Struct: - case Struct_Fwd: - case Struct_Body: - case Template: - case Typedef: - case Typename: - case Union: - case Union_Body: - case Using: - case Using_Namespace: - case Variable: - s32 index = 0; - s32 left = num_entries(); - while ( left -- ) - { - // This will naturally duplicate the entire chain duplicate all of the ast nodes. - // It may not be the most optimal way for memory reasons, however figuring out the heuristic - // For when it should reparent all nodes or not is not within the simple scope of this library. - result->add_entry( entry(index)->duplicate() ); - index++; - } - return result; - } - - log_failure( "AST::duplicate: Unknown AST type %s.", type_str() ); - return nullptr; + return result; } String AST::to_string() @@ -1995,41 +1913,39 @@ namespace gen result.append( Name ); break; - case Attributes: + case PlatformAttributes: result.append( Content ); case Class: { ProcessModuleFlags(); - CodeClass self = cast(); - - if ( self.attributes() || self.parent() ) + if ( Attributes || ParentType ) { result.append( "class " ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.parent() ) + if ( ParentType ) { char const* access_level = to_str( ParentAccess ); result.append_fmt( "%s : %s %s\n{\n%s\n};" , Name , access_level - , self.parent()->to_string() - , self.body()->to_string() + , ParentType->to_string() + , Body->to_string() ); } else { - result.append_fmt( "%s \n{\n%s\n};", Name, self.body()->to_string() ); + result.append_fmt( "%s \n{\n%s\n};", Name, Body->to_string() ); } } else { - result.append_fmt( "class %s\n{\n%s\n};", Name, self.body()->to_string() ); + result.append_fmt( "class %s\n{\n%s\n};", Name, Body->to_string() ); } } break; @@ -2038,10 +1954,8 @@ namespace gen { ProcessModuleFlags(); - CodeClass self = cast(); - - if ( self.attributes() ) - result.append_fmt( "class %s %s;", self.attributes()->to_string(), Name ); + if ( Attributes ) + result.append_fmt( "class %s %s;", Attributes->to_string(), Name ); else result.append_fmt( "class %s;", Name ); } @@ -2051,29 +1965,27 @@ namespace gen { ProcessModuleFlags(); - CodeEnum self = cast(); - - if ( num_entries() > 1 ) + if ( Attributes || UnderlyingType ) { result.append( "enum " ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.type() ) + if ( UnderlyingType ) result.append_fmt( "%s : %s\n{\n" , Name - , self.type()->to_string() + , UnderlyingType->to_string() ); else result.append_fmt( "%s\n{\n%s\n};" , Name - , self.body()->to_string() + , Body->to_string() ); } else result.append_fmt( "enum %s\n{\n%s\n};" , Name - , self.body()->to_string() + , Body->to_string() ); } break; @@ -2082,12 +1994,10 @@ namespace gen { ProcessModuleFlags(); - CodeEnum self = cast(); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); - - result.append_fmt( "enum %s : %s;", Name, self.type()->to_string() ); + result.append_fmt( "enum %s : %s;", Name, UnderlyingType->to_string() ); } break; @@ -2095,37 +2005,35 @@ namespace gen { ProcessModuleFlags(); - CodeEnum self = cast(); - - if ( self.attributes() || self.type() ) + if ( Attributes || UnderlyingType ) { result.append( "enum class " ); - if ( self.attributes() ) + if ( Attributes ) { - result.append_fmt( "%s ", self.attributes()->to_string() ); + result.append_fmt( "%s ", Attributes->to_string() ); } - if ( self.type() ) + if ( UnderlyingType ) { result.append_fmt( "%s : %s\n{\n%s\n};" , Name - , self.type()->to_string() - , self.body()->to_string() + , UnderlyingType->to_string() + , Body->to_string() ); } else { result.append_fmt( "%s\n{\n$s\n};" , Name - , self.body()->to_string() + , Body->to_string() ); } } else { result.append_fmt( "enum class %s\n{\n%s\n};" - , self.body()->to_string() + , Body->to_string() ); } } @@ -2135,14 +2043,12 @@ namespace gen { ProcessModuleFlags(); - CodeEnum self = cast(); - result.append( "enum class " ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - result.append_fmt( "%s : %s;", Name, self.type()->to_string() ); + result.append_fmt( "%s : %s;", Name, UnderlyingType->to_string() ); } break; @@ -2150,12 +2056,12 @@ namespace gen { result.append_fmt( "export\n{\n" ); - s32 index = 0; - s32 left = num_entries(); - while ( left -- ) + Code curr = cast(); + s32 left = NumEntries; + while ( left-- ) { - result.append_fmt( "%s\n", entry( index )->to_string() ); - index++; + result.append_fmt( "%s\n", curr->to_string() ); + ++curr; } result.append_fmt( "};" ); @@ -2167,40 +2073,38 @@ namespace gen result.append_fmt( "extern \"%s\"\n{\n%s\n}" , Name - , cast().body()->to_string() + , Body->to_string() ); break; case Friend: - result.append_fmt( "friend %s;", cast().symbol()->to_string() ); + result.append_fmt( "friend %s;", Declaration->to_string() ); break; case Function: { ProcessModuleFlags(); - CodeFn self = cast(); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( Specs ) + result.append_fmt( "%s\n", Specs->to_string() ); - if ( self.specifiers() ) - result.append_fmt( "%s\n", self.specifiers()->to_string() ); - - if ( self.return_type() ) - result.append_fmt( "%s %s", self.return_type()->to_string(), Name ); + if ( ReturnType ) + result.append_fmt( "%s %s", ReturnType->to_string(), Name ); else result.append_fmt( "%s(", Name ); - if ( self.params() ) - result.append_fmt( "%s", self.params()->to_string() ); + if ( Params ) + result.append_fmt( "%s", Params->to_string() ); else result.append( "void" ); result.append_fmt( ")\n{\n%s\n}" - , self.body()->to_string() + , Body->to_string() ); } break; @@ -2209,22 +2113,20 @@ namespace gen { ProcessModuleFlags(); - CodeFn self = cast(); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( Specs ) + result.append_fmt( "%s\n", Specs->to_string() ); - if ( self.specifiers() ) - result.append_fmt( "%s\n", self.specifiers()->to_string() ); - - if ( self.return_type() ) - result.append_fmt( "%s %s(", self.return_type()->to_string(), Name ); + if ( ReturnType ) + result.append_fmt( "%s %s(", ReturnType->to_string(), Name ); else result.append_fmt( "%s(", Name ); - if ( self.params() ) - result.append_fmt( "%s", self.params()->to_string() ); + if ( Params ) + result.append_fmt( "%s", Params->to_string() ); else result.append( "void" ); @@ -2248,7 +2150,7 @@ namespace gen result.append_fmt( "namespace %s\n{\n%s}" , Name - , cast().body()->to_string() + , Body->to_string() ); break; @@ -2257,25 +2159,23 @@ namespace gen { ProcessModuleFlags(); - CodeOperator self = cast(); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( Attributes ) + result.append_fmt( "%s\n", Attributes->to_string() ); - if ( self.specifiers() ) - result.append_fmt( "%s\n", self.specifiers()->to_string() ); + if ( ReturnType ) + result.append_fmt( "%s %s (", ReturnType->to_string(), Name ); - if ( self.return_type() ) - result.append_fmt( "%s %s (", self.return_type()->to_string(), Name ); - - if ( self.params() ) - result.append_fmt( "%s", self.params()->to_string() ); + if ( Params ) + result.append_fmt( "%s", Params->to_string() ); else result.append( "void" ); result.append_fmt( ")\n{\n%s\n}" - , self.body()->to_string() + , Body->to_string() ); } break; @@ -2285,18 +2185,16 @@ namespace gen { ProcessModuleFlags(); - CodeOperator self = cast(); + if ( Attributes ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( Specs ) + result.append_fmt( "%s", Specs->to_string() ); - if ( self.specifiers() ) - result.append_fmt( "%s", self.specifiers()->to_string() ); + result.append_fmt( "%s %s (", ReturnType->to_string(), Name ); - result.append_fmt( "%s %s (", self.specifiers()->to_string(), Name ); - - if ( self.params() ) - result.append_fmt( "%s);", self.params()->to_string() ); + if ( Params ) + result.append_fmt( "%s);", Params->to_string() ); else result.append_fmt( "void);" ); @@ -2305,44 +2203,29 @@ namespace gen case Operator_Cast: { - CodeOpCast self = cast(); - result.append_fmt("operator %s(){\n%s\n}", self.type()->to_string(), self.body()->to_string() ); + result.append_fmt("operator %s(){\n%s\n}", ValueType->to_string(), Body->to_string() ); } break; case Operator_Cast_Fwd: - result.append_fmt("operator %s();", cast().type()->to_string() ); + result.append_fmt("operator %s();", ValueType->to_string() ); break; case Parameters: { - CodeParams self = cast(); + // TODO : Parameters can have default values. if ( Name ) - { - result.append_fmt( "%s %s", self.type()->to_string(), Name ); - } + result.append_fmt( "%s %s", ValueType->to_string(), Name ); + else - result.append_fmt( "%s", self.type()->to_string() ); + result.append_fmt( "%s", ValueType->to_string() ); - s32 index = 1; - s32 left = num_entries() - 1; - - while ( left-- ) - { - CodeParams next = entry( index )->cast(); - - if ( Name ) - result.append_fmt( ", %s %s" - , next->to_string() - , next->Name - ); - - else - result.append_fmt( "%s", self.type()->to_string() ); - - index++; - } + if ( NumEntries ) + for ( CodeParam param : cast() ) + { + result.append(param->to_string()); + } } break; @@ -2353,7 +2236,7 @@ namespace gen case Specifiers: { s32 idx = 0; - s32 left = StaticIndex; + s32 left = NumEntries; while ( left-- ) { result.append_fmt( "%s ", (char const*)ESpecifier::to_str( ArrSpecs[idx]) ); @@ -2368,32 +2251,34 @@ namespace gen CodeStruct self = cast(); - if ( self.attributes() || self.parent() ) + if ( Attributes || ParentType ) { result.append( "struct " ); - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); + if ( ParentType ) + result.append_fmt( "%s ", Attributes->to_string() ); - if ( self.parent() ) + // TODO : Structs can be anonymous, so we need to check for that + + if ( ParentType ) { char const* access_level = to_str( ParentAccess ); result.append_fmt( "%s : %s %s\n{\n%s\n};" , Name , access_level - , self.parent()->to_string() - , self.body()->to_string() + , ParentType->to_string() + , Body->to_string() ); } else { - result.append_fmt( "%s \n{\n%s\n};", Name, self.body()->to_string() ); + result.append_fmt( "%s \n{\n%s\n};", Name, Body->to_string() ); } } else { - result.append_fmt( "struct %s\n{\n%s\n};", Name, self.body()->to_string() ); + result.append_fmt( "struct %s\n{\n%s\n};", Name, Body->to_string() ); } } break; @@ -2404,52 +2289,13 @@ namespace gen CodeStruct self = cast(); - if ( self.attributes() ) - result.append_fmt( "struct %s %s;", self.attributes()->to_string(), Name ); + if ( Attributes ) + result.append_fmt( "struct %s %s;", Attributes->to_string(), Name ); else result.append_fmt( "struct %s;", Name ); } break; - case Variable: - { - ProcessModuleFlags(); - - CodeVar self = cast(); - - if ( self.attributes() || self.specifiers() ) - { - if ( self.attributes() ) - result.append_fmt( "%s ", self.attributes()->to_string() ); - - if ( self.specifiers() ) - result.append_fmt( "%s\n", self.specifiers()->to_string() ); - - result.append_fmt( "%s %s", entry( 0 )->to_string(), Name ); - - AST* type = entry( 0); - AST* type_arr = type->entry( 0 ); - - if ( self.type().array_expr() ) - result.append_fmt( "[%s]", type_arr->to_string() ); - - if ( self.value() ) - result.append_fmt( " = %s;", self.value()->to_string() ); - - break; - } - - CodeType type = self.type(); - Code type_arr = type.array_expr(); - - if ( type_arr ) - result.append_fmt( "%s %s[%s];", type->to_string(), Name, type_arr->to_string() ); - - else - result.append_fmt( "%s %s;", entry( 0 )->to_string(), Name ); - } - break; - case Template: { ProcessModuleFlags(); @@ -2488,61 +2334,49 @@ namespace gen case Typename: { - - } - CodeType sef = cast(); + CodeType self = cast(); if ( self.attributes() || self.specifiers() ) { - s32 idx = 0; - if ( self.attributes() ) - { result.append_fmt( "%s ", self.attributes()->to_string() ); - } if ( self.specifiers() ) - { result.append_fmt( "%s %s", Name, self.specifiers()->to_string() ); - } - else - { - result.append_fmt( "%s", Name ); - } + else + result.append_fmt( "%s", Name ); } else { result.append_fmt( "%s", Name ); } + } break; case Union: { ProcessModuleFlags(); - s32 idx = 0; + CodeUnion self = cast(); result.append( "union " ); - if ( entry( idx )->Type == Attributes ) - { - result.append_fmt( "%s ", entry( idx )->to_string() ); - idx++; - } + if ( self.attributes() ) + result.append_fmt( "%s ", self.attributes()->to_string() ); if ( Name ) { result.append_fmt( "%s\n{\n%s\n};" , Name - , body()->to_string() + , self.body()->to_string() ); } else { // Anonymous union result.append_fmt( "\n{\n%s\n};" - , body()->to_string() + , self.body()->to_string() ); } } @@ -2554,7 +2388,7 @@ namespace gen AST* type = entry( 0 ); - if ( entry( 1 ) && entry( 1 )->Type == Attributes ) + if ( entry( 1 ) && entry( 1 )->Type == PlatformAttributes ) { result.append_fmt( "%s ", entry( 1 )->to_string() ); } @@ -2577,6 +2411,45 @@ namespace gen result.append_fmt( "using namespace %s;", Name ); break; + case Variable: + { + ProcessModuleFlags(); + + CodeVar self = cast(); + + if ( self.attributes() || self.specifiers() ) + { + if ( self.attributes() ) + result.append_fmt( "%s ", self.attributes()->to_string() ); + + if ( self.specifiers() ) + result.append_fmt( "%s\n", self.specifiers()->to_string() ); + + result.append_fmt( "%s %s", entry( 0 )->to_string(), Name ); + + AST* type = entry( 0); + AST* type_arr = type->entry( 0 ); + + if ( self.type().array_expr() ) + result.append_fmt( "[%s]", type_arr->to_string() ); + + if ( self.value() ) + result.append_fmt( " = %s;", self.value()->to_string() ); + + break; + } + + CodeType type = self.type(); + Code type_arr = type.array_expr(); + + if ( type_arr ) + result.append_fmt( "%s %s[%s];", type->to_string(), Name, type_arr->to_string() ); + + else + result.append_fmt( "%s %s;", entry( 0 )->to_string(), Name ); + } + break; + case Class_Body: case Enum_Body: case Extern_Linkage_Body: @@ -2586,12 +2459,12 @@ namespace gen case Struct_Body: case Union_Body: { - s32 index = 0; - s32 left = num_entries(); + Code curr = Front->cast(); + s32 left = NumEntries; while ( left -- ) { - result.append_fmt( "%s\n", entry( index )->to_string() ); - index++; + result.append_fmt( "%s\n", curr->to_string() ); + ++curr; } } break; @@ -2609,21 +2482,13 @@ namespace gen switch ( Type ) { + // TODO : Finish this... case ECode::Typedef: case ECode::Typename: { if ( Name != other->Name ) return false; - if ( num_entries() != other->num_entries() ) - return false; - - for ( s32 i = 0; i < num_entries(); ++i ) - { - if ( entry( i ) != other->entry( i ) ) - return false; - } - return true; } } @@ -2637,7 +2502,6 @@ namespace gen bool AST::validate_body() { using namespace ECode; - using namespace EEntry; #define CheckBodyType( BodyType ) \ if ( Type != BodyType ) \ @@ -2646,21 +2510,19 @@ namespace gen return false; \ } - #define CheckEntries( Unallowed_Types ) \ - do \ - { \ - for ( s32 idx = 0; idx < num_entries(); idx++ ) \ - { \ - AST* elem = entry( idx ); \ - \ - switch ( elem->Type ) \ - { \ - Unallowed_Types \ - log_failure( "AST::validate_body: Invalid entry in body %s", elem->debug_str() ); \ - return false; \ - } \ - } \ - } \ + #define CheckEntries( Unallowed_Types ) \ + do \ + { \ + for ( Code entry : Body->cast() ) \ + { \ + switch ( entry->Type ) \ + { \ + Unallowed_Types \ + log_failure( "AST::validate_body: Invalid entry in body %s", entry->debug_str() ); \ + return false; \ + } \ + } \ + } \ while (0); switch ( Type ) @@ -2671,25 +2533,21 @@ namespace gen break; case Enum_Body: CheckBodyType( Enum_Body ); - for ( s32 idx = 0; idx < entry( Entry_Body )->num_entries(); idx++ ) + for ( Code entry : Body->cast() ) { - AST* elem = entry( idx ); - - if ( elem->Type != Untyped ) + if ( entry->Type != Untyped ) { - log_failure( "AST::validate_body: Invalid entry in enum body (needs to be untyped or comment) %s", elem->debug_str() ); + log_failure( "AST::validate_body: Invalid entry in enum body (needs to be untyped or comment) %s", entry->debug_str() ); return false; } } break; case Export_Body: - for ( s32 idx = 0; idx < num_entries(); idx++ ) + for ( Code entry : Body->cast() ) { - AST* elem = entry( idx ); - - if ( elem->Type != Untyped ) + if ( entry->Type != Untyped ) { - log_failure( "AST::validate_body: Invalid entry in export body %s", elem->debug_str() ); + log_failure( "AST::validate_body: Invalid entry in export body %s", entry->debug_str() ); return false; } } @@ -2703,7 +2561,7 @@ namespace gen CheckEntries( AST_BODY_FUNCTION_UNALLOWED_TYPES ); break; case Global_Body: - for ( s32 idx = 0; idx < num_entries(); idx++ ) + for ( s32 idx = 0; idx < NumEntries; idx++ ) { AST* elem = entry( idx ); @@ -2777,13 +2635,6 @@ namespace gen CodePools.append( code_pool ); - Arena code_entires_arena = Arena::init_from_allocator( Allocator_CodeEntriesArena, SizePer_CodeEntriresArena ); - - if ( code_entires_arena.PhysicalStart == nullptr ) - fatal( "gen::init: Failed to initialize the code entries arena" ); - - CodeEntriesArenas.append( code_entires_arena ); - Arena string_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena ); if ( string_arena.PhysicalStart == nullptr ) @@ -2927,16 +2778,6 @@ namespace gen } while ( left--, left ); - index = 0; - left = CodeEntriesArenas.num(); - do - { - Arena* code_entries_arena = & CodeEntriesArenas[index]; - code_entries_arena->free(); - index++; - } - while ( left--, left ); - index = 0; left = StringArenas.num(); do @@ -3039,43 +2880,11 @@ namespace gen result->Op = EOperator::Invalid; result->ModuleFlags = ModuleFlag::Invalid; result->ParentAccess = AccessSpec::Invalid; - result->StaticIndex = 0; - result->DynamicEntries = false; + result->NumEntries = 0; return result; } - Array< AST* > make_code_entries() - { - using namespace StaticData; - - AllocatorInfo allocator = { nullptr, nullptr }; - - s32 index = 0; - s32 left = CodeEntriesArenas.num(); - do - { - if ( CodeEntriesArenas[index].size_remaining( GEN_DEFAULT_MEMORY_ALIGNMENT) >= InitSize_CodeEntiresArray ) - allocator = CodeEntriesArenas[index]; - index++; - } - while( left--, left ); - - if ( allocator.Data == nullptr ) - { - Arena arena = Arena::init_from_allocator( Allocator_CodeEntriesArena, SizePer_CodeEntriresArena ); - - if ( arena.PhysicalStart == nullptr ) - fatal( "gen::make_code: Failed to allocate a new code entries arena - CodeEntriesArena allcoator returned nullptr." ); - - allocator = arena; - CodeEntriesArenas.append( arena ); - } - - Array< AST* > entry_array = Array< AST* >::init( allocator ); - return entry_array; - } - enum class OpValidateResult : u32 { Fail, @@ -3498,7 +3307,7 @@ namespace gen Code result = make_code(); - result->Type = ECode::Attributes; + result->Type = ECode::PlatformAttributes; result->Name = get_cached_string( content ); result->Content = result->Name; @@ -3533,9 +3342,9 @@ namespace gen name_check( def_class, name ); - if ( attributes && attributes->Type != Attributes ) + if ( attributes && attributes->Type != PlatformAttributes ) { - log_failure( "gen::def_class: attributes was not a 'Attributes' type: %s", attributes->debug_str() ); + log_failure( "gen::def_class: attributes was not a 'PlatformAttributes' type: %s", attributes->debug_str() ); return CodeInvalid; } @@ -3599,9 +3408,9 @@ namespace gen return CodeInvalid; } - if ( attributes && attributes->Type != Attributes ) + if ( attributes && attributes->Type != PlatformAttributes ) { - log_failure( "gen::def_enum: attributes was not a 'Attributes' type: %s", attributes->debug_str() ); + log_failure( "gen::def_enum: attributes was not a 'PlatformAttributes' type: %s", attributes->debug_str() ); return CodeInvalid; } @@ -3753,9 +3562,9 @@ namespace gen return CodeInvalid; } - if ( attributes && attributes->Type != Attributes ) + if ( attributes && attributes->Type != PlatformAttributes ) { - log_failure( "gen::def_function: attributes was not a `Attributes` type: %s", attributes->debug_str() ); + log_failure( "gen::def_function: attributes was not a `PlatformAttributes` type: %s", attributes->debug_str() ); return CodeInvalid; } @@ -3859,7 +3668,7 @@ namespace gen result->Name = get_cached_string( name ); result->ModuleFlags = mflags; - result->add_entry( body ); + result->entry( EEntry::Entry_Body ) = body; return (CodeNamespace) result; } @@ -3871,9 +3680,9 @@ namespace gen { using namespace ECode; - if ( attributes && attributes->Type != Attributes ) + if ( attributes && attributes->Type != PlatformAttributes ) { - log_failure( "gen::def_operator: Attributes was provided but its not of attributes type: %s", attributes->debug_str() ); + log_failure( "gen::def_operator: PlatformAttributes was provided but its not of attributes type: %s", attributes->debug_str() ); return CodeInvalid; } @@ -3909,7 +3718,7 @@ namespace gen default: { log_failure("gen::def_operator: body must be either of Function_Body, Execution, or Untyped type. %s", body->debug_str()); - return Code::Invalid; + return CodeInvalid; } } @@ -3935,10 +3744,10 @@ namespace gen if (params_code) result->add_entry( params_code ); - return result; + return (CodeOperator) result; } - Code def_operator_cast( Code type, Code body ) + CodeOpCast def_operator_cast( Code type, Code body ) { using namespace ECode; null_check( def_operator_cast, type ); @@ -3946,7 +3755,7 @@ namespace gen if ( type->Type != Typename ) { log_failure( "gen::def_operator_cast: type is not a typename - %s", type->debug_str() ); - return Code::Invalid; + return CodeInvalid; } Code result = make_code(); @@ -3958,7 +3767,7 @@ namespace gen if ( body->Type != Function_Body && body->Type != Execution ) { log_failure( "gen::def_operator_cast: body is not of function body or execution type - %s", body->debug_str() ); - return Code::Invalid; + return CodeInvalid; } result->add_entry( body ); @@ -3969,10 +3778,10 @@ namespace gen } result->add_entry( type ); - return result; + return (CodeOpCast) result; } - Code def_param( Code type, StrC name, Code value ) + CodeParams def_param( Code type, StrC name, Code value ) { using namespace ECode; @@ -3982,13 +3791,13 @@ namespace gen if ( type->Type != Typename ) { log_failure( "gen::def_param: type is not a typename - %s", type->debug_str() ); - return Code::Invalid; + return CodeInvalid; } if ( value && value->Type != Untyped ) { log_failure( "gen::def_param: value is not untyped - %s", value->debug_str() ); - return Code::Invalid; + return CodeInvalid; } Code @@ -4001,16 +3810,15 @@ namespace gen if ( value ) result->add_entry( value ); - return result; + return (CodeParams) result; } - Code def_specifier( SpecifierT spec ) + CodeSpecifiers def_specifier( SpecifierT spec ) { - Code - result = make_code(); + CodeSpecifiers + result = (CodeSpecifiers) make_code(); result->Type = ECode::Specifiers; - - result->add_specifier( spec ); + result.add( spec ); return result; } @@ -4026,9 +3834,9 @@ namespace gen name_check( def_struct, name ); - if ( attributes && attributes->Type != Attributes ) + if ( attributes && attributes->Type != PlatformAttributes ) { - log_failure( "gen::def_struct: attributes was not a `Attributes` type" ); + log_failure( "gen::def_struct: attributes was not a `PlatformAttributes` type" ); return CodeInvalid; } @@ -4071,14 +3879,16 @@ namespace gen return (CodeStruct) result; } - Code def_template( Code params, Code definition, ModuleFlag mflags ) + CodeTemplate def_template( Code params, Code definition, ModuleFlag mflags ) { + using namespace EEntry; + null_check( def_template, definition ); if ( params && params->Type != ECode::Parameters ) { log_failure( "gen::def_template: params is not of parameters type - %s", params->debug_str() ); - return Code::Invalid; + return CodeInvalid; } switch (definition->Type ) @@ -4099,32 +3909,34 @@ namespace gen result->Type = ECode::Template; result->ModuleFlags = mflags; - result->add_entry( definition ); + result->entry( Entry_Value ) = definition; result->add_entry( params ); - return result; + return (CodeTemplate) result; } - Code def_type( StrC name, Code arrayexpr, Code specifiers, Code attributes ) + CodeType def_type( StrC name, Code arrayexpr, Code specifiers, Code attributes ) { + using namespace EEntry; + name_check( def_type, name ); - if ( attributes && attributes->Type != ECode::Attributes ) + if ( attributes && attributes->Type != ECode::PlatformAttributes ) { log_failure( "gen::def_type: attributes is not of attributes type - %s", attributes->debug_str() ); - return Code::Invalid; + return CodeInvalid; } if ( specifiers && specifiers->Type != ECode::Specifiers ) { log_failure( "gen::def_type: specifiers is not of specifiers type - %s", specifiers->debug_str() ); - return Code::Invalid; + return CodeInvalid; } if ( arrayexpr && arrayexpr->Type != ECode::Untyped ) { log_failure( "gen::def_type: arrayexpr is not of untyped type - %s", arrayexpr->debug_str() ); - return Code::Invalid; + return CodeInvalid; } Code @@ -4133,32 +3945,34 @@ namespace gen result->Type = ECode::Typename; if ( attributes ) - result->add_entry( attributes ); + result->entry( Entry_Attributes) = attributes; if ( specifiers ) - result->add_entry( specifiers ); + result->entry( Entry_Specifiers ) = specifiers; if ( arrayexpr ) - result->add_entry( arrayexpr ); + result->entry( Entry_Array_Expression) = arrayexpr; - return result; + return (CodeType) result; } - Code def_typedef( StrC name, Code type, Code attributes, ModuleFlag mflags ) + CodeTypedef def_typedef( StrC name, Code type, Code attributes, ModuleFlag mflags ) { + using namespace EEntry; + name_check( def_typedef, name ); null_check( def_typedef, type ); if ( type->Type != ECode::Typename ) { log_failure( "gen::def_typedef: type was not a Typename" ); - return Code::Invalid; + return CodeInvalid; } - if ( attributes && attributes->Type != ECode::Attributes ) + if ( attributes && attributes->Type != ECode::PlatformAttributes ) { - log_failure( "gen::def_typedef: attributes was not a Attributes" ); - return Code::Invalid; + log_failure( "gen::def_typedef: attributes was not a PlatformAttributes" ); + return CodeInvalid; } // Registering the type. @@ -4167,7 +3981,7 @@ namespace gen if ( ! registered_type ) { log_failure( "gen::def_typedef: failed to register type" ); - return Code::Invalid; + return CodeInvalid; } Code @@ -4176,28 +3990,30 @@ namespace gen result->Type = ECode::Typedef; result->ModuleFlags = mflags; - result->add_entry( type ); + result->entry( Entry_Value ) = type; if ( attributes ) - result->add_entry( attributes ); + result->entry( Entry_Attributes ) = attributes; - return result; + return (CodeTypedef) result; } - Code def_union( StrC name, Code body, Code attributes, ModuleFlag mflags ) + CodeUnion def_union( StrC name, Code body, Code attributes, ModuleFlag mflags ) { + using namespace EEntry; + null_check( def_union, body ); if ( body->Type != ECode::Union_Body ) { log_failure( "gen::def_union: body was not a Union_Body type - %s", body->debug_str() ); - return Code::Invalid; + return CodeInvalid; } - if ( attributes && attributes->Type != ECode::Attributes ) + if ( attributes && attributes->Type != ECode::PlatformAttributes ) { - log_failure( "gen::def_union: attributes was not a Attributes type - %s", attributes->debug_str() ); - return Code::Invalid; + log_failure( "gen::def_union: attributes was not a PlatformAttributes type - %s", attributes->debug_str() ); + return CodeInvalid; } Code @@ -4208,18 +4024,20 @@ namespace gen if ( name.Ptr ) result->Name = get_cached_string( name ); - result->add_entry( body ); + result->entry( Entry_Body ) = body; if ( attributes ) - result->add_entry( attributes ); + result->entry( Entry_Attributes ) = attributes; - return result; + return (CodeUnion) result; } - Code def_using( StrC name, Code type + CodeUsing def_using( StrC name, Code type , Code attributes , ModuleFlag mflags ) { + using namespace EEntry; + name_check( def_using, name ); null_check( def_using, type ); @@ -4228,13 +4046,13 @@ namespace gen if ( ! register_type ) { log_failure( "gen::def_using: failed to register type" ); - return Code::Invalid; + return CodeInvalid; } - if ( attributes && attributes->Type != ECode::Attributes ) + if ( attributes && attributes->Type != ECode::PlatformAttributes ) { - log_failure( "gen::def_using: attributes was not a Attributes type - %s", attributes->debug_str() ); - return Code::Invalid; + log_failure( "gen::def_using: attributes was not a PlatformAttributes type - %s", attributes->debug_str() ); + return CodeInvalid; } Code @@ -4244,15 +4062,15 @@ namespace gen result->Type = ECode::Using; if ( type ) - result->add_entry( type ); + result->entry( Entry_Value ) = type; if ( attributes ) result->add_entry( attributes ); - return result; + return (CodeUsing) result; } - Code def_using_namespace( StrC name ) + CodeUsingNamespace def_using_namespace( StrC name ) { name_check( def_using_namespace, name ); @@ -4262,38 +4080,40 @@ namespace gen result->Content = result->Name; result->Type = ECode::Using_Namespace; - return result; + return (CodeUsingNamespace) result; } - Code def_variable( Code type, StrC name, Code value + CodeVar def_variable( Code type, StrC name, Code value , Code specifiers, Code attributes , ModuleFlag mflags ) { + using namespace EEntry; + name_check( def_variable, name ); null_check( def_variable, type ); - if ( attributes && attributes->Type != ECode::Attributes ) + if ( attributes && attributes->Type != ECode::PlatformAttributes ) { - log_failure( "gen::def_variable: attributes was not a `Attributes` type" ); - return Code::Invalid; + log_failure( "gen::def_variable: attributes was not a `PlatformAttributes` type" ); + return CodeInvalid; } if ( specifiers && specifiers->Type != ECode::Specifiers ) { log_failure( "gen::def_variable: specifiers was not a `Specifiers` type" ); - return Code::Invalid; + return CodeInvalid; } if ( type->Type != ECode::Typename ) { log_failure( "gen::def_variable: type was not a Typename" ); - return Code::Invalid; + return CodeInvalid; } if ( value && value->Type != ECode::Untyped ) { log_failure( "gen::def_variable: value was not a `Untyped` type" ); - return Code::Invalid; + return CodeInvalid; } Code @@ -4302,18 +4122,18 @@ namespace gen result->Type = ECode::Variable; result->ModuleFlags = mflags; - result->add_entry( type ); + result->entry( Entry_Type ) = type; if ( attributes ) - result->add_entry( attributes ); + result->entry( Entry_Attributes ) = attributes; if ( specifiers ) - result->add_entry( specifiers ); + result->entry( Entry_Specifiers ) = specifiers; if ( value ) - result->add_entry( value ); + result->entry( Entry_Value) = value; - return result; + return (CodeVar) result; } /* @@ -4668,8 +4488,9 @@ namespace gen return result; } - Code def_params( s32 num, ... ) + CodeParams def_params( s32 num, ... ) { + using namespace EEntry; def_body_start( def_params ); va_list va; @@ -4683,7 +4504,7 @@ namespace gen if ( param->Type != Parameters ) { log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); - return Code::Invalid; + return CodeInvalid; } Code result = { param->duplicate() }; @@ -4696,14 +4517,14 @@ namespace gen if ( param->Type != Parameters ) { log_failure( "gen::def_params: param %d is not a Parameters", num - num + 1 ); - return Code::Invalid; + return CodeInvalid; } - result->add_entry( param ); + result->entry( Entry_Parameters ) = param; } va_end(va); - return result; + return (CodeParams) result; } Code def_params( s32 num, Code* codes ) @@ -4743,22 +4564,22 @@ namespace gen return result; } - Code def_specifiers( s32 num, ... ) + CodeSpecifiers def_specifiers( s32 num, ... ) { if ( num <= 0 ) { log_failure("gen::def_specifiers: num cannot be zero or less"); - return Code::Invalid; + return CodeInvalid; } if ( num > AST::ArrSpecs_Cap ) { log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); - return Code::Invalid; + return CodeInvalid; } - Code - result = make_code(); + CodeSpecifiers + result = (CodeSpecifiers) make_code(); result->Type = ECode::Specifiers; va_list va; @@ -4767,7 +4588,7 @@ namespace gen { SpecifierT type = (SpecifierT)va_arg(va, int); - result->add_specifier( type ); + result.add( type ); } while ( --num, num ); va_end(va); @@ -4775,28 +4596,28 @@ namespace gen return result; } - Code def_specifiers( s32 num, SpecifierT* specs ) + CodeSpecifiers def_specifiers( s32 num, SpecifierT* specs ) { if ( num <= 0 ) { log_failure("gen::def_specifiers: num cannot be zero or less"); - return Code::Invalid; + return CodeInvalid; } if ( num > AST::ArrSpecs_Cap ) { log_failure("gen::def_specifiers: num of speciifers to define AST larger than AST specicifier capacity - %d", num); - return Code::Invalid; + return CodeInvalid; } - Code - result = make_code(); + CodeSpecifiers + result = (CodeSpecifiers) make_code(); result->Type = ECode::Specifiers; s32 idx = 0; do { - result->add_specifier( specs[idx] ); + result.add( specs[idx] ); idx++; } while ( --num, num ); @@ -4804,7 +4625,7 @@ namespace gen return result; } - Code def_struct_body( s32 num, ... ) + CodeStructBody def_struct_body( s32 num, ... ) { def_body_start( def_struct_body ); @@ -4819,10 +4640,10 @@ namespace gen def_body_code_validation_end( def_struct_body ); va_end(va); - return result; + return (CodeStructBody) result; } - Code def_struct_body( s32 num, Code* codes ) + CodeStructBody def_struct_body( s32 num, Code* codes ) { def_body_code_array_start( def_struct_body ); @@ -4834,7 +4655,7 @@ namespace gen AST_BODY_STRUCT_UNALLOWED_TYPES def_body_code_validation_end( def_struct_body ); - return result; + return (CodeStructBody) result; } Code def_union_body( s32 num, ... ) diff --git a/project/gen.hpp b/project/gen.hpp index d2b97fb..70547fb 100644 --- a/project/gen.hpp +++ b/project/gen.hpp @@ -8,6 +8,8 @@ */ #pragma once +#define GEN_FEATURE_PARSING + #ifdef gen_time #pragma region GENCPP DEPENDENCIES //! If its desired to roll your own dependencies, define GENCPP_PROVIDE_DEPENDENCIES before including this file. @@ -2259,7 +2261,7 @@ namespace gen Entry( Access_Private ) \ Entry( Access_Protected ) \ Entry( Access_Public ) \ - Entry( Attributes ) \ + Entry( PlatformAttributes ) \ Entry( Class ) \ Entry( Class_Fwd ) \ Entry( Class_Body ) \ @@ -2611,7 +2613,7 @@ namespace gen struct CodeNamespace; struct CodeOperator; struct CodeOpCast; - struct CodeParams; + struct CodeParam; struct CodeSpecifiers; struct CodeStruct; struct CodeTemplate; @@ -2622,35 +2624,9 @@ namespace gen struct CodeUsingNamespace; struct CodeVar; struct CodeBody; - struct CodeClassBody; - struct CodeEnumBody; - struct CodeExportBody; - struct CodeExternBody; - struct CodeFnBody; - struct CodeGlobalBody; - struct CodeNamespaceBody; - struct CodeStructBody; - struct CodeUnionBody; // Desired width of the AST data structure. - constexpr u32 AST_POD_Size = 256; - - namespace EEntry - { - enum Type : u32 - { - Entry_Array_Expression, - Entry_Attributes, - Entry_Body, - Entry_Parameters, - Entry_Parameter_Type, - Entry_Parent, - Entry_Return_Type, - Entry_Specifiers, - Entry_Value, - }; - } - using EntryT = EEntry::Type; + constexpr u32 AST_POD_Size = 128; /* Simple AST POD with functionality to seralize into C++ syntax. @@ -2658,144 +2634,130 @@ namespace gen struct AST { # pragma region Member Functions - void add_entry( AST* other ); - AST* duplicate(); - AST*& entry( u32 idx ); - bool has_entries(); - bool is_equal( AST* other ); - s32 num_entries(); - - // Serialization - - char const* debug_str() - { - char const* fmt = stringize( - \nCode Debug: - \nType : %s - \nParent : %s - \nName : %s - \nComment : %s - ); - - // These should be used immediately in a log. - // Thus if its desired to keep the debug str - // for multiple calls to bprintf, - // allocate this to proper string. - return str_fmt_buf( fmt - , type_str() - , Parent ? Parent->Name : "" - , Name ? Name : "" - ); - } - - String to_string(); - + void add ( AST* other ); + AST* duplicate (); + AST*& entry ( u32 idx ); + bool has_entries(); + bool is_equal ( AST* other ); + char const* debug_str (); + String to_string (); char const* type_str() { return ECode::to_str( Type ); } - - // Validation - - bool validate_body(); - - operator Code(); + bool validate_body(); template< class Type > Type cast() { return (Type) { this }; } + + operator Code(); # pragma endregion Member Functions constexpr static - uw ArrS_Cap = - ( AST_POD_Size - - sizeof(AST*) // Parent - - sizeof(StringCached) // Name - - sizeof(CodeT) // Type - - sizeof(OperatorT) // Op - - sizeof(ModuleFlag) // ModuleFlags - - sizeof(AccessSpec) // ParentAccess - - sizeof(u32) // StaticIndex - - sizeof(bool) // DynamicEntries - - sizeof(u8) * 3 ) // _Align_Pad - / sizeof(AST*); - - constexpr static - uw ArrSpecs_Cap = ArrS_Cap * (sizeof(AST*) / sizeof(SpecifierT)); - - # define Using_AST_POD \ - union { \ - AST* ArrStatic[AST::ArrS_Cap]; \ - Array< AST* > ArrDyn; \ - StringCached Content; \ - SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; \ - }; \ - AST* Parent; \ - StringCached Name; \ - CodeT Type; \ - OperatorT Op; \ - ModuleFlag ModuleFlags; \ - AccessSpec ParentAccess; \ - u32 StaticIndex; \ - bool DynamicEntries; \ - u8 _Align_Pad[3]; - - Using_AST_POD - }; - - struct AST_Experimental - { - using AST = AST_Experimental; - - static constexpr uw ArrSpecs_Cap = sizeof( AST* ) * 9; - - // Should only be used for body types. - void add( AST* other ) - { - Back->Right = other; - Back = other; - } + uw ArrSpecs_Cap = + ( + AST_POD_Size + - sizeof(AST*) * 4 + - sizeof(StringCached) + - sizeof(CodeT) + - sizeof(ModuleFlag) + - sizeof(u32) + ) + / sizeof(SpecifierT); union { struct { - AST* ArrExpr; - AST* Attributes; - AST* Parameters; - AST* ParameterType; - AST* ParentType; - AST* ReturnType; - AST* Specifiers; - AST* Value; + AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable + AST* Specs; // Function, Operator, Type symbol, Variable + union { + AST* ParentType; // Class, Struct + AST* ReturnType; // Function, Operator + AST* UnderlyingType; // Enum, Typedef + AST* ValueType; // Parameter, Variable + }; + AST* Params; // Function, Operator, Template + union { + AST* ArrExpr; // Type Symbol + AST* Body; // Class, Enum, Function, Namespace, Struct, Union + AST* Declaration; // Friend, Template + AST* Value; // Parameter, Variable + }; }; - struct - { - AST* Left; - AST* Right; - }; - struct - { - AST* Front; - AST* Back; - }; - StringCached Content; - SpecifierT ArrSpecs[ArrSpecs_Cap]; + StringCached Content; // Attributes, Comment, Execution, Include + SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers }; - AST* Parent; + union { + // Entry Node + struct { + AST* Prev; + AST* Next; + }; + // Body Node + struct { + AST* Front; + AST* Back; + }; + }; + AST* Parent; StringCached Name; CodeT Type; - OperatorT Op; ModuleFlag ModuleFlags; - AccessSpec ParentAccess; - u32 NumEntries; + union { + OperatorT Op; + AccessSpec ParentAccess; + u32 NumEntries; + }; }; struct AST_POD { - Using_AST_POD - # undef Using_CodePOD + union { + struct + { + AST* Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable + AST* Specs; // Function, Operator, Type symbol, Variable + union { + AST* ParentType; // Class, Struct + AST* ReturnType; // Function, Operator + AST* UnderlyingType; // Enum, Typedef + AST* ValueType; // Parameter, Variable + }; + AST* Params; // Function, Operator, Template + union { + AST* ArrExpr; // Type Symbol + AST* Body; // Class, Enum, Function, Namespace, Struct, Union + AST* Declaration; // Friend, Template + AST* Value; // Parameter, Variable + }; + }; + StringCached Content; // Attributes, Comment, Execution, Include + SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; // Specifiers + }; + union { + // Entry Node + struct { + AST* Prev; + AST* Next; + }; + // Body Node + struct { + AST* Front; + AST* Back; + }; + }; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + union { + OperatorT Op; + AccessSpec ParentAccess; + u32 NumEntries; + }; }; // Its intended for the AST to have equivalent size to its POD. @@ -2824,20 +2786,20 @@ namespace gen log_failure("Code::set_global: Cannot set code as global, AST is null!"); \ return; \ } \ - \ + \ ast->Parent = Code::Global.ast; \ } \ bool is_valid() \ { \ - return ast != nullptr && ast->Type != CodeT::Invalid; \ + return (AST*) ast != nullptr && ast->Type != CodeT::Invalid; \ } \ bool operator ==( Code other ) \ { \ - return ast == other.ast; \ + return (AST*) ast == other.ast; \ } \ bool operator !=( Code other ) \ { \ - return ast != other.ast; \ + return (AST*) ast != other.ast; \ } \ AST* operator->() \ { \ @@ -2846,17 +2808,26 @@ namespace gen log_failure("Attempt to dereference a nullptr!"); \ return nullptr; \ } \ - \ - return ast; \ + \ + return (AST*) ast; \ } \ operator AST*() \ { \ - return ast; \ - } \ - AST* ast + return (AST*) ast; \ + } + + Code& operator++() + { + if ( ast ) + ast = ast->Next; + + return *this; + } Using_Code; + AST* ast; + #define GEN_ENFORCE_STRONG_CODE_TYPES #ifdef GEN_ENFORCE_STRONG_CODE_TYPES @@ -2875,7 +2846,7 @@ namespace gen operator CodeNamespace() const; operator CodeOperator() const; operator CodeOpCast() const; - operator CodeParams() const; + operator CodeParam() const; operator CodeSpecifiers() const; operator CodeStruct() const; operator CodeTemplate() const; @@ -2886,15 +2857,6 @@ namespace gen operator CodeUsingNamespace() const; operator CodeVar() const; operator CodeBody() const; - operator CodeClassBody() const; - operator CodeEnumBody() const; - operator CodeExportBody() const; - operator CodeExternBody() const; - operator CodeFnBody() const; - operator CodeGlobalBody() const; - operator CodeNamespaceBody() const; - operator CodeStructBody() const; - operator CodeUnionBody() const; #undef operator }; @@ -2904,11 +2866,11 @@ namespace gen AST* ast; }; - static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" ); + static_assert( sizeof(Code) == sizeof(Code_POD), "ERROR: Code is not POD" ); #ifdef GEN_ENFORCE_STRONG_CODE_TYPES // Used when the its desired when omission is allowed in a definition. - #define NoCode { nullptr } + #define NoCode { nullptr } #define CodeInvalid { Code::Invalid.ast } #else // Used when the its desired when omission is allowed in a definition. @@ -2916,6 +2878,469 @@ namespace gen constexpr Code CodeInvalid = Code::Invalid; #endif +#pragma region Filtered ASTs + struct AST_Body + { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + AST* Front; + AST* Back; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Body) == sizeof(AST), "ERROR: AST_Filtered is not the same size as AST"); + + struct AST_Attributes + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + StringCached Content; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Attributes) == sizeof(AST), "ERROR: AST_Attributes is not the same size as AST"); + + struct AST_Comment + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + StringCached Content; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Comment) == sizeof(AST), "ERROR: AST_Comment is not the same size as AST"); + + struct AST_Class + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + char _PAD_SPECS_ [ sizeof(AST*) ]; + AST* ParentType; + char _PAD_PARAMS_[ sizeof(AST*) ]; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + AccessSpec ParentAccess; + }; + static_assert( sizeof(AST_Class) == sizeof(AST), "ERROR: AST_Class is not the same size as AST"); + + struct AST_Exec + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ]; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Exec) == sizeof(AST), "ERROR: AST_Exec is not the same size as AST"); + + struct AST_Enum + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + char _PAD_SPEC_ [ sizeof(AST*) ]; + AST* UnderlyingType; + char _PAD_PARAMS_[ sizeof(AST*) ]; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST"); + + struct AST_Extern + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ]; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Extern) == sizeof(AST), "ERROR: AST_Extern is not the same size as AST"); + + struct AST_Include + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + StringCached Content; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Include) == sizeof(AST), "ERROR: AST_Include is not the same size as AST"); + + struct AST_Friend + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + char _PAD_PROPERTIES_[ sizeof(AST*) * 4 ]; + AST* Declaration; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Friend) == sizeof(AST), "ERROR: AST_Friend is not the same size as AST"); + + struct AST_Fn + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + AST* Specs; + AST* ReturnType; + AST* Params; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Fn) == sizeof(AST), "ERROR: AST_Fn is not the same size as AST"); + + struct AST_Module + { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Module) == sizeof(AST), "ERROR: AST_Module is not the same size as AST"); + + struct AST_Namespace + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + AST* Body; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Namespace) == sizeof(AST), "ERROR: AST_Namespace is not the same size as AST"); + + struct AST_Operator + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + AST* Specs; + AST* ReturnType; + AST* Params; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + OperatorT Op; + }; + static_assert( sizeof(AST_Operator) == sizeof(AST), "ERROR: AST_Operator is not the same size as AST"); + + struct AST_OpCast + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ]; + AST* ValueType; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_OpCast) == sizeof(AST), "ERROR: AST_OpCast is not the same size as AST"); + + struct AST_Param + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ]; + AST* ValueType; + AST* Value; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + u32 NumEntries; + }; + static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the same size as AST"); + + struct AST_Specifiers + { + SpecifierT ArrSpecs[ AST::ArrSpecs_Cap ]; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + u32 NumEntries; + }; + static_assert( sizeof(AST_Specifiers) == sizeof(AST), "ERROR: AST_Specifiers is not the same size as AST"); + + struct AST_Struct + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + char _PAD_SPECS_ [ sizeof(AST*) ]; + AST* ParentType; + char _PAD_PARAMS_[ sizeof(AST*) ]; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + AccessSpec ParentAccess; + }; + static_assert( sizeof(AST_Struct) == sizeof(AST), "ERROR: AST_Struct is not the same size as AST"); + + struct AST_Template + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + AST* ReturnType; + AST* Specs; + AST* Params; + AST* Declaration; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Template) == sizeof(AST), "ERROR: AST_Template is not the same size as AST"); + + struct AST_Type + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + AST* Specs; + char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ]; + AST* ArrExpr; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_Type) == sizeof(AST), "ERROR: AST_Type is not the same size as AST"); + + struct AST_Typedef + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + char _PAD_SPECS_ [ sizeof(AST*) ]; + AST* UnderlyingType; + char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ]; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Typedef) == sizeof(AST), "ERROR: AST_Typedef is not the same size as AST"); + + struct AST_Union + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + char _PAD_PROPERTIES_[ sizeof(AST*) * 3 ]; + AST* Body; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Union) == sizeof(AST), "ERROR: AST_Union is not the same size as AST"); + + struct AST_Using + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + char _PAD_SPECS_ [ sizeof(AST*) ]; + AST* UnderlyingType; + char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ]; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + union { + OperatorT Op; + AccessSpec ParentAccess; + u32 NumEntries; + }; + }; + static_assert( sizeof(AST_Using) == sizeof(AST), "ERROR: AST_Using is not the same size as AST"); + + struct AST_UsingNamespace + { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + char _PAD_UNUSED_[ sizeof(ModuleFlag) + sizeof(u32) ]; + }; + static_assert( sizeof(AST_UsingNamespace) == sizeof(AST), "ERROR: AST_UsingNamespace is not the same size as AST"); + + struct AST_Var + { + union { + char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; + struct + { + AST* Attributes; + AST* Specs; + AST* ValueType; + char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ]; + AST* Value; + }; + }; + AST* Prev; + AST* Next; + AST* Parent; + StringCached Name; + CodeT Type; + ModuleFlag ModuleFlags; + char _PAD_UNUSED_[ sizeof(u32) ]; + }; + static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST"); +#pragma endregion Filtered ASTs + #pragma region Code Types #define Define_ParentCast \ operator Code() \ @@ -2923,156 +3348,81 @@ namespace gen return * rcast( Code*, this ); \ } - #define Define_CodeBodyType( Name ) \ - struct Code##Name \ - { \ - Using_Code; \ - Define_ParentCast; \ - \ - Code* begin() \ - { \ - return rcast( Code*, ast->entry(0)); \ - } \ - Code* end() \ - { \ - return rcast( Code*, ast->entry( ast->num_entries() ) ); \ - } \ + #define Define_CodeType( name ) \ + struct Code##name \ + { \ + Using_Code; \ + Define_ParentCast; \ + AST_##name* ast; \ } - Define_CodeBodyType( Body ); - Define_CodeBodyType( ClassBody ); - Define_CodeBodyType( EnumBody ); - Define_CodeBodyType( ExportBody ); - Define_CodeBodyType( ExternBody ); - Define_CodeBodyType( FnBody ); - Define_CodeBodyType( GlobalBody ); - Define_CodeBodyType( NamespaceBody ); - Define_CodeBodyType( StructBody ); - Define_CodeBodyType( UnionBody ); - - struct CodeAttributes + struct CodeBody { Using_Code; Define_ParentCast; + + Code* begin() + { + if ( ast ) + return rcast( Code*, ast->Front ); + + return { nullptr }; + } + Code* end() + { + return nullptr; + } + + AST_Body* ast; }; - struct CodeComment - { - Using_Code; - Define_ParentCast; - }; + Define_CodeType( Attributes ); + Define_CodeType( Comment ); + Define_CodeType( Class ); + Define_CodeType( Enum ); + Define_CodeType( Exec ); + Define_CodeType( Extern ); + Define_CodeType( Include ); + Define_CodeType( Friend ); + Define_CodeType( Fn ); + Define_CodeType( Module ); + Define_CodeType( Namespace ); + Define_CodeType( Operator ); + Define_CodeType( OpCast ); + Define_CodeType( Struct ); + Define_CodeType( Template ); + Define_CodeType( Type ); + Define_CodeType( Typedef ); + Define_CodeType( Union ); + Define_CodeType( Using ); + Define_CodeType( UsingNamespace ); + Define_CodeType( Var ); - struct CodeClass + struct CodeParam { Using_Code; Define_ParentCast; - CodeAttributes attributes(); - CodeClassBody body(); - CodeType parent(); - }; + CodeParam* begin() + { + if ( ast ) + return rcast( CodeParam*, ast ); - struct CodeExec - { - Using_Code; - Define_ParentCast; - }; + return { nullptr }; + } + CodeParam* end() + { + return nullptr; + } + CodeParam& operator++() + { + if ( ast && ast->Next ) + ast = rcast( AST_Param*, ast->Next ); - struct CodeEnum - { - Using_Code; - Define_ParentCast; + return * this; + } - CodeAttributes attributes(); - CodeEnumBody body(); - CodeType type(); - }; - - struct CodeExtern - { - Using_Code; - Define_ParentCast; - - CodeExternBody body(); - }; - - struct CodeInclude - { - Using_Code; - Define_ParentCast; - }; - - struct CodeFriend - { - Using_Code; - Define_ParentCast; - - Code symbol(); - }; - - struct CodeFn - { - Using_Code; - Define_ParentCast; - - CodeAttributes attributes(); - CodeFnBody body(); - CodeParams params(); - CodeType return_type(); - CodeSpecifiers specifiers(); - }; - - struct CodeModule - { - Using_Code; - Define_ParentCast; - }; - - struct CodeNamespace - { - Using_Code; - Define_ParentCast; - - CodeNamespaceBody body(); - }; - - struct CodeUsingNamespace - { - Using_Code; - Define_ParentCast; - }; - - struct CodeOperator - { - Using_Code; - Define_ParentCast; - - CodeAttributes attributes(); - CodeFnBody body(); - CodeParams params(); - CodeType return_type(); - CodeSpecifiers specifiers(); - }; - - struct CodeOpCast - { - Using_Code; - Define_ParentCast; - - CodeFnBody body(); - CodeType type(); - }; - - struct CodeParams - { - Using_Code; - Define_ParentCast; - - void add_param( CodeParams param ); - bool has_params(); - CodeParams get( s32 idx ); - s32 num(); - CodeType type(); + AST_Param* ast; }; struct CodeSpecifiers @@ -3080,81 +3430,43 @@ namespace gen Using_Code; Define_ParentCast; - SpecifierT begin(); - SpecifierT end(); + bool add( SpecifierT spec ) + { + if ( ast->NumEntries == AST::ArrSpecs_Cap ) + { + log_failure("CodeSpecifiers: Attempted to add over %d specifiers to a specifiers AST!", AST::ArrSpecs_Cap ); + return false; + } - bool add( SpecifierT spec ); - s32 has( SpecifierT spec ); + ast->ArrSpecs[ ast->NumEntries ] = spec; + ast->NumEntries++; + return true; + } + s32 has( SpecifierT spec ) + { + for ( s32 idx = 0; idx < ast->NumEntries; idx++ ) + { + if ( ast->ArrSpecs[ ast->NumEntries ] == spec ) + return idx; + } + + return -1; + } + SpecifierT* begin() + { + if ( ast ) + return & ast->ArrSpecs[0]; + + return nullptr; + } + SpecifierT* end() + { + return ast->ArrSpecs + ast->NumEntries; + } + + AST_Specifiers* ast; }; - struct CodeStruct - { - Using_Code; - Define_ParentCast; - - CodeAttributes attributes(); - CodeStructBody body(); - CodeType parent(); - }; - - struct CodeTemplate - { - Using_Code; - Define_ParentCast; - - Code definition(); - Code params(); - }; - - struct CodeType - { - Using_Code; - Define_ParentCast; - - Code array_expr(); - CodeAttributes attributes(); - CodeSpecifiers specifiers(); - }; - - struct CodeTypedef - { - Using_Code; - Define_ParentCast; - - CodeAttributes attributes(); - CodeType type(); - }; - - struct CodeUnion - { - Using_Code; - Define_ParentCast; - - CodeAttributes attributes(); - CodeUnionBody body(); - }; - - struct CodeUsing - { - Using_Code; - Define_ParentCast; - - Code attributes(); - Code type(); - }; - - struct CodeVar - { - Using_Code; - Define_ParentCast; - - CodeAttributes attributes(); - CodeSpecifiers specifiers(); - CodeType type(); - Code value(); - }; - - #undef Define_CodeBodyType #undef Define_ParentCast #undef Using_Code #pragma endregion Code Types @@ -3181,16 +3493,11 @@ namespace gen */ Code make_code(); - // This provides a fresh Code AST array for the entries field of the AST. - // This is done separately from the regular CodePool allocator. - Array< AST* > make_code_entries(); - // Set these before calling gen's init() procedure. // Data void set_allocator_data_arrays ( AllocatorInfo data_array_allocator ); void set_allocator_code_pool ( AllocatorInfo pool_allocator ); - void set_allocator_code_enrties_arena( AllocatorInfo pool_allocator ); void set_allocator_string_arena ( AllocatorInfo string_allocator ); void set_allocator_string_table ( AllocatorInfo string_allocator ); void set_allocator_type_table ( AllocatorInfo type_reg_allocator ); @@ -3215,7 +3522,7 @@ namespace gen CodeFriend def_friend ( Code symbol ); CodeFn def_function( StrC name - , CodeParams params = NoCode, CodeType ret_type = NoCode, CodeFnBody body = NoCode + , CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); @@ -3224,22 +3531,22 @@ namespace gen CodeNamespace def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); CodeOperator def_operator( OperatorT op - , CodeParams params = NoCode, CodeType ret_type = NoCode, Code body = NoCode + , CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); CodeOpCast def_operator_cast( Code type, Code body = NoCode ); - CodeParams def_param ( Code type, StrC name, Code value = NoCode ); + CodeParam def_param ( Code type, StrC name, Code value = NoCode ); CodeSpecifiers def_specifier( SpecifierT specifier ); CodeStruct def_struct( StrC name - , Code body + , Code body = NoCode , CodeType parent = NoCode, AccessSpec access = AccessSpec::Default , CodeAttributes attributes = NoCode , ModuleFlag mflags = ModuleFlag::None ); - CodeTemplate def_template( CodeParams params, Code definition, ModuleFlag mflags = ModuleFlag::None ); + CodeTemplate def_template( CodeParam params, Code definition, ModuleFlag mflags = ModuleFlag::None ); CodeType def_type ( StrC name, Code arrayexpr = NoCode, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode ); CodeTypedef def_typedef( StrC name, CodeType type, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); @@ -3262,39 +3569,39 @@ namespace gen // There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num, /// or provide as an array of Code objects. - CodeClassBody def_class_body ( s32 num, ... ); - CodeClassBody def_class_body ( s32 num, Code* codes ); - CodeEnumBody def_enum_body ( s32 num, ... ); - CodeEnumBody def_enum_body ( s32 num, Code* codes ); - CodeExportBody def_export_body ( s32 num, ... ); - CodeExportBody def_export_body ( s32 num, Code* codes); - CodeExternBody def_extern_link_body( s32 num, ... ); - CodeExternBody def_extern_link_body( s32 num, Code* codes ); - CodeFnBody def_function_body ( s32 num, ... ); - CodeFnBody def_function_body ( s32 num, Code* codes ); - CodeGlobalBody def_global_body ( s32 num, ... ); - CodeGlobalBody def_global_body ( s32 num, Code* codes ); - CodeNamespace def_namespace_body ( s32 num, ... ); - CodeNamespace def_namespace_body ( s32 num, Code* codes ); - CodeParams def_params ( s32 num, ... ); - CodeParams def_params ( s32 num, CodeParams* params ); + CodeBody def_class_body ( s32 num, ... ); + CodeBody def_class_body ( s32 num, Code* codes ); + CodeBody def_enum_body ( s32 num, ... ); + CodeBody def_enum_body ( s32 num, Code* codes ); + CodeBody def_export_body ( s32 num, ... ); + CodeBody def_export_body ( s32 num, Code* codes); + CodeBody def_extern_link_body( s32 num, ... ); + CodeBody def_extern_link_body( s32 num, Code* codes ); + CodeBody def_function_body ( s32 num, ... ); + CodeBody def_function_body ( s32 num, Code* codes ); + CodeBody def_global_body ( s32 num, ... ); + CodeBody def_global_body ( s32 num, Code* codes ); + CodeBody def_namespace_body ( s32 num, ... ); + CodeBody def_namespace_body ( s32 num, Code* codes ); + CodeParam def_params ( s32 num, ... ); + CodeParam def_params ( s32 num, CodeParam* params ); CodeSpecifiers def_specifiers ( s32 num, ... ); CodeSpecifiers def_specifiers ( s32 num, SpecifierT* specs ); - CodeStructBody def_struct_body ( s32 num, ... ); - CodeStructBody def_struct_body ( s32 num, Code* codes ); - CodeUnionBody def_union_body ( s32 num, ... ); - CodeUnionBody def_union_body ( s32 num, Code* codes ); + CodeBody def_struct_body ( s32 num, ... ); + CodeBody def_struct_body ( s32 num, Code* codes ); + CodeBody def_union_body ( s32 num, ... ); + CodeBody def_union_body ( s32 num, Code* codes ); # pragma endregion Upfront # pragma region Parsing # ifdef GEN_FEATURE_PARSING CodeClass parse_class ( StrC class_def ); CodeEnum parse_enum ( StrC enum_def ); - CodeExportBody parse_export_body ( StrC export_def ); + CodeBody parse_export_body ( StrC export_def ); CodeExtern parse_extern_link ( StrC exten_link_def); CodeFriend parse_friend ( StrC friend_def ); CodeFn parse_function ( StrC fn_def ); - CodeGlobalBody parse_global_body ( StrC body_def ); + CodeBody parse_global_body ( StrC body_def ); CodeNamespace parse_namespace ( StrC namespace_def ); CodeOperator parse_operator ( StrC operator_def ); CodeOpCast parse_operator_cast( StrC operator_def ); @@ -3496,8 +3803,6 @@ namespace gen constexpr s32 InitSize_TypeTable = megabytes(4); constexpr s32 CodePool_NumBlocks = 4096; - constexpr s32 InitSize_CodeEntiresArray = 512; - constexpr s32 SizePer_CodeEntriresArena = megabytes(16); constexpr s32 SizePer_StringArena = megabytes(32); constexpr s32 MaxCommentLineLength = 1024; @@ -3546,55 +3851,68 @@ namespace gen #pragma region Inlines namespace gen { - void AST::add_entry( AST* other ) + void AST::add( AST* other ) { - AST* to_add = other->Parent ? - other->duplicate() : other; + if ( other->Parent ) + other = other->duplicate(); - if (DynamicEntries) - ArrDyn.append( to_add ); - - else - { - if ( StaticIndex < ArrS_Cap ) + if ( Front == nullptr ) { - ArrStatic[StaticIndex] = to_add; - StaticIndex++; + Front = other; + Back = other; + + return; } - else - { - ArrDyn = make_code_entries(); - s32 index = 0; - do - { - ArrDyn.append( ArrStatic[index] ); - } - while ( StaticIndex--, StaticIndex ); - - ArrDyn.append( to_add ); - } - } - - to_add->Parent = this; + AST* + Current = Back; + Current->Next = other; + other->Prev = Current; + Back = other; } inline bool AST::has_entries() { - return num_entries(); + return NumEntries; } inline AST*& AST::entry( u32 idx ) { - return DynamicEntries ? ArrDyn[ idx ] : ArrStatic[ idx ]; + AST* current = Front; + while ( idx >= 0 && current != nullptr ) + { + if ( idx == 0 ) + return current; + + current = current->Next; + idx--; + } + + return current; } inline - s32 AST::num_entries() + char const* AST::debug_str() { - return DynamicEntries ? ArrDyn.num() : StaticIndex; + char const* fmt = stringize( + \nCode Debug: + \nType : %s + \nParent : %s + \nName : %s + \nComment : %s + ); + + // These should be used immediately in a log. + // Thus if its desired to keep the debug str + // for multiple calls to bprintf, + // allocate this to proper string. + return str_fmt_buf( fmt + , type_str() + , Parent ? Parent->Name : "" + , Name ? Name : "" + ); } inline @@ -3603,48 +3921,6 @@ namespace gen return { this }; } - inline - CodeParams CodeParams::get( s32 index ) - { - if ( index <= 0 ) - return * this; - - return (CodeParams){ ast->entry( index + 1 ) }; - } - - inline - s32 CodeParams::num() - { - // The first entry (which holds the type) represents the first parameter. - return ast->num_entries(); - } - - inline - bool CodeSpecifiers::add( SpecifierT spec ) - { - if ( ast->StaticIndex == AST::ArrSpecs_Cap ) - { - log_failure("AST::add_specifier: Attempted to add over %d specifiers to a specifiers AST!", AST::ArrSpecs_Cap ); - return false; - } - - ast->ArrSpecs[ ast->StaticIndex ] = spec; - ast->StaticIndex++; - return true; - } - - inline - s32 CodeSpecifiers::has( SpecifierT spec ) - { - for ( s32 idx = 0; idx < ast->StaticIndex; idx++ ) - { - if ( ast->ArrSpecs[ ast->StaticIndex ] == spec ) - return idx; - } - - return -1; - } - #pragma region Operater Cast Impl #define Define_CodeCast( type ) \ inline Code::operator type() const \ @@ -3665,7 +3941,7 @@ namespace gen Define_CodeCast( CodeNamespace ); Define_CodeCast( CodeOperator ); Define_CodeCast( CodeOpCast ); - Define_CodeCast( CodeParams ); + Define_CodeCast( CodeParam ); Define_CodeCast( CodeSpecifiers ); Define_CodeCast( CodeStruct ); Define_CodeCast( CodeTemplate ); @@ -3676,15 +3952,6 @@ namespace gen Define_CodeCast( CodeUsingNamespace ); Define_CodeCast( CodeVar ); Define_CodeCast( CodeBody); - Define_CodeCast( CodeClassBody ); - Define_CodeCast( CodeEnumBody ); - Define_CodeCast( CodeExportBody ); - Define_CodeCast( CodeExternBody ); - Define_CodeCast( CodeFnBody ); - Define_CodeCast( CodeGlobalBody ); - Define_CodeCast( CodeNamespaceBody ); - Define_CodeCast( CodeStructBody ); - Define_CodeCast( CodeUnionBody ); #undef Define_CodeCast #pragma endregion Operater Cast Impl diff --git a/scripts/gencpp.natvis b/scripts/gencpp.natvis index 8a9a7c3..115446a 100644 --- a/scripts/gencpp.natvis +++ b/scripts/gencpp.natvis @@ -6,7 +6,8 @@ - Num:{((Header*)((char*)Data - sizeof(Header)))->Num}, Capacity:{((Header*)((char*)Data - sizeof(Header)))->Capacity} + Num:{((Header*)((char*)Data - sizeof(Header)))->Num}, + Capacity:{((Header*)((char*)Data - sizeof(Header)))->Capacity} {(Header*)((char*)Data - sizeof(Header))} @@ -52,42 +53,848 @@ + AST: {Name} + + Parent + Name + Type + ModuleFlags + + + + Content + + + + ArrSpecs + + + + + + + + Prev + Next + + + Front + Back + + + + + Attributes + Specs + + + + ParentType + + + ReturnType + + + UnderlyingType + + + ValueType + + + + Params + + + + ArrExpr + + + Body + + + Declaration + + + Value + + + + + + + + Op + + + ParentAccess + + + NumEntries + + + + + + + + AST: {ast->Name} Type: {ast->Type} + + ast->Parent + ast->ModuleFlags + + + + ast->Content + + + + ast->ArrSpecs + + + + + + + + ast->Prev + ast->Next + + + ast->Front + ast->Back + + + + + ast->Attributes + ast->Specs + + + + ast->ParentType + + + ast->ReturnType + + + ast->UnderlyingType + + + ast->ValueType + + + + ast->Params + + + + ast->ArrExpr + + + ast->Body + + + ast->Declaration + + + ast->Value + + + + + + + + ast->Op + + + ast->ParentAccess + + + ast->NumEntries + + + + + + + {Name} {Type} + Name Type + Parent + Front + Back + + + + + {Name} {Type} + + Name + Type + Parent + Prev + Next + Content + + + + + {Name} {Type} + + Name + Type + Parent + Prev + Next + Content + + + + + {Name} {Type} + + Name + Type + ModuleFlags + Parent + Attributes + ParentType + Body + Prev + Next + ParentAccess + + + + + {Name} {Type} + + Name + Type + Parent + Body + Prev + Next + + + + + {Name} {Type} + + Name + Type + ModuleFlags + Parent + Attributes + UnderlyingType + Body + Prev + Next + + + + + {Name} {Type} + + Name + Type + Parent + Prev + Next + Body + + + + + {Name} {Type} + + Name + Type + Parent + Prev + Next + Content + + + + + {Name} {Type} + + Name + Type + Parent + Prev + Next + Declaration + + + + + {Name} {Type} + + Name + Type + ModuleFlags + Parent + Prev + Next + Attributes + Specs + ReturnType + Params + Body + + + + + {Name} {Type} + + Name + Type + ModuleFlags + Parent + Prev + Next + + + + + {Name} {Type} + + Name + Type + ModuleFlags + Parent + Prev + Next + Body + + + + + {Name} {Type} + + Name + Type + ModuleFlags + Parent + Prev + Next + Attributes + Specs + ReturnType + Params + Body + Op + + + + + {Name} {Type} + + Name + Type + ModuleFlags + Parent + Prev + Next + ValueType + Body + + + + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + ValueType + Value + NumEntries + + + + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + + ArrSpecs + + NumEntries + + + + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + Attributes + ParentType + Body + ParentAccess + + + + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + Attributes + ReturnType + Specs + Params + Declaration + + + + + {Name} {Type} + Name Parent - Op - ModuleFlags - ParentAccess - ArrStatic - StaticIndex - ArrDyn - ArrDyn.num() + Prev + Next + Attributes + Specs + ArrExpr - + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + Attributes + UnderlyingType + + + + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + Attributes + Body + + + + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + Attributes + UnderlyingType + Op + ParentAccess + NumEntries + + + + + {Name} {Type} + + Name + Parent + Prev + Next + + + + + {Name} {Type} + + Name + ModuleFlags + Parent + Prev + Next + Attributes + Specs + ValueType + Value + Op + ParentAccess + NumEntries + + + + {ast->Name} {ast->Type} - ast->Type - ast->Name - ast->Parent - ast->Op - ast->ModuleFlags - ast->ParentAccess - ast->ArrStatic - ast->StaticIndex - ast->ArrDyn - ast->ArrDyn.num() + ast->Attributes + ast->Specs + ast->Front + ast->Back - - {ast.Name} {ast.Type} + + {ast->Name} {ast->Type} + + ast->Attributes + ast->Specs + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + - + + {ast->Name} {ast->Type} + + ast->Content + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->ParentType + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + ast->ParentAccess + + + + + {ast->Name} {ast->Type} + + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->UnderlyingType + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Content + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + + + + + {ast->Name} {ast->Type} + + ast->Declaration + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->Specs + ast->ReturnType + ast->Params + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->Specs + ast->ReturnType + ast->Params + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + ast->Op + + + + + {ast->Name} {ast->Type} + + ast->ValueType + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->ValueType + ast->Value + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + ast->NumEntries + + + + + {ast->Name} {ast->Type} + + + ast->ArrSpecs + + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + ast->NumEntries + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->ParentType + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + ast->ParentAccess + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->Specs + ast->ValueType + ast->Value + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->ReturnType + ast->Specs + ast->Params + ast->Declaration + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->Specs + ast->ArrExpr + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->UnderlyingType + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->Body + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->UnderlyingType + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + ast->Op + ast->ParentAccess + ast->NumEntries + + + + + {ast->Name} {ast->Type} + + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + + + + + {ast->Name} {ast->Type} + + ast->Attributes + ast->Specs + ast->ValueType + ast->Value + ast->Prev + ast->Next + ast->Parent + ast->Name + ast->Type + ast->ModuleFlags + + + + Length:{Length} Text:{Text, [Length]s} Type:{Type} @@ -95,4 +902,4 @@ Current[ { Arr[Idx] } ] Idx:{ Idx } - + \ No newline at end of file