End of gencpp experimentation. Parsed Scene and Actor component header + AttributeSet.h

This commit is contained in:
Edward R. Gonzalez 2024-04-16 05:02:58 -04:00
parent 020a2de91a
commit d3deeb31a0
5 changed files with 499 additions and 236 deletions

View File

@ -143,7 +143,8 @@ public:
#pragma region UObject #pragma region UObject
void GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const override; void GetLifetimeReplicatedProps( TArray< FLifetimeProperty >& OutLifetimeProps ) const override = 0;
;
#pragma endregion UObject #pragma endregion UObject
}; };

View File

@ -9,9 +9,9 @@
using namespace gen; using namespace gen;
#include "GasaGenCommon.cpp" #include "GasaGenCommon.cpp"
#include "GasaGen_ue_parse_testing.cpp"
#include "GasaGen_UGasaAttributeSet.cpp" #include "GasaGen_UGasaAttributeSet.cpp"
int gen_main() int gen_main()
{ {
gen::init(); gen::init();
@ -22,24 +22,23 @@ int gen_main()
umeta_generated_body = code_str( GENERATED_BODY() ); umeta_generated_body = code_str( GENERATED_BODY() );
gasa_api = code_str( GASA_API ); gasa_api = code_str( GASA_API );
StrC str_generated_body = txt("GENERATED_BODY("); StrC str_GENERATED_BODY = txt("GENERATED_BODY(");
StrC str_generated_uclass_body = txt("GENERATED_UCLASS_BODY("); StrC str_GENERATED_UCLASS_BODY = txt("GENERATED_UCLASS_BODY(");
StrC str_property_binding_impl = txt("PROPERTY_BINDING_IMPLEMENTATION"); StrC str_PROPERTY_BINDING_IMPLEMENTATION = txt("PROPERTY_BINDING_IMPLEMENTATION(");
StrC str_uclass = txt("UCLASS("); StrC str_UCLASS = txt("UCLASS(");
StrC str_ufunction = txt("UFUNCTION("); StrC str_UFUNCTION = txt("UFUNCTION(");
StrC str_uproperty = txt("UPROPERTY("); StrC str_UPROPERTY = txt("UPROPERTY(");
StrC str_declare_log_category_extern = txt("DECLARE_LOG_CATEGORY_EXTERN("); StrC str_DECLARE_LOG_CATEGORY_EXTERN = txt("DECLARE_LOG_CATEGORY_EXTERN(");
StrC str_enum_class_flags = txt("ENUM_CLASS_FLAGS("); StrC str_ENUM_CLASS_FLAGS = txt("ENUM_CLASS_FLAGS(");
StrC str_declare_class = txt("DECLARE_CLASS("); StrC str_DECLARE_CLASS = txt("DECLARE_CLASS(");
StrC str_define_default_object_initializer_constructor_call = txt("DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL("); StrC str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL = txt("DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL(");
StrC str_macro_text = txt("TEXT("); StrC str_TEXT = txt("TEXT(");
StrC str_declare_multicast_delegate_one_parameter = txt("DECLARE_MULTICAST_DELEGATE_OneParam("); StrC str_DECLARE_MULTICAST_DELEGATE_OneParam = txt("DECLARE_MULTICAST_DELEGATE_OneParam(");
StrC str_declare_multicast_delegate_two_parameter = txt("DECLARE_MULTICAST_DELEGATE_TwoParams("); StrC str_DECLARE_MULTICAST_DELEGATE_TwoParams = txt("DECLARE_MULTICAST_DELEGATE_TwoParams(");
StrC str_declare_multicast_delegate_three_parameter = txt("DECLARE_MULTICAST_DELEGATE_ThreeParams("); StrC str_DECLARE_MULTICAST_DELEGATE_ThreeParams = txt("DECLARE_MULTICAST_DELEGATE_ThreeParams(");
StrC str_declare_delegate_retval_one_param = txt("DECLARE_DELEGATE_RetVal_OneParam("); StrC str_DECLARE_DELEGATE_RetVal_OneParam = txt("DECLARE_DELEGATE_RetVal_OneParam(");
StrC str_declare_function = txt("DECLARE_FUNCTION("); StrC str_DECLARE_FUNCTION = txt("DECLARE_FUNCTION(");
StrC str_result_decl = txt("RESULT_DECL"); StrC str_RESULT_DECL = txt("RESULT_DECL");
StrC str_property_binding_implementation = txt("PROPERTY_BINDING_IMPLEMENTATION(");
StrC str_FORCEINLINE = txt("FORCEINLINE"); StrC str_FORCEINLINE = txt("FORCEINLINE");
StrC str_UENUM = txt("UENUM("); StrC str_UENUM = txt("UENUM(");
StrC str_UMETA = txt("UMETA("); StrC str_UMETA = txt("UMETA(");
@ -57,28 +56,27 @@ int gen_main()
StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam("); StrC str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam = txt("DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam(");
StrC str_UPARAM = txt("UPARAM("); StrC str_UPARAM = txt("UPARAM(");
StrC str_FORCEINLINE_DEBUGGABLE = txt("FORCEINLINE_DEBUGGABLE"); StrC str_FORCEINLINE_DEBUGGABLE = txt("FORCEINLINE_DEBUGGABLE");
StrC str_DECLARE_EVENT_ThreeParams = txt("DECLARE_EVENT_ThreeParams(");
StrC str_USTRUCT = txt("USTRUCT(");
StrC str_GENERATED_USTRUCT_BODY = txt("GENERATED_USTRUCT_BODY(");
PreprocessorDefines.append( get_cached_string(str_generated_body)); PreprocessorDefines.append( get_cached_string(str_GENERATED_BODY));
PreprocessorDefines.append( get_cached_string(str_generated_uclass_body)); PreprocessorDefines.append( get_cached_string(str_GENERATED_UCLASS_BODY));
PreprocessorDefines.append( get_cached_string(str_property_binding_impl)); PreprocessorDefines.append( get_cached_string(str_PROPERTY_BINDING_IMPLEMENTATION));
// PreprocessorDefines.append( get_cached_string(str_ue_deprecated)); PreprocessorDefines.append( get_cached_string(str_UCLASS));
PreprocessorDefines.append( get_cached_string(str_uclass)); PreprocessorDefines.append( get_cached_string(str_UFUNCTION));
PreprocessorDefines.append( get_cached_string(str_ufunction)); PreprocessorDefines.append( get_cached_string(str_UPROPERTY));
PreprocessorDefines.append( get_cached_string(str_uproperty)); PreprocessorDefines.append( get_cached_string(str_DECLARE_LOG_CATEGORY_EXTERN));
// PreprocessorDefines.append( get_cached_string(str_umg_api)); PreprocessorDefines.append( get_cached_string(str_ENUM_CLASS_FLAGS));
PreprocessorDefines.append( get_cached_string(str_declare_log_category_extern)); PreprocessorDefines.append( get_cached_string(str_DECLARE_CLASS));
PreprocessorDefines.append( get_cached_string(str_enum_class_flags)); PreprocessorDefines.append( get_cached_string(str_DEFINE_DEFAULT_OBJECT_INITIALIZER_CONSTRUCTOR_CALL));
PreprocessorDefines.append( get_cached_string(str_declare_class)); PreprocessorDefines.append( get_cached_string(str_TEXT));
PreprocessorDefines.append( get_cached_string(str_define_default_object_initializer_constructor_call)); PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_OneParam));
// PreprocessorDefines.append( get_cached_string(str_core_object_api)); PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_TwoParams));
PreprocessorDefines.append( get_cached_string(str_macro_text)); PreprocessorDefines.append( get_cached_string(str_DECLARE_MULTICAST_DELEGATE_ThreeParams));
PreprocessorDefines.append( get_cached_string(str_declare_multicast_delegate_one_parameter)); PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_RetVal_OneParam));
PreprocessorDefines.append( get_cached_string(str_declare_multicast_delegate_two_parameter)); PreprocessorDefines.append( get_cached_string(str_DECLARE_FUNCTION));
PreprocessorDefines.append( get_cached_string(str_declare_multicast_delegate_three_parameter)); PreprocessorDefines.append( get_cached_string(str_RESULT_DECL));
PreprocessorDefines.append( get_cached_string(str_declare_delegate_retval_one_param));
PreprocessorDefines.append( get_cached_string(str_declare_function));
PreprocessorDefines.append( get_cached_string(str_result_decl));
PreprocessorDefines.append( get_cached_string(str_property_binding_implementation));
PreprocessorDefines.append( get_cached_string(str_FORCEINLINE)); PreprocessorDefines.append( get_cached_string(str_FORCEINLINE));
PreprocessorDefines.append( get_cached_string(str_UENUM)); PreprocessorDefines.append( get_cached_string(str_UENUM));
PreprocessorDefines.append( get_cached_string(str_UMETA)); PreprocessorDefines.append( get_cached_string(str_UMETA));
@ -89,7 +87,6 @@ int gen_main()
PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_SixParams)); PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_SixParams));
PreprocessorDefines.append( get_cached_string(str_DECLARE_EVENT_TwoParams)); PreprocessorDefines.append( get_cached_string(str_DECLARE_EVENT_TwoParams));
PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_RetVal_ThreeParams)); PreprocessorDefines.append( get_cached_string(str_DECLARE_DELEGATE_RetVal_ThreeParams));
// PreprocessorDefines.append( get_cached_string(str_ENGINE_API));
PreprocessorDefines.append( get_cached_string(str_PRAGMA_DISABLE_DEPRECATION_WARNINGS)); PreprocessorDefines.append( get_cached_string(str_PRAGMA_DISABLE_DEPRECATION_WARNINGS));
PreprocessorDefines.append( get_cached_string(str_PRAGMA_ENABLE_DEPRECATION_WARNINGS)); PreprocessorDefines.append( get_cached_string(str_PRAGMA_ENABLE_DEPRECATION_WARNINGS));
PreprocessorDefines.append( get_cached_string(str_DEFINE_ACTORDESC_TYPE)); PreprocessorDefines.append( get_cached_string(str_DEFINE_ACTORDESC_TYPE));
@ -97,117 +94,13 @@ int gen_main()
PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam)); PreprocessorDefines.append( get_cached_string(str_DECLARE_DYNAMIC_MULTICAST_SPARSE_DELEGATE_OneParam));
PreprocessorDefines.append( get_cached_string(str_UPARAM)); PreprocessorDefines.append( get_cached_string(str_UPARAM));
PreprocessorDefines.append( get_cached_string(str_FORCEINLINE_DEBUGGABLE)); PreprocessorDefines.append( get_cached_string(str_FORCEINLINE_DEBUGGABLE));
PreprocessorDefines.append( get_cached_string(str_DECLARE_EVENT_ThreeParams));
PreprocessorDefines.append( get_cached_string(str_USTRUCT));
PreprocessorDefines.append( get_cached_string(str_GENERATED_USTRUCT_BODY));
FileContents content; ue_parse_testing();
#define path_UProgressBar \ StrC str_gasa_api = txt("GASA_API");
"C:/projects/Unreal/Surgo/UE/Engine/Source/Runtime/UMG/Public/Components/ProgressBar.h"
#if 0
content = file_read_contents( GlobalAllocator, true, path_UProgressBar );
CodeBody parsed_uprogressbar = parse_global_body( StrC { content.size, (char const*)content.data });
log_fmt("\n\n");
for ( Code gcode : parsed_uprogressbar )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("Class %S - Definitions:\n", gcode->Name);
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
// log_fmt("%s\n", class_code->to_string() );
}
break;
}
}
}
}
#endif
#define path_UObject \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\CoreUObject\Public\UObject\Object.h)"
#if 0
content = file_read_contents( GlobalAllocator, true, path_UObject );
CodeBody parsed_uobject = parse_global_body( StrC { content.size, (char const*)content.data });
log_fmt("\n\n");
for ( Code gcode : parsed_uobject )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("Class %S - Definitions:\n", gcode->Name);
// log_fmt("%s\n", gcode->to_string() );
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Constructor:
case CodeT::Constructor_Fwd:
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
// log_fmt("%s\n", class_code->to_string() );
}
break;
}
}
}
}
#endif
#define path_AActor \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\Engine\Classes\GameFramework\Actor.h)"
#if 1
content = file_read_contents( GlobalAllocator, true, path_AActor );
CodeBody parsed_aactor = parse_global_body( StrC { content.size, (char const*)content.data });
log_fmt("\n\n");
for ( Code gcode : parsed_aactor )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("Class %S - Definitions:\n", gcode->Name);
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
}
break;
}
}
}
}
#endif
// StrC str_gasa_api = txt("GASA_API");
gen_UGasaAttributeSet(); gen_UGasaAttributeSet();
return 0; return 0;

View File

@ -0,0 +1,213 @@
void ue_parse_testing()
{
FileContents content;
#define path_UProgressBar \
"C:/projects/Unreal/Surgo/UE/Engine/Source/Runtime/UMG/Public/Components/ProgressBar.h"
#if 0
content = file_read_contents( GlobalAllocator, true, path_UProgressBar );
CodeBody parsed_uprogressbar = parse_global_body( StrC { content.size, (char const*)content.data });
log_fmt("\n\n");
for ( Code gcode : parsed_uprogressbar )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("Class %S - Definitions:\n", gcode->Name);
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
// log_fmt("%s\n", class_code->to_string() );
}
break;
}
}
}
}
#endif
#define path_UObject \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\CoreUObject\Public\UObject\Object.h)"
#if 0
content = file_read_contents( GlobalAllocator, true, path_UObject );
CodeBody parsed_uobject = parse_global_body( StrC { content.size, (char const*)content.data });
log_fmt("\n\n");
for ( Code gcode : parsed_uobject )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("Class %S - Definitions:\n", gcode->Name);
// log_fmt("%s\n", gcode->to_string() );
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Constructor:
case CodeT::Constructor_Fwd:
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
// log_fmt("%s\n", class_code->to_string() );
}
break;
}
}
}
}
#endif
#define path_AActor \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\Engine\Classes\GameFramework\Actor.h)"
#if 0
content = file_read_contents( GlobalAllocator, true, path_AActor );
CodeBody parsed_aactor = parse_global_body( StrC { content.size, (char const*)content.data });
log_fmt("\n\n");
for ( Code gcode : parsed_aactor )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("Class %S - Definitions:\n", gcode->Name);
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
}
break;
}
}
}
}
#endif
#define path_ActorComponent \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\Engine\Classes\Components\ActorComponent.h)"
#if 0
content = file_read_contents( GlobalAllocator, true, path_ActorComponent );
CodeBody parsed_actor_component = parse_global_body( StrC { content.size, (char const*)content.data });
for ( Code gcode : parsed_actor_component )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("\n\n");
log_fmt("Class %S - Definitions:\n", gcode->Name);
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
}
break;
}
}
}
}
#endif
#define path_SceneComponent \
R"(C:\projects\Unreal\Surgo\UE\Engine\Source\Runtime\Engine\Classes\Components\SceneComponent.h)"
#if 0
content = file_read_contents( GlobalAllocator, true, path_SceneComponent );
CodeBody parsed_scene_component = parse_global_body( StrC { content.size, (char const*)content.data });
for ( Code gcode : parsed_scene_component )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("\n\n");
log_fmt("Class %S - Definitions:\n", gcode->Name);
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
}
break;
}
}
}
}
#endif
#define path_AttributeSet \
R"(C:\projects\Unreal\Surgo\UE\Engine\Plugins\Runtime\GameplayAbilities\Source\GameplayAbilities\Public\AttributeSet.h)"
#if 0
content = file_read_contents( GlobalAllocator, true, path_AttributeSet );
CodeBody parsed_attribute_set = parse_global_body( StrC { content.size, (char const*)content.data });
for ( Code gcode : parsed_attribute_set )
{
if ( gcode->Type == CodeT::Class )
{
log_fmt("\n\n");
log_fmt("Class %S - Definitions:\n", gcode->Name);
if (gcode->Body->Type != CodeT::Class_Body)
continue;
for ( Code class_code : gcode->Body->cast<CodeBody>() )
{
switch ( class_code->Type )
{
case CodeT::Variable:
case CodeT::Function:
case CodeT::Function_Fwd:
if ( class_code->Name )
{
log_fmt("%s\n", class_code->Name );
}
break;
}
}
}
}
#endif
}

View File

@ -1742,6 +1742,8 @@ void CodeDestructor::to_string_fwd( String& result )
if ( ast->Specs.has( ESpecifier::Pure ) ) if ( ast->Specs.has( ESpecifier::Pure ) )
result.append( " = 0;" ); result.append( " = 0;" );
else if (ast->Body)
result.append_fmt( " = %S;", ast->Body.to_string() );
} }
else else
result.append_fmt( "~%S();", ast->Parent->Name ); result.append_fmt( "~%S();", ast->Parent->Name );
@ -1905,7 +1907,7 @@ void CodeFriend::to_string( String& result )
{ {
result.append_fmt( "friend %S", ast->Declaration->to_string() ); result.append_fmt( "friend %S", ast->Declaration->to_string() );
if ( result[ result.length() - 1 ] != ';' ) if ( ast->Declaration->Type != ECode::Function && result[ result.length() - 1 ] != ';' )
{ {
result.append( ";" ); result.append( ";" );
} }
@ -2023,7 +2025,7 @@ void CodeFn::to_string_fwd( String& result )
{ {
for ( SpecifierT spec : ast->Specs ) for ( SpecifierT spec : ast->Specs )
{ {
if ( ESpecifier::is_trailing( spec ) ) if ( ESpecifier::is_trailing( spec ) && ! spec != ESpecifier::Pure )
{ {
StrC spec_str = ESpecifier::to_str( spec ); StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
@ -2031,6 +2033,11 @@ void CodeFn::to_string_fwd( String& result )
} }
} }
if ( ast->Specs.has( ESpecifier::Pure ) )
result.append( " = 0;" );
else if (ast->Body)
result.append_fmt( " = %S;", ast->Body.to_string() );
if ( ast->InlineCmt ) if ( ast->InlineCmt )
result.append_fmt( "; %S", ast->InlineCmt->Content ); result.append_fmt( "; %S", ast->InlineCmt->Content );
else else
@ -3408,7 +3415,6 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
case Unary_Plus : case Unary_Plus :
case Unary_Minus : case Unary_Minus :
case BNot :
if ( ! params_code ) if ( ! params_code )
is_member_symbol = true; is_member_symbol = true;
@ -3444,6 +3450,38 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
} }
} }
break; break;
case BNot:
{
// Some compilers let you do this...
// if ( ! ret_type.is_equal( t_bool) )
// {
// log_failure( "gen::def_operator: return type is not a boolean - %s", params_code.debug_str() );
// return OpValidateResult::Fail;
// }
if ( ! params_code )
is_member_symbol = true;
else
{
if ( params_code->Type != ECode::Parameters )
{
log_failure( "gen::def_operator: params is not of Parameters type - %s", params_code.debug_str() );
return OpValidateResult::Fail;
}
if ( params_code->NumEntries > 1 )
{
log_failure(
"gen::def_operator: operator%s may not have more than one parameter - param count: %d",
to_str( op ),
params_code->NumEntries
);
return OpValidateResult::Fail;
}
}
break;
}
case Add : case Add :
case Subtract : case Subtract :
@ -3578,6 +3616,11 @@ OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeTy
case Comma : case Comma :
check_params(); check_params();
break; break;
case New:
case Delete:
// This library doesn't support validating new and delete yet.
break;
#undef specs #undef specs
} }
@ -5611,7 +5654,8 @@ namespace parser
Entry( UMG_API, "UMG_API" ) \ Entry( UMG_API, "UMG_API" ) \
Entry( COREUOBJECT_API, "COREUOBJECT_API" ) \ Entry( COREUOBJECT_API, "COREUOBJECT_API" ) \
Entry( ENGINE_API, "ENGINE_API" ) \ Entry( ENGINE_API, "ENGINE_API" ) \
Entry( GASA_API, "GASA_API" ) Entry( GASA_API, "GASA_API" ) \
Entry( GAMEPLAYABILITIES_API, "GAMEPLAYABILITIES_API" )
enum Type : u32 enum Type : u32
{ {
@ -5717,6 +5761,7 @@ namespace parser
COREUOBJECT_API, COREUOBJECT_API,
ENGINE_API, ENGINE_API,
GASA_API, GASA_API,
GAMEPLAYABILITIES_API,
NumTokens NumTokens
}; };
@ -5825,6 +5870,7 @@ namespace parser
{ sizeof( "COREUOBJECT_API" ), "COREUOBJECT_API" }, { sizeof( "COREUOBJECT_API" ), "COREUOBJECT_API" },
{ sizeof( "ENGINE_API" ), "ENGINE_API" }, { sizeof( "ENGINE_API" ), "ENGINE_API" },
{ sizeof( "GASA_API" ), "GASA_API" }, { sizeof( "GASA_API" ), "GASA_API" },
{ sizeof( "GAMEPLAYABILITIES_API" ), "GAMEPLAYABILITIES_API" },
}; };
return lookup[ type ]; return lookup[ type ];
} }
@ -5992,7 +6038,7 @@ namespace parser
while ( Arr[ idx ].Type == TokType::NewLine ) while ( Arr[ idx ].Type == TokType::NewLine )
idx++; idx++;
return Arr[ idx ]; return Arr[ idx + 1 ];
} }
return Arr[ idx + 1 ]; return Arr[ idx + 1 ];
@ -8360,7 +8406,6 @@ namespace parser
if ( tok.Type == TokType::Identifier ) if ( tok.Type == TokType::Identifier )
{ {
tok = tokens[ idx - 2 ]; tok = tokens[ idx - 2 ];
bool is_indirection = tok.Type == TokType::Ampersand || tok.Type == TokType::Star; bool is_indirection = tok.Type == TokType::Ampersand || tok.Type == TokType::Star;
bool ok_to_parse = false; bool ok_to_parse = false;
@ -8378,10 +8423,12 @@ namespace parser
ok_to_parse = true; ok_to_parse = true;
} }
else if ( tok.Type == TokType::Assign_Classifer else if ( tok.Type == TokType::Assign_Classifer
&& tokens[idx - 4].Type == TokType::Decl_Class && ( ( tokens[idx - 5].Type == which && tokens[idx - 4].Type == TokType::Decl_Class )
&& tokens[idx - 5].Type == which ) || ( tokens[idx - 4].Type == which))
)
{ {
// Its a forward declaration of an enum class // Its a forward declaration of an enum
// <enum> <type_identifier> : <identifier>;
// <enum> <class> <type_identifier> : <identifier>; // <enum> <class> <type_identifier> : <identifier>;
ok_to_parse = true; ok_to_parse = true;
Code result = parse_enum(); Code result = parse_enum();
@ -8407,6 +8454,27 @@ namespace parser
Context.pop(); Context.pop();
return result; return result;
} }
else if ( tok.Type >= TokType::Type_Unsigned && tok.Type <= TokType::Type_MS_W64 )
{
tok = tokens[ idx - 2 ];
if ( tok.Type != TokType::Assign_Classifer
|| ( ( tokens[idx - 5].Type != which && tokens[idx - 4].Type != TokType::Decl_Class )
&& ( tokens[idx - 4].Type != which))
)
{
log_failure( "Unsupported or bad member definition after %s declaration\n%s", to_str(which), Context.to_string() );
Context.pop();
return CodeInvalid;
}
// Its a forward declaration of an enum class
// <enum> <type_identifier> : <identifier>;
// <enum> <class> <type_identifier> : <identifier>;
Code result = parse_enum();
Context.pop();
return result;
}
else if ( tok.Type == TokType::BraceCurly_Close ) else if ( tok.Type == TokType::BraceCurly_Close )
{ {
// Its a definition // Its a definition
@ -8580,6 +8648,20 @@ namespace parser
} }
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> { <Body> } // <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> { <Body> }
} }
else if ( check(TokType::Operator) && currtok.Text[0] == '=' )
{
eat(TokType::Operator);
specifiers.append( ESpecifier::Pure );
eat( TokType::Number);
Token stmt_end = currtok;
eat( TokType::Statement_End );
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> = 0;
if ( currtok_noskip.Type == TokType::Comment && currtok_noskip.Line == stmt_end.Line )
inline_cmt = parse_comment();
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers>; <InlineCmt>
}
else else
{ {
Token stmt_end = currtok; Token stmt_end = currtok;
@ -9111,6 +9193,8 @@ namespace parser
Context.Scope->Name = currtok; Context.Scope->Name = currtok;
bool was_new_or_delete = false;
OperatorT op = Invalid; OperatorT op = Invalid;
switch ( currtok.Text[ 0 ] ) switch ( currtok.Text[ 0 ] )
{ {
@ -9301,17 +9385,70 @@ namespace parser
break; break;
default : default :
{ {
break; StrC str_new = to_str(OperatorT::New);
} StrC str_delete = to_str(OperatorT::Delete);
} if ( str_compare( currtok.Text, str_new.Ptr, max(str_new.Len - 1, currtok.Length)) == 0)
{
op = OperatorT::New;
eat( ETokType::Identifier );
was_new_or_delete = true;
s32 idx = Context.Tokens.Idx + 1;
{
while ( Context.Tokens[ idx ].Type == TokType::NewLine )
idx++;
}
Token next = Context.Tokens[idx];
if ( currtok.Type == TokType::Operator && str_compare(currtok.Text, "[]", 2) == 0)
{
eat(ETokType::Operator);
op = OperatorT::NewArray;
}
else if ( currtok.Type == TokType::BraceSquare_Open && next.Type == TokType::BraceSquare_Close)
{
eat(ETokType::BraceSquare_Open);
eat(ETokType::BraceSquare_Close);
op = OperatorT::NewArray;
}
}
else if ( str_compare( currtok.Text, str_delete.Ptr, max(str_delete.Len - 1, currtok.Length )) == 0)
{
op = OperatorT::Delete;
eat(ETokType::Identifier);
was_new_or_delete = true;
s32 idx = Context.Tokens.Idx + 1;
{
while ( Context.Tokens[ idx ].Type == TokType::NewLine )
idx++;
}
Token next = Context.Tokens[idx];
if ( currtok.Type == TokType::Operator && str_compare(currtok.Text, "[]", 2) == 0)
{
eat(ETokType::Operator);
op = OperatorT::DeleteArray;
}
else if ( currtok.Type == TokType::BraceSquare_Open && next.Type == TokType::BraceSquare_Close)
{
eat(ETokType::BraceSquare_Open);
eat(ETokType::BraceSquare_Close);
op = OperatorT::DeleteArray;
}
}
else
{
if ( op == Invalid ) if ( op == Invalid )
{ {
log_failure( "Invalid operator '%s'\n%s", currtok.Text, Context.to_string() ); log_failure( "Invalid operator '%s'\n%s", prevtok.Text, Context.to_string() );
Context.pop(); Context.pop();
return CodeInvalid; return CodeInvalid;
} }
}
}
break;
}
if ( ! was_new_or_delete)
eat( currtok.Type ); eat( currtok.Type );
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> // <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op>
@ -10288,19 +10425,26 @@ namespace parser
if ( check( TokType::Operator ) && currtok.Text[ 0 ] == '=' ) if ( check( TokType::Operator ) && currtok.Text[ 0 ] == '=' )
{ {
eat( TokType::Operator );
// <Virtual Specifier> ~<Name>() = // <Virtual Specifier> ~<Name>() =
if ( left && currtok.Text[ 0 ] == '0' ) bool skip_formatting = true;
Token next = Context.Tokens.next(skip_formatting);
if ( left && next.Text[ 0 ] == '0' )
{ {
eat( TokType::Operator );
eat( TokType::Number ); eat( TokType::Number );
// <Virtual Specifier> ~<Name>() = 0 // <Virtual Specifier> ~<Name>() = 0
specifiers.append( ESpecifier::Pure ); specifiers.append( ESpecifier::Pure );
} }
else if ( left && str_compare( next.Text, "default", sizeof("default") - 1 ) == 0)
{
body = parse_assignment_expression();
// <Virtual Specifier> ~<
}
else else
{ {
log_failure( "Pure specifier expected due to '=' token\n%s", Context.to_string() ); log_failure( "Pure or default specifier expected due to '=' token\n%s", Context.to_string() );
return CodeInvalid; return CodeInvalid;
} }
@ -10326,7 +10470,7 @@ namespace parser
if ( specifiers ) if ( specifiers )
result->Specs = specifiers; result->Specs = specifiers;
if ( body ) if ( body && body->Type == ECode::Function_Body )
{ {
result->Body = body; result->Body = body;
result->Type = ECode::Destructor; result->Type = ECode::Destructor;
@ -10640,36 +10784,40 @@ namespace parser
Context.Scope->Name = name; Context.Scope->Name = name;
// friend <ReturnType> <Name> // friend <ReturnType> <Name>
function = parse_function_after_name( ModuleFlag::None, NoCode, NoCode, type, name );
// Parameter list // Parameter list
CodeParam params = parse_params(); // CodeParam params = parse_params();
// friend <ReturnType> <Name> ( <Parameters> ) // friend <ReturnType> <Name> ( <Parameters> )
function = make_code(); // function = make_code();
function->Type = Function_Fwd; // function->Type = Function_Fwd;
function->Name = get_cached_string( name ); // function->Name = get_cached_string( name );
function->ReturnType = type; // function->ReturnType = type;
if ( params ) // if ( params )
function->Params = params; // function->Params = params;
} }
CodeComment inline_cmt = NoCode;
if ( function && function->Type == ECode::Function_Fwd )
{
Token stmt_end = currtok; Token stmt_end = currtok;
eat( TokType::Statement_End ); eat( TokType::Statement_End );
// friend <Type>; // friend <Type>;
// friend <ReturnType> <Name> ( <Parameters> ); // friend <ReturnType> <Name> ( <Parameters> );
CodeComment inline_cmt = NoCode;
if ( currtok_noskip.Type == TokType::Comment && currtok_noskip.Line == stmt_end.Line ) if ( currtok_noskip.Type == TokType::Comment && currtok_noskip.Line == stmt_end.Line )
inline_cmt = parse_comment(); inline_cmt = parse_comment();
// friend <Type>; <InlineCmt> // friend <Type>; <InlineCmt>
// friend <ReturnType> <Name> ( <Parameters> ); <InlineCmt> // friend <ReturnType> <Name> ( <Parameters> ); <InlineCmt>
}
CodeFriend result = ( CodeFriend )make_code(); CodeFriend result = ( CodeFriend )make_code();
result->Type = Friend; result->Type = Friend;
if ( function ) if ( function )
result->Declaration = function; result->Declaration = function;
else else
result->Declaration = type; result->Declaration = type;

View File

@ -339,6 +339,10 @@ namespace EOperator
PtrToMemOfPtr, PtrToMemOfPtr,
FunctionCall, FunctionCall,
Comma, Comma,
New,
NewArray,
Delete,
DeleteArray,
NumOps NumOps
}; };
@ -388,6 +392,10 @@ namespace EOperator
{ sizeof( "->*" ), "->*" }, { sizeof( "->*" ), "->*" },
{ sizeof( "()" ), "()" }, { sizeof( "()" ), "()" },
{ sizeof( "," ), "," }, { sizeof( "," ), "," },
{ sizeof( "new" ), "new" },
{ sizeof( "new[]" ), "new[]" },
{ sizeof( "delete" ), "delete" },
{ sizeof( "delete[]" ), "delete[]" },
}; };
return lookup[ op ]; return lookup[ op ];
} }
@ -822,7 +830,7 @@ struct AST
union union
{ {
AST* ArrExpr; // Typename AST* ArrExpr; // Typename
AST* Body; // Class, Constructr, Destructor, Enum, Function, Namespace, Struct, Union AST* Body; // Class, Constructr, Destructor, Enum, Friend, Function, Namespace, Struct, Union
AST* Declaration; // Friend, Template AST* Declaration; // Friend, Template
AST* Value; // Parameter, Variable AST* Value; // Parameter, Variable
}; };
@ -902,7 +910,7 @@ struct AST_POD
union union
{ {
AST* ArrExpr; // Typename AST* ArrExpr; // Typename
AST* Body; // Class, Constructr, Destructor, Enum, Function, Namespace, Struct, Union AST* Body; // Class, Constructr, Destructor, Enum, Friend, Function, Namespace, Struct, Union
AST* Declaration; // Friend, Template AST* Declaration; // Friend, Template
AST* Value; // Parameter, Variable AST* Value; // Parameter, Variable
}; };