Looking into what the library's convention for enums will be.

Most likely will just reduce them to C-enums with underlying type.
Otherwise there has to be a mechanism to drop the defs down to them anyways, and eliminate the namespace wraps.
This commit is contained in:
Edward R. Gonzalez 2024-12-01 05:30:37 -05:00
parent e5acac1d18
commit ed0c0422ad
15 changed files with 195 additions and 128 deletions

View File

@ -39,7 +39,8 @@
"raylib.h": "c", "raylib.h": "c",
"*.m": "cpp", "*.m": "cpp",
"atomic": "cpp", "atomic": "cpp",
"gen.h": "c" "gen.h": "c",
"string_ops.hpp": "c"
}, },
"C_Cpp.intelliSenseEngineFallback": "disabled", "C_Cpp.intelliSenseEngineFallback": "disabled",
"mesonbuild.configureOnOpen": true, "mesonbuild.configureOnOpen": true,

View File

@ -1,6 +1,7 @@
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 1
#include "../project/gen.cpp" #include "../project/gen.cpp"
#include "helpers/push_ignores.inline.hpp" #include "helpers/push_ignores.inline.hpp"

View File

@ -1,6 +1,7 @@
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#define GEN_ENFORCE_STRONG_CODE_TYPES #define GEN_ENFORCE_STRONG_CODE_TYPES
#define GEN_EXPOSE_BACKEND #define GEN_EXPOSE_BACKEND
#define GEN_SUPPORT_CPP_MEMBER_FEATURES 0
#include "gen.cpp" #include "gen.cpp"
#include "helpers/push_ignores.inline.hpp" #include "helpers/push_ignores.inline.hpp"

View File

@ -377,6 +377,7 @@ struct AST
AccessSpec ParentAccess; AccessSpec ParentAccess;
s32 NumEntries; s32 NumEntries;
s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression. s32 VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
b32 EnumUnderlyingMacro; // Used by enums incase the user wants to wrap underlying type specification in a macro
}; };
}; };

View File

@ -174,7 +174,7 @@ struct AST_Enum
CodeAttributes Attributes; CodeAttributes Attributes;
char _PAD_SPEC_ [ sizeof(AST*) ]; char _PAD_SPEC_ [ sizeof(AST*) ];
CodeType UnderlyingType; CodeType UnderlyingType;
char _PAD_PARAMS_[ sizeof(AST*) ]; Code UnderlyingTypeMacro;
CodeBody Body; CodeBody Body;
char _PAD_PROPERTIES_2_[ sizeof(AST*) ]; char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
}; };
@ -186,7 +186,7 @@ struct AST_Enum
StringCached Name; StringCached Name;
CodeT Type; CodeT Type;
ModuleFlag ModuleFlags; ModuleFlag ModuleFlags;
char _PAD_UNUSED_[ sizeof(u32) ]; b32 EnumUnderlyingMacro;
}; };
static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST"); static_assert( sizeof(AST_Enum) == sizeof(AST), "ERROR: AST_Enum is not the same size as AST");

View File

@ -160,7 +160,7 @@ String CodeClass::to_string()
void CodeClass::to_string_def( String& result ) void CodeClass::to_string_def( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
append( result, "class " ); append( result, "class " );
@ -204,7 +204,7 @@ void CodeClass::to_string_def( String& result )
void CodeClass::to_string_fwd( String& result ) void CodeClass::to_string_fwd( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes ) if ( ast->Attributes )
@ -314,7 +314,7 @@ String CodeEnum::to_string()
void CodeEnum::to_string_def( String& result ) void CodeEnum::to_string_def( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes || ast->UnderlyingType ) if ( ast->Attributes || ast->UnderlyingType )
@ -330,6 +330,12 @@ void CodeEnum::to_string_def( String& result )
, ast->UnderlyingType.to_string() , ast->UnderlyingType.to_string()
, ast->Body.to_string() , ast->Body.to_string()
); );
else if ( ast->UnderlyingTypeMacro )
append_fmt( result, "%S : %S\n{\n%S\n}"
, ast->Name
, ast->UnderlyingTypeMacro.to_string()
, ast->Body.to_string()
);
else append_fmt( result, "%S\n{\n%S\n}", ast->Name, ast->Body.to_string() ); else append_fmt( result, "%S\n{\n%S\n}", ast->Name, ast->Body.to_string() );
} }
@ -341,7 +347,7 @@ void CodeEnum::to_string_def( String& result )
void CodeEnum::to_string_fwd( String& result ) void CodeEnum::to_string_fwd( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes ) if ( ast->Attributes )
@ -360,7 +366,7 @@ void CodeEnum::to_string_fwd( String& result )
void CodeEnum::to_string_class_def( String& result ) void CodeEnum::to_string_class_def( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes || ast->UnderlyingType ) if ( ast->Attributes || ast->UnderlyingType )
@ -392,7 +398,7 @@ void CodeEnum::to_string_class_def( String& result )
void CodeEnum::to_string_class_fwd( String& result ) void CodeEnum::to_string_class_fwd( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
append( result, "enum class " ); append( result, "enum class " );
@ -474,7 +480,7 @@ String CodeFn::to_string()
void CodeFn::to_string_def( String& result ) void CodeFn::to_string_def( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export" ); append( result, "export" );
if ( ast->Attributes ) if ( ast->Attributes )
@ -527,7 +533,7 @@ void CodeFn::to_string_def( String& result )
void CodeFn::to_string_fwd( String& result ) void CodeFn::to_string_fwd( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes ) if ( ast->Attributes )
@ -597,10 +603,10 @@ String CodeModule::to_string()
void CodeModule::to_string( String& result ) void CodeModule::to_string( String& result )
{ {
if (((u32(ModuleFlag::Export) & u32(ast->ModuleFlags)) == u32(ModuleFlag::Export))) if (((u32(ModuleFlag_Export) & u32(ast->ModuleFlags)) == u32(ModuleFlag_Export)))
append( result, "export "); append( result, "export ");
if (((u32(ModuleFlag::Import) & u32(ast->ModuleFlags)) == u32(ModuleFlag::Import))) if (((u32(ModuleFlag_Import) & u32(ast->ModuleFlags)) == u32(ModuleFlag_Import)))
append( result, "import "); append( result, "import ");
append_fmt( result, "%S;\n", ast->Name ); append_fmt( result, "%S;\n", ast->Name );
@ -615,7 +621,7 @@ String CodeNS::to_string()
void CodeNS::to_string( String& result ) void CodeNS::to_string( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
append_fmt( result, "namespace %S\n{\n%S\n}\n", ast->Name , ast->Body.to_string() ); append_fmt( result, "namespace %S\n{\n%S\n}\n", ast->Name , ast->Body.to_string() );
@ -641,7 +647,7 @@ String CodeOperator::to_string()
void CodeOperator::to_string_def( String& result ) void CodeOperator::to_string_def( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes ) if ( ast->Attributes )
@ -695,7 +701,7 @@ void CodeOperator::to_string_def( String& result )
void CodeOperator::to_string_fwd( String& result ) void CodeOperator::to_string_fwd( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes ) if ( ast->Attributes )
@ -985,7 +991,7 @@ String CodeStruct::to_string()
void CodeStruct::to_string_def( String& result ) void CodeStruct::to_string_def( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
append( result, "struct " ); append( result, "struct " );
@ -1029,7 +1035,7 @@ void CodeStruct::to_string_def( String& result )
void CodeStruct::to_string_fwd( String& result ) void CodeStruct::to_string_fwd( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes ) if ( ast->Attributes )
@ -1055,7 +1061,7 @@ String CodeTemplate::to_string()
void CodeTemplate::to_string( String& result ) void CodeTemplate::to_string( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Params ) if ( ast->Params )
@ -1073,7 +1079,7 @@ String CodeTypedef::to_string()
void CodeTypedef::to_string( String& result ) void CodeTypedef::to_string( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
append( result, "typedef "); append( result, "typedef ");
@ -1168,7 +1174,7 @@ String CodeUnion::to_string()
void CodeUnion::to_string( String& result ) void CodeUnion::to_string( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
append( result, "union " ); append( result, "union " );
@ -1213,7 +1219,7 @@ String CodeUsing::to_string()
void CodeUsing::to_string( String& result ) void CodeUsing::to_string( String& result )
{ {
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes ) if ( ast->Attributes )
@ -1302,7 +1308,7 @@ void CodeVar::to_string( String& result )
return; return;
} }
if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag::Export )) if ( bitfield_is_equal( u32, ast->ModuleFlags, ModuleFlag_Export ))
append( result, "export " ); append( result, "export " );
if ( ast->Attributes || ast->Specs ) if ( ast->Attributes || ast->Specs )

View File

@ -78,7 +78,7 @@ void CodeClass::add_interface( CodeType type )
if ( possible_slot.ast ) if ( possible_slot.ast )
{ {
// Were adding an interface to parent type, so we need to make sure the parent type is public. // Were adding an interface to parent type, so we need to make sure the parent type is public.
ast->ParentAccess = AccessSpec::Public; ast->ParentAccess = AccessSpec_Public;
// If your planning on adding a proper parent, // If your planning on adding a proper parent,
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly. // then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
} }
@ -151,7 +151,7 @@ void CodeStruct::add_interface( CodeType type )
if ( possible_slot.ast ) if ( possible_slot.ast )
{ {
// Were adding an interface to parent type, so we need to make sure the parent type is public. // Were adding an interface to parent type, so we need to make sure the parent type is public.
ast->ParentAccess = AccessSpec::Public; ast->ParentAccess = AccessSpec_Public;
// If your planning on adding a proper parent, // If your planning on adding a proper parent,
// then you'll need to move this over to ParentType->next and update ParentAccess accordingly. // then you'll need to move this over to ParentType->next and update ParentAccess accordingly.
} }

View File

@ -83,17 +83,17 @@ void define_constants()
t_empty = (CodeType) make_code(); t_empty = (CodeType) make_code();
t_empty->Type = ECode::Typename; t_empty->Type = ECode::Typename;
scast(String, t_empty->Name) = get_cached_string( txt("") ); t_empty->Name = get_cached_string( txt("") );
t_empty.set_global(); t_empty.set_global();
access_private = make_code(); access_private = make_code();
access_private->Type = ECode::Access_Private; access_private->Type = ECode::Access_Private;
scast(String, access_private->Name) = get_cached_string( txt("private:\n") ); access_private->Name = get_cached_string( txt("private:\n") );
access_private.set_global(); access_private.set_global();
access_protected = make_code(); access_protected = make_code();
access_protected->Type = ECode::Access_Protected; access_protected->Type = ECode::Access_Protected;
scast(String, access_protected->Name) = get_cached_string( txt("protected:\n") ); access_protected->Name = get_cached_string( txt("protected:\n") );
access_protected.set_global(); access_protected.set_global();
access_public = make_code(); access_public = make_code();
@ -226,6 +226,10 @@ void define_constants()
# pragma pop_macro("local_persist") # pragma pop_macro("local_persist")
# pragma pop_macro("neverinline") # pragma pop_macro("neverinline")
# pragma push_macro("enum_underlying")
# pragma pop_macro("enum_underlying")
# undef def_constant_spec # undef def_constant_spec
} }

View File

@ -44,9 +44,9 @@ CodeComment def_comment ( StrC content );
CodeClass def_class( StrC name CodeClass def_class( StrC name
, Code body = NoCode , Code body = NoCode
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default , CodeType parent = NoCode, AccessSpec access = AccessSpec_Default
, CodeAttributes attributes = NoCode , CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None , ModuleFlag mflags = ModuleFlag_None
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 ); , CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
CodeConstructor def_constructor( CodeParam params = NoCode, Code initializer_list = NoCode, Code body = NoCode ); CodeConstructor def_constructor( CodeParam params = NoCode, Code initializer_list = NoCode, Code body = NoCode );
@ -57,8 +57,8 @@ CodeDestructor def_destructor( Code body = NoCode, CodeSpecifiers specifiers = N
CodeEnum def_enum( StrC name CodeEnum def_enum( StrC name
, Code body = NoCode, CodeType type = NoCode , Code body = NoCode, CodeType type = NoCode
, EnumT specifier = EnumRegular, CodeAttributes attributes = NoCode , EnumT specifier = EnumDecl_Regular, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag_None );
CodeExec def_execution ( StrC content ); CodeExec def_execution ( StrC content );
CodeExtern def_extern_link( StrC name, Code body ); CodeExtern def_extern_link( StrC name, Code body );
@ -67,16 +67,16 @@ CodeFriend def_friend ( Code symbol );
CodeFn def_function( StrC name CodeFn def_function( StrC name
, CodeParam 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 , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag_None );
CodeInclude def_include ( StrC content, bool foreign = false ); CodeInclude def_include ( StrC content, bool foreign = false );
CodeModule def_module ( StrC name, ModuleFlag mflags = ModuleFlag::None ); CodeModule def_module ( StrC name, ModuleFlag mflags = ModuleFlag_None );
CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag::None ); CodeNS def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFlag_None );
CodeOperator def_operator( OperatorT op, StrC nspace CodeOperator def_operator( OperatorT op, StrC nspace
, CodeParam 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 , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag_None );
CodeOpCast def_operator_cast( CodeType type, Code body = NoCode, CodeSpecifiers specs = NoCode ); CodeOpCast def_operator_cast( CodeType type, Code body = NoCode, CodeSpecifiers specs = NoCode );
@ -89,27 +89,27 @@ CodeSpecifiers def_specifier( SpecifierT specifier );
CodeStruct def_struct( StrC name CodeStruct def_struct( StrC name
, Code body = NoCode , Code body = NoCode
, CodeType parent = NoCode, AccessSpec access = AccessSpec::Default , CodeType parent = NoCode, AccessSpec access = AccessSpec_Default
, CodeAttributes attributes = NoCode , CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None , ModuleFlag mflags = ModuleFlag_None
, CodeType* interfaces = nullptr, s32 num_interfaces = 0 ); , CodeType* interfaces = nullptr, s32 num_interfaces = 0 );
CodeTemplate def_template( CodeParam 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 ); CodeType def_type ( StrC name, Code arrayexpr = NoCode, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode );
CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); CodeTypedef def_typedef( StrC name, Code type, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag_None );
CodeUnion def_union( StrC name, Code body, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag::None ); CodeUnion def_union( StrC name, Code body, CodeAttributes attributes = NoCode, ModuleFlag mflags = ModuleFlag_None );
CodeUsing def_using( StrC name, CodeType type = NoCode CodeUsing def_using( StrC name, CodeType type = NoCode
, CodeAttributes attributess = NoCode , CodeAttributes attributess = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag_None );
CodeUsing def_using_namespace( StrC name ); CodeUsing def_using_namespace( StrC name );
CodeVar def_variable( CodeType type, StrC name, Code value = NoCode CodeVar def_variable( CodeType type, StrC name, Code value = NoCode
, CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag_None );
// Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries. // Constructs an empty body. Use AST::validate_body() to check if the body is was has valid entries.
CodeBody def_body( CodeT type ); CodeBody def_body( CodeT type );

View File

@ -719,14 +719,14 @@ CodeEnum def_enum( StrC name
return CodeInvalid; return CodeInvalid;
} }
result->Type = specifier == EnumClass ? result->Type = specifier == EnumDecl_Class ?
Enum_Class : Enum; Enum_Class : Enum;
result->Body = body; result->Body = body;
} }
else else
{ {
result->Type = specifier == EnumClass ? result->Type = specifier == EnumDecl_Class ?
Enum_Class_Fwd : Enum_Fwd; Enum_Class_Fwd : Enum_Fwd;
} }
@ -1145,16 +1145,16 @@ CodePreprocessCond def_preprocess_cond( EPreprocessCond type, StrC expr )
switch (type) switch (type)
{ {
case EPreprocessCond::If: case PreprocessCond_If:
result->Type = Preprocess_If; result->Type = Preprocess_If;
break; break;
case EPreprocessCond::IfDef: case PreprocessCond_IfDef:
result->Type = Preprocess_IfDef; result->Type = Preprocess_IfDef;
break; break;
case EPreprocessCond::IfNotDef: case PreprocessCond_IfNotDef:
result->Type = Preprocess_IfNotDef; result->Type = Preprocess_IfNotDef;
break; break;
case EPreprocessCond::ElIf: case PreprocessCond_ElIf:
result->Type = Preprocess_ElIf; result->Type = Preprocess_ElIf;
break; break;
} }

View File

@ -682,17 +682,17 @@ Code parse_class_struct( TokType which, bool inplace_def = false )
Token name { nullptr, 0, TokType::Invalid }; Token name { nullptr, 0, TokType::Invalid };
AccessSpec access = AccessSpec::Default; AccessSpec access = AccessSpec_Default;
CodeType parent = { nullptr }; CodeType parent = { nullptr };
CodeBody body = { nullptr }; CodeBody body = { nullptr };
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
CodeClass result = CodeInvalid; CodeClass result = CodeInvalid;
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <ModuleFlags> // <ModuleFlags>
@ -2534,7 +2534,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
if ( found_operator ) if ( found_operator )
{ {
// Dealing with an operator overload // Dealing with an operator overload
result = parse_operator_after_ret_type( ModuleFlag::None, attributes, specifiers, type ); result = parse_operator_after_ret_type( ModuleFlag_None, attributes, specifiers, type );
// <Attributes> <Specifiers> <ReturnType> operator ... // <Attributes> <Specifiers> <ReturnType> operator ...
} }
else else
@ -2552,7 +2552,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
if ( detected_capture && ! detected_comma ) if ( detected_capture && ! detected_comma )
{ {
// Dealing with a function // Dealing with a function
result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name ); result = parse_function_after_name( ModuleFlag_None, attributes, specifiers, type, name );
// <Attributes> <Specifiers> <ReturnType> <Name> ( ... // <Attributes> <Specifiers> <ReturnType> <Name> ( ...
} }
else else
@ -2565,7 +2565,7 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
} }
// Dealing with a variable // Dealing with a variable
result = parse_variable_after_name( ModuleFlag::None, attributes, specifiers, type, name ); result = parse_variable_after_name( ModuleFlag_None, attributes, specifiers, type, name );
// <Attributes> <Specifiers> <ValueType> <Name> ... // <Attributes> <Specifiers> <ValueType> <Name> ...
} }
} }
@ -3319,7 +3319,7 @@ CodeVar parse_variable_declaration_list()
eat( TokType::Identifier ); eat( TokType::Identifier );
// , <Specifiers> <Name> // , <Specifiers> <Name>
CodeVar var = parse_variable_after_name( ModuleFlag::None, NoCode, specifiers, NoCode, name ); CodeVar var = parse_variable_after_name( ModuleFlag_None, NoCode, specifiers, NoCode, name );
// , <Specifiers> <Name> ... // , <Specifiers> <Name> ...
if ( ! result ) if ( ! result )
@ -3589,6 +3589,8 @@ CodeEnum parse_enum( bool inplace_def )
} }
// enum <class> <Attributes> <Name> // enum <class> <Attributes> <Name>
b32 use_macro_underlying = false;
Code underlying_macro = { nullptr };
if ( currtok.Type == TokType::Assign_Classifer ) if ( currtok.Type == TokType::Assign_Classifer )
{ {
eat( TokType::Assign_Classifer ); eat( TokType::Assign_Classifer );
@ -3603,6 +3605,17 @@ CodeEnum parse_enum( bool inplace_def )
} }
// enum <class> <Attributes> <Name> : <UnderlyingType> // enum <class> <Attributes> <Name> : <UnderlyingType>
} }
else if ( currtok.Type == TokType::Preprocess_Define )
{
// We'll support the enum_underlying macro
StrC sig = txt("enum_underlying");
if (currtok.Length >= sig.Len && str_compare(currtok.Text, sig.Ptr, sig.Len) == 0 )
{
use_macro_underlying = true;
underlying_macro = parse_simple_preprocess( ETokType::Preprocess_Macro);
}
}
CodeBody body = { nullptr }; CodeBody body = { nullptr };
@ -3770,11 +3783,18 @@ CodeEnum parse_enum( bool inplace_def )
result->Attributes = attributes; result->Attributes = attributes;
if ( type ) if ( type )
{
result->EnumUnderlyingMacro = use_macro_underlying;
if ( use_macro_underlying )
result->UnderlyingTypeMacro = underlying_macro;
else
result->UnderlyingType = type; result->UnderlyingType = type;
}
if ( inline_cmt ) if ( inline_cmt )
result->InlineCmt = inline_cmt; result->InlineCmt = inline_cmt;
Context.pop(); Context.pop();
return result; return result;
} }
@ -3860,7 +3880,7 @@ CodeFriend parse_friend()
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 ); function = parse_function_after_name( ModuleFlag_None, NoCode, NoCode, type, name );
// Parameter list // Parameter list
// CodeParam params = parse_params(); // CodeParam params = parse_params();
@ -3914,11 +3934,11 @@ CodeFn parse_function()
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifiers specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <export> // <export>
@ -4024,14 +4044,14 @@ CodeOperator parse_operator()
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifiers specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
s32 NumSpecifiers = 0; s32 NumSpecifiers = 0;
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <export> // <export>
@ -4212,11 +4232,11 @@ CodeTemplate parse_template()
push_scope(); push_scope();
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
if ( check( TokType::Module_Export ) ) if ( check( TokType::Module_Export ) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <export> template // <export> template
@ -4855,11 +4875,11 @@ CodeTypedef parse_typedef()
Code array_expr = { nullptr }; Code array_expr = { nullptr };
Code type = { nullptr }; Code type = { nullptr };
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <ModuleFlags> // <ModuleFlags>
@ -5050,11 +5070,11 @@ CodeUnion parse_union( bool inplace_def )
{ {
push_scope(); push_scope();
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <ModuleFlags> // <ModuleFlags>
@ -5199,12 +5219,12 @@ CodeUsing parse_using()
bool is_namespace = false; bool is_namespace = false;
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <ModuleFlags> // <ModuleFlags>
@ -5293,13 +5313,13 @@ CodeVar parse_variable()
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
s32 NumSpecifiers = 0; s32 NumSpecifiers = 0;
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag_None;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifiers specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {
mflags = ModuleFlag::Export; mflags = ModuleFlag_Export;
eat( TokType::Module_Export ); eat( TokType::Module_Export );
} }
// <ModuleFlags> // <ModuleFlags>

View File

@ -13,63 +13,71 @@ using LogFailType = ssize(*)(char const*, ...);
#define log_failure GEN_FATAL #define log_failure GEN_FATAL
#endif #endif
enum class AccessSpec : u32 enum AccessSpec enum_underlying(u32)
{ {
Default, AccessSpec_Default,
Private, AccessSpec_Private,
Protected, AccessSpec_Protected,
Public, AccessSpec_Public,
Num_AccessSpec, AccessSpec_Num_AccessSpec,
Invalid, AccessSpec_Invalid,
AccessSpec_SizeDef = GEN_U32_MAX,
}; };
static_assert( size_of(AccessSpec) == size_of(u32));
inline inline
char const* to_str( AccessSpec type ) char const* to_str( AccessSpec type )
{ {
local_persist local_persist
char const* lookup[ (u32)AccessSpec::Num_AccessSpec ] = { char const* lookup[ (u32)AccessSpec_Num_AccessSpec ] = {
"", "",
"private", "private",
"protected", "protected",
"public", "public",
}; };
if ( type > AccessSpec::Public ) if ( type > AccessSpec_Public )
return "Invalid"; return "Invalid";
return lookup[ (u32)type ]; return lookup[ (u32)type ];
} }
enum CodeFlag enum_underlying(u32)
enum CodeFlag : u32
{ {
None = 0, CodeFlag_None = 0,
FunctionType = bit(0), CodeFlag_FunctionType = bit(0),
ParamPack = bit(1), CodeFlag_ParamPack = bit(1),
Module_Export = bit(2), CodeFlag_Module_Export = bit(2),
Module_Import = bit(3), CodeFlag_Module_Import = bit(3),
CodeFlag_SizeDef = GEN_U32_MAX,
}; };
static_assert( size_of(CodeFlag) == size_of(u32));
// Used to indicate if enum definitoin is an enum class or regular enum. // Used to indicate if enum definitoin is an enum class or regular enum.
enum class EnumT : u8 enum EnumDecl enum_underlying(u8)
{ {
Regular, EnumDecl_Regular,
Class EnumDecl_Class,
EnumT_SizeDef = GEN_U8_MAX,
}; };
typedef u8 EnumT;
constexpr EnumT EnumClass = EnumT::Class; enum ModuleFlag enum_underlying(u32)
constexpr EnumT EnumRegular = EnumT::Regular;
enum class ModuleFlag : u32
{ {
None = 0, ModuleFlag_None = 0,
Export = bit(0), ModuleFlag_Export = bit(0),
Import = bit(1), ModuleFlag_Import = bit(1),
Num_ModuleFlags, Num_ModuleFlags,
Invalid, ModuleFlag_Invalid,
ModuleFlag_SizeDef = GEN_U32_MAX,
}; };
static_assert( size_of(ModuleFlag) == size_of(u32));
inline inline
StrC to_str( ModuleFlag flag ) StrC to_str( ModuleFlag flag )
@ -81,7 +89,7 @@ StrC to_str( ModuleFlag flag )
{ sizeof("import"), "import" }, { sizeof("import"), "import" },
}; };
if ( flag > ModuleFlag::Import ) if ( flag > ModuleFlag_Import )
return { sizeof("invalid"), "invalid" }; return { sizeof("invalid"), "invalid" };
return lookup[ (u32)flag ]; return lookup[ (u32)flag ];
@ -93,15 +101,13 @@ ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
return (ModuleFlag)( (u32)A | (u32)B ); return (ModuleFlag)( (u32)A | (u32)B );
} }
enum class EPreprocessCond : u32 enum EPreprocessCond enum_underlying(u32)
{ {
If, PreprocessCond_If,
IfDef, PreprocessCond_IfDef,
IfNotDef, PreprocessCond_IfNotDef,
ElIf PreprocessCond_ElIf,
};
constexpr EPreprocessCond PreprocessCond_If = EPreprocessCond::If; EPreprocessCond_SizeDef = GEN_U32_MAX,
constexpr EPreprocessCond PreprocessCond_IfDef = EPreprocessCond::IfDef; };
constexpr EPreprocessCond PreprocessCond_IfNotDef = EPreprocessCond::IfNotDef; static_assert( size_of(EPreprocessCond) == size_of(u32));
constexpr EPreprocessCond PreprocessCond_ElIf = EPreprocessCond::ElIf;

View File

@ -205,4 +205,14 @@
# define foreach(Type, entry_id, iterable) for ( Type entry_id : iterable ) # define foreach(Type, entry_id, iterable) for ( Type entry_id : iterable )
#endif #endif
#if GENC_COMPILERC
# if __STDC_VERSION__ >= 202311L
# define enum_underlying(type) : type
# else
# define enum_underlying(type)
# endif
#else
# define enum_underlying(type) : type
#endif
#pragma endregion Macros #pragma endregion Macros

View File

@ -76,13 +76,18 @@
/* Platform compiler */ /* Platform compiler */
#if defined( _MSC_VER ) #if defined( _MSC_VER )
# define GEN_COMPILER_CLANG 0
# define GEN_COMPILER_MSVC 1 # define GEN_COMPILER_MSVC 1
# define GEN_COMPILER_GCC 0
#elif defined( __GNUC__ ) #elif defined( __GNUC__ )
# define GEN_COMPILER_CLANG 0
# define GEN_COMPILER_MSVC 0
# define GEN_COMPILER_GCC 1 # define GEN_COMPILER_GCC 1
#elif defined( __clang__ ) #elif defined( __clang__ )
# define GEN_COMPILER_CLANG 1 # define GEN_COMPILER_CLANG 1
#elif defined( __MINGW32__ ) # define GEN_COMPILER_MSVC 0
# define GEN_COMPILER_MINGW 1 # define GEN_COMPILER_GCC 1
#else
# error Unknown compiler # error Unknown compiler
#endif #endif
@ -122,11 +127,23 @@
#pragma endregion Mandatory Includes #pragma endregion Mandatory Includes
#if GEN_DONT_USE_NAMESPACE || GEN_COMPILER_C #if GEN_DONT_USE_NAMESPACE
# if GEN_COMPILER_C
# define GEN_NS_ENUM_BEGIN
# define GEN_NS_ENUM_END
# define GEN_NS # define GEN_NS
# define GEN_NS_BEGIN # define GEN_NS_BEGIN
# define GEN_NS_END # define GEN_NS_END
# else
# define GEN_NS_ENUM_BEGIN namespace gen_internal_enums {
# define GEN_NS_ENUM_END }
# define GEN_NS ::
# define GEN_NS_BEGIN
# define GEN_NS_END
# endif
#else #else
# define GEN_NS_ENUM_BEGIN namespace gen_internal_enums {
# define GEN_NS_ENUM_END }
# define GEN_NS gen:: # define GEN_NS gen::
# define GEN_NS_BEGIN namespace gen { # define GEN_NS_BEGIN namespace gen {
# define GEN_NS_END } # define GEN_NS_END }

View File

@ -85,7 +85,7 @@ struct String
forceinline operator bool() { return Data != nullptr; } forceinline operator bool() { return Data != nullptr; }
forceinline operator char*() { return Data; } forceinline operator char*() { return Data; }
forceinline operator char const*() const { return Data; } forceinline operator char const*() const { return Data; }
forceinline operator StrC() const { return { length(* this), Data }; } forceinline operator StrC() const { return { GEN_NS length(* this), Data }; }
String const& operator=(String const& other) const { String const& operator=(String const& other) const {
if (this == &other) if (this == &other)
@ -101,7 +101,7 @@ struct String
forceinline char const& operator[](ssize index) const { return Data[index]; } forceinline char const& operator[](ssize index) const { return Data[index]; }
forceinline char* begin() const { return Data; } forceinline char* begin() const { return Data; }
forceinline char* end() const { return Data + length(* this); } forceinline char* end() const { return Data + GEN_NS length(* this); }
#if GEN_SUPPORT_CPP_MEMBER_FEATURES #if GEN_SUPPORT_CPP_MEMBER_FEATURES
#pragma region Member Mapping #pragma region Member Mapping