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,
"C_Cpp.errorSquiggles": "enabled",
"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*
* 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
* Exceptions
* 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:
**There is no support for validating expressions.**
**The reason:** Its difficult to parse without enough benefits.
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.
Its difficult to parse without enough benefits (At the metaprogramming level).
When it comes to templates:
@ -328,7 +323,7 @@ The following CodeTypes are used which the user may optionally use strong typing
* CodeOperator
* CodeOpCast
* 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
* CodeTemplate
* CodeType

View File

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

View File

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

View File

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

View File

@ -29,9 +29,9 @@ Code gen__array( StrC type )
static CodeType t_allocator_info = def_type( name(AllocatorInfo) );
static Code v_nullptr = code_str(nullptr);
static CodeSpecifier spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static );
static CodeSpecifier spec_static_inline = def_specifiers( 2, ESpecifier::Static, ESpecifier::Inline );
static CodeSpecifier spec_static = def_specifier( ESpecifier::Static );
static CodeSpecifiers spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static );
static CodeSpecifiers spec_static_inline = def_specifiers( 2, ESpecifier::Static, ESpecifier::Inline );
static CodeSpecifiers spec_static = def_specifier( ESpecifier::Static );
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 );