diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp index 7727533..5ab06d6 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.cpp @@ -24,7 +24,6 @@ #include "gen.hpp" GEN_NS_BEGIN - #pragma region StaticData // TODO : Convert global allocation strategy to use a slab allocation strategy. @@ -2728,11 +2727,19 @@ 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; } @@ -2766,11 +2773,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 @@ -2798,11 +2813,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 ) @@ -2993,16 +3016,17 @@ internal void define_constants() spec_##Type_ = def_specifiers( num_args( __VA_ARGS__ ), __VA_ARGS__ ); \ spec_##Type_.set_global(); -#pragma push_macro( "FORCEINLINE" ) -#pragma push_macro( "global" ) -#pragma push_macro( "internal" ) -#pragma push_macro( "local_persist" ) -#pragma push_macro( "neverinline" ) +#pragma push_macro("FORCEINLINE") +#pragma push_macro("global") +#pragma push_macro("internal") +#pragma push_macro("local_persist") +#pragma push_macro("neverinline") #undef FORCEINLINE #undef global #undef internal #undef local_persist #undef neverinline + def_constant_spec( const, ESpecifier::Const ); def_constant_spec( consteval, ESpecifier::Consteval ); def_constant_spec( constexpr, ESpecifier::Constexpr ); @@ -3027,14 +3051,14 @@ internal void define_constants() def_constant_spec( virtual, ESpecifier::Virtual ); def_constant_spec( volatile, ESpecifier::Volatile ) - spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); + spec_local_persist = def_specifiers( 1, ESpecifier::Local_Persist ); spec_local_persist.set_global(); -#pragma pop_macro( "FORCEINLINE" ) -#pragma pop_macro( "global" ) -#pragma pop_macro( "internal" ) -#pragma pop_macro( "local_persist" ) -#pragma pop_macro( "neverinline" ) +#pragma pop_macro("FORCEINLINE") +#pragma pop_macro("global") +#pragma pop_macro("internal") +#pragma pop_macro("local_persist") +#pragma pop_macro("neverinline") #undef def_constant_spec } @@ -7096,6 +7120,26 @@ namespace parser 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; @@ -9563,6 +9607,7 @@ namespace parser return result; } + __pragma(optimize("",off)) internal Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers ) { push_scope(); @@ -9623,7 +9668,14 @@ namespace parser 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 ); @@ -9647,6 +9699,7 @@ namespace parser Context.pop(); return result; } + __pragma(optimize("",on)) internal CodePragma parse_pragma() { @@ -10150,6 +10203,8 @@ namespace parser Code expr = { nullptr }; Code bitfield_expr = { nullptr }; + b32 using_constructor_initializer = false; + if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) ) { // = @@ -10180,6 +10235,33 @@ namespace parser expr = untyped_str( expr_tok ); // = { } } + + 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 ) { @@ -10274,6 +10356,8 @@ namespace parser result->NextVar->Parent = result; } + result->VarConstructorInit = using_constructor_initializer; + Context.pop(); return result; } diff --git a/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp b/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp index c914357..9daab5b 100644 --- a/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp +++ b/Project/Source/GasaEditor/GasaGen/gencpp/gen.hpp @@ -886,6 +886,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. }; }; @@ -968,6 +969,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. }; }; @@ -3174,7 +3176,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" );