From b8e1aa6eb7eaa1f67735c3d92b6584ec0ef2d5cd Mon Sep 17 00:00:00 2001 From: Ed_ Date: Fri, 25 Oct 2024 01:04:17 -0400 Subject: [PATCH] WIP : Fixes and other changes * Number literals weren't getting properly lexed * Fixes for compiler errors with Unreal Engine configuration. * Support for "post-name" macros in parameters * Support for variables initializing directly using constructor syntax. * Explicitly added inline keyword to header inlines for compiling compile library in multiple translation units. --- project/auxillary/builder.cpp | 4 +- project/bootstrap.cpp | 1 + project/components/ast.hpp | 6 +- project/components/ast_types.hpp | 5 +- project/components/code_serialization.cpp | 41 ++++- project/components/header_end.hpp | 1 - project/components/inlines.hpp | 16 +- project/components/interface.cpp | 2 +- project/components/lexer.cpp | 22 ++- project/components/parser.cpp | 180 ++++++++++++++-------- project/components/types.hpp | 2 + project/dependencies/containers.hpp | 11 +- project/dependencies/filesystem.cpp | 2 +- project/dependencies/macros.hpp | 6 + project/dependencies/memory.hpp | 4 + project/dependencies/strings.cpp | 2 +- project/dependencies/strings.hpp | 4 +- project/helpers/helper.hpp | 25 ++- project/helpers/pop_ignores.inline.hpp | 4 +- project/helpers/push_ignores.inline.hpp | 4 +- 20 files changed, 248 insertions(+), 94 deletions(-) diff --git a/project/auxillary/builder.cpp b/project/auxillary/builder.cpp index fb98e5e..a117278 100644 --- a/project/auxillary/builder.cpp +++ b/project/auxillary/builder.cpp @@ -5,7 +5,7 @@ Builder Builder::open( char const* path ) { Builder result; - + FileError error = file_open_mode( & result.File, EFileMode_WRITE, path ); if ( error != EFileError_NONE ) { @@ -48,7 +48,7 @@ void Builder::print_fmt( char const* fmt, ... ) void Builder::write() { - bool result = file_write( & File, Buffer, Buffer.length() ); + b32 result = file_write( & File, Buffer, Buffer.length() ); if ( result == false ) log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) ); diff --git a/project/bootstrap.cpp b/project/bootstrap.cpp index 505b5cb..581bab2 100644 --- a/project/bootstrap.cpp +++ b/project/bootstrap.cpp @@ -283,6 +283,7 @@ int gen_main() } // gen_scanner.cpp + if (0) { Code parsing = scan_file( "dependencies/parsing.cpp" ); Code scanner = scan_file( "auxillary/scanner.cpp" ); diff --git a/project/components/ast.hpp b/project/components/ast.hpp index 69cfa27..17bbd75 100644 --- a/project/components/ast.hpp +++ b/project/components/ast.hpp @@ -339,13 +339,14 @@ struct AST }; union { AST* ArrExpr; // Typename - AST* Body; // Class, Constructr, Destructor, Enum, Friend, Function, Namespace, Struct, Union + AST* Body; // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union AST* Declaration; // Friend, Template AST* Value; // Parameter, Variable }; union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) }; }; StringCached Content; // Attributes, Comment, Execution, Include @@ -375,6 +376,7 @@ struct AST OperatorT Op; AccessSpec ParentAccess; s32 NumEntries; + s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. }; }; @@ -407,6 +409,7 @@ struct AST_POD union { AST* NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) AST* SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) + AST* PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) }; }; StringCached Content; // Attributes, Comment, Execution, Include @@ -436,6 +439,7 @@ struct AST_POD OperatorT Op; AccessSpec ParentAccess; s32 NumEntries; + s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. }; }; diff --git a/project/components/ast_types.hpp b/project/components/ast_types.hpp index c5c5b6e..30798a8 100644 --- a/project/components/ast_types.hpp +++ b/project/components/ast_types.hpp @@ -644,7 +644,8 @@ struct AST_Param CodeType ValueType; Code Macro; Code Value; - char _PAD_PROPERTIES_3_[ sizeof(AST*) ]; + Code PostNameMacro; // Thanks Unreal + // char _PAD_PROPERTIES_3_[sizeof( AST* )]; }; }; CodeParam Last; @@ -1115,7 +1116,7 @@ struct AST_Var StringCached Name; CodeT Type; ModuleFlag ModuleFlags; - char _PAD_UNUSED_[ sizeof(u32) ]; + s32 VarConstructorInit; }; static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST"); diff --git a/project/components/code_serialization.cpp b/project/components/code_serialization.cpp index 69a2233..2c6f435 100644 --- a/project/components/code_serialization.cpp +++ b/project/components/code_serialization.cpp @@ -480,7 +480,7 @@ void CodeFn::to_string_def( String& result ) if ( ast->Attributes ) result.append_fmt( " %S ", ast->Attributes.to_string() ); - b32 prefix_specs = false; + bool prefix_specs = false; if ( ast->Specs ) { for ( SpecifierT spec : ast->Specs ) @@ -847,6 +847,11 @@ void CodeParam::to_string( String& result ) else if ( ast->ValueType ) result.append_fmt( " %S", ast->ValueType.to_string() ); + if ( ast->PostNameMacro ) + { + result.append_fmt(" %S", ast->PostNameMacro.to_string() ); + } + if ( ast->Value ) result.append_fmt( " = %S", ast->Value.to_string() ); @@ -1096,7 +1101,7 @@ String CodeType::to_string() void CodeType::to_string( String& result ) { - #if GEN_USE_NEW_TYPENAME_PARSING + #if defined(GEN_USE_NEW_TYPENAME_PARSING) if ( ast->ReturnType && ast->Params ) { if ( ast->Attributes ) @@ -1253,7 +1258,7 @@ void CodeVar::to_string( String& result ) result.append( ast->Name ); - if ( ast->ValueType && ast->ValueType->ArrExpr ) + if ( ast->ValueType->ArrExpr ) { result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() ); @@ -1266,12 +1271,20 @@ void CodeVar::to_string( String& result ) } if ( ast->Value ) - result.append_fmt( " = %S", ast->Value.to_string() ); + { + if ( ast->VarConstructorInit ) + result.append_fmt( "( %S ", ast->Value.to_string() ); + else + result.append_fmt( " = %S", ast->Value.to_string() ); + } // Keep the chain going... if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); + if ( ast->VarConstructorInit ) + result.append( " )"); + return; } @@ -1304,11 +1317,19 @@ void CodeVar::to_string( String& result ) result.append_fmt( " : %S", ast->BitfieldSize.to_string() ); if ( ast->Value ) - result.append_fmt( " = %S", ast->Value.to_string() ); + { + if ( ast->VarConstructorInit ) + result.append_fmt( "( %S ", ast->Value.to_string() ); + else + result.append_fmt( " = %S", ast->Value.to_string() ); + } if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); + if ( ast->VarConstructorInit ) + result.append( " )"); + if ( ast->InlineCmt ) result.append_fmt("; %S", ast->InlineCmt->Content); else @@ -1336,11 +1357,19 @@ void CodeVar::to_string( String& result ) result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name ); if ( ast->Value ) - result.append_fmt( " = %S", ast->Value.to_string() ); + { + if ( ast->VarConstructorInit ) + result.append_fmt( "( %S ", ast->Value.to_string() ); + else + result.append_fmt( " = %S", ast->Value.to_string() ); + } if ( ast->NextVar ) result.append_fmt( ", %S", ast->NextVar.to_string() ); + if ( ast->VarConstructorInit ) + result.append( " )"); + result.append( ";" ); if ( ast->InlineCmt ) diff --git a/project/components/header_end.hpp b/project/components/header_end.hpp index 238da02..b5194f6 100644 --- a/project/components/header_end.hpp +++ b/project/components/header_end.hpp @@ -63,7 +63,6 @@ extern CodeAttributes attrib_api_import; extern Code module_global_fragment; extern Code module_private_fragment; -// Exposed, but this is really used for parsing. extern Code fmt_newline; extern CodePragma pragma_once; diff --git a/project/components/inlines.hpp b/project/components/inlines.hpp index 7f35ab9..36fd03a 100644 --- a/project/components/inlines.hpp +++ b/project/components/inlines.hpp @@ -3,6 +3,7 @@ #include "interface.hpp" #endif +inline void AST::append( AST* other ) { if ( other->Parent ) @@ -27,6 +28,7 @@ void AST::append( AST* other ) NumEntries++; } +inline Code& AST::entry( u32 idx ) { AST** current = & Front; @@ -42,21 +44,25 @@ Code& AST::entry( u32 idx ) return * rcast( Code*, current); } +inline bool AST::has_entries() { - return NumEntries; + return NumEntries > 0; } +inline char const* AST::type_str() { return ECode::to_str( Type ); } +inline AST::operator Code() { return { this }; } +inline Code& Code::operator ++() { if ( ast ) @@ -65,6 +71,7 @@ Code& Code::operator ++() return *this; } +inline void CodeClass::add_interface( CodeType type ) { CodeType possible_slot = ast->ParentType; @@ -84,6 +91,7 @@ void CodeClass::add_interface( CodeType type ) possible_slot.ast = type.ast; } +inline void CodeParam::append( CodeParam other ) { AST* self = (AST*) ast; @@ -107,6 +115,7 @@ void CodeParam::append( CodeParam other ) self->NumEntries++; } +inline CodeParam CodeParam::get( s32 idx ) { CodeParam param = *this; @@ -122,17 +131,20 @@ CodeParam CodeParam::get( s32 idx ) return { nullptr }; } +inline bool CodeParam::has_entries() { return ast->NumEntries > 0; } +inline CodeParam& CodeParam::operator ++() { ast = ast->Next.ast; return * this; } +inline void CodeStruct::add_interface( CodeType type ) { CodeType possible_slot = ast->ParentType; @@ -152,6 +164,7 @@ void CodeStruct::add_interface( CodeType type ) possible_slot.ast = type.ast; } +inline CodeBody def_body( CodeT type ) { switch ( type ) @@ -179,6 +192,7 @@ CodeBody def_body( CodeT type ) return (CodeBody)result; } +inline StrC token_fmt_impl( sw num, ... ) { local_persist thread_local diff --git a/project/components/interface.cpp b/project/components/interface.cpp index 3cd845c..c031260 100644 --- a/project/components/interface.cpp +++ b/project/components/interface.cpp @@ -374,7 +374,7 @@ AllocatorInfo get_string_allocator( s32 str_length ) uw size_req = str_length + sizeof(String::Header) + sizeof(char*); - if ( last->TotalUsed + size_req > last->TotalSize ) + if ( last->TotalUsed + sw(size_req) > last->TotalSize ) { Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena ); diff --git a/project/components/lexer.cpp b/project/components/lexer.cpp index 0a8b547..36b8ea1 100644 --- a/project/components/lexer.cpp +++ b/project/components/lexer.cpp @@ -586,7 +586,7 @@ TokArray lex( StrC content ) { s32 length = 0; char const* scanner = entry.Data; - while ( entry.length() > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') ) + while ( entry.length() > length && char_is_alphanumeric( *scanner ) || *scanner == '_' ) { scanner++; length ++; @@ -1202,6 +1202,26 @@ TokArray lex( StrC content ) move_forward(); token.Length++; } + + // Handle number literal suffixes in a botched way + if (left && ( + current == 'l' || current == 'L' || // long/long long + current == 'u' || current == 'U' || // unsigned + current == 'f' || current == 'F' || // float + current == 'i' || current == 'I' || // imaginary + current == 'z' || current == 'Z')) // complex + { + char prev = current; + move_forward(); + token.Length++; + + // Handle 'll'/'LL' as a special case when we just processed an 'l'/'L' + if (left && (prev == 'l' || prev == 'L') && (current == 'l' || current == 'L')) + { + move_forward(); + token.Length++; + } + } } goto FoundToken; diff --git a/project/components/parser.cpp b/project/components/parser.cpp index 953fffe..42d9038 100644 --- a/project/components/parser.cpp +++ b/project/components/parser.cpp @@ -481,7 +481,7 @@ Code parse_array_decl() if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' ) { - Code array_expr = untyped_str( get_cached_string(txt(" ")) ); + Code array_expr = untyped_str( currtok ); eat( TokType::Operator ); // [] @@ -554,44 +554,6 @@ Code parse_array_decl() return { nullptr }; } -internal inline -Code parse_assignment_expression() -{ - Code expr = { nullptr }; - - eat( TokType::Operator ); - // = - - Token expr_tok = currtok; - - if ( currtok.Type == TokType::Statement_End && currtok.Type != TokType::Comma ) - { - log_failure( "Expected expression after assignment operator\n%s", Context.to_string() ); - Context.pop(); - return CodeInvalid; - } - - s32 level = 0; - while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) ) - { - if (currtok.Type == TokType::BraceCurly_Open ) - level++; - if (currtok.Type == TokType::BraceCurly_Close ) - level--; - if (currtok.Type == TokType::Capture_Start) - level++; - else if (currtok.Type == TokType::Capture_End) - level--; - - eat( currtok.Type ); - } - - expr_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )expr_tok.Text - 1; - expr = untyped_str( expr_tok ); - // = - return expr; -} - internal inline CodeAttributes parse_attributes() { @@ -1349,17 +1311,14 @@ CodeDefine parse_define() eat( TokType::Identifier ); // #define - // Defines don't necessarily need content. -#if 0 if ( ! check( TokType::Preprocess_Content )) { log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() ); Context.pop(); return CodeInvalid; } -#endif - if ( check(TokType::Preprocess_Content) && currtok.Length != 0 ) + if ( currtok.Length == 0 ) { define->Content = get_cached_string( currtok ); eat( TokType::Preprocess_Content ); @@ -1377,6 +1336,44 @@ CodeDefine parse_define() return define; } +internal inline +Code parse_assignment_expression() +{ + Code expr = { nullptr }; + + eat( TokType::Operator ); + // = + + Token expr_tok = currtok; + + if ( currtok.Type == TokType::Statement_End && currtok.Type != TokType::Comma ) + { + log_failure( "Expected expression after assignment operator\n%s", Context.to_string() ); + Context.pop(); + return CodeInvalid; + } + + s32 level = 0; + while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) ) + { + if (currtok.Type == TokType::BraceCurly_Open ) + level++; + if (currtok.Type == TokType::BraceCurly_Close ) + level--; + if (currtok.Type == TokType::Capture_Start) + level++; + else if (currtok.Type == TokType::Capture_End) + level--; + + eat( currtok.Type ); + } + + expr_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )expr_tok.Text - 1; + expr = untyped_str( expr_tok ); + // = + return expr; +} + internal inline Code parse_forward_or_definition( TokType which, bool is_inplace ) { @@ -1407,8 +1404,6 @@ Code parse_forward_or_definition( TokType which, bool is_inplace ) return CodeInvalid; } - - return CodeInvalid; } // Function parsing is handled in multiple places because its initial signature is shared with variable parsing @@ -1755,7 +1750,6 @@ CodeBody parse_global_nspace( CodeT which ) case TokType::Spec_Internal_Linkage: case TokType::Spec_NeverInline: case TokType::Spec_Static: - case TokType::Spec_ThreadLocal: { SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; s32 NumSpecifiers = 0; @@ -1779,7 +1773,6 @@ CodeBody parse_global_nspace( CodeT which ) case ESpecifier::NeverInline: case ESpecifier::Static: case ESpecifier::Volatile: - case ESpecifier::Thread_Local: break; case ESpecifier::Consteval: @@ -2300,7 +2293,7 @@ CodeOperator parse_operator_after_ret_type( case '<': { if ( currtok.Text[1] == '=' ) - op = LesserEqual; + op = LEqual; else if ( currtok.Text[1] == '<' ) { @@ -2540,7 +2533,14 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes Token name = parse_identifier(); Context.Scope->Name = name; - if ( check( TokType::Capture_Start) ) + bool detected_capture = check( TokType::Capture_Start ); + + // Check three tokens ahead to make sure that were not dealing with a constructor initialization... + // ( 350.0f , <--- Could be the scenario + // Example : + // idx +1 +2 + bool detected_comma = Context.Tokens.Arr[ Context.Tokens.Idx + 2 ].Type == TokType::Comma; + if ( detected_capture && ! detected_comma ) { // Dealing with a function result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name ); @@ -2625,10 +2625,11 @@ CodeParam parse_params( bool use_template_capture ) return { nullptr }; } - Code macro = { nullptr }; - CodeType type = { nullptr }; - Code value = { nullptr }; - Token name = NullToken; + Code macro = { nullptr }; + CodeType type = { nullptr }; + Code value = { nullptr }; + Token name = NullToken; + Code post_name_macro = { nullptr }; if ( check( TokType::Varadic_Argument ) ) { @@ -2670,6 +2671,15 @@ CodeParam parse_params( bool use_template_capture ) // ( } + // Unreal has yet another type of macro: + // template::Value)> + // class T ... and then ^this^ UE_REQUIRES shows up + // So we need to consume that. + if ( check( TokType::Preprocess_Macro )) + { + post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro ); + } + // In template captures you can have a typename have direct assignment without a name // typename = typename ... // Which would result in a static value type from a struct expansion (traditionally) @@ -2689,7 +2699,7 @@ CodeParam parse_params( bool use_template_capture ) s32 capture_level = 0; s32 template_level = 0; - while ( left && (currtok.Type != TokType::Comma) && template_level >= 0 && (CheckEndParams() || capture_level > 0 || template_level > 0) ) + while ( left && ( currtok.Type != TokType::Comma ) && template_level >= 0 && CheckEndParams() || capture_level > 0 || template_level > 0 ) { if (currtok.Text[ 0 ] == '<') ++ template_level; @@ -2773,6 +2783,15 @@ CodeParam parse_params( bool use_template_capture ) // ( = , } + // Unreal has yet another type of macro: + // template::Value)> + // class T ... and then ^this^ UE_REQUIRES shows up + // So we need to consume that. + if ( check( TokType::Preprocess_Macro )) + { + post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro ); + } + // In template captures you can have a typename have direct assignment without a name // typename = typename ... // Which would result in a static value type from a struct expansion (traditionally) @@ -2795,7 +2814,7 @@ CodeParam parse_params( bool use_template_capture ) while ( left && currtok.Type != TokType::Comma && template_level >= 0 - && (CheckEndParams() || capture_level > 0 || template_level > 0) ) + && CheckEndParams() || capture_level > 0 || template_level > 0 ) { if (currtok.Text[ 0 ] == '<') ++ template_level; @@ -2829,7 +2848,8 @@ CodeParam parse_params( bool use_template_capture ) if ( name.Length > 0 ) param->Name = get_cached_string( name ); - param->ValueType = type; + param->PostNameMacro = post_name_macro; + param->ValueType = type; if ( value ) param->Value = value; @@ -2872,7 +2892,7 @@ CodePreprocessCond parse_preprocess_cond() CodePreprocessCond cond = (CodePreprocessCond) make_code(); - cond->Type = scast(CodeT, currtok.Type - (s32(ETokType::Preprocess_If) - s32(ECode::Preprocess_If)) ); + cond->Type = scast(CodeT, currtok.Type - ( TokType::Preprocess_If - ECode::Preprocess_If ) ); eat( currtok.Type ); // # @@ -3067,6 +3087,8 @@ CodeVar parse_variable_after_name( Code expr = { nullptr }; Code bitfield_expr = { nullptr }; + b32 using_constructor_initializer = false; + if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) { // = @@ -3098,6 +3120,33 @@ CodeVar parse_variable_after_name( // = { } } + if ( currtok.Type == TokType::Capture_Start ) + { + eat( TokType:: Capture_Start); + // ( + + Token expr_token = currtok; + + using_constructor_initializer = true; + + s32 level = 0; + while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ) ) + { + if ( currtok.Type == TokType::Capture_Start ) + level++; + + else if ( currtok.Type == TokType::Capture_End && level > 0 ) + level--; + + eat( currtok.Type ); + } + + expr_token.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)expr_token.Text; + expr = untyped_str( expr_token ); + eat( TokType::Capture_End ); + // ( ) + } + if ( currtok.Type == TokType::Assign_Classifer ) { eat( TokType::Assign_Classifer ); @@ -3192,6 +3241,8 @@ CodeVar parse_variable_after_name( result->NextVar->Parent = result; } + result->VarConstructorInit = using_constructor_initializer; + Context.pop(); return result; } @@ -3246,7 +3297,7 @@ CodeVar parse_variable_declaration_list() break; } - eat(currtok.Type); + // eat(currtok.Type); if ( specifiers ) specifiers.append( spec ); @@ -3650,11 +3701,11 @@ CodeEnum parse_enum( bool inplace_def ) } // Consume inline comments - if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line ) - { - eat( TokType::Comment ); + // if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line ) + // { + // eat( TokType::Comment ); // = , // - } + // } entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text; @@ -4399,13 +4450,10 @@ CodeType parse_type( bool from_template, bool* typedef_is_function ) else if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct || currtok.Type == TokType::Decl_Union ) { - Token fwd_key = currtok; eat( currtok.Type ); // - name = parse_identifier(); - fwd_key.Length = sptr(name.Text + name.Length) - sptr(fwd_key.Text); - name = fwd_key; + name = parse_identifier(); // name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text; // eat( TokType::Identifier ); diff --git a/project/components/types.hpp b/project/components/types.hpp index 70c3ca1..104c202 100644 --- a/project/components/types.hpp +++ b/project/components/types.hpp @@ -71,6 +71,7 @@ enum class ModuleFlag : u32 Invalid, }; +inline StrC to_str( ModuleFlag flag ) { local_persist @@ -86,6 +87,7 @@ StrC to_str( ModuleFlag flag ) return lookup[ (u32)flag ]; } +inline ModuleFlag operator|( ModuleFlag A, ModuleFlag B) { return (ModuleFlag)( (u32)A | (u32)B ); diff --git a/project/dependencies/containers.hpp b/project/dependencies/containers.hpp index 6649c80..ed4cc00 100644 --- a/project/dependencies/containers.hpp +++ b/project/dependencies/containers.hpp @@ -50,6 +50,11 @@ struct Array return 2 * value + 8; } + bool append( Array other ) + { + return append( other, other.num() ); + } + bool append( Type value ) { Header* header = get_header(); @@ -158,7 +163,7 @@ struct Array if ( begin < 0 || end > header.Num ) return false; - for ( sw idx = begin; idx < end; idx++ ) + for ( sw idx = sw(begin); idx < sw(end); idx++ ) { Data[ idx ] = value; } @@ -365,7 +370,7 @@ struct HashTable { GEN_ASSERT_NOT_NULL( map_proc ); - for ( sw idx = 0; idx < Entries.num(); idx++ ) + for ( sw idx = 0; idx < sw(Entries.num()); ++idx ) { map_proc( Entries[ idx ].Key, Entries[ idx ].Value ); } @@ -377,7 +382,7 @@ struct HashTable { GEN_ASSERT_NOT_NULL( map_proc ); - for ( sw idx = 0; idx < Entries.num(); idx++ ) + for ( sw idx = 0; idx < sw(Entries.num()); ++idx ) { map_proc( Entries[ idx ].Key, & Entries[ idx ].Value ); } diff --git a/project/dependencies/filesystem.cpp b/project/dependencies/filesystem.cpp index 9e7241e..d87bd6f 100644 --- a/project/dependencies/filesystem.cpp +++ b/project/dependencies/filesystem.cpp @@ -594,7 +594,7 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write ) { Array arr = { d->buf }; - if ( arr.get_header()->Capacity < new_cap ) + if ( arr.get_header()->Capacity < uw(new_cap) ) { if ( ! arr.grow( ( s64 )( new_cap ) ) ) return false; diff --git a/project/dependencies/macros.hpp b/project/dependencies/macros.hpp index 8125840..b125947 100644 --- a/project/dependencies/macros.hpp +++ b/project/dependencies/macros.hpp @@ -13,6 +13,7 @@ #define internal static // Internal linkage #define local_persist static // Local Persisting variables +#pragma region ForceInline_Definition #ifdef GEN_COMPILER_MSVC # define forceinline __forceinline # define neverinline __declspec( noinline ) @@ -31,18 +32,23 @@ # define forceinline # define neverinline #endif +#pragma endregion ForceInline_Definition // Bits +#ifndef bit #define bit( Value ) ( 1 << Value ) #define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) ) +#endif // Casting +#ifndef ccast #define ccast( Type, Value ) ( * const_cast< Type* >( & (Value) ) ) #define pcast( Type, Value ) ( * reinterpret_cast< Type* >( & ( Value ) ) ) #define rcast( Type, Value ) reinterpret_cast< Type >( Value ) #define scast( Type, Value ) static_cast< Type >( Value ) +#endif // Num Arguments (Varadics) // #if defined(__GNUC__) || defined(__clang__) diff --git a/project/dependencies/memory.hpp b/project/dependencies/memory.hpp index 8ea2ae0..243e675 100644 --- a/project/dependencies/memory.hpp +++ b/project/dependencies/memory.hpp @@ -445,10 +445,14 @@ struct Arena return alignment_offset; } +// This id is defined by Unreal for asserts +#pragma push_macro("check") +#undef check void check() { GEN_ASSERT( TempCount == 0 ); } +#pragma pop_macro("check") void free() { diff --git a/project/dependencies/strings.cpp b/project/dependencies/strings.cpp index 86b6247..4172c51 100644 --- a/project/dependencies/strings.cpp +++ b/project/dependencies/strings.cpp @@ -124,7 +124,7 @@ bool String::make_space_for( char const* str, sw add_len ) Data = rcast( char*, header + 1 ); - return str; + return true; } } #pragma endregion String diff --git a/project/dependencies/strings.hpp b/project/dependencies/strings.hpp index 95c6e14..d1d1f07 100644 --- a/project/dependencies/strings.hpp +++ b/project/dependencies/strings.hpp @@ -139,7 +139,7 @@ struct String header.Length = curr_len + length; } - return str; + return str != nullptr; } bool append( StrC str) @@ -353,7 +353,7 @@ struct String operator bool() { - return Data; + return Data != nullptr; } operator char* () diff --git a/project/helpers/helper.hpp b/project/helpers/helper.hpp index 83f3c7f..ca23158 100644 --- a/project/helpers/helper.hpp +++ b/project/helpers/helper.hpp @@ -35,6 +35,7 @@ CodeBody gen_ecode( char const* path ) #pragma push_macro("local_persist") #undef local_persist CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( + inline StrC to_str( Type type ) { local_persist @@ -89,6 +90,7 @@ CodeBody gen_eoperator( char const* path ) #pragma push_macro("local_persist") #undef local_persist CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize( + inline StrC to_str( Type op ) { local_persist @@ -142,6 +144,7 @@ CodeBody gen_especifier( char const* path ) ))); CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize( + inline bool is_trailing( Type specifier ) { return specifier > Virtual; @@ -159,6 +162,7 @@ CodeBody gen_especifier( char const* path ) #undef forceinline #undef neverinline CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize( + inline StrC to_str( Type type ) { local_persist @@ -171,6 +175,7 @@ CodeBody gen_especifier( char const* path ) ))); CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( + inline Type to_type( StrC str ) { local_persist @@ -282,6 +287,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) #undef do_once_start #undef do_once_end CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, "attribute_toks", (StrC)to_str_attributes, stringize( + inline StrC to_str( Type type ) { local_persist @@ -295,6 +301,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path ) ))); CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize( + inline Type to_type( StrC str ) { local_persist @@ -339,6 +346,7 @@ CodeBody gen_ast_inlines() #undef log_failure char const* code_impl_tmpl = stringize( \n + inline char const* ::debug_str() { if ( ast == nullptr ) @@ -346,6 +354,7 @@ CodeBody gen_ast_inlines() return rcast(AST*, ast)->debug_str(); } + inline Code ::duplicate() { if ( ast == nullptr ) @@ -356,19 +365,23 @@ CodeBody gen_ast_inlines() return { rcast(AST*, ast)->duplicate() }; } + inline bool ::is_equal( Code other ) { if ( ast == nullptr || other.ast == nullptr ) { // Just check if they're both null. - return rcast(AST*, ast) == other.ast; + log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); + return false; } return rcast(AST*, ast)->is_equal( other.ast ); } + inline bool ::is_valid() { return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid; } + inline void ::set_global() { if ( ast == nullptr ) @@ -379,6 +392,7 @@ CodeBody gen_ast_inlines() rcast(AST*, ast)->Parent = Code::Global.ast; } + inline & ::operator =( Code other ) { if ( other.ast && other->Parent ) @@ -390,14 +404,17 @@ CodeBody gen_ast_inlines() ast = rcast( decltype(ast), other.ast ); return *this; } + inline bool ::operator ==( Code other ) { return (AST*) ast == other.ast; } + inline bool ::operator !=( Code other ) { return (AST*) ast != other.ast; } + inline ::operator bool() { return ast != nullptr; @@ -405,14 +422,17 @@ CodeBody gen_ast_inlines() ); char const* codetype_impl_tmpl = stringize( + inline AST* Code::raw() { return rcast( AST*, ast ); } + inline Code::operator Code() { return *rcast( Code*, this ); } + inline AST_* Code::operator->() { if ( ast == nullptr ) @@ -480,11 +500,12 @@ CodeBody gen_ast_inlines() impl_code_var. append( parse_global_body( token_fmt( "typename", StrC name(Var), codetype_impl_tmpl ))); char const* cast_tmpl = stringize( + inline AST::operator Code() { return { rcast( AST_*, this ) }; } - + inline Code::operator Code() const { return { (AST_*) ast }; diff --git a/project/helpers/pop_ignores.inline.hpp b/project/helpers/pop_ignores.inline.hpp index 269ffa4..ab6a57f 100644 --- a/project/helpers/pop_ignores.inline.hpp +++ b/project/helpers/pop_ignores.inline.hpp @@ -1,7 +1,7 @@ -#if __clang__ +#ifdef __clang__ # pragma clang diagnostic pop #endif -#if __GNUC__ +#ifdef __GNUC__ # pragma GCC diagnostic pop #endif diff --git a/project/helpers/push_ignores.inline.hpp b/project/helpers/push_ignores.inline.hpp index a6e24a8..a6b2df8 100644 --- a/project/helpers/push_ignores.inline.hpp +++ b/project/helpers/push_ignores.inline.hpp @@ -1,4 +1,4 @@ -#if __clang__ +#ifdef __clang__ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wunused-const-variable" # pragma clang diagnostic ignored "-Wunused-but-set-variable" @@ -9,7 +9,7 @@ # pragma clang diagnostic ignored "-Wunused-function" #endif -#if __GNUC__ +#ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunknown-pragmas" # pragma GCC diagnostic ignored "-Wcomment"