Suppeort for trailing specifiers for member functions, operators, and operator type casts (Untested)

This commit is contained in:
Edward R. Gonzalez 2023-07-24 00:27:13 -04:00
parent 5df21998ef
commit cee55ad080
6 changed files with 280 additions and 153 deletions

View File

@ -24,5 +24,11 @@
"mesonbuild.configureOnOpen": true, "mesonbuild.configureOnOpen": true,
"C_Cpp.errorSquiggles": "enabled", "C_Cpp.errorSquiggles": "enabled",
"godot_tools.scene_file_config": "", "godot_tools.scene_file_config": "",
"C_Cpp.default.compilerPath": "cl.exe" "C_Cpp.default.compilerPath": "cl.exe",
"C_Cpp.exclusionPolicy": "checkFilesAndFolders",
"C_Cpp.files.exclude": {
"**/.vscode": true,
"**/.vs": true,
"**/sanity.gen.hpp": true
}
} }

View File

@ -161,8 +161,6 @@ This method is setup where all the metaprogram's code are the within the same fi
### *WHAT IS NOT PROVIDED* ### *WHAT IS NOT PROVIDED*
* Lambdas * Lambdas
* Lang provided dynamic dispatch (virtuals) : `override` and `final` specifiers complicate the specifier parsing and serialization. (Its a todo)
* Suffix specifiers for functions (Ex: void() const ). Same reason as virtual/override/final missing for now.
* RTTI * RTTI
* Exceptions * Exceptions
* Execution statement validation : Execution expressions are defined using the untyped API. * Execution statement validation : Execution expressions are defined using the untyped API.
@ -180,10 +178,7 @@ Keywords kept from "Modern C++":
When it comes to expressions: When it comes to expressions:
**There is no support for validating expressions.** **There is no support for validating expressions.**
**The reason:** Its difficult to parse without enough benefits. Its difficult to parse without enough benefits (At the metaprogramming level).
Most of the time, the critical complex metaprogramming conundrums are producing the frame of abstractions around the expressions (which this library provides constructors to help validate, you can skip that process by using the untyped constructors).
Its not a priority to add such a level of complexity to the library when there isn't a high reward or need for it.
Especially when the priority is to keep this library small and easy to grasp for what it is.
When it comes to templates: When it comes to templates:
@ -328,7 +323,7 @@ The following CodeTypes are used which the user may optionally use strong typing
* CodeOperator * CodeOperator
* CodeOpCast * CodeOpCast
* CodeParam : Has support for `for-range` iterating across parameters. * CodeParam : Has support for `for-range` iterating across parameters.
* CodeSpecifier : Has support for `for-range` iterating across specifiers. * CodeSpecifiers : Has support for `for-range` iterating across specifiers.
* CodeStruct * CodeStruct
* CodeTemplate * CodeTemplate
* CodeType * CodeType

View File

@ -75,23 +75,23 @@ global Code module_private_fragment;
global Code pragma_once; global Code pragma_once;
global CodeSpecifier spec_const; global CodeSpecifiers spec_const;
global CodeSpecifier spec_consteval; global CodeSpecifiers spec_consteval;
global CodeSpecifier spec_constexpr; global CodeSpecifiers spec_constexpr;
global CodeSpecifier spec_constinit; global CodeSpecifiers spec_constinit;
global CodeSpecifier spec_extern_linkage; global CodeSpecifiers spec_extern_linkage;
global CodeSpecifier spec_global; global CodeSpecifiers spec_global;
global CodeSpecifier spec_inline; global CodeSpecifiers spec_inline;
global CodeSpecifier spec_internal_linkage; global CodeSpecifiers spec_internal_linkage;
global CodeSpecifier spec_local_persist; global CodeSpecifiers spec_local_persist;
global CodeSpecifier spec_mutable; global CodeSpecifiers spec_mutable;
global CodeSpecifier spec_ptr; global CodeSpecifiers spec_ptr;
global CodeSpecifier spec_ref; global CodeSpecifiers spec_ref;
global CodeSpecifier spec_register; global CodeSpecifiers spec_register;
global CodeSpecifier spec_rvalue; global CodeSpecifiers spec_rvalue;
global CodeSpecifier spec_static_member; global CodeSpecifiers spec_static_member;
global CodeSpecifier spec_thread_local; global CodeSpecifiers spec_thread_local;
global CodeSpecifier spec_volatile; global CodeSpecifiers spec_volatile;
#pragma endregion Constants #pragma endregion Constants
#pragma region AST Body Case Macros #pragma region AST Body Case Macros
@ -632,12 +632,23 @@ String AST::to_string()
result.append_fmt( "%s(", Name ); result.append_fmt( "%s(", Name );
if ( Params ) if ( Params )
result.append_fmt( "%s", Params->to_string() ); result.append_fmt( "%s)", Params->to_string() );
else else
result.append( "void" ); result.append( "void)" );
result.append_fmt( ")\n{\n%s\n}" if ( Specs )
{
CodeSpecifiers specs = cast<CodeSpecifiers>();
for ( SpecifierT spec : specs )
{
if ( ESpecifier::is_trailing( spec ) )
result.append_fmt( " %s", (char const*)ESpecifier::to_str( spec ) );
}
}
result.append_fmt( "\n{\n%s\n}"
, Body->to_string() , Body->to_string()
); );
} }
@ -660,12 +671,23 @@ String AST::to_string()
result.append_fmt( "%s(", Name ); result.append_fmt( "%s(", Name );
if ( Params ) if ( Params )
result.append_fmt( "%s", Params->to_string() ); result.append_fmt( "%s)", Params->to_string() );
else else
result.append( "void" ); result.append( "void)" );
result.append( ");" ); if ( Specs )
{
CodeSpecifiers specs = cast<CodeSpecifiers>();
for ( SpecifierT spec : specs )
{
if ( ESpecifier::is_trailing( spec ) )
result.append_fmt( " %s", (char const*)ESpecifier::to_str( spec ) );
}
}
result.append( ";" );
} }
break; break;
@ -703,12 +725,23 @@ String AST::to_string()
result.append_fmt( "%s %s (", ReturnType->to_string(), Name ); result.append_fmt( "%s %s (", ReturnType->to_string(), Name );
if ( Params ) if ( Params )
result.append_fmt( "%s", Params->to_string() ); result.append_fmt( "%s)", Params->to_string() );
else else
result.append( "void" ); result.append( "void)" );
result.append_fmt( ")\n{\n%s\n}" if ( Specs )
{
CodeSpecifiers specs = cast<CodeSpecifiers>();
for ( SpecifierT spec : specs )
{
if ( ESpecifier::is_trailing( spec ) )
result.append_fmt( " %s", (char const*)ESpecifier::to_str( spec ) );
}
}
result.append_fmt( "\n{\n%s\n}"
, Body->to_string() , Body->to_string()
); );
} }
@ -728,20 +761,65 @@ String AST::to_string()
result.append_fmt( "%s %s (", ReturnType->to_string(), Name ); result.append_fmt( "%s %s (", ReturnType->to_string(), Name );
if ( Params ) if ( Params )
result.append_fmt( "%s);", Params->to_string() ); result.append_fmt( "%s)", Params->to_string() );
else else
result.append_fmt( "void);" ); result.append_fmt( "void)" );
if ( Specs )
{
CodeSpecifiers specs = cast<CodeSpecifiers>();
for ( SpecifierT spec : specs )
{
if ( ESpecifier::is_trailing( spec ) )
result.append_fmt( " %s", (char const*)ESpecifier::to_str( spec ) );
}
}
result.append( ";" );
} }
break; break;
case Operator_Cast: case Operator_Cast:
{ {
result.append_fmt("operator %s(){\n%s\n}", ValueType->to_string(), Body->to_string() ); if ( Specs )
{
result.append_fmt( "operator %s()" );
CodeSpecifiers specs = cast<CodeSpecifiers>();
for ( SpecifierT spec : specs )
{
if ( ESpecifier::is_trailing( spec ) )
result.append_fmt( " %s", (char const*)ESpecifier::to_str( spec ) );
}
result.append_fmt( "\n{\n%s\n}", Body->to_string() );
break;
}
result.append_fmt("operator %s()\n{\n%s\n}", ValueType->to_string(), Body->to_string() );
} }
break; break;
case Operator_Cast_Fwd: case Operator_Cast_Fwd:
if ( Specs )
{
result.append_fmt( "operator %s()" );
CodeSpecifiers specs = cast<CodeSpecifiers>();
for ( SpecifierT spec : specs )
{
if ( ESpecifier::is_trailing( spec ) )
result.append_fmt( " %s", (char const*)ESpecifier::to_str( spec ) );
}
result.append_fmt( ";", Body->to_string() );
break;
}
result.append_fmt("operator %s();", ValueType->to_string() ); result.append_fmt("operator %s();", ValueType->to_string() );
break; break;
@ -776,6 +854,12 @@ String AST::to_string()
s32 left = NumEntries; s32 left = NumEntries;
while ( left-- ) while ( left-- )
{ {
if ( ESpecifier::is_trailing( ArrSpecs[idx]) )
{
idx++;
continue;
}
result.append_fmt( "%s ", (char const*)ESpecifier::to_str( ArrSpecs[idx]) ); result.append_fmt( "%s ", (char const*)ESpecifier::to_str( ArrSpecs[idx]) );
idx++; idx++;
} }
@ -1477,7 +1561,7 @@ enum class OpValidateResult : u32
}; };
inline inline
OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeType ret_type, CodeSpecifier specifier ) OpValidateResult operator__validate( OperatorT op, CodeParam params_code, CodeType ret_type, CodeSpecifiers specifier )
{ {
using namespace EOperator; using namespace EOperator;
@ -2114,7 +2198,7 @@ CodeFriend def_friend( Code declaration )
CodeFn def_function( StrC name CodeFn def_function( StrC name
, CodeParam params , CodeType ret_type, Code body , CodeParam params , CodeType ret_type, Code body
, CodeSpecifier specifiers, CodeAttributes attributes , CodeSpecifiers specifiers, CodeAttributes attributes
, ModuleFlag mflags ) , ModuleFlag mflags )
{ {
using namespace ECode; using namespace ECode;
@ -2251,7 +2335,7 @@ CodeNamespace def_namespace( StrC name, Code body, ModuleFlag mflags )
CodeOperator def_operator( OperatorT op CodeOperator def_operator( OperatorT op
, CodeParam params_code, CodeType ret_type, Code body , CodeParam params_code, CodeType ret_type, Code body
, CodeSpecifier specifiers, CodeAttributes attributes , CodeSpecifiers specifiers, CodeAttributes attributes
, ModuleFlag mflags ) , ModuleFlag mflags )
{ {
using namespace ECode; using namespace ECode;
@ -2323,7 +2407,7 @@ CodeOperator def_operator( OperatorT op
return result; return result;
} }
CodeOpCast def_operator_cast( CodeType type, Code body ) CodeOpCast def_operator_cast( CodeType type, Code body, CodeSpecifiers const_spec )
{ {
using namespace ECode; using namespace ECode;
null_check( def_operator_cast, type ); null_check( def_operator_cast, type );
@ -2353,6 +2437,11 @@ CodeOpCast def_operator_cast( CodeType type, Code body )
result->Type = Operator_Cast_Fwd; result->Type = Operator_Cast_Fwd;
} }
if ( const_spec )
{
result->Specs = const_spec;
}
result->ValueType = type; result->ValueType = type;
return result; return result;
} }
@ -2391,10 +2480,10 @@ CodeParam def_param( CodeType type, StrC name, Code value )
return result; return result;
} }
CodeSpecifier def_specifier( SpecifierT spec ) CodeSpecifiers def_specifier( SpecifierT spec )
{ {
CodeSpecifier CodeSpecifiers
result = (CodeSpecifier) make_code(); result = (CodeSpecifiers) make_code();
result->Type = ECode::Specifiers; result->Type = ECode::Specifiers;
result.append( spec ); result.append( spec );
@ -2489,7 +2578,7 @@ CodeTemplate def_template( CodeParam params, Code declaration, ModuleFlag mflags
return result; return result;
} }
CodeType def_type( StrC name, Code arrayexpr, CodeSpecifier specifiers, CodeAttributes attributes ) CodeType def_type( StrC name, Code arrayexpr, CodeSpecifiers specifiers, CodeAttributes attributes )
{ {
name_check( def_type, name ); name_check( def_type, name );
@ -2661,7 +2750,7 @@ CodeUsing def_using_namespace( StrC name )
} }
CodeVar def_variable( CodeType type, StrC name, Code value CodeVar def_variable( CodeType type, StrC name, Code value
, CodeSpecifier specifiers, CodeAttributes attributes , CodeSpecifiers specifiers, CodeAttributes attributes
, ModuleFlag mflags ) , ModuleFlag mflags )
{ {
name_check( def_variable, name ); name_check( def_variable, name );
@ -3137,7 +3226,7 @@ CodeParam def_params( s32 num, CodeParam* codes )
return result; return result;
} }
CodeSpecifier def_specifiers( s32 num, ... ) CodeSpecifiers def_specifiers( s32 num, ... )
{ {
if ( num <= 0 ) if ( num <= 0 )
{ {
@ -3151,8 +3240,8 @@ CodeSpecifier def_specifiers( s32 num, ... )
return CodeInvalid; return CodeInvalid;
} }
CodeSpecifier CodeSpecifiers
result = (CodeSpecifier) make_code(); result = (CodeSpecifiers) make_code();
result->Type = ECode::Specifiers; result->Type = ECode::Specifiers;
va_list va; va_list va;
@ -3169,7 +3258,7 @@ CodeSpecifier def_specifiers( s32 num, ... )
return result; return result;
} }
CodeSpecifier def_specifiers( s32 num, SpecifierT* specs ) CodeSpecifiers def_specifiers( s32 num, SpecifierT* specs )
{ {
if ( num <= 0 ) if ( num <= 0 )
{ {
@ -3183,8 +3272,8 @@ CodeSpecifier def_specifiers( s32 num, SpecifierT* specs )
return CodeInvalid; return CodeInvalid;
} }
CodeSpecifier CodeSpecifiers
result = (CodeSpecifier) make_code(); result = (CodeSpecifiers) make_code();
result->Type = ECode::Specifiers; result->Type = ECode::Specifiers;
s32 idx = 0; s32 idx = 0;
@ -3364,12 +3453,15 @@ namespace Parser
Entry( Spec_Consteval, "consteval" ) \ Entry( Spec_Consteval, "consteval" ) \
Entry( Spec_Constexpr, "constexpr" ) \ Entry( Spec_Constexpr, "constexpr" ) \
Entry( Spec_Constinit, "constinit" ) \ Entry( Spec_Constinit, "constinit" ) \
Entry( Spec_Explicit, "explicit" ) \
Entry( Spec_Extern, "extern" ) \ Entry( Spec_Extern, "extern" ) \
Entry( Spec_Final, "final" ) \
Entry( Spec_Global, "global" ) \ Entry( Spec_Global, "global" ) \
Entry( Spec_Inline, "inline" ) \ Entry( Spec_Inline, "inline" ) \
Entry( Spec_Internal_Linkage, "internal" ) \ Entry( Spec_Internal_Linkage, "internal" ) \
Entry( Spec_LocalPersist, "local_persist" ) \ Entry( Spec_LocalPersist, "local_persist" ) \
Entry( Spec_Mutable, "mutable" ) \ Entry( Spec_Mutable, "mutable" ) \
Entry( Spec_Override, "override" ) \
Entry( Spec_Static, "static" ) \ Entry( Spec_Static, "static" ) \
Entry( Spec_ThreadLocal, "thread_local" ) \ Entry( Spec_ThreadLocal, "thread_local" ) \
Entry( Spec_Volatile, "volatile") \ Entry( Spec_Volatile, "volatile") \
@ -4374,7 +4466,7 @@ internal inline
CodeFn parse_function_after_name( CodeFn parse_function_after_name(
ModuleFlag mflags ModuleFlag mflags
, CodeAttributes attributes , CodeAttributes attributes
, CodeSpecifier specifiers , CodeSpecifiers specifiers
, CodeType ret_type , CodeType ret_type
, StrC name , StrC name
, Parser::TokArray& toks , Parser::TokArray& toks
@ -4385,6 +4477,12 @@ CodeFn parse_function_after_name(
CodeParam params = parse_params( toks, stringize(parse_function) ); CodeParam params = parse_params( toks, stringize(parse_function) );
while ( left && tok_is_specifier( currtok ) )
{
specifiers.append( ESpecifier::to_type(currtok) );
eat( currtok.Type );
}
CodeBody body = { nullptr }; CodeBody body = { nullptr };
if ( check( TokType::BraceCurly_Open ) ) if ( check( TokType::BraceCurly_Open ) )
{ {
@ -4441,7 +4539,7 @@ CodeFn parse_function_after_name(
internal inline internal inline
CodeOperator parse_operator_after_ret_type( ModuleFlag mflags CodeOperator parse_operator_after_ret_type( ModuleFlag mflags
, CodeAttributes attributes , CodeAttributes attributes
, CodeSpecifier specifiers , CodeSpecifiers specifiers
, CodeType ret_type , CodeType ret_type
, Parser::TokArray& toks , Parser::TokArray& toks
, char const* context ) , char const* context )
@ -4649,6 +4747,12 @@ CodeOperator parse_operator_after_ret_type( ModuleFlag mflags
// Parse Params // Parse Params
CodeParam params = parse_params( toks, stringize(parse_operator) ); CodeParam params = parse_params( toks, stringize(parse_operator) );
while ( left && tok_is_specifier( currtok ) )
{
specifiers.append( ESpecifier::to_type(currtok) );
eat( currtok.Type );
}
// Parse Body // Parse Body
CodeBody body = { nullptr }; CodeBody body = { nullptr };
if ( check( TokType::BraceCurly_Open ) ) if ( check( TokType::BraceCurly_Open ) )
@ -4670,9 +4774,9 @@ CodeOperator parse_operator_after_ret_type( ModuleFlag mflags
// Variable parsing is handled in multiple places because its initial signature is shared with function parsing // Variable parsing is handled in multiple places because its initial signature is shared with function parsing
internal inline internal inline
CodeVar parse_variable_after_name( CodeVar parse_variable_after_name(
ModuleFlag mflags ModuleFlag mflags
, CodeAttributes attributes , CodeAttributes attributes
, CodeSpecifier specifiers ,CodeSpecifiers specifiers
, CodeType type , CodeType type
, StrC name , StrC name
, Parser::TokArray& toks , Parser::TokArray& toks
@ -4764,7 +4868,7 @@ Code parse_variable_assignment( Parser::TokArray& toks, char const* context )
} }
internal inline internal inline
Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifier specifiers, Parser::TokArray& toks, char const* context ) Code parse_operator_function_or_variable( bool expects_function, CodeAttributes attributes, CodeSpecifiers specifiers, Parser::TokArray& toks, char const* context )
{ {
using namespace Parser; using namespace Parser;
@ -4828,7 +4932,7 @@ CodeBody parse_class_struct_body( Parser::TokType which, Parser::TokArray& toks,
{ {
Code member = Code::Invalid; Code member = Code::Invalid;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifier specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
bool expects_function = false; bool expects_function = false;
@ -5117,7 +5221,7 @@ CodeBody parse_global_nspace( CodeT which, Parser::TokArray& toks, char const* c
{ {
Code member = Code::Invalid; Code member = Code::Invalid;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifier specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
bool expects_function = false; bool expects_function = false;
@ -5532,7 +5636,7 @@ CodeFn parse_functon( Parser::TokArray& toks, char const* context )
s32 num_specifiers = 0; s32 num_specifiers = 0;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifier specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag::None;
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
@ -5562,6 +5666,9 @@ CodeFn parse_functon( Parser::TokArray& toks, char const* context )
return CodeInvalid; return CodeInvalid;
} }
if ( spec == ESpecifier::Const )
continue;
specs_found[num_specifiers] = spec; specs_found[num_specifiers] = spec;
num_specifiers++; num_specifiers++;
eat( currtok.Type ); eat( currtok.Type );
@ -5650,7 +5757,7 @@ CodeOperator parse_operator( Parser::TokArray& toks, char const* context )
using namespace Parser; using namespace Parser;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifier specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag::None;
SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; SpecifierT specs_found[16] { ESpecifier::Num_Specifiers };
@ -5681,6 +5788,9 @@ CodeOperator parse_operator( Parser::TokArray& toks, char const* context )
return CodeInvalid; return CodeInvalid;
} }
if ( spec == ESpecifier::Const )
continue;
specs_found[num_specifiers] = spec; specs_found[num_specifiers] = spec;
num_specifiers++; num_specifiers++;
eat( currtok.Type ); eat( currtok.Type );
@ -5721,6 +5831,11 @@ CodeOpCast parse_operator_cast( Parser::TokArray& toks, char const* context )
eat( TokType::Capture_Start ); eat( TokType::Capture_Start );
eat( TokType::Capture_End ); eat( TokType::Capture_End );
CodeSpecifiers specifiers = { nullptr };
if ( check(TokType::Spec_Const))
specifiers = spec_const;
Code body = { nullptr }; Code body = { nullptr };
if ( check( TokType::BraceCurly_Open) ) if ( check( TokType::BraceCurly_Open) )
@ -5760,6 +5875,9 @@ CodeOpCast parse_operator_cast( Parser::TokArray& toks, char const* context )
result->Type = ECode::Operator_Cast_Fwd; result->Type = ECode::Operator_Cast_Fwd;
} }
if ( specifiers )
result->Specs = specifiers;
result->ValueType = type; result->ValueType = type;
return result; return result;
@ -5842,7 +5960,7 @@ CodeTemplate parse_template( Parser::TokArray& toks, char const* context )
Token name = { nullptr, 0, TokType::Invalid }; Token name = { nullptr, 0, TokType::Invalid };
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifier specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
bool expects_function = false; bool expects_function = false;
@ -6354,7 +6472,7 @@ CodeVar parse_variable( Parser::TokArray& toks, char const* context )
ModuleFlag mflags = ModuleFlag::None; ModuleFlag mflags = ModuleFlag::None;
CodeAttributes attributes = { nullptr }; CodeAttributes attributes = { nullptr };
CodeSpecifier specifiers = { nullptr }; CodeSpecifiers specifiers = { nullptr };
if ( check(TokType::Module_Export) ) if ( check(TokType::Module_Export) )
{ {

View File

@ -212,10 +212,10 @@ namespace ESpecifier
# define Define_Specifiers \ # define Define_Specifiers \
Entry( Invalid, INVALID ) \ Entry( Invalid, INVALID ) \
Entry( Const, const ) \
Entry( Consteval, consteval ) \ Entry( Consteval, consteval ) \
Entry( Constexpr, constexpr ) \ Entry( Constexpr, constexpr ) \
Entry( Constinit, constinit ) \ Entry( Constinit, constinit ) \
Entry( Explicit, explicit ) \
Entry( External_Linkage, extern ) \ Entry( External_Linkage, extern ) \
Entry( Global, global ) \ Entry( Global, global ) \
Entry( Inline, inline ) \ Entry( Inline, inline ) \
@ -230,7 +230,7 @@ namespace ESpecifier
Entry( Thread_Local, thread_local ) \ Entry( Thread_Local, thread_local ) \
Entry( Volatile, volatile ) \ Entry( Volatile, volatile ) \
Entry( Virtual, virtual ) \ Entry( Virtual, virtual ) \
Entry( Const_Fn, const ) \ Entry( Const, const ) \
Entry( Final, final ) \ Entry( Final, final ) \
Entry( Override, override ) Entry( Override, override )
@ -243,6 +243,12 @@ namespace ESpecifier
Num_Specifiers, Num_Specifiers,
}; };
inline
bool is_trailing( Type specifier )
{
return specifier > Virtual;
}
// Specifier to string // Specifier to string
inline inline
StrC to_str( Type specifier ) StrC to_str( Type specifier )
@ -413,7 +419,7 @@ struct AST_Namespace;
struct AST_Operator; struct AST_Operator;
struct AST_OpCast; struct AST_OpCast;
struct AST_Param; struct AST_Param;
struct AST_Specifier; struct AST_Specifiers;
struct AST_Struct; struct AST_Struct;
struct AST_Template; struct AST_Template;
struct AST_Type; struct AST_Type;
@ -440,7 +446,7 @@ struct CodeNamespace;
struct CodeOperator; struct CodeOperator;
struct CodeOpCast; struct CodeOpCast;
struct CodeParam; struct CodeParam;
struct CodeSpecifier; struct CodeSpecifiers;
struct CodeStruct; struct CodeStruct;
struct CodeTemplate; struct CodeTemplate;
struct CodeType; struct CodeType;
@ -518,7 +524,7 @@ struct Code
operator CodeOperator() const; operator CodeOperator() const;
operator CodeOpCast() const; operator CodeOpCast() const;
operator CodeParam() const; operator CodeParam() const;
operator CodeSpecifier() const; operator CodeSpecifiers() const;
operator CodeStruct() const; operator CodeStruct() const;
operator CodeTemplate() const; operator CodeTemplate() const;
operator CodeType() const; operator CodeType() const;
@ -579,7 +585,7 @@ struct AST
operator CodeOperator(); operator CodeOperator();
operator CodeOpCast(); operator CodeOpCast();
operator CodeParam(); operator CodeParam();
operator CodeSpecifier(); operator CodeSpecifiers();
operator CodeStruct(); operator CodeStruct();
operator CodeTemplate(); operator CodeTemplate();
operator CodeType(); operator CodeType();
@ -838,15 +844,15 @@ struct CodeParam
AST_Param* ast; AST_Param* ast;
}; };
struct CodeSpecifier struct CodeSpecifiers
{ {
Using_Code( CodeSpecifier ); Using_Code( CodeSpecifiers );
bool append( SpecifierT spec ) bool append( SpecifierT spec )
{ {
if ( raw()->NumEntries == AST::ArrSpecs_Cap ) if ( raw()->NumEntries == AST::ArrSpecs_Cap )
{ {
log_failure("CodeSpecifier: Attempted to append over %d specifiers to a specifiers AST!", AST::ArrSpecs_Cap ); log_failure("CodeSpecifiers: Attempted to append over %d specifiers to a specifiers AST!", AST::ArrSpecs_Cap );
return false; return false;
} }
@ -868,7 +874,7 @@ struct CodeSpecifier
{ {
return rcast( AST*, ast ); return rcast( AST*, ast );
} }
AST_Specifier* operator->() AST_Specifiers* operator->()
{ {
if ( ast == nullptr ) if ( ast == nullptr )
{ {
@ -895,7 +901,7 @@ struct CodeSpecifier
} }
#pragma endregion Iterator #pragma endregion Iterator
AST_Specifier* ast; AST_Specifiers* ast;
}; };
#undef Define_CodeType #undef Define_CodeType
@ -1076,7 +1082,7 @@ struct AST_Fn
struct struct
{ {
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifier Specs; CodeSpecifiers Specs;
CodeType ReturnType; CodeType ReturnType;
CodeParam Params; CodeParam Params;
CodeBody Body; CodeBody Body;
@ -1131,7 +1137,7 @@ struct AST_Operator
struct struct
{ {
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifier Specs; CodeSpecifiers Specs;
CodeType ReturnType; CodeType ReturnType;
CodeParam Params; CodeParam Params;
CodeBody Body; CodeBody Body;
@ -1153,10 +1159,11 @@ struct AST_OpCast
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ]; char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap ];
struct struct
{ {
char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ]; char _PAD_PROPERTIES_[ sizeof(AST*) ];
CodeType ValueType; CodeSpecifiers Specs;
char _PAD_PROPERTIES_2_[ sizeof(AST*) ]; CodeType ValueType;
CodeBody Body; char _PAD_PROPERTIES_2_[ sizeof(AST*) ];
CodeBody Body;
}; };
}; };
Code Prev; Code Prev;
@ -1190,7 +1197,7 @@ struct AST_Param
}; };
static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the same size as AST"); static_assert( sizeof(AST_Param) == sizeof(AST), "ERROR: AST_Param is not the same size as AST");
struct AST_Specifier struct AST_Specifiers
{ {
SpecifierT ArrSpecs[ AST::ArrSpecs_Cap ]; SpecifierT ArrSpecs[ AST::ArrSpecs_Cap ];
Code Prev; Code Prev;
@ -1201,7 +1208,7 @@ struct AST_Specifier
char _PAD_UNUSED_[ sizeof(ModuleFlag) ]; char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
s32 NumEntries; s32 NumEntries;
}; };
static_assert( sizeof(AST_Specifier) == sizeof(AST), "ERROR: AST_Specifier is not the same size as AST"); static_assert( sizeof(AST_Specifiers) == sizeof(AST), "ERROR: AST_Specifier is not the same size as AST");
struct AST_Struct struct AST_Struct
{ {
@ -1254,7 +1261,7 @@ struct AST_Type
struct struct
{ {
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifier Specs; CodeSpecifiers Specs;
char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ]; char _PAD_PROPERTIES_[ sizeof(AST*) * 2 ];
Code ArrExpr; Code ArrExpr;
}; };
@ -1339,7 +1346,7 @@ struct AST_Var
struct struct
{ {
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifier Specs; CodeSpecifiers Specs;
CodeType ValueType; CodeType ValueType;
char _PAD_PROPERTIES_[ sizeof(AST*) ]; char _PAD_PROPERTIES_[ sizeof(AST*) ];
Code Value; Code Value;
@ -1413,7 +1420,7 @@ 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
, CodeSpecifier specifiers = NoCode, CodeAttributes attributes = NoCode , CodeSpecifiers specifiers = NoCode, CodeAttributes attributes = NoCode
, ModuleFlag mflags = ModuleFlag::None ); , ModuleFlag mflags = ModuleFlag::None );
CodeInclude def_include ( StrC content ); CodeInclude def_include ( StrC content );
@ -1422,13 +1429,13 @@ CodeNamespace def_namespace( StrC name, Code body, ModuleFlag mflags = ModuleFla
CodeOperator def_operator( OperatorT op CodeOperator def_operator( OperatorT op
, CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode , CodeParam params = NoCode, CodeType ret_type = NoCode, Code body = NoCode
, CodeSpecifier 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 ); CodeOpCast def_operator_cast( CodeType type, Code body = NoCode, CodeSpecifiers specs = NoCode );
CodeParam def_param ( CodeType type, StrC name, Code value = NoCode ); CodeParam def_param ( CodeType type, StrC name, Code value = NoCode );
CodeSpecifier def_specifier( SpecifierT specifier ); CodeSpecifiers def_specifier( SpecifierT specifier );
CodeStruct def_struct( StrC name CodeStruct def_struct( StrC name
, Code body = NoCode , Code body = NoCode
@ -1438,7 +1445,7 @@ CodeStruct def_struct( StrC name
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, CodeSpecifier 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 );
@ -1450,7 +1457,7 @@ CodeUsing def_using( StrC name, CodeType type = NoCode
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
, CodeSpecifier 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.
@ -1459,48 +1466,48 @@ CodeBody def_body( CodeT type );
// There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num, // There are two options for defining a struct body, either varadically provided with the args macro to auto-deduce the arg num,
/// or provide as an array of Code objects. /// or provide as an array of Code objects.
CodeBody def_class_body ( s32 num, ... ); CodeBody def_class_body ( s32 num, ... );
CodeBody def_class_body ( s32 num, Code* codes ); CodeBody def_class_body ( s32 num, Code* codes );
CodeBody def_enum_body ( s32 num, ... ); CodeBody def_enum_body ( s32 num, ... );
CodeBody def_enum_body ( s32 num, Code* codes ); CodeBody def_enum_body ( s32 num, Code* codes );
CodeBody def_export_body ( s32 num, ... ); CodeBody def_export_body ( s32 num, ... );
CodeBody def_export_body ( s32 num, Code* codes); CodeBody def_export_body ( s32 num, Code* codes);
CodeBody def_extern_link_body( s32 num, ... ); CodeBody def_extern_link_body( s32 num, ... );
CodeBody def_extern_link_body( s32 num, Code* codes ); CodeBody def_extern_link_body( s32 num, Code* codes );
CodeBody def_function_body ( s32 num, ... ); CodeBody def_function_body ( s32 num, ... );
CodeBody def_function_body ( s32 num, Code* codes ); CodeBody def_function_body ( s32 num, Code* codes );
CodeBody def_global_body ( s32 num, ... ); CodeBody def_global_body ( s32 num, ... );
CodeBody def_global_body ( s32 num, Code* codes ); CodeBody def_global_body ( s32 num, Code* codes );
CodeBody def_namespace_body ( s32 num, ... ); CodeBody def_namespace_body ( s32 num, ... );
CodeBody def_namespace_body ( s32 num, Code* codes ); CodeBody def_namespace_body ( s32 num, Code* codes );
CodeParam def_params ( s32 num, ... ); CodeParam def_params ( s32 num, ... );
CodeParam def_params ( s32 num, CodeParam* params ); CodeParam def_params ( s32 num, CodeParam* params );
CodeSpecifier def_specifiers ( s32 num, ... ); CodeSpecifiers def_specifiers ( s32 num, ... );
CodeSpecifier def_specifiers ( s32 num, SpecifierT* specs ); CodeSpecifiers def_specifiers ( s32 num, SpecifierT* specs );
CodeBody def_struct_body ( s32 num, ... ); CodeBody def_struct_body ( s32 num, ... );
CodeBody def_struct_body ( s32 num, Code* codes ); CodeBody def_struct_body ( s32 num, Code* codes );
CodeBody def_union_body ( s32 num, ... ); CodeBody def_union_body ( s32 num, ... );
CodeBody def_union_body ( s32 num, Code* codes ); CodeBody def_union_body ( s32 num, Code* codes );
#pragma endregion Upfront #pragma endregion Upfront
#pragma region Parsing #pragma region Parsing
CodeClass parse_class ( StrC class_def ); CodeClass parse_class ( StrC class_def );
CodeEnum parse_enum ( StrC enum_def ); CodeEnum parse_enum ( StrC enum_def );
CodeBody parse_export_body ( StrC export_def ); CodeBody parse_export_body ( StrC export_def );
CodeExtern parse_extern_link ( StrC exten_link_def); CodeExtern parse_extern_link ( StrC exten_link_def);
CodeFriend parse_friend ( StrC friend_def ); CodeFriend parse_friend ( StrC friend_def );
CodeFn parse_function ( StrC fn_def ); CodeFn parse_function ( StrC fn_def );
CodeBody parse_global_body ( StrC body_def ); CodeBody parse_global_body ( StrC body_def );
CodeNamespace parse_namespace ( StrC namespace_def ); CodeNamespace parse_namespace ( StrC namespace_def );
CodeOperator parse_operator ( StrC operator_def ); CodeOperator parse_operator ( StrC operator_def );
CodeOpCast parse_operator_cast( StrC operator_def ); CodeOpCast parse_operator_cast( StrC operator_def );
CodeStruct parse_struct ( StrC struct_def ); CodeStruct parse_struct ( StrC struct_def );
CodeTemplate parse_template ( StrC template_def ); CodeTemplate parse_template ( StrC template_def );
CodeType parse_type ( StrC type_def ); CodeType parse_type ( StrC type_def );
CodeTypedef parse_typedef ( StrC typedef_def ); CodeTypedef parse_typedef ( StrC typedef_def );
CodeUnion parse_union ( StrC union_def ); CodeUnion parse_union ( StrC union_def );
CodeUsing parse_using ( StrC using_def ); CodeUsing parse_using ( StrC using_def );
CodeVar parse_variable ( StrC var_def ); CodeVar parse_variable ( StrC var_def );
#pragma endregion Parsing #pragma endregion Parsing
#pragma region Untyped text #pragma region Untyped text
@ -1699,7 +1706,7 @@ Define_CodeImpl( CodeNamespace );
Define_CodeImpl( CodeOperator ); Define_CodeImpl( CodeOperator );
Define_CodeImpl( CodeOpCast ); Define_CodeImpl( CodeOpCast );
Define_CodeImpl( CodeParam ); Define_CodeImpl( CodeParam );
Define_CodeImpl( CodeSpecifier ); Define_CodeImpl( CodeSpecifiers );
Define_CodeImpl( CodeStruct ); Define_CodeImpl( CodeStruct );
Define_CodeImpl( CodeTemplate ); Define_CodeImpl( CodeTemplate );
Define_CodeImpl( CodeType ); Define_CodeImpl( CodeType );
@ -1730,7 +1737,7 @@ Define_AST_Cast( Namespace );
Define_AST_Cast( Operator ); Define_AST_Cast( Operator );
Define_AST_Cast( OpCast ); Define_AST_Cast( OpCast );
Define_AST_Cast( Param ); Define_AST_Cast( Param );
Define_AST_Cast( Specifier ); Define_AST_Cast( Specifiers );
Define_AST_Cast( Struct ); Define_AST_Cast( Struct );
Define_AST_Cast( Template ); Define_AST_Cast( Template );
Define_AST_Cast( Type ); Define_AST_Cast( Type );
@ -1760,7 +1767,7 @@ Define_CodeCast( Namespace );
Define_CodeCast( Operator ); Define_CodeCast( Operator );
Define_CodeCast( OpCast ); Define_CodeCast( OpCast );
Define_CodeCast( Param ); Define_CodeCast( Param );
Define_CodeCast( Specifier ); Define_CodeCast( Specifiers );
Define_CodeCast( Struct ); Define_CodeCast( Struct );
Define_CodeCast( Template ); Define_CodeCast( Template );
Define_CodeCast( Type ); Define_CodeCast( Type );
@ -1956,23 +1963,23 @@ StrC token_fmt_impl( sw num, ... )
extern Code pragma_once; extern Code pragma_once;
extern CodeSpecifier spec_const; extern CodeSpecifiers spec_const;
extern CodeSpecifier spec_consteval; extern CodeSpecifiers spec_consteval;
extern CodeSpecifier spec_constexpr; extern CodeSpecifiers spec_constexpr;
extern CodeSpecifier spec_constinit; extern CodeSpecifiers spec_constinit;
extern CodeSpecifier spec_extern_linkage; extern CodeSpecifiers spec_extern_linkage;
extern CodeSpecifier spec_global; extern CodeSpecifiers spec_global;
extern CodeSpecifier spec_inline; extern CodeSpecifiers spec_inline;
extern CodeSpecifier spec_internal_linkage; extern CodeSpecifiers spec_internal_linkage;
extern CodeSpecifier spec_local_persist; extern CodeSpecifiers spec_local_persist;
extern CodeSpecifier spec_mutable; extern CodeSpecifiers spec_mutable;
extern CodeSpecifier spec_ptr; extern CodeSpecifiers spec_ptr;
extern CodeSpecifier spec_ref; extern CodeSpecifiers spec_ref;
extern CodeSpecifier spec_register; extern CodeSpecifiers spec_register;
extern CodeSpecifier spec_rvalue; extern CodeSpecifiers spec_rvalue;
extern CodeSpecifier spec_static_member; extern CodeSpecifiers spec_static_member;
extern CodeSpecifier spec_thread_local; extern CodeSpecifiers spec_thread_local;
extern CodeSpecifier spec_volatile; extern CodeSpecifiers spec_volatile;
#pragma endregion Constants #pragma endregion Constants
#pragma region Macros #pragma region Macros

View File

@ -243,6 +243,7 @@
<Type Name="gen::AST_OpCast"> <Type Name="gen::AST_OpCast">
<DisplayString>{Name} Type: {Type}</DisplayString> <DisplayString>{Name} Type: {Type}</DisplayString>
<Expand> <Expand>
<Item Name="Specs">Specs</Item>
<Item Name="ValueType">ValueType</Item> <Item Name="ValueType">ValueType</Item>
<Item Name="Body">Body</Item> <Item Name="Body">Body</Item>
<Item Name="Parent">Parent</Item> <Item Name="Parent">Parent</Item>
@ -551,7 +552,7 @@
</Expand> </Expand>
</Type> </Type>
<Type Name="gen::CodeSpecifier"> <Type Name="gen::CodeSpecifiers">
<DisplayString Condition="ast == nullptr">Null</DisplayString> <DisplayString Condition="ast == nullptr">Null</DisplayString>
<DisplayString Condition="ast != nullptr">{ast->Name} {ast->Type}</DisplayString> <DisplayString Condition="ast != nullptr">{ast->Name} {ast->Type}</DisplayString>
<Expand> <Expand>

View File

@ -29,9 +29,9 @@ Code gen__array( StrC type )
static CodeType t_allocator_info = def_type( name(AllocatorInfo) ); static CodeType t_allocator_info = def_type( name(AllocatorInfo) );
static Code v_nullptr = code_str(nullptr); static Code v_nullptr = code_str(nullptr);
static CodeSpecifier spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static ); static CodeSpecifiers spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static );
static CodeSpecifier spec_static_inline = def_specifiers( 2, ESpecifier::Static, ESpecifier::Inline ); static CodeSpecifiers spec_static_inline = def_specifiers( 2, ESpecifier::Static, ESpecifier::Inline );
static CodeSpecifier spec_static = def_specifier( ESpecifier::Static ); static CodeSpecifiers spec_static = def_specifier( ESpecifier::Static );
static CodeUsing using_header = def_using( name(Header), def_type( name(ArrayHeader) ) ); static CodeUsing using_header = def_using( name(Header), def_type( name(ArrayHeader) ) );
static CodeVar ct_grow_formula = def_variable( t_auto, name(grow_formula), untyped_str( code( & array_grow_formula )), spec_ct_member ); static CodeVar ct_grow_formula = def_variable( t_auto, name(grow_formula), untyped_str( code( & array_grow_formula )), spec_ct_member );