WIP (Not compiling prob): Started to overhaul macro handling

This commit is contained in:
Edward R. Gonzalez 2024-12-14 14:02:16 -05:00
parent 3c249d2fae
commit 76257123da
14 changed files with 282 additions and 176 deletions

View File

@ -26,6 +26,7 @@ struct AST_Constructor;
// struct AST_BaseClass; // struct AST_BaseClass;
struct AST_Class; struct AST_Class;
struct AST_Define; struct AST_Define;
struct AST_DefineParams;
struct AST_Destructor; struct AST_Destructor;
struct AST_Enum; struct AST_Enum;
struct AST_Exec; struct AST_Exec;
@ -98,6 +99,7 @@ typedef AST_Comment* CodeComment;
typedef AST_Class* CodeClass; typedef AST_Class* CodeClass;
typedef AST_Constructor* CodeConstructor; typedef AST_Constructor* CodeConstructor;
typedef AST_Define* CodeDefine; typedef AST_Define* CodeDefine;
typedef AST_DefineParams* CodeDefineParams;
typedef AST_Destructor* CodeDestructor; typedef AST_Destructor* CodeDestructor;
typedef AST_Enum* CodeEnum; typedef AST_Enum* CodeEnum;
typedef AST_Exec* CodeExec; typedef AST_Exec* CodeExec;
@ -120,6 +122,7 @@ struct CodeComment;
struct CodeClass; struct CodeClass;
struct CodeConstructor; struct CodeConstructor;
struct CodeDefine; struct CodeDefine;
struct CodeDefineParams;
struct CodeDestructor; struct CodeDestructor;
struct CodeEnum; struct CodeEnum;
struct CodeExec; struct CodeExec;
@ -305,6 +308,7 @@ struct Code
operator CodeClass() const; operator CodeClass() const;
operator CodeConstructor() const; operator CodeConstructor() const;
operator CodeDefine() const; operator CodeDefine() const;
operator CodeDefineParams() const;
operator CodeDestructor() const; operator CodeDestructor() const;
operator CodeExec() const; operator CodeExec() const;
operator CodeEnum() const; operator CodeEnum() const;
@ -365,6 +369,7 @@ int AST_ArrSpecs_Cap =
/* /*
Simple AST POD with functionality to seralize into C++ syntax. Simple AST POD with functionality to seralize into C++ syntax.
TODO(Ed): Eventually haven't a transparent AST like this will longer be viable once statements & expressions are in (most likely....)
*/ */
struct AST struct AST
{ {
@ -372,7 +377,7 @@ struct AST
struct struct
{ {
Code InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable Code InlineCmt; // Class, Constructor, Destructor, Enum, Friend, Functon, Operator, OpCast, Struct, Typedef, Using, Variable
Code Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable Code Attributes; // Class, Enum, Function, Struct, Typedef, Union, Using, Variable // TODO(Ed): Parameters can have attributes
Code Specs; // Destructor, Function, Operator, Typename, Variable Code Specs; // Destructor, Function, Operator, Typename, Variable
union { union {
Code InitializerList; // Constructor Code InitializerList; // Constructor
@ -384,12 +389,12 @@ struct AST
union { union {
Code Macro; // Parameter Code Macro; // Parameter
Code BitfieldSize; // Variable (Class/Struct Data Member) Code BitfieldSize; // Variable (Class/Struct Data Member)
Code Params; // Constructor, Function, Operator, Template, Typename Code Params; // Constructor, Define, Function, Operator, Template, Typename
Code UnderlyingTypeMacro; // Enum Code UnderlyingTypeMacro; // Enum
}; };
union { union {
Code ArrExpr; // Typename Code ArrExpr; // Typename
Code Body; // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union Code Body; // Class, Constructor, Define, Destructor, Enum, Friend, Function, Namespace, Struct, Union
Code Declaration; // Friend, Template Code Declaration; // Friend, Template
Code Value; // Parameter, Variable Code Value; // Parameter, Variable
}; };

View File

@ -146,9 +146,15 @@ struct AST_Define
{ {
union { union {
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
StrCached Content; struct
{
char _PAD_PROPERTIES_ [ sizeof(AST*) * 4 ];
CodeDefineParams Params;
Code Body; // Should be completely serialized for now to a: StrCached Content.
char _PAD_PROPERTIES_ [ sizeof(AST*) * 1 ];
};
}; };
StrCached Name; StrCached Name;
Code Prev; Code Prev;
Code Next; Code Next;
Token* Tok; Token* Tok;
@ -158,6 +164,22 @@ struct AST_Define
}; };
static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST"); static_assert( sizeof(AST_Define) == sizeof(AST), "ERROR: AST_Define is not the same size as AST");
struct AST_DefineParams
{
union {
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
};
StrCached Name;
CodeDefineParams Last;
CodeDefineParams Next;
Token* Tok;
Code Parent;
CodeType Type;
char _PAD_UNUSED_[ sizeof(ModuleFlag) ];
s32 NumEntries;
};
static_assert( sizeof(AST_DefineParams) == sizeof(AST), "ERROR: AST_DefineParams is not the same size as AST");
struct AST_Destructor struct AST_Destructor
{ {
union { union {
@ -660,6 +682,7 @@ struct AST_Params
char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ]; char _PAD_[ sizeof(Specifier) * AST_ArrSpecs_Cap + sizeof(AST*) ];
struct struct
{ {
// TODO(Ed): Support attributes for parameters (Some prefix macros can be converted to that...)
char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ]; char _PAD_PROPERTIES_2_[ sizeof(AST*) * 3 ];
CodeTypename ValueType; CodeTypename ValueType;
Code Macro; Code Macro;
@ -668,7 +691,7 @@ struct AST_Params
// char _PAD_PROPERTIES_3_[sizeof( AST* )]; // char _PAD_PROPERTIES_3_[sizeof( AST* )];
}; };
}; };
StrCached Name; StrCached Name;
CodeParams Last; CodeParams Last;
CodeParams Next; CodeParams Next;
Token* Tok; Token* Tok;

View File

@ -32,7 +32,17 @@ GEN_API StrBuilder class_to_strbuilder ( CodeClass self );
GEN_API void class_to_strbuilder_def( CodeClass self, StrBuilder* result ); GEN_API void class_to_strbuilder_def( CodeClass self, StrBuilder* result );
GEN_API void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result ); GEN_API void class_to_strbuilder_fwd( CodeClass self, StrBuilder* result );
GEN_API void params_append (CodeParams params, CodeParams param ); GEN_API void define_params_append (CodeDefineParams appendee, CodeDefineParams other );
GEN_API CodeDefineParams define_params_get (CodeDefineParams params, s32 idx);
GEN_API bool define_params_has_entries (CodeDefineParams params );
GEN_API StrBuilder define_params_to_strbuilder (CodeDefineParams params );
GEN_API void define_params_to_strbuilder_ref(CodeDefineParams params, StrBuilder* result );
GEN_API CodeDefineParams begin_CodeDefineParams(CodeDefineParams params);
GEN_API CodeDefineParams end_CodeDefineParams (CodeDefineParams params);
GEN_API CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter);
GEN_API void params_append (CodeParams appendee, CodeParams other );
GEN_API CodeParams params_get (CodeParams params, s32 idx); GEN_API CodeParams params_get (CodeParams params, s32 idx);
GEN_API bool params_has_entries (CodeParams params ); GEN_API bool params_has_entries (CodeParams params );
GEN_API StrBuilder params_to_strbuilder (CodeParams params ); GEN_API StrBuilder params_to_strbuilder (CodeParams params );
@ -192,12 +202,11 @@ struct CodeParams
{ {
#if ! GEN_C_LIKE_CPP #if ! GEN_C_LIKE_CPP
Using_Code( CodeParams ); Using_Code( CodeParams );
forceinline void append( CodeParams other ); forceinline void append( CodeParams other ) { return params_append(* this, other) }
forceinline CodeParams get( s32 idx ); forceinline CodeParams get( s32 idx ) { return params_get( * this, idx); }
forceinline bool has_entries(); forceinline bool has_entries() { return params_has_entries(* this); }
forceinline StrBuilder to_strbuilder(); forceinline StrBuilder to_strbuilder() { return params_to_strbuilder(* this); }
forceinline void to_strbuilder( StrBuilder& result ); forceinline void to_strbuilder( StrBuilder& result ) { return params_to_strbuilder_ref(*this, & result); }
#endif #endif
Using_CodeOps( CodeParams ); Using_CodeOps( CodeParams );
forceinline CodeParams begin() { return begin_CodeParams(* this); } forceinline CodeParams begin() { return begin_CodeParams(* this); }
@ -212,6 +221,29 @@ struct CodeParams
AST_Params* ast; AST_Params* ast;
}; };
struct CodeDefineParams
{
#if ! GEN_C_LIKE_CPP
Using_Code( CodeDefineParams );
forceinline void append( CodeDefineParams other ) { return params_append( cast(CodeParams, * this), other) }
forceinline CodeDefineParams get( s32 idx ) { return params_get( cast(CodeParams, * this), idx); }
forceinline bool has_entries() { return params_has_entries( cast(CodeParams, * this)); }
forceinline StrBuilder to_strbuilder() { return define_params_to_strbuilder(* this); }
forceinline void to_strbuilder( StrBuilder& result ) { return define_params_to_strbuilder_ref(* this, & result); }
#endif
Using_CodeOps( CodeDefineParams );
forceinline CodeDefineParams begin() { return begin_CodeParams( cast(CodeParams, * this)); }
forceinline CodeDefineParams end() { return end_CodeParams( cast(CodeParams, * this)); }
forceinline operator Code() { return { (AST*)ast }; }
forceinline CodeDefineParams operator *() { return * this; } // Required to support for-range iteration.
forceinline AST_DefineParams* operator->() {
GEN_ASSERT(ast);
return ast;
}
forceinline CodeDefineParams& operator++() { return cast(CodeParams, * this).operator ++() };
AST_DefineParams* ast;
};
struct CodeSpecifiers struct CodeSpecifiers
{ {
#if ! GEN_C_LIKE_CPP #if ! GEN_C_LIKE_CPP
@ -941,6 +973,7 @@ struct InvalidCode_ImplictCaster
operator CodeClass () const { return cast(CodeClass, Code_Invalid); } operator CodeClass () const { return cast(CodeClass, Code_Invalid); }
operator CodeConstructor () const { return cast(CodeConstructor, Code_Invalid); } operator CodeConstructor () const { return cast(CodeConstructor, Code_Invalid); }
operator CodeDefine () const { return cast(CodeDefine, Code_Invalid); } operator CodeDefine () const { return cast(CodeDefine, Code_Invalid); }
operator CodeDefineParams () const { return cast(CodeDefineParams, Code_Invalid); }
operator CodeDestructor () const { return cast(CodeDestructor, Code_Invalid); } operator CodeDestructor () const { return cast(CodeDestructor, Code_Invalid); }
operator CodeExec () const { return cast(CodeExec, Code_Invalid); } operator CodeExec () const { return cast(CodeExec, Code_Invalid); }
operator CodeEnum () const { return cast(CodeEnum, Code_Invalid); } operator CodeEnum () const { return cast(CodeEnum, Code_Invalid); }
@ -974,6 +1007,7 @@ struct NullCode_ImplicitCaster
operator CodeClass () const { return {nullptr}; } operator CodeClass () const { return {nullptr}; }
operator CodeConstructor () const { return {nullptr}; } operator CodeConstructor () const { return {nullptr}; }
operator CodeDefine () const { return {nullptr}; } operator CodeDefine () const { return {nullptr}; }
operator CodeDefineParams () const { return {nullptr}; }
operator CodeDestructor () const { return {nullptr}; } operator CodeDestructor () const { return {nullptr}; }
operator CodeExec () const { return {nullptr}; } operator CodeExec () const { return {nullptr}; }
operator CodeEnum () const { return {nullptr}; } operator CodeEnum () const { return {nullptr}; }
@ -1024,17 +1058,23 @@ forceinline StrBuilder to_strbuilder ( CodeClass self )
forceinline void to_strbuilder_def( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_def(self, & result); } forceinline void to_strbuilder_def( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_def(self, & result); }
forceinline void to_strbuilder_fwd( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_fwd(self, & result); } forceinline void to_strbuilder_fwd( CodeClass self, StrBuilder& result ) { return class_to_strbuilder_fwd(self, & result); }
forceinline void append (CodeParams params, CodeParams param ) { return params_append(params, param); } forceinline void append (CodeDefineParams appendee, CodeDefineParams other ) { return params_append(cast(CodeParam, appendee), other); }
forceinline CodeParams get (CodeParams params, s32 idx) { return params_get(params, idx); } forceinline CodeDefineParams get (CodeDefineParams params, s32 idx) { return params_get(cast(CodeParam, params), idx); }
forceinline bool has_entries (CodeParams params ) { return params_has_entries(params); } forceinline bool has_entries (CodeDefineParams params ) { return params_has_entries(cast(CodeParam, params)); }
forceinline StrBuilder to_strbuilder(CodeParams params ) { return params_to_strbuilder(params); } forceinline StrBuilder to_strbuilder(CodeDefineParams params ) { return define_params_to_strbuilder(params); }
forceinline void to_strbuilder(CodeParams params, StrBuilder& result ) { return params_to_strbuilder_ref(params, & result); } forceinline void to_strbuilder(CodeDefineParams params, StrBuilder& result ) { return define_params_to_strbuilder_ref(params, & result); }
forceinline void append (CodeParams appendee, CodeParams other ) { return params_append(appendee, other); }
forceinline CodeParams get (CodeParams params, s32 idx) { return params_get(params, idx); }
forceinline bool has_entries (CodeParams params ) { return params_has_entries(params); }
forceinline StrBuilder to_strbuilder(CodeParams params ) { return params_to_strbuilder(params); }
forceinline void to_strbuilder(CodeParams params, StrBuilder& result ) { return params_to_strbuilder_ref(params, & result); }
forceinline bool append (CodeSpecifiers specifiers, Specifier spec) { return specifiers_append(specifiers, spec); } forceinline bool append (CodeSpecifiers specifiers, Specifier spec) { return specifiers_append(specifiers, spec); }
forceinline s32 has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); } forceinline s32 has (CodeSpecifiers specifiers, Specifier spec) { return specifiers_has(specifiers, spec); }
forceinline s32 remove (CodeSpecifiers specifiers, Specifier to_remove ) { return specifiers_remove(specifiers, to_remove); } forceinline s32 remove (CodeSpecifiers specifiers, Specifier to_remove ) { return specifiers_remove(specifiers, to_remove); }
forceinline StrBuilder to_strbuilder(CodeSpecifiers specifiers) { return specifiers_to_strbuilder(specifiers); } forceinline StrBuilder to_strbuilder(CodeSpecifiers specifiers) { return specifiers_to_strbuilder(specifiers); }
forceinline void to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result) { return specifiers_to_strbuilder_ref(specifiers, & result); } forceinline void to_strbuilder(CodeSpecifiers specifiers, StrBuilder& result) { return specifiers_to_strbuilder_ref(specifiers, & result); }
forceinline void add_interface (CodeStruct self, CodeTypename interface) { return struct_add_interface(self, interface); } forceinline void add_interface (CodeStruct self, CodeTypename interface) { return struct_add_interface(self, interface); }
forceinline StrBuilder to_strbuilder (CodeStruct self) { return struct_to_strbuilder(self); } forceinline StrBuilder to_strbuilder (CodeStruct self) { return struct_to_strbuilder(self); }

View File

@ -257,6 +257,16 @@ CodeParams next_CodeParams(CodeParams params, CodeParams param_iter)
} }
#pragma endregion CodeParams #pragma endregion CodeParams
#pragma region CodeDefineParams
forceinline void define_params_append (CodeDefineParams appendee, CodeDefineParams other ) { params_append( cast(CodeParams, appendee), cast(CodeParams, other) ); }
forceinline CodeDefineParams define_params_get (CodeDefineParams self, s32 idx ) { return params_get( cast(CodeParams, self), idx); }
forceinline bool define_params_has_entries(CodeDefineParams self) { return params_has_entries( cast(CodeParams, self)); }
CodeDefineParams begin_CodeDefineParams(CodeDefineParams params) { return begin_CodeParams( cast(CodeParams, params)); }
CodeDefineParams end_CodeDefineParams (CodeDefineParams params) { return end_CodeParams ( cast(CodeParams, params)); }
CodeDefineParams next_CodeDefineParams (CodeDefineParams params, CodeDefineParams entry_iter) { return next_CodeParams ( cast(CodeParams, params), cast(CoeParams, entry_iter)); }
#pragma endregion CodeDefineParams
#pragma region CodeSpecifiers #pragma region CodeSpecifiers
inline inline
bool specifiers_append(CodeSpecifiers self, Specifier spec ) bool specifiers_append(CodeSpecifiers self, Specifier spec )

View File

@ -354,7 +354,7 @@ void deinit(Context* ctx)
array_free( ctx->CodePools); array_free( ctx->CodePools);
array_free( ctx->StringArenas); array_free( ctx->StringArenas);
arena_free(& ctx->LexArena); // arena_free(& ctx->LexArena);
array_free(ctx->PreprocessorDefines); array_free(ctx->PreprocessorDefines);
@ -463,10 +463,12 @@ Code make_code()
return result; return result;
} }
void set_preprocess_define( Str id, b32 is_functional ) { PreprocessorMacro* lookup_preprocess_macro( Str name ) {
StrBuilder builder = strbuilder_make_str( _ctx->Allocator_Temp, id ); u32 key = crc32( name.Ptr, name.Len );
if (is_functional) { return hashtable_get( _ctx->PreprocessorMacros, key );
strbuilder_append_char( & builder, '(' ); }
}
array_append( _ctx->PreprocessorDefines, cache_str( strbuilder_to_str(builder)) ); void register_preprocess_macro( PreprocessorMacro macro ) {
u32 key = crc32( macro.Name.Ptr, macro.Name.Len );
hashtable_set( _ctx->PreprocessorMacros, key, macro );
} }

View File

@ -71,7 +71,7 @@ struct Context
// Used by the lexer to persistently treat all these identifiers as preprocessor defines. // Used by the lexer to persistently treat all these identifiers as preprocessor defines.
// Populate with strings via gen::cache_str. // Populate with strings via gen::cache_str.
// Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments. // Functional defines must have format: id( ;at minimum to indicate that the define is only valid with arguments.
Array(StrCached) PreprocessorDefines; HashTable(PreprocessorMacro) PreprocessorMacros;
// Backend // Backend
@ -88,8 +88,8 @@ struct Context
// TODO(Ed): This needs to be just handled by a parser context // TODO(Ed): This needs to be just handled by a parser context
Arena LexArena; // Arena LexArena;
StringTable Lexer_defines; // StringTable Lexer_defines;
Array(Token) Lexer_Tokens; Array(Token) Lexer_Tokens;
// TODO(Ed): Active parse context vs a parse result need to be separated conceptually // TODO(Ed): Active parse context vs a parse result need to be separated conceptually
@ -109,9 +109,13 @@ GEN_API void reset(Context* ctx);
GEN_API void set_context(Context* ctx); GEN_API void set_context(Context* ctx);
// Mostly used to verify a macro entry exists for the given name
GEN_API PreprocessMacro* lookup_preprocess_macro( Str Name );
// Alternative way to add a preprocess define entry for the lexer & parser to utilize // Alternative way to add a preprocess define entry for the lexer & parser to utilize
// if the user doesn't want to use def_define // if the user doesn't want to use def_define
GEN_API void set_preprocess_define( Str id, b32 is_functional ); // Macros are tracked by name so if the name already exists the entry will be overwritten.
GEN_API void register_preprocess_macro( PreprocessorMacro macro );
// Used internally to retrive or make string allocations. // Used internally to retrive or make string allocations.
// Strings are stored in a series of string arenas of fixed size (SizePer_StringArena) // Strings are stored in a series of string arenas of fixed size (SizePer_StringArena)
@ -150,9 +154,11 @@ struct Opts_def_constructor {
GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT ); GEN_API CodeConstructor def_constructor( Opts_def_constructor opts GEN_PARAM_DEFAULT );
struct Opts_def_define { struct Opts_def_define {
b32 dont_append_preprocess_defines; MacroFlags flags;
CodeDefineParams params;
b32 dont_register_to_preprocess_macros;
}; };
GEN_API CodeDefine def_define( Str name, Str content, Opts_def_define opts GEN_PARAM_DEFAULT ); GEN_API CodeDefine def_define( Str name, MacroType type, Opts_def_define opts GEN_PARAM_DEFAULT );
struct Opts_def_destructor { struct Opts_def_destructor {
Code body; Code body;

View File

@ -221,6 +221,9 @@ s32 lex_preprocessor_directive( LexContext* ctx )
name.Text.Len = 1; name.Text.Len = 1;
move_forward(); move_forward();
PreprocessorMacro* registered_macro = lookup_preprocess_macro(name.Text);
while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) ) while ( ctx->left && ( char_is_alphanumeric((* ctx->scanner)) || (* ctx->scanner) == '_' ) )
{ {
move_forward(); move_forward();
@ -477,23 +480,24 @@ TokArray lex( Str content )
return null_array; return null_array;
} }
for ( StrCached* entry = array_begin(_ctx->PreprocessorDefines); entry != array_end(_ctx->PreprocessorDefines); entry = array_next(_ctx->PreprocessorDefines, entry)) // TODO(ED): Remove this when preprocess defines has been converted
{ // for ( StrCached* entry = array_begin(_ctx->PreprocessorDefines); entry != array_end(_ctx->PreprocessorDefines); entry = array_next(_ctx->PreprocessorDefines, entry))
s32 length = 0; // {
char const* entry_scanner = (*entry).Ptr; // s32 length = 0;
while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') ) // char const* entry_scanner = (*entry).Ptr;
{ // while ( entry->Len > length && (char_is_alphanumeric( *entry_scanner ) || *entry_scanner == '_') )
entry_scanner++; // {
length ++; // entry_scanner++;
} // length ++;
if ( entry_scanner[0] == '(' ) // }
{ // if ( entry_scanner[0] == '(' )
length++; // {
} // length++;
// }
u64 key = crc32( entry->Ptr, length ); // u64 key = crc32( entry->Ptr, length );
hashtable_set(c.defines, key, * entry ); // hashtable_set(c.defines, key, * entry );
} // }
array_clear(_ctx->Lexer_Tokens); array_clear(_ctx->Lexer_Tokens);
@ -1210,8 +1214,6 @@ TokArray lex( Str content )
} }
} }
hashtable_clear(_ctx->Lexer_defines);
// defines_map_arena.free();
TokArray result = { _ctx->Lexer_Tokens, 0 }; TokArray result = { _ctx->Lexer_Tokens, 0 };
return result; return result;
} }

View File

@ -1774,7 +1774,7 @@ CodeBody parse_global_nspace( CodeType which )
// <Attributes> // <Attributes>
} }
//! Fallthrough intentional //! Fallthrough intentional
GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES: GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES:
{ {
Specifier specs_found[16] = { Spec_NumSpecifiers }; Specifier specs_found[16] = { Spec_NumSpecifiers };
s32 NumSpecifiers = 0; s32 NumSpecifiers = 0;
@ -1787,7 +1787,7 @@ CodeBody parse_global_nspace( CodeType which )
switch ( spec ) switch ( spec )
{ {
GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIERS_CASES: GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES:
break; break;
case Spec_Consteval: case Spec_Consteval:
@ -2687,6 +2687,7 @@ CodeParams parse_params( bool use_template_capture )
#define CheckEndParams() \ #define CheckEndParams() \
(use_template_capture ? (currtok.Text.Ptr[ 0 ] != '>') : (currtok.Type != Tok_Capture_End)) (use_template_capture ? (currtok.Text.Ptr[ 0 ] != '>') : (currtok.Type != Tok_Capture_End))
// TODO(Ed): Use expression macros or this? macro as attribute?
// Ex: Unreal has this type of macro: vvvvvvvvv // Ex: Unreal has this type of macro: vvvvvvvvv
// COREUOBJECT_API void CallFunction( FFrame& Stack, RESULT_DECL, UFunction* Function ); // COREUOBJECT_API void CallFunction( FFrame& Stack, RESULT_DECL, UFunction* Function );
// and: vvvv // and: vvvv
@ -2713,6 +2714,7 @@ CodeParams parse_params( bool use_template_capture )
// ( <Macro> <ValueType> <Name> // ( <Macro> <ValueType> <Name>
} }
// TODO(Ed): Use expression macro for this?
// Unreal has yet another type of macro: // Unreal has yet another type of macro:
// template<class T UE_REQUIRES(TPointerIsConvertibleFromTo<T, UInterface>::Value)> // template<class T UE_REQUIRES(TPointerIsConvertibleFromTo<T, UInterface>::Value)>
// class T ... and then ^this^ UE_REQUIRES shows up // class T ... and then ^this^ UE_REQUIRES shows up

View File

@ -25,7 +25,7 @@ case Spec_Static: \
case Spec_Volatile: \ case Spec_Volatile: \
case Spec_Virtual case Spec_Virtual
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \ #define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
case Tok_Spec_Consteval: \ case Tok_Spec_Consteval: \
case Tok_Spec_Constexpr: \ case Tok_Spec_Constexpr: \
case Tok_Spec_Constinit: \ case Tok_Spec_Constinit: \
@ -37,7 +37,7 @@ case Tok_Spec_Internal_Linkage: \
case Tok_Spec_NeverInline: \ case Tok_Spec_NeverInline: \
case Tok_Spec_Static case Tok_Spec_Static
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIERS_CASES \ #define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES \
case Spec_Constexpr: \ case Spec_Constexpr: \
case Spec_Constinit: \ case Spec_Constinit: \
case Spec_ForceInline: \ case Spec_ForceInline: \

View File

@ -6,37 +6,49 @@
#include "gen/especifier.hpp" #include "gen/especifier.hpp"
#endif #endif
enum MacroFlags : u32 enum MacroTypes : u16
{ {
// Can only be one of these at a time (required) MT_Block_Start, // Not Supported yet
MF_Block_Start = bit(0), // Start of a "block" scope MT_Block_End, // Not Supported yet
MF_Block_End = bit(1), // End of a "block" scope MT_Case_Statement, // Not Supported yet
MF_Case_Statement = bit(2), // Used as a case statement (not utilized by the parser yet) MT_Expression,
MF_Expression = bit(3), // Used as an expresssion (not utilized by the parser yet) MT_Statement,
MF_Statement = bit(4), // Used a statement (will expect to be a lone macro) MT_Typename,
MF_Expects_Body = bit(5), // Expects to consume a braced scope
MF_Typename = bit(6), // Behaves as a typename
// Optional MF_UnderlyingType = GEN_U16_Max,
MF_Functional = bit(7), };
enum MacroFlags : u16
{
MF_Functional = bit(0), // Macro has parameters (args expected to be passed)
MF_Expects_Body = bit(1), // Expects to assign a braced scope to its body.
MF_Null = 0, MF_Null = 0,
MF_UnderlyingType = GEN_U32_MAX, MF_UnderlyingType = GEN_U16_Max,
};
struct PreprocessorMacro
{
StrCached Name;
MacroTypes Type;
MacroFlags Flags;
}; };
enum TokFlags : u32 enum TokFlags : u32
{ {
TF_Operator = bit(0), TF_Operator = bit(0),
TF_Assign = bit(1), TF_Assign = bit(1),
TF_Preprocess = bit(2), TF_Preprocess = bit(2),
TF_Preprocess_Cond = bit(3), TF_Preprocess_Cond = bit(3),
TF_Attribute = bit(6), TF_Attribute = bit(6),
TF_AccessOperator = bit( 7 ), TF_AccessOperator = bit(7),
TF_AccessSpecifier = bit( 8 ), TF_AccessSpecifier = bit(8),
TF_Specifier = bit( 9 ), TF_Specifier = bit(9),
TF_EndDefinition = bit( 10 ), // Either ; or } TF_EndDefinition = bit(10), // Either ; or }
TF_Formatting = bit( 11 ), TF_Formatting = bit(11),
TF_Literal = bit( 12 ), TF_Literal = bit(12),
TF_Macro_Functional = bit(13),
TF_Macro_Expects_Body = bit(14),
TF_Null = 0, TF_Null = 0,
TF_UnderlyingType = GEN_U32_MAX, TF_UnderlyingType = GEN_U32_MAX,
@ -123,7 +135,7 @@ struct LexContext
char const* scanner; char const* scanner;
s32 line; s32 line;
s32 column; s32 column;
StringTable defines; // StringTable defines;
Token token; Token token;
}; };

View File

@ -37,6 +37,7 @@ Operator_Member_Fwd, "operator"
Operator_Cast, "operator" Operator_Cast, "operator"
Operator_Cast_Fwd, "operator" Operator_Cast_Fwd, "operator"
Parameters, "__NA__" Parameters, "__NA__"
Parameters_Define, "__NA__"
Preprocess_Define, "define" Preprocess_Define, "define"
Preprocess_Include, "include" Preprocess_Include, "include"
Preprocess_If, "if" Preprocess_If, "if"

1 Invalid __NA__
37 Operator_Cast operator
38 Operator_Cast_Fwd operator
39 Parameters __NA__
40 Parameters_Define __NA__
41 Preprocess_Define define
42 Preprocess_Include include
43 Preprocess_If if

View File

@ -1,95 +1,97 @@
Invalid, "__invalid__" Invalid, "__invalid__"
Access_Private, "private" Access_Private, "private"
Access_Protected, "protected" Access_Protected, "protected"
Access_Public, "public" Access_Public, "public"
Access_MemberSymbol, "." Access_MemberSymbol, "."
Access_StaticSymbol, "::" Access_StaticSymbol, "::"
Ampersand, "&" Ampersand, "&"
Ampersand_DBL, "&&" Ampersand_DBL, "&&"
Assign_Classifer, ":" Assign_Classifer, ":"
Attribute_Open, "[[" Attribute_Open, "[["
Attribute_Close, "]]" Attribute_Close, "]]"
BraceCurly_Open, "{" BraceCurly_Open, "{"
BraceCurly_Close, "}" BraceCurly_Close, "}"
BraceSquare_Open, "[" BraceSquare_Open, "["
BraceSquare_Close, "]" BraceSquare_Close, "]"
Capture_Start, "(" Capture_Start, "("
Capture_End, ")" Capture_End, ")"
Comment, "__comment__" Comment, "__comment__"
Comment_End, "__comment_end__" Comment_End, "__comment_end__"
Comment_Start, "__comment_start__" Comment_Start, "__comment_start__"
Char, "__character__" Char, "__character__"
Comma, "," Comma, ","
Decl_Class, "class" Decl_Class, "class"
Decl_GNU_Attribute, "__attribute__" Decl_GNU_Attribute, "__attribute__"
Decl_MSVC_Attribute, "__declspec" Decl_MSVC_Attribute, "__declspec"
Decl_Enum, "enum" Decl_Enum, "enum"
Decl_Extern_Linkage, "extern" Decl_Extern_Linkage, "extern"
Decl_Friend, "friend" Decl_Friend, "friend"
Decl_Module, "module" Decl_Module, "module"
Decl_Namespace, "namespace" Decl_Namespace, "namespace"
Decl_Operator, "operator" Decl_Operator, "operator"
Decl_Struct, "struct" Decl_Struct, "struct"
Decl_Template, "template" Decl_Template, "template"
Decl_Typedef, "typedef" Decl_Typedef, "typedef"
Decl_Using, "using" Decl_Using, "using"
Decl_Union, "union" Decl_Union, "union"
Identifier, "__identifier__" Identifier, "__identifier__"
Module_Import, "import" Module_Import, "import"
Module_Export, "export" Module_Export, "export"
NewLine, "__new_line__" NewLine, "__new_line__"
Number, "__number__" Number, "__number__"
Operator, "__operator__" Operator, "__operator__"
Preprocess_Hash, "#" Preprocess_Hash, "#"
Preprocess_Define, "define" Preprocess_Define, "define"
Preprocess_If, "if" Preprocess_If, "if"
Preprocess_IfDef, "ifdef" Preprocess_IfDef, "ifdef"
Preprocess_IfNotDef, "ifndef" Preprocess_IfNotDef, "ifndef"
Preprocess_ElIf, "elif" Preprocess_ElIf, "elif"
Preprocess_Else, "else" Preprocess_Else, "else"
Preprocess_EndIf, "endif" Preprocess_EndIf, "endif"
Preprocess_Include, "include" Preprocess_Include, "include"
Preprocess_Pragma, "pragma" Preprocess_Pragma, "pragma"
Preprocess_Content, "__macro_content__" Preprocess_Content, "__macro_content__"
Preprocess_Macro, "__macro__" Preprocess_Macro_Expr, "__macro_expression__"
Preprocess_Unsupported, "__unsupported__" Preprocess_Macro_Stmt, "__macro_statment__"
Spec_Alignas, "alignas" Preprocess_Macro_Typename, "__macro_typename__"
Spec_Const, "const" Preprocess_Unsupported, "__unsupported__"
Spec_Consteval, "consteval" Spec_Alignas, "alignas"
Spec_Constexpr, "constexpr" Spec_Const, "const"
Spec_Constinit, "constinit" Spec_Consteval, "consteval"
Spec_Explicit, "explicit" Spec_Constexpr, "constexpr"
Spec_Extern, "extern" Spec_Constinit, "constinit"
Spec_Final, "final" Spec_Explicit, "explicit"
Spec_ForceInline, "forceinline" Spec_Extern, "extern"
Spec_Global, "global" Spec_Final, "final"
Spec_Inline, "inline" Spec_ForceInline, "forceinline"
Spec_Internal_Linkage, "internal" Spec_Global, "global"
Spec_LocalPersist, "local_persist" Spec_Inline, "inline"
Spec_Mutable, "mutable" Spec_Internal_Linkage, "internal"
Spec_NeverInline, "neverinline" Spec_LocalPersist, "local_persist"
Spec_Override, "override" Spec_Mutable, "mutable"
Spec_Static, "static" Spec_NeverInline, "neverinline"
Spec_ThreadLocal, "thread_local" Spec_Override, "override"
Spec_Volatile, "volatile" Spec_Static, "static"
Spec_Virtual, "virtual" Spec_ThreadLocal, "thread_local"
Star, "*" Spec_Volatile, "volatile"
Statement_End, ";" Spec_Virtual, "virtual"
StaticAssert, "static_assert" Star, "*"
String, "__string__" Statement_End, ";"
Type_Typename, "typename" StaticAssert, "static_assert"
Type_Unsigned, "unsigned" String, "__string__"
Type_Signed, "signed" Type_Typename, "typename"
Type_Short, "short" Type_Unsigned, "unsigned"
Type_Long, "long" Type_Signed, "signed"
Type_bool, "bool" Type_Short, "short"
Type_char, "char" Type_Long, "long"
Type_int, "int" Type_bool, "bool"
Type_double, "double" Type_char, "char"
Type_MS_int8, "__int8" Type_int, "int"
Type_MS_int16, "__int16" Type_double, "double"
Type_MS_int32, "__int32" Type_MS_int8, "__int8"
Type_MS_int64, "__int64" Type_MS_int16, "__int16"
Type_MS_W64, "_W64" Type_MS_int32, "__int32"
Varadic_Argument, "..." Type_MS_int64, "__int64"
__Attributes_Start, "__attrib_start__" Type_MS_W64, "_W64"
Varadic_Argument, "..."
__Attributes_Start, "__attrib_start__"

1 Invalid __invalid__
2 Access_Private private
3 Access_Protected protected
4 Access_Public public
5 Access_MemberSymbol .
6 Access_StaticSymbol ::
7 Ampersand &
8 Ampersand_DBL &&
9 Assign_Classifer :
10 Attribute_Open [[
11 Attribute_Close ]]
12 BraceCurly_Open {
13 BraceCurly_Close }
14 BraceSquare_Open [
15 BraceSquare_Close ]
16 Capture_Start (
17 Capture_End )
18 Comment __comment__
19 Comment_End __comment_end__
20 Comment_Start __comment_start__
21 Char __character__
22 Comma ,
23 Decl_Class class
24 Decl_GNU_Attribute __attribute__
25 Decl_MSVC_Attribute __declspec
26 Decl_Enum enum
27 Decl_Extern_Linkage extern
28 Decl_Friend friend
29 Decl_Module module
30 Decl_Namespace namespace
31 Decl_Operator operator
32 Decl_Struct struct
33 Decl_Template template
34 Decl_Typedef typedef
35 Decl_Using using
36 Decl_Union union
37 Identifier __identifier__
38 Module_Import import
39 Module_Export export
40 NewLine __new_line__
41 Number __number__
42 Operator __operator__
43 Preprocess_Hash #
44 Preprocess_Define define
45 Preprocess_If if
46 Preprocess_IfDef ifdef
47 Preprocess_IfNotDef ifndef
48 Preprocess_ElIf elif
49 Preprocess_Else else
50 Preprocess_EndIf endif
51 Preprocess_Include include
52 Preprocess_Pragma pragma
53 Preprocess_Content __macro_content__
54 Preprocess_Macro Preprocess_Macro_Expr __macro__ __macro_expression__
55 Preprocess_Unsupported Preprocess_Macro_Stmt __unsupported__ __macro_statment__
56 Spec_Alignas Preprocess_Macro_Typename alignas __macro_typename__
57 Spec_Const Preprocess_Unsupported const __unsupported__
58 Spec_Consteval Spec_Alignas consteval alignas
59 Spec_Constexpr Spec_Const constexpr const
60 Spec_Constinit Spec_Consteval constinit consteval
61 Spec_Explicit Spec_Constexpr explicit constexpr
62 Spec_Extern Spec_Constinit extern constinit
63 Spec_Final Spec_Explicit final explicit
64 Spec_ForceInline Spec_Extern forceinline extern
65 Spec_Global Spec_Final global final
66 Spec_Inline Spec_ForceInline inline forceinline
67 Spec_Internal_Linkage Spec_Global internal global
68 Spec_LocalPersist Spec_Inline local_persist inline
69 Spec_Mutable Spec_Internal_Linkage mutable internal
70 Spec_NeverInline Spec_LocalPersist neverinline local_persist
71 Spec_Override Spec_Mutable override mutable
72 Spec_Static Spec_NeverInline static neverinline
73 Spec_ThreadLocal Spec_Override thread_local override
74 Spec_Volatile Spec_Static volatile static
75 Spec_Virtual Spec_ThreadLocal virtual thread_local
76 Star Spec_Volatile * volatile
77 Statement_End Spec_Virtual ; virtual
78 StaticAssert Star static_assert *
79 String Statement_End __string__ ;
80 Type_Typename StaticAssert typename static_assert
81 Type_Unsigned String unsigned __string__
82 Type_Signed Type_Typename signed typename
83 Type_Short Type_Unsigned short unsigned
84 Type_Long Type_Signed long signed
85 Type_bool Type_Short bool short
86 Type_char Type_Long char long
87 Type_int Type_bool int bool
88 Type_double Type_char double char
89 Type_MS_int8 Type_int __int8 int
90 Type_MS_int16 Type_double __int16 double
91 Type_MS_int32 Type_MS_int8 __int32 __int8
92 Type_MS_int64 Type_MS_int16 __int64 __int16
93 Type_MS_W64 Type_MS_int32 _W64 __int32
94 Varadic_Argument Type_MS_int64 ... __int64
95 __Attributes_Start Type_MS_W64 __attrib_start__ _W64
96 Varadic_Argument ...
97 __Attributes_Start __attrib_start__

View File

@ -7,12 +7,13 @@ void convert_cpp_enum_to_c( CodeEnum to_convert, CodeBody to_append )
{ {
#pragma push_macro("enum_underlying") #pragma push_macro("enum_underlying")
#undef enum_underlying #undef enum_underlying
StrCached type = to_convert->UnderlyingType ? to_convert->UnderlyingType : to_convert->Name
CodeTypedef tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef enum <type> <name>; )));
if (to_convert->UnderlyingType) if (to_convert->UnderlyingType)
{ {
to_convert->UnderlyingTypeMacro = untyped_str(token_fmt("type", to_convert->UnderlyingType->Name, stringize(enum_underlying(<type>)))); to_convert->UnderlyingTypeMacro = untyped_str(token_fmt("type", to_convert->UnderlyingType->Name, stringize(enum_underlying(<type>))));
to_convert->UnderlyingType = CodeTypename{nullptr}; to_convert->UnderlyingType = CodeTypename{nullptr};
} }
CodeTypedef tdef = parse_typedef(token_fmt("name", to_convert->Name, stringize( typedef enum <name> <name>; )));
to_append.append(to_convert); to_append.append(to_convert);
to_append.append(tdef); to_append.append(tdef);
#pragma pop_macro("enum_underlying") #pragma pop_macro("enum_underlying")

View File

@ -27,7 +27,7 @@ case Spec_Static: \
case Spec_Volatile: \ case Spec_Volatile: \
case Spec_Virtual case Spec_Virtual
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIERS_CASES \ #define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_TOK_SPECIFIER_CASES \
case Tok_Spec_Consteval: \ case Tok_Spec_Consteval: \
case Tok_Spec_Constexpr: \ case Tok_Spec_Constexpr: \
case Tok_Spec_Constinit: \ case Tok_Spec_Constinit: \
@ -40,7 +40,7 @@ case Tok_Spec_Internal_Linkage: \
case Tok_Spec_NeverInline: \ case Tok_Spec_NeverInline: \
case Tok_Spec_Static case Tok_Spec_Static
#define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIERS_CASES \ #define GEN_PARSER_CLASS_GLOBAL_NSPACE_ALLOWED_MEMBER_SPECIFIER_CASES \
case Spec_Constexpr: \ case Spec_Constexpr: \
case Spec_Constinit: \ case Spec_Constinit: \
case Spec_ForceInline: \ case Spec_ForceInline: \