12 Commits

Author SHA1 Message Date
Ed_
13ebd105c4 Fix for convert_cpp_enum_to_c for gen_c_library
It wasn't generating correct typedefs for when underlying type was used over the enum name.
2025-01-30 14:14:53 -05:00
Ed_
bdd9c9bcdf Fixes for building all library types 2025-01-30 13:57:42 -05:00
Ed_
16bc66c80e Backporting changes done on UnrealGencpp repo
Commits:
ec77e8b - Fixes while parsing EditorEngine.h
5017429 - parse_complicated_definition fix when parsing Controller.h
aac0dd5 - Add  IRISCORE_API
049b59c - Support for attributes retated to an operator or function between the return type and the identifier/op (Thanks World.h...)
97d7e6d - Fix for attributes after name in using statements
9f204e7 - Support for final specifier on class & struct definitions
f0698cc - Added support for Spec_Delete (= delete on functions and operators) [Part 3]
1f6650a - Added support for Spec_Delete (= delete on functions and operators) [Part 2]
06ac8da - Added support for Spec_Delete (= delete on functions and operators)
2025-01-30 13:25:56 -05:00
Ed_
f8c42a53c6 Fix for parse_function_after_name suffix specifier macro 2025-01-29 02:35:55 -05:00
Ed_
eca538c6af Fixes for GEN_API symbol exports necessary for dynamic linking 2025-01-29 02:04:50 -05:00
Ed_
ce2be411d7 Add support for non Specifier enum SuffixSpecs in AST_Fn and parsing (Thanks Unreal) 2025-01-29 01:29:55 -05:00
Ed_
16fc3fa379 Separate ifndef for bitfield_is_set 2025-01-28 21:09:35 -05:00
Ed_
62b36ec8bb misc changes to clang format spacing 2025-01-28 14:49:19 -05:00
Ed_
b6b246fb38 Added refactor.exe binary 2024-12-19 09:40:41 -05:00
Ed_
d91d3c6b6f typo in _Generic psuedo 2024-12-17 13:30:41 -05:00
Ed_
3ab2673fd3 gen_c_library doc update 2024-12-17 13:29:38 -05:00
Ed_
ca7ff99a79 Code type coercion for builder_print in C11 library using generic selector. 2024-12-17 10:03:50 -05:00
41 changed files with 1207 additions and 884 deletions

2
.gitignore vendored
View File

@ -42,3 +42,5 @@ gen_c_library/gen
**/*.vcxproj.user **/*.vcxproj.user
test/c_library/gen test/c_library/gen
test/cpp_library/gen test/cpp_library/gen
!scripts/helpers/refactor.exe

View File

@ -21,11 +21,11 @@ using namespace gen;
struct Builder; struct Builder;
typedef struct Builder Builder; typedef struct Builder Builder;
Builder builder_open ( char const* path ); GEN_API Builder builder_open ( char const* path );
void builder_pad_lines ( Builder* builder, s32 num ); GEN_API void builder_pad_lines ( Builder* builder, s32 num );
void builder_print ( Builder* builder, Code code ); GEN_API void builder_print ( Builder* builder, Code code );
void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va ); GEN_API void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
void builder_write ( Builder* builder ); GEN_API void builder_write ( Builder* builder );
forceinline void builder_print_fmt ( Builder* builder, char const* fmt, ... ) { forceinline void builder_print_fmt ( Builder* builder, char const* fmt, ... ) {
va_list va; va_list va;

View File

@ -20,9 +20,9 @@
// This is a simple file reader that reads the entire file into memory. // This is a simple file reader that reads the entire file into memory.
// It has an extra option to skip the first few lines for undesired includes. // It has an extra option to skip the first few lines for undesired includes.
// This is done so that includes can be kept in dependency and component files so that intellisense works. // This is done so that includes can be kept in dependency and component files so that intellisense works.
Code scan_file( char const* path ); GEN_API Code scan_file( char const* path );
CodeBody parse_file( const char* path ); GEN_API CodeBody parse_file( const char* path );
// The follow is basic support for light csv parsing (use it as an example) // The follow is basic support for light csv parsing (use it as an example)
// Make something robust if its more serious. // Make something robust if its more serious.
@ -40,7 +40,7 @@ struct CSV_Columns2 {
Array(ADT_Node) Col_2; Array(ADT_Node) Col_2;
}; };
CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path); GEN_API CSV_Column parse_csv_one_column (AllocatorInfo allocator, char const* path);
CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path); GEN_API CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path);
#pragma endregion Scanner #pragma endregion Scanner

View File

@ -337,10 +337,10 @@ struct Code
#pragma region Statics #pragma region Statics
// Used to identify ASTs that should always be duplicated. (Global constant ASTs) // Used to identify ASTs that should always be duplicated. (Global constant ASTs)
extern Code Code_Global; GEN_API extern Code Code_Global;
// Used to identify invalid generated code. // Used to identify invalid generated code.
extern Code Code_Invalid; GEN_API extern Code Code_Invalid;
#pragma endregion Statics #pragma endregion Statics
struct Code_POD struct Code_POD
@ -378,7 +378,7 @@ struct AST
{ {
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 // TODO(Ed): Parameters can have attributes 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; // Class, Destructor, Function, Operator, Struct, Typename, Variable
union { union {
Code InitializerList; // Constructor Code InitializerList; // Constructor
Code ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces. Code ParentType; // Class, Struct, ParentType->Next has a possible list of interfaces.
@ -400,7 +400,7 @@ struct AST
}; };
union { union {
Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value ) Code NextVar; // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
Code SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed ) Code SuffixSpecs; // Typename, Function (Thanks Unreal)
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
}; };
}; };

View File

@ -100,7 +100,7 @@ struct AST_Class
{ {
CodeComment InlineCmt; // Only supported by forward declarations CodeComment InlineCmt; // Only supported by forward declarations
CodeAttributes Attributes; CodeAttributes Attributes;
char _PAD_SPECS_ [ sizeof(AST*) ]; CodeSpecifiers Specs; // Support for final
CodeTypename ParentType; CodeTypename ParentType;
char _PAD_PARAMS_[ sizeof(AST*) ]; char _PAD_PARAMS_[ sizeof(AST*) ];
CodeBody Body; CodeBody Body;
@ -575,7 +575,7 @@ struct AST_Fn
CodeTypename ReturnType; CodeTypename ReturnType;
CodeParams Params; CodeParams Params;
CodeBody Body; CodeBody Body;
char _PAD_PROPERTIES_ [ sizeof(AST*) ]; Code SuffixSpecs; // Thanks Unreal
}; };
}; };
StrCached Name; StrCached Name;
@ -970,7 +970,7 @@ struct AST_Struct
{ {
CodeComment InlineCmt; CodeComment InlineCmt;
CodeAttributes Attributes; CodeAttributes Attributes;
char _PAD_SPECS_ [ sizeof(AST*) ]; CodeSpecifiers Specs; // Support for final
CodeTypename ParentType; CodeTypename ParentType;
char _PAD_PARAMS_[ sizeof(AST*) ]; char _PAD_PARAMS_[ sizeof(AST*) ];
CodeBody Body; CodeBody Body;

View File

@ -186,10 +186,16 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) ); strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) );
} }
if ( self->Name.Len )
strbuilder_append_str( result, self->Name );
if (self->Specs && specifiers_has(self->Specs, Spec_Final) > -1)
strbuilder_append_str(result, txt(" final"));
if ( self->ParentType ) if ( self->ParentType )
{ {
Str access_level = access_spec_to_str( self->ParentAccess ); Str access_level = access_spec_to_str( self->ParentAccess );
strbuilder_append_fmt( result, "%S : %S %SB", self->Name, access_level, typename_to_strbuilder(self->ParentType) ); strbuilder_append_fmt( result, " : %S %SB", self->Name, access_level, typename_to_strbuilder(self->ParentType) );
CodeTypename interface = cast(CodeTypename, self->ParentType->Next); CodeTypename interface = cast(CodeTypename, self->ParentType->Next);
if ( interface ) if ( interface )
@ -201,10 +207,6 @@ void class_to_strbuilder_def( CodeClass self, StrBuilder* result )
interface = interface->Next ? cast(CodeTypename, interface->Next) : NullCode; interface = interface->Next ? cast(CodeTypename, interface->Next) : NullCode;
} }
} }
else if ( self->Name.Len )
{
strbuilder_append_str( result, self->Name );
}
if ( self->InlineCmt ) if ( self->InlineCmt )
{ {
@ -589,6 +591,10 @@ void fn_to_strbuilder_def(CodeFn self, StrBuilder* result )
} }
} }
// This is bodged in for now SOLEY for Unreal's PURE_VIRTUAL functional macro
if ( self->SuffixSpecs )
strbuilder_append_fmt( result, " %SB", code_to_strbuilder(self->SuffixSpecs) );
strbuilder_append_fmt( result, "\n{\n%SB\n}\n", body_to_strbuilder(self->Body) ); strbuilder_append_fmt( result, "\n{\n%SB\n}\n", body_to_strbuilder(self->Body) );
} }
@ -642,11 +648,18 @@ void fn_to_strbuilder_fwd(CodeFn self, StrBuilder* result )
strbuilder_append_fmt( result, " %.*s", spec_str.Len, spec_str.Ptr ); strbuilder_append_fmt( result, " %.*s", spec_str.Len, spec_str.Ptr );
} }
} }
if ( specifiers_has(self->Specs, Spec_Pure ) >= 0 )
strbuilder_append_str( result, txt(" = 0") );
else if ( specifiers_has(self->Specs, Spec_Delete ) >= 0 )
strbuilder_append_str( result, txt(" = delete") );
} }
if ( self->Specs && specifiers_has(self->Specs, Spec_Pure ) >= 0 ) // This is bodged in for now SOLEY for Unreal's PURE_VIRTUAL functional macro (I kept it open ended for other jank)
strbuilder_append_str( result, txt(" = 0;") ); if ( self->SuffixSpecs )
else if (self->Body) strbuilder_append_fmt( result, " %SB", code_to_strbuilder(self->SuffixSpecs) );
if (self->Body)
strbuilder_append_fmt( result, " = %SB;", body_to_strbuilder(self->Body) ); strbuilder_append_fmt( result, " = %SB;", body_to_strbuilder(self->Body) );
if ( self->InlineCmt ) if ( self->InlineCmt )
@ -1087,11 +1100,17 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) ); strbuilder_append_fmt( result, "%SB ", attributes_to_strbuilder(self->Attributes) );
} }
if ( self->Name.Len )
strbuilder_append_str( result, self->Name );
if (self->Specs && specifiers_has(self->Specs, Spec_Final))
strbuilder_append_str( result, txt(" final"));
if ( self->ParentType ) if ( self->ParentType )
{ {
Str access_level = access_spec_to_str( self->ParentAccess ); Str access_level = access_spec_to_str( self->ParentAccess );
strbuilder_append_fmt( result, "%S : %S %SB", self->Name, access_level, typename_to_strbuilder(self->ParentType) ); strbuilder_append_fmt( result, " : %S %SB", access_level, typename_to_strbuilder(self->ParentType) );
CodeTypename interface = cast(CodeTypename, self->ParentType->Next); CodeTypename interface = cast(CodeTypename, self->ParentType->Next);
if ( interface ) if ( interface )
@ -1103,10 +1122,6 @@ void struct_to_strbuilder_def( CodeStruct self, StrBuilder* result )
interface = interface->Next ? cast( CodeTypename, interface->Next) : NullCode; interface = interface->Next ? cast( CodeTypename, interface->Next) : NullCode;
} }
} }
else if ( self->Name.Len )
{
strbuilder_append_str( result, self->Name );
}
if ( self->InlineCmt ) if ( self->InlineCmt )
{ {

View File

@ -7,14 +7,14 @@
#pragma region generated code inline implementation #pragma region generated code inline implementation
inline Code& Code::operator=( Code other ) inline Code& Code::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -23,14 +23,14 @@ inline Code::operator bool()
return ast != nullptr; return ast != nullptr;
} }
inline CodeBody& CodeBody::operator=( Code other ) inline CodeBody& CodeBody::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -39,14 +39,14 @@ inline CodeBody::operator bool()
return ast != nullptr; return ast != nullptr;
} }
inline CodeAttributes& CodeAttributes::operator=( Code other ) inline CodeAttributes& CodeAttributes::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -57,27 +57,27 @@ inline CodeAttributes::operator bool()
inline CodeAttributes::operator Code() inline CodeAttributes::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Attributes* CodeAttributes::operator->() inline AST_Attributes* CodeAttributes::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeComment& CodeComment::operator=( Code other ) inline CodeComment& CodeComment::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -88,27 +88,27 @@ inline CodeComment::operator bool()
inline CodeComment::operator Code() inline CodeComment::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Comment* CodeComment::operator->() inline AST_Comment* CodeComment::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeConstructor& CodeConstructor::operator=( Code other ) inline CodeConstructor& CodeConstructor::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -119,27 +119,27 @@ inline CodeConstructor::operator bool()
inline CodeConstructor::operator Code() inline CodeConstructor::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Constructor* CodeConstructor::operator->() inline AST_Constructor* CodeConstructor::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeClass& CodeClass::operator=( Code other ) inline CodeClass& CodeClass::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -148,14 +148,14 @@ inline CodeClass::operator bool()
return ast != nullptr; return ast != nullptr;
} }
inline CodeDefine& CodeDefine::operator=( Code other ) inline CodeDefine& CodeDefine::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -166,27 +166,27 @@ inline CodeDefine::operator bool()
inline CodeDefine::operator Code() inline CodeDefine::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Define* CodeDefine::operator->() inline AST_Define* CodeDefine::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeDefineParams& CodeDefineParams::operator=( Code other ) inline CodeDefineParams& CodeDefineParams::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -195,14 +195,14 @@ inline CodeDefineParams::operator bool()
return ast != nullptr; return ast != nullptr;
} }
inline CodeDestructor& CodeDestructor::operator=( Code other ) inline CodeDestructor& CodeDestructor::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -213,27 +213,27 @@ inline CodeDestructor::operator bool()
inline CodeDestructor::operator Code() inline CodeDestructor::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Destructor* CodeDestructor::operator->() inline AST_Destructor* CodeDestructor::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeEnum& CodeEnum::operator=( Code other ) inline CodeEnum& CodeEnum::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -244,27 +244,27 @@ inline CodeEnum::operator bool()
inline CodeEnum::operator Code() inline CodeEnum::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Enum* CodeEnum::operator->() inline AST_Enum* CodeEnum::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeExec& CodeExec::operator=( Code other ) inline CodeExec& CodeExec::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -275,27 +275,27 @@ inline CodeExec::operator bool()
inline CodeExec::operator Code() inline CodeExec::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Exec* CodeExec::operator->() inline AST_Exec* CodeExec::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeExtern& CodeExtern::operator=( Code other ) inline CodeExtern& CodeExtern::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -306,27 +306,27 @@ inline CodeExtern::operator bool()
inline CodeExtern::operator Code() inline CodeExtern::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Extern* CodeExtern::operator->() inline AST_Extern* CodeExtern::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeFriend& CodeFriend::operator=( Code other ) inline CodeFriend& CodeFriend::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -337,27 +337,27 @@ inline CodeFriend::operator bool()
inline CodeFriend::operator Code() inline CodeFriend::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Friend* CodeFriend::operator->() inline AST_Friend* CodeFriend::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeFn& CodeFn::operator=( Code other ) inline CodeFn& CodeFn::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -368,27 +368,27 @@ inline CodeFn::operator bool()
inline CodeFn::operator Code() inline CodeFn::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Fn* CodeFn::operator->() inline AST_Fn* CodeFn::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeInclude& CodeInclude::operator=( Code other ) inline CodeInclude& CodeInclude::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -399,27 +399,27 @@ inline CodeInclude::operator bool()
inline CodeInclude::operator Code() inline CodeInclude::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Include* CodeInclude::operator->() inline AST_Include* CodeInclude::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeModule& CodeModule::operator=( Code other ) inline CodeModule& CodeModule::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -430,27 +430,27 @@ inline CodeModule::operator bool()
inline CodeModule::operator Code() inline CodeModule::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Module* CodeModule::operator->() inline AST_Module* CodeModule::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeNS& CodeNS::operator=( Code other ) inline CodeNS& CodeNS::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -461,27 +461,27 @@ inline CodeNS::operator bool()
inline CodeNS::operator Code() inline CodeNS::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_NS* CodeNS::operator->() inline AST_NS* CodeNS::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeOperator& CodeOperator::operator=( Code other ) inline CodeOperator& CodeOperator::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -492,27 +492,27 @@ inline CodeOperator::operator bool()
inline CodeOperator::operator Code() inline CodeOperator::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Operator* CodeOperator::operator->() inline AST_Operator* CodeOperator::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeOpCast& CodeOpCast::operator=( Code other ) inline CodeOpCast& CodeOpCast::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -523,27 +523,27 @@ inline CodeOpCast::operator bool()
inline CodeOpCast::operator Code() inline CodeOpCast::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_OpCast* CodeOpCast::operator->() inline AST_OpCast* CodeOpCast::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeParams& CodeParams::operator=( Code other ) inline CodeParams& CodeParams::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -552,14 +552,14 @@ inline CodeParams::operator bool()
return ast != nullptr; return ast != nullptr;
} }
inline CodePragma& CodePragma::operator=( Code other ) inline CodePragma& CodePragma::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -570,27 +570,27 @@ inline CodePragma::operator bool()
inline CodePragma::operator Code() inline CodePragma::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Pragma* CodePragma::operator->() inline AST_Pragma* CodePragma::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodePreprocessCond& CodePreprocessCond::operator=( Code other ) inline CodePreprocessCond& CodePreprocessCond::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -601,27 +601,27 @@ inline CodePreprocessCond::operator bool()
inline CodePreprocessCond::operator Code() inline CodePreprocessCond::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_PreprocessCond* CodePreprocessCond::operator->() inline AST_PreprocessCond* CodePreprocessCond::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeSpecifiers& CodeSpecifiers::operator=( Code other ) inline CodeSpecifiers& CodeSpecifiers::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -630,14 +630,14 @@ inline CodeSpecifiers::operator bool()
return ast != nullptr; return ast != nullptr;
} }
inline CodeStruct& CodeStruct::operator=( Code other ) inline CodeStruct& CodeStruct::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -646,14 +646,14 @@ inline CodeStruct::operator bool()
return ast != nullptr; return ast != nullptr;
} }
inline CodeTemplate& CodeTemplate::operator=( Code other ) inline CodeTemplate& CodeTemplate::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -664,27 +664,27 @@ inline CodeTemplate::operator bool()
inline CodeTemplate::operator Code() inline CodeTemplate::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Template* CodeTemplate::operator->() inline AST_Template* CodeTemplate::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeTypename& CodeTypename::operator=( Code other ) inline CodeTypename& CodeTypename::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -695,27 +695,27 @@ inline CodeTypename::operator bool()
inline CodeTypename::operator Code() inline CodeTypename::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Typename* CodeTypename::operator->() inline AST_Typename* CodeTypename::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeTypedef& CodeTypedef::operator=( Code other ) inline CodeTypedef& CodeTypedef::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -726,27 +726,27 @@ inline CodeTypedef::operator bool()
inline CodeTypedef::operator Code() inline CodeTypedef::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Typedef* CodeTypedef::operator->() inline AST_Typedef* CodeTypedef::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeUnion& CodeUnion::operator=( Code other ) inline CodeUnion& CodeUnion::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -757,27 +757,27 @@ inline CodeUnion::operator bool()
inline CodeUnion::operator Code() inline CodeUnion::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Union* CodeUnion::operator->() inline AST_Union* CodeUnion::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeUsing& CodeUsing::operator=( Code other ) inline CodeUsing& CodeUsing::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -788,27 +788,27 @@ inline CodeUsing::operator bool()
inline CodeUsing::operator Code() inline CodeUsing::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Using* CodeUsing::operator->() inline AST_Using* CodeUsing::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;
} }
inline CodeVar& CodeVar::operator=( Code other ) inline CodeVar& CodeVar::operator=(Code other)
{ {
if ( other.ast != nullptr && other->Parent != nullptr ) if (other.ast != nullptr && other->Parent != nullptr)
{ {
ast = rcast( decltype( ast ), code_duplicate( other ).ast ); ast = rcast(decltype(ast), code_duplicate(other).ast);
ast->Parent = { nullptr }; ast->Parent = { nullptr };
} }
ast = rcast( decltype( ast ), other.ast ); ast = rcast(decltype(ast), other.ast);
return *this; return *this;
} }
@ -819,14 +819,14 @@ inline CodeVar::operator bool()
inline CodeVar::operator Code() inline CodeVar::operator Code()
{ {
return *rcast( Code*, this ); return *rcast(Code*, this);
} }
inline AST_Var* CodeVar::operator->() inline AST_Var* CodeVar::operator->()
{ {
if ( ast == nullptr ) if (ast == nullptr)
{ {
log_failure( "Attempt to dereference a nullptr!\n" ); log_failure("Attempt to dereference a nullptr!\n");
return nullptr; return nullptr;
} }
return ast; return ast;

View File

@ -73,150 +73,150 @@ enum CodeType : u32
CT_UnderlyingType = GEN_U32_MAX CT_UnderlyingType = GEN_U32_MAX
}; };
inline Str codetype_to_str( CodeType type ) inline Str codetype_to_str(CodeType type)
{ {
local_persist Str lookup[] = { local_persist Str lookup[] = {
{ "Invalid", sizeof( "Invalid" ) - 1 }, { "Invalid", sizeof("Invalid") - 1 },
{ "Untyped", sizeof( "Untyped" ) - 1 }, { "Untyped", sizeof("Untyped") - 1 },
{ "NewLine", sizeof( "NewLine" ) - 1 }, { "NewLine", sizeof("NewLine") - 1 },
{ "Comment", sizeof( "Comment" ) - 1 }, { "Comment", sizeof("Comment") - 1 },
{ "Access_Private", sizeof( "Access_Private" ) - 1 }, { "Access_Private", sizeof("Access_Private") - 1 },
{ "Access_Protected", sizeof( "Access_Protected" ) - 1 }, { "Access_Protected", sizeof("Access_Protected") - 1 },
{ "Access_Public", sizeof( "Access_Public" ) - 1 }, { "Access_Public", sizeof("Access_Public") - 1 },
{ "PlatformAttributes", sizeof( "PlatformAttributes" ) - 1 }, { "PlatformAttributes", sizeof("PlatformAttributes") - 1 },
{ "Class", sizeof( "Class" ) - 1 }, { "Class", sizeof("Class") - 1 },
{ "Class_Fwd", sizeof( "Class_Fwd" ) - 1 }, { "Class_Fwd", sizeof("Class_Fwd") - 1 },
{ "Class_Body", sizeof( "Class_Body" ) - 1 }, { "Class_Body", sizeof("Class_Body") - 1 },
{ "Constructor", sizeof( "Constructor" ) - 1 }, { "Constructor", sizeof("Constructor") - 1 },
{ "Constructor_Fwd", sizeof( "Constructor_Fwd" ) - 1 }, { "Constructor_Fwd", sizeof("Constructor_Fwd") - 1 },
{ "Destructor", sizeof( "Destructor" ) - 1 }, { "Destructor", sizeof("Destructor") - 1 },
{ "Destructor_Fwd", sizeof( "Destructor_Fwd" ) - 1 }, { "Destructor_Fwd", sizeof("Destructor_Fwd") - 1 },
{ "Enum", sizeof( "Enum" ) - 1 }, { "Enum", sizeof("Enum") - 1 },
{ "Enum_Fwd", sizeof( "Enum_Fwd" ) - 1 }, { "Enum_Fwd", sizeof("Enum_Fwd") - 1 },
{ "Enum_Body", sizeof( "Enum_Body" ) - 1 }, { "Enum_Body", sizeof("Enum_Body") - 1 },
{ "Enum_Class", sizeof( "Enum_Class" ) - 1 }, { "Enum_Class", sizeof("Enum_Class") - 1 },
{ "Enum_Class_Fwd", sizeof( "Enum_Class_Fwd" ) - 1 }, { "Enum_Class_Fwd", sizeof("Enum_Class_Fwd") - 1 },
{ "Execution", sizeof( "Execution" ) - 1 }, { "Execution", sizeof("Execution") - 1 },
{ "Export_Body", sizeof( "Export_Body" ) - 1 }, { "Export_Body", sizeof("Export_Body") - 1 },
{ "Extern_Linkage", sizeof( "Extern_Linkage" ) - 1 }, { "Extern_Linkage", sizeof("Extern_Linkage") - 1 },
{ "Extern_Linkage_Body", sizeof( "Extern_Linkage_Body" ) - 1 }, { "Extern_Linkage_Body", sizeof("Extern_Linkage_Body") - 1 },
{ "Friend", sizeof( "Friend" ) - 1 }, { "Friend", sizeof("Friend") - 1 },
{ "Function", sizeof( "Function" ) - 1 }, { "Function", sizeof("Function") - 1 },
{ "Function_Fwd", sizeof( "Function_Fwd" ) - 1 }, { "Function_Fwd", sizeof("Function_Fwd") - 1 },
{ "Function_Body", sizeof( "Function_Body" ) - 1 }, { "Function_Body", sizeof("Function_Body") - 1 },
{ "Global_Body", sizeof( "Global_Body" ) - 1 }, { "Global_Body", sizeof("Global_Body") - 1 },
{ "Module", sizeof( "Module" ) - 1 }, { "Module", sizeof("Module") - 1 },
{ "Namespace", sizeof( "Namespace" ) - 1 }, { "Namespace", sizeof("Namespace") - 1 },
{ "Namespace_Body", sizeof( "Namespace_Body" ) - 1 }, { "Namespace_Body", sizeof("Namespace_Body") - 1 },
{ "Operator", sizeof( "Operator" ) - 1 }, { "Operator", sizeof("Operator") - 1 },
{ "Operator_Fwd", sizeof( "Operator_Fwd" ) - 1 }, { "Operator_Fwd", sizeof("Operator_Fwd") - 1 },
{ "Operator_Member", sizeof( "Operator_Member" ) - 1 }, { "Operator_Member", sizeof("Operator_Member") - 1 },
{ "Operator_Member_Fwd", sizeof( "Operator_Member_Fwd" ) - 1 }, { "Operator_Member_Fwd", sizeof("Operator_Member_Fwd") - 1 },
{ "Operator_Cast", sizeof( "Operator_Cast" ) - 1 }, { "Operator_Cast", sizeof("Operator_Cast") - 1 },
{ "Operator_Cast_Fwd", sizeof( "Operator_Cast_Fwd" ) - 1 }, { "Operator_Cast_Fwd", sizeof("Operator_Cast_Fwd") - 1 },
{ "Parameters", sizeof( "Parameters" ) - 1 }, { "Parameters", sizeof("Parameters") - 1 },
{ "Parameters_Define", sizeof( "Parameters_Define" ) - 1 }, { "Parameters_Define", sizeof("Parameters_Define") - 1 },
{ "Preprocess_Define", sizeof( "Preprocess_Define" ) - 1 }, { "Preprocess_Define", sizeof("Preprocess_Define") - 1 },
{ "Preprocess_Include", sizeof( "Preprocess_Include" ) - 1 }, { "Preprocess_Include", sizeof("Preprocess_Include") - 1 },
{ "Preprocess_If", sizeof( "Preprocess_If" ) - 1 }, { "Preprocess_If", sizeof("Preprocess_If") - 1 },
{ "Preprocess_IfDef", sizeof( "Preprocess_IfDef" ) - 1 }, { "Preprocess_IfDef", sizeof("Preprocess_IfDef") - 1 },
{ "Preprocess_IfNotDef", sizeof( "Preprocess_IfNotDef" ) - 1 }, { "Preprocess_IfNotDef", sizeof("Preprocess_IfNotDef") - 1 },
{ "Preprocess_ElIf", sizeof( "Preprocess_ElIf" ) - 1 }, { "Preprocess_ElIf", sizeof("Preprocess_ElIf") - 1 },
{ "Preprocess_Else", sizeof( "Preprocess_Else" ) - 1 }, { "Preprocess_Else", sizeof("Preprocess_Else") - 1 },
{ "Preprocess_EndIf", sizeof( "Preprocess_EndIf" ) - 1 }, { "Preprocess_EndIf", sizeof("Preprocess_EndIf") - 1 },
{ "Preprocess_Pragma", sizeof( "Preprocess_Pragma" ) - 1 }, { "Preprocess_Pragma", sizeof("Preprocess_Pragma") - 1 },
{ "Specifiers", sizeof( "Specifiers" ) - 1 }, { "Specifiers", sizeof("Specifiers") - 1 },
{ "Struct", sizeof( "Struct" ) - 1 }, { "Struct", sizeof("Struct") - 1 },
{ "Struct_Fwd", sizeof( "Struct_Fwd" ) - 1 }, { "Struct_Fwd", sizeof("Struct_Fwd") - 1 },
{ "Struct_Body", sizeof( "Struct_Body" ) - 1 }, { "Struct_Body", sizeof("Struct_Body") - 1 },
{ "Template", sizeof( "Template" ) - 1 }, { "Template", sizeof("Template") - 1 },
{ "Typedef", sizeof( "Typedef" ) - 1 }, { "Typedef", sizeof("Typedef") - 1 },
{ "Typename", sizeof( "Typename" ) - 1 }, { "Typename", sizeof("Typename") - 1 },
{ "Union", sizeof( "Union" ) - 1 }, { "Union", sizeof("Union") - 1 },
{ "Union_Fwd", sizeof( "Union_Fwd" ) - 1 }, { "Union_Fwd", sizeof("Union_Fwd") - 1 },
{ "Union_Body", sizeof( "Union_Body" ) - 1 }, { "Union_Body", sizeof("Union_Body") - 1 },
{ "Using", sizeof( "Using" ) - 1 }, { "Using", sizeof("Using") - 1 },
{ "Using_Namespace", sizeof( "Using_Namespace" ) - 1 }, { "Using_Namespace", sizeof("Using_Namespace") - 1 },
{ "Variable", sizeof( "Variable" ) - 1 }, { "Variable", sizeof("Variable") - 1 },
}; };
return lookup[type]; return lookup[type];
} }
inline Str codetype_to_keyword_str( CodeType type ) inline Str codetype_to_keyword_str(CodeType type)
{ {
local_persist Str lookup[] = { local_persist Str lookup[] = {
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "//", sizeof( "//" ) - 1 }, { "//", sizeof("//") - 1 },
{ "private", sizeof( "private" ) - 1 }, { "private", sizeof("private") - 1 },
{ "protected", sizeof( "protected" ) - 1 }, { "protected", sizeof("protected") - 1 },
{ "public", sizeof( "public" ) - 1 }, { "public", sizeof("public") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "class", sizeof( "class" ) - 1 }, { "class", sizeof("class") - 1 },
{ "clsss", sizeof( "clsss" ) - 1 }, { "clsss", sizeof("clsss") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "enum", sizeof( "enum" ) - 1 }, { "enum", sizeof("enum") - 1 },
{ "enum", sizeof( "enum" ) - 1 }, { "enum", sizeof("enum") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "enum class", sizeof( "enum class" ) - 1 }, { "enum class", sizeof("enum class") - 1 },
{ "enum class", sizeof( "enum class" ) - 1 }, { "enum class", sizeof("enum class") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "extern", sizeof( "extern" ) - 1 }, { "extern", sizeof("extern") - 1 },
{ "extern", sizeof( "extern" ) - 1 }, { "extern", sizeof("extern") - 1 },
{ "friend", sizeof( "friend" ) - 1 }, { "friend", sizeof("friend") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "module", sizeof( "module" ) - 1 }, { "module", sizeof("module") - 1 },
{ "namespace", sizeof( "namespace" ) - 1 }, { "namespace", sizeof("namespace") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof("operator") - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof("operator") - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof("operator") - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof("operator") - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof("operator") - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof("operator") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "define", sizeof( "define" ) - 1 }, { "define", sizeof("define") - 1 },
{ "include", sizeof( "include" ) - 1 }, { "include", sizeof("include") - 1 },
{ "if", sizeof( "if" ) - 1 }, { "if", sizeof("if") - 1 },
{ "ifdef", sizeof( "ifdef" ) - 1 }, { "ifdef", sizeof("ifdef") - 1 },
{ "ifndef", sizeof( "ifndef" ) - 1 }, { "ifndef", sizeof("ifndef") - 1 },
{ "elif", sizeof( "elif" ) - 1 }, { "elif", sizeof("elif") - 1 },
{ "else", sizeof( "else" ) - 1 }, { "else", sizeof("else") - 1 },
{ "endif", sizeof( "endif" ) - 1 }, { "endif", sizeof("endif") - 1 },
{ "pragma", sizeof( "pragma" ) - 1 }, { "pragma", sizeof("pragma") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "struct", sizeof( "struct" ) - 1 }, { "struct", sizeof("struct") - 1 },
{ "struct", sizeof( "struct" ) - 1 }, { "struct", sizeof("struct") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "template", sizeof( "template" ) - 1 }, { "template", sizeof("template") - 1 },
{ "typedef", sizeof( "typedef" ) - 1 }, { "typedef", sizeof("typedef") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "union", sizeof( "union" ) - 1 }, { "union", sizeof("union") - 1 },
{ "union", sizeof( "union" ) - 1 }, { "union", sizeof("union") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
{ "using", sizeof( "using" ) - 1 }, { "using", sizeof("using") - 1 },
{ "using namespace", sizeof( "using namespace" ) - 1 }, { "using namespace", sizeof("using namespace") - 1 },
{ "__NA__", sizeof( "__NA__" ) - 1 }, { "__NA__", sizeof("__NA__") - 1 },
}; };
return lookup[type]; return lookup[type];
} }
forceinline Str to_str( CodeType type ) forceinline Str to_str(CodeType type)
{ {
return codetype_to_str( type ); return codetype_to_str(type);
} }
forceinline Str to_keyword_str( CodeType type ) forceinline Str to_keyword_str(CodeType type)
{ {
return codetype_to_keyword_str( type ); return codetype_to_keyword_str(type);
} }

View File

@ -58,61 +58,61 @@ enum Operator : u32
Op_UnderlyingType = 0xffffffffu Op_UnderlyingType = 0xffffffffu
}; };
inline Str operator_to_str( Operator op ) inline Str operator_to_str(Operator op)
{ {
local_persist Str lookup[] = { local_persist Str lookup[] = {
{ "INVALID", sizeof( "INVALID" ) - 1 }, { "INVALID", sizeof("INVALID") - 1 },
{ "=", sizeof( "=" ) - 1 }, { "=", sizeof("=") - 1 },
{ "+=", sizeof( "+=" ) - 1 }, { "+=", sizeof("+=") - 1 },
{ "-=", sizeof( "-=" ) - 1 }, { "-=", sizeof("-=") - 1 },
{ "*=", sizeof( "*=" ) - 1 }, { "*=", sizeof("*=") - 1 },
{ "/=", sizeof( "/=" ) - 1 }, { "/=", sizeof("/=") - 1 },
{ "%=", sizeof( "%=" ) - 1 }, { "%=", sizeof("%=") - 1 },
{ "&=", sizeof( "&=" ) - 1 }, { "&=", sizeof("&=") - 1 },
{ "|=", sizeof( "|=" ) - 1 }, { "|=", sizeof("|=") - 1 },
{ "^=", sizeof( "^=" ) - 1 }, { "^=", sizeof("^=") - 1 },
{ "<<=", sizeof( "<<=" ) - 1 }, { "<<=", sizeof("<<=") - 1 },
{ ">>=", sizeof( ">>=" ) - 1 }, { ">>=", sizeof(">>=") - 1 },
{ "++", sizeof( "++" ) - 1 }, { "++", sizeof("++") - 1 },
{ "--", sizeof( "--" ) - 1 }, { "--", sizeof("--") - 1 },
{ "+", sizeof( "+" ) - 1 }, { "+", sizeof("+") - 1 },
{ "-", sizeof( "-" ) - 1 }, { "-", sizeof("-") - 1 },
{ "!", sizeof( "!" ) - 1 }, { "!", sizeof("!") - 1 },
{ "+", sizeof( "+" ) - 1 }, { "+", sizeof("+") - 1 },
{ "-", sizeof( "-" ) - 1 }, { "-", sizeof("-") - 1 },
{ "*", sizeof( "*" ) - 1 }, { "*", sizeof("*") - 1 },
{ "/", sizeof( "/" ) - 1 }, { "/", sizeof("/") - 1 },
{ "%", sizeof( "%" ) - 1 }, { "%", sizeof("%") - 1 },
{ "~", sizeof( "~" ) - 1 }, { "~", sizeof("~") - 1 },
{ "&", sizeof( "&" ) - 1 }, { "&", sizeof("&") - 1 },
{ "|", sizeof( "|" ) - 1 }, { "|", sizeof("|") - 1 },
{ "^", sizeof( "^" ) - 1 }, { "^", sizeof("^") - 1 },
{ "<<", sizeof( "<<" ) - 1 }, { "<<", sizeof("<<") - 1 },
{ ">>", sizeof( ">>" ) - 1 }, { ">>", sizeof(">>") - 1 },
{ "&&", sizeof( "&&" ) - 1 }, { "&&", sizeof("&&") - 1 },
{ "||", sizeof( "||" ) - 1 }, { "||", sizeof("||") - 1 },
{ "==", sizeof( "==" ) - 1 }, { "==", sizeof("==") - 1 },
{ "!=", sizeof( "!=" ) - 1 }, { "!=", sizeof("!=") - 1 },
{ "<", sizeof( "<" ) - 1 }, { "<", sizeof("<") - 1 },
{ ">", sizeof( ">" ) - 1 }, { ">", sizeof(">") - 1 },
{ "<=", sizeof( "<=" ) - 1 }, { "<=", sizeof("<=") - 1 },
{ ">=", sizeof( ">=" ) - 1 }, { ">=", sizeof(">=") - 1 },
{ "[]", sizeof( "[]" ) - 1 }, { "[]", sizeof("[]") - 1 },
{ "*", sizeof( "*" ) - 1 }, { "*", sizeof("*") - 1 },
{ "&", sizeof( "&" ) - 1 }, { "&", sizeof("&") - 1 },
{ "->", sizeof( "->" ) - 1 }, { "->", sizeof("->") - 1 },
{ "->*", sizeof( "->*" ) - 1 }, { "->*", sizeof("->*") - 1 },
{ "()", sizeof( "()" ) - 1 }, { "()", sizeof("()") - 1 },
{ ",", sizeof( "," ) - 1 }, { ",", sizeof(",") - 1 },
{ "new", sizeof( "new" ) - 1 }, { "new", sizeof("new") - 1 },
{ "new[]", sizeof( "new[]" ) - 1 }, { "new[]", sizeof("new[]") - 1 },
{ "delete", sizeof( "delete" ) - 1 }, { "delete", sizeof("delete") - 1 },
{ "delete[]", sizeof( "delete[]" ) - 1 }, { "delete[]", sizeof("delete[]") - 1 },
}; };
return lookup[op]; return lookup[op];
} }
forceinline Str to_str( Operator op ) forceinline Str to_str(Operator op)
{ {
return operator_to_str( op ); return operator_to_str(op);
} }

View File

@ -33,89 +33,92 @@ enum Specifier : u32
Spec_NoExceptions, Spec_NoExceptions,
Spec_Override, Spec_Override,
Spec_Pure, Spec_Pure,
Spec_Delete,
Spec_Volatile, Spec_Volatile,
Spec_NumSpecifiers, Spec_NumSpecifiers,
Spec_UnderlyingType = 0xffffffffu Spec_UnderlyingType = 0xffffffffu
}; };
inline Str spec_to_str( Specifier type ) inline Str spec_to_str(Specifier type)
{ {
local_persist Str lookup[] = { local_persist Str lookup[] = {
{ "INVALID", sizeof( "INVALID" ) - 1 }, { "INVALID", sizeof("INVALID") - 1 },
{ "consteval", sizeof( "consteval" ) - 1 }, { "consteval", sizeof("consteval") - 1 },
{ "constexpr", sizeof( "constexpr" ) - 1 }, { "constexpr", sizeof("constexpr") - 1 },
{ "constinit", sizeof( "constinit" ) - 1 }, { "constinit", sizeof("constinit") - 1 },
{ "explicit", sizeof( "explicit" ) - 1 }, { "explicit", sizeof("explicit") - 1 },
{ "extern", sizeof( "extern" ) - 1 }, { "extern", sizeof("extern") - 1 },
{ "forceinline", sizeof( "forceinline" ) - 1 }, { "forceinline", sizeof("forceinline") - 1 },
{ "global", sizeof( "global" ) - 1 }, { "global", sizeof("global") - 1 },
{ "inline", sizeof( "inline" ) - 1 }, { "inline", sizeof("inline") - 1 },
{ "internal", sizeof( "internal" ) - 1 }, { "internal", sizeof("internal") - 1 },
{ "local_persist", sizeof( "local_persist" ) - 1 }, { "local_persist", sizeof("local_persist") - 1 },
{ "mutable", sizeof( "mutable" ) - 1 }, { "mutable", sizeof("mutable") - 1 },
{ "neverinline", sizeof( "neverinline" ) - 1 }, { "neverinline", sizeof("neverinline") - 1 },
{ "*", sizeof( "*" ) - 1 }, { "*", sizeof("*") - 1 },
{ "&", sizeof( "&" ) - 1 }, { "&", sizeof("&") - 1 },
{ "register", sizeof( "register" ) - 1 }, { "register", sizeof("register") - 1 },
{ "restrict", sizeof( "restrict" ) - 1 }, { "restrict", sizeof("restrict") - 1 },
{ "&&", sizeof( "&&" ) - 1 }, { "&&", sizeof("&&") - 1 },
{ "static", sizeof( "static" ) - 1 }, { "static", sizeof("static") - 1 },
{ "thread_local", sizeof( "thread_local" ) - 1 }, { "thread_local", sizeof("thread_local") - 1 },
{ "virtual", sizeof( "virtual" ) - 1 }, { "virtual", sizeof("virtual") - 1 },
{ "const", sizeof( "const" ) - 1 }, { "const", sizeof("const") - 1 },
{ "final", sizeof( "final" ) - 1 }, { "final", sizeof("final") - 1 },
{ "noexcept", sizeof( "noexcept" ) - 1 }, { "noexcept", sizeof("noexcept") - 1 },
{ "override", sizeof( "override" ) - 1 }, { "override", sizeof("override") - 1 },
{ "= 0", sizeof( "= 0" ) - 1 }, { "= 0", sizeof("= 0") - 1 },
{ "volatile", sizeof( "volatile" ) - 1 }, { "= delete", sizeof("= delete") - 1 },
{ "volatile", sizeof("volatile") - 1 },
}; };
return lookup[type]; return lookup[type];
} }
inline bool spec_is_trailing( Specifier specifier ) inline bool spec_is_trailing(Specifier specifier)
{ {
switch ( specifier ) switch (specifier)
{ {
case Spec_Const : case Spec_Const:
case Spec_Final : case Spec_Final:
case Spec_NoExceptions : case Spec_NoExceptions:
case Spec_Override : case Spec_Override:
case Spec_Pure : case Spec_Pure:
case Spec_Volatile : case Spec_Delete:
case Spec_Volatile:
return true; return true;
default : default:
return false; return false;
} }
} }
inline Specifier str_to_specifier( Str str ) inline Specifier str_to_specifier(Str str)
{ {
local_persist u32 keymap[Spec_NumSpecifiers]; local_persist u32 keymap[Spec_NumSpecifiers];
do_once_start for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) do_once_start for (u32 index = 0; index < Spec_NumSpecifiers; index++)
{ {
Str enum_str = spec_to_str( (Specifier)index ); Str enum_str = spec_to_str((Specifier)index);
keymap[index] = crc32( enum_str.Ptr, enum_str.Len ); keymap[index] = crc32(enum_str.Ptr, enum_str.Len);
} }
do_once_end u32 hash = crc32( str.Ptr, str.Len ); do_once_end u32 hash = crc32(str.Ptr, str.Len);
for ( u32 index = 0; index < Spec_NumSpecifiers; index++ ) for (u32 index = 0; index < Spec_NumSpecifiers; index++)
{ {
if ( keymap[index] == hash ) if (keymap[index] == hash)
return (Specifier)index; return (Specifier)index;
} }
return Spec_Invalid; return Spec_Invalid;
} }
forceinline Str to_str( Specifier spec ) forceinline Str to_str(Specifier spec)
{ {
return spec_to_str( spec ); return spec_to_str(spec);
} }
forceinline Specifier to_type( Str str ) forceinline Specifier to_type(Str str)
{ {
return str_to_specifier( str ); return str_to_specifier(str);
} }
forceinline bool is_trailing( Specifier specifier ) forceinline bool is_trailing(Specifier specifier)
{ {
return spec_is_trailing( specifier ); return spec_is_trailing(specifier);
} }

View File

@ -5,7 +5,7 @@
// This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp) // This file was generated automatially by gencpp's bootstrap.cpp (See: https://github.com/Ed94/gencpp)
#define GEN_DEFINE_ATTRIBUTE_TOKENS Entry( Tok_Attribute_GEN_API, "GEN_API" ) #define GEN_DEFINE_ATTRIBUTE_TOKENS Entry(Tok_Attribute_GEN_API, "GEN_API")
enum TokType : u32 enum TokType : u32
{ {
@ -112,125 +112,125 @@ enum TokType : u32
Tok_NumTokens Tok_NumTokens
}; };
inline Str toktype_to_str( TokType type ) inline Str toktype_to_str(TokType type)
{ {
local_persist Str lookup[] = { local_persist Str lookup[] = {
{ "__invalid__", sizeof( "__invalid__" ) - 1 }, { "__invalid__", sizeof("__invalid__") - 1 },
{ "private", sizeof( "private" ) - 1 }, { "private", sizeof("private") - 1 },
{ "protected", sizeof( "protected" ) - 1 }, { "protected", sizeof("protected") - 1 },
{ "public", sizeof( "public" ) - 1 }, { "public", sizeof("public") - 1 },
{ ".", sizeof( "." ) - 1 }, { ".", sizeof(".") - 1 },
{ "::", sizeof( "::" ) - 1 }, { "::", sizeof("::") - 1 },
{ "&", sizeof( "&" ) - 1 }, { "&", sizeof("&") - 1 },
{ "&&", sizeof( "&&" ) - 1 }, { "&&", sizeof("&&") - 1 },
{ ":", sizeof( ":" ) - 1 }, { ":", sizeof(":") - 1 },
{ "[[", sizeof( "[[" ) - 1 }, { "[[", sizeof("[[") - 1 },
{ "]]", sizeof( "]]" ) - 1 }, { "]]", sizeof("]]") - 1 },
{ "{", sizeof( "{" ) - 1 }, { "{", sizeof("{") - 1 },
{ "}", sizeof( "}" ) - 1 }, { "}", sizeof("}") - 1 },
{ "[", sizeof( "[" ) - 1 }, { "[", sizeof("[") - 1 },
{ "]", sizeof( "]" ) - 1 }, { "]", sizeof("]") - 1 },
{ "(", sizeof( "(" ) - 1 }, { "(", sizeof("(") - 1 },
{ ")", sizeof( ")" ) - 1 }, { ")", sizeof(")") - 1 },
{ "__comment__", sizeof( "__comment__" ) - 1 }, { "__comment__", sizeof("__comment__") - 1 },
{ "__comment_end__", sizeof( "__comment_end__" ) - 1 }, { "__comment_end__", sizeof("__comment_end__") - 1 },
{ "__comment_start__", sizeof( "__comment_start__" ) - 1 }, { "__comment_start__", sizeof("__comment_start__") - 1 },
{ "__character__", sizeof( "__character__" ) - 1 }, { "__character__", sizeof("__character__") - 1 },
{ ",", sizeof( "," ) - 1 }, { ",", sizeof(",") - 1 },
{ "class", sizeof( "class" ) - 1 }, { "class", sizeof("class") - 1 },
{ "__attribute__", sizeof( "__attribute__" ) - 1 }, { "__attribute__", sizeof("__attribute__") - 1 },
{ "__declspec", sizeof( "__declspec" ) - 1 }, { "__declspec", sizeof("__declspec") - 1 },
{ "enum", sizeof( "enum" ) - 1 }, { "enum", sizeof("enum") - 1 },
{ "extern", sizeof( "extern" ) - 1 }, { "extern", sizeof("extern") - 1 },
{ "friend", sizeof( "friend" ) - 1 }, { "friend", sizeof("friend") - 1 },
{ "module", sizeof( "module" ) - 1 }, { "module", sizeof("module") - 1 },
{ "namespace", sizeof( "namespace" ) - 1 }, { "namespace", sizeof("namespace") - 1 },
{ "operator", sizeof( "operator" ) - 1 }, { "operator", sizeof("operator") - 1 },
{ "struct", sizeof( "struct" ) - 1 }, { "struct", sizeof("struct") - 1 },
{ "template", sizeof( "template" ) - 1 }, { "template", sizeof("template") - 1 },
{ "typedef", sizeof( "typedef" ) - 1 }, { "typedef", sizeof("typedef") - 1 },
{ "using", sizeof( "using" ) - 1 }, { "using", sizeof("using") - 1 },
{ "union", sizeof( "union" ) - 1 }, { "union", sizeof("union") - 1 },
{ "__identifier__", sizeof( "__identifier__" ) - 1 }, { "__identifier__", sizeof("__identifier__") - 1 },
{ "import", sizeof( "import" ) - 1 }, { "import", sizeof("import") - 1 },
{ "export", sizeof( "export" ) - 1 }, { "export", sizeof("export") - 1 },
{ "__new_line__", sizeof( "__new_line__" ) - 1 }, { "__new_line__", sizeof("__new_line__") - 1 },
{ "__number__", sizeof( "__number__" ) - 1 }, { "__number__", sizeof("__number__") - 1 },
{ "__operator__", sizeof( "__operator__" ) - 1 }, { "__operator__", sizeof("__operator__") - 1 },
{ "#", sizeof( "#" ) - 1 }, { "#", sizeof("#") - 1 },
{ "define", sizeof( "define" ) - 1 }, { "define", sizeof("define") - 1 },
{ "__define_param__", sizeof( "__define_param__" ) - 1 }, { "__define_param__", sizeof("__define_param__") - 1 },
{ "if", sizeof( "if" ) - 1 }, { "if", sizeof("if") - 1 },
{ "ifdef", sizeof( "ifdef" ) - 1 }, { "ifdef", sizeof("ifdef") - 1 },
{ "ifndef", sizeof( "ifndef" ) - 1 }, { "ifndef", sizeof("ifndef") - 1 },
{ "elif", sizeof( "elif" ) - 1 }, { "elif", sizeof("elif") - 1 },
{ "else", sizeof( "else" ) - 1 }, { "else", sizeof("else") - 1 },
{ "endif", sizeof( "endif" ) - 1 }, { "endif", sizeof("endif") - 1 },
{ "include", sizeof( "include" ) - 1 }, { "include", sizeof("include") - 1 },
{ "pragma", sizeof( "pragma" ) - 1 }, { "pragma", sizeof("pragma") - 1 },
{ "__macro_content__", sizeof( "__macro_content__" ) - 1 }, { "__macro_content__", sizeof("__macro_content__") - 1 },
{ "__macro_expression__", sizeof( "__macro_expression__" ) - 1 }, { "__macro_expression__", sizeof("__macro_expression__") - 1 },
{ "__macro_statment__", sizeof( "__macro_statment__" ) - 1 }, { "__macro_statment__", sizeof("__macro_statment__") - 1 },
{ "__macro_typename__", sizeof( "__macro_typename__" ) - 1 }, { "__macro_typename__", sizeof("__macro_typename__") - 1 },
{ "__unsupported__", sizeof( "__unsupported__" ) - 1 }, { "__unsupported__", sizeof("__unsupported__") - 1 },
{ "alignas", sizeof( "alignas" ) - 1 }, { "alignas", sizeof("alignas") - 1 },
{ "const", sizeof( "const" ) - 1 }, { "const", sizeof("const") - 1 },
{ "consteval", sizeof( "consteval" ) - 1 }, { "consteval", sizeof("consteval") - 1 },
{ "constexpr", sizeof( "constexpr" ) - 1 }, { "constexpr", sizeof("constexpr") - 1 },
{ "constinit", sizeof( "constinit" ) - 1 }, { "constinit", sizeof("constinit") - 1 },
{ "explicit", sizeof( "explicit" ) - 1 }, { "explicit", sizeof("explicit") - 1 },
{ "extern", sizeof( "extern" ) - 1 }, { "extern", sizeof("extern") - 1 },
{ "final", sizeof( "final" ) - 1 }, { "final", sizeof("final") - 1 },
{ "forceinline", sizeof( "forceinline" ) - 1 }, { "forceinline", sizeof("forceinline") - 1 },
{ "global", sizeof( "global" ) - 1 }, { "global", sizeof("global") - 1 },
{ "inline", sizeof( "inline" ) - 1 }, { "inline", sizeof("inline") - 1 },
{ "internal", sizeof( "internal" ) - 1 }, { "internal", sizeof("internal") - 1 },
{ "local_persist", sizeof( "local_persist" ) - 1 }, { "local_persist", sizeof("local_persist") - 1 },
{ "mutable", sizeof( "mutable" ) - 1 }, { "mutable", sizeof("mutable") - 1 },
{ "neverinline", sizeof( "neverinline" ) - 1 }, { "neverinline", sizeof("neverinline") - 1 },
{ "override", sizeof( "override" ) - 1 }, { "override", sizeof("override") - 1 },
{ "restrict", sizeof( "restrict" ) - 1 }, { "restrict", sizeof("restrict") - 1 },
{ "static", sizeof( "static" ) - 1 }, { "static", sizeof("static") - 1 },
{ "thread_local", sizeof( "thread_local" ) - 1 }, { "thread_local", sizeof("thread_local") - 1 },
{ "volatile", sizeof( "volatile" ) - 1 }, { "volatile", sizeof("volatile") - 1 },
{ "virtual", sizeof( "virtual" ) - 1 }, { "virtual", sizeof("virtual") - 1 },
{ "*", sizeof( "*" ) - 1 }, { "*", sizeof("*") - 1 },
{ ";", sizeof( ";" ) - 1 }, { ";", sizeof(";") - 1 },
{ "static_assert", sizeof( "static_assert" ) - 1 }, { "static_assert", sizeof("static_assert") - 1 },
{ "__string__", sizeof( "__string__" ) - 1 }, { "__string__", sizeof("__string__") - 1 },
{ "typename", sizeof( "typename" ) - 1 }, { "typename", sizeof("typename") - 1 },
{ "unsigned", sizeof( "unsigned" ) - 1 }, { "unsigned", sizeof("unsigned") - 1 },
{ "signed", sizeof( "signed" ) - 1 }, { "signed", sizeof("signed") - 1 },
{ "short", sizeof( "short" ) - 1 }, { "short", sizeof("short") - 1 },
{ "long", sizeof( "long" ) - 1 }, { "long", sizeof("long") - 1 },
{ "bool", sizeof( "bool" ) - 1 }, { "bool", sizeof("bool") - 1 },
{ "char", sizeof( "char" ) - 1 }, { "char", sizeof("char") - 1 },
{ "int", sizeof( "int" ) - 1 }, { "int", sizeof("int") - 1 },
{ "double", sizeof( "double" ) - 1 }, { "double", sizeof("double") - 1 },
{ "__int8", sizeof( "__int8" ) - 1 }, { "__int8", sizeof("__int8") - 1 },
{ "__int16", sizeof( "__int16" ) - 1 }, { "__int16", sizeof("__int16") - 1 },
{ "__int32", sizeof( "__int32" ) - 1 }, { "__int32", sizeof("__int32") - 1 },
{ "__int64", sizeof( "__int64" ) - 1 }, { "__int64", sizeof("__int64") - 1 },
{ "_W64", sizeof( "_W64" ) - 1 }, { "_W64", sizeof("_W64") - 1 },
{ "...", sizeof( "..." ) - 1 }, { "...", sizeof("...") - 1 },
{ "__attrib_start__", sizeof( "__attrib_start__" ) - 1 }, { "__attrib_start__", sizeof("__attrib_start__") - 1 },
{ "GEN_API", sizeof( "GEN_API" ) - 1 }, { "GEN_API", sizeof("GEN_API") - 1 },
}; };
return lookup[type]; return lookup[type];
} }
inline TokType str_to_toktype( Str str ) inline TokType str_to_toktype(Str str)
{ {
local_persist u32 keymap[Tok_NumTokens]; local_persist u32 keymap[Tok_NumTokens];
do_once_start for ( u32 index = 0; index < Tok_NumTokens; index++ ) do_once_start for (u32 index = 0; index < Tok_NumTokens; index++)
{ {
Str enum_str = toktype_to_str( (TokType)index ); Str enum_str = toktype_to_str((TokType)index);
keymap[index] = crc32( enum_str.Ptr, enum_str.Len ); keymap[index] = crc32(enum_str.Ptr, enum_str.Len);
} }
do_once_end u32 hash = crc32( str.Ptr, str.Len ); do_once_end u32 hash = crc32(str.Ptr, str.Len);
for ( u32 index = 0; index < Tok_NumTokens; index++ ) for (u32 index = 0; index < Tok_NumTokens; index++)
{ {
if ( keymap[index] == hash ) if (keymap[index] == hash)
return (TokType)index; return (TokType)index;
} }
return Tok_Invalid; return Tok_Invalid;

View File

@ -6,83 +6,83 @@
#pragma region Constants #pragma region Constants
extern Macro enum_underlying_macro; GEN_API extern Macro enum_underlying_macro;
extern Code access_public; GEN_API extern Code access_public;
extern Code access_protected; GEN_API extern Code access_protected;
extern Code access_private; GEN_API extern Code access_private;
extern CodeAttributes attrib_api_export; GEN_API extern CodeAttributes attrib_api_export;
extern CodeAttributes attrib_api_import; GEN_API extern CodeAttributes attrib_api_import;
extern Code module_global_fragment; GEN_API extern Code module_global_fragment;
extern Code module_private_fragment; GEN_API extern Code module_private_fragment;
extern Code fmt_newline; GEN_API extern Code fmt_newline;
extern CodePragma pragma_once; GEN_API extern CodePragma pragma_once;
extern CodeParams param_varadic; GEN_API extern CodeParams param_varadic;
extern CodePreprocessCond preprocess_else; GEN_API extern CodePreprocessCond preprocess_else;
extern CodePreprocessCond preprocess_endif; GEN_API extern CodePreprocessCond preprocess_endif;
extern CodeSpecifiers spec_const; GEN_API extern CodeSpecifiers spec_const;
extern CodeSpecifiers spec_consteval; GEN_API extern CodeSpecifiers spec_consteval;
extern CodeSpecifiers spec_constexpr; GEN_API extern CodeSpecifiers spec_constexpr;
extern CodeSpecifiers spec_constinit; GEN_API extern CodeSpecifiers spec_constinit;
extern CodeSpecifiers spec_extern_linkage; GEN_API extern CodeSpecifiers spec_extern_linkage;
extern CodeSpecifiers spec_final; GEN_API extern CodeSpecifiers spec_final;
extern CodeSpecifiers spec_forceinline; GEN_API extern CodeSpecifiers spec_forceinline;
extern CodeSpecifiers spec_global; GEN_API extern CodeSpecifiers spec_global;
extern CodeSpecifiers spec_inline; GEN_API extern CodeSpecifiers spec_inline;
extern CodeSpecifiers spec_internal_linkage; GEN_API extern CodeSpecifiers spec_internal_linkage;
extern CodeSpecifiers spec_local_persist; GEN_API extern CodeSpecifiers spec_local_persist;
extern CodeSpecifiers spec_mutable; GEN_API extern CodeSpecifiers spec_mutable;
extern CodeSpecifiers spec_neverinline; GEN_API extern CodeSpecifiers spec_neverinline;
extern CodeSpecifiers spec_noexcept; GEN_API extern CodeSpecifiers spec_noexcept;
extern CodeSpecifiers spec_override; GEN_API extern CodeSpecifiers spec_override;
extern CodeSpecifiers spec_ptr; GEN_API extern CodeSpecifiers spec_ptr;
extern CodeSpecifiers spec_pure; GEN_API extern CodeSpecifiers spec_pure;
extern CodeSpecifiers spec_ref; GEN_API extern CodeSpecifiers spec_ref;
extern CodeSpecifiers spec_register; GEN_API extern CodeSpecifiers spec_register;
extern CodeSpecifiers spec_rvalue; GEN_API extern CodeSpecifiers spec_rvalue;
extern CodeSpecifiers spec_static_member; GEN_API extern CodeSpecifiers spec_static_member;
extern CodeSpecifiers spec_thread_local; GEN_API extern CodeSpecifiers spec_thread_local;
extern CodeSpecifiers spec_virtual; GEN_API extern CodeSpecifiers spec_virtual;
extern CodeSpecifiers spec_volatile; GEN_API extern CodeSpecifiers spec_volatile;
extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance) GEN_API extern CodeTypename t_empty; // Used with varaidc parameters. (Exposing just in case its useful for another circumstance)
extern CodeTypename t_auto; GEN_API extern CodeTypename t_auto;
extern CodeTypename t_void; GEN_API extern CodeTypename t_void;
extern CodeTypename t_int; GEN_API extern CodeTypename t_int;
extern CodeTypename t_bool; GEN_API extern CodeTypename t_bool;
extern CodeTypename t_char; GEN_API extern CodeTypename t_char;
extern CodeTypename t_wchar_t; GEN_API extern CodeTypename t_wchar_t;
extern CodeTypename t_class; GEN_API extern CodeTypename t_class;
extern CodeTypename t_typename; GEN_API extern CodeTypename t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
// Predefined typename codes. Are set to readonly and are setup during gen::init() // Predefined typename codes. Are set to readonly and are setup during gen::init()
extern Context* _ctx; GEN_API extern Context* _ctx;
extern CodeTypename t_b32; GEN_API extern CodeTypename t_b32;
extern CodeTypename t_s8; GEN_API extern CodeTypename t_s8;
extern CodeTypename t_s16; GEN_API extern CodeTypename t_s16;
extern CodeTypename t_s32; GEN_API extern CodeTypename t_s32;
extern CodeTypename t_s64; GEN_API extern CodeTypename t_s64;
extern CodeTypename t_u8; GEN_API extern CodeTypename t_u8;
extern CodeTypename t_u16; GEN_API extern CodeTypename t_u16;
extern CodeTypename t_u32; GEN_API extern CodeTypename t_u32;
extern CodeTypename t_u64; GEN_API extern CodeTypename t_u64;
extern CodeTypename t_ssize; GEN_API extern CodeTypename t_ssize;
extern CodeTypename t_usize; GEN_API extern CodeTypename t_usize;
extern CodeTypename t_f32; GEN_API extern CodeTypename t_f32;
extern CodeTypename t_f64; GEN_API extern CodeTypename t_f64;
#endif #endif
#pragma endregion Constants #pragma endregion Constants

View File

@ -50,6 +50,7 @@ struct Context
// LoggerCallaback* log_callback; // TODO(Ed): Impl user logger callback as an option. // LoggerCallaback* log_callback; // TODO(Ed): Impl user logger callback as an option.
// Initalization config
u32 Max_CommentLineLength; // Used by def_comment u32 Max_CommentLineLength; // Used by def_comment
u32 Max_StrCacheLength; // Any cached string longer than this is always allocated again. u32 Max_StrCacheLength; // Any cached string longer than this is always allocated again.
@ -155,6 +156,7 @@ struct Opts_def_struct {
CodeAttributes attributes; CodeAttributes attributes;
CodeTypename* interfaces; CodeTypename* interfaces;
s32 num_interfaces; s32 num_interfaces;
CodeSpecifiers specifiers; // Only used for final specifier for now.
ModuleFlag mflags; ModuleFlag mflags;
}; };
GEN_API CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT ); GEN_API CodeClass def_class( Str name, Opts_def_struct opts GEN_PARAM_DEFAULT );

View File

@ -532,6 +532,7 @@ CodeClass def_class( Str name, Opts_def_struct p )
result->Name = cache_str( name ); result->Name = cache_str( name );
result->ModuleFlags = p.mflags; result->ModuleFlags = p.mflags;
result->Attributes = p.attributes; result->Attributes = p.attributes;
result->Specs = p.specifiers;
result->ParentAccess = p.parent_access; result->ParentAccess = p.parent_access;
result->ParentType = p.parent; result->ParentType = p.parent;
if ( p.body ) if ( p.body )
@ -1065,6 +1066,7 @@ CodeStruct def_struct( Str name, Opts_def_struct p )
result->Type = CT_Struct_Fwd; result->Type = CT_Struct_Fwd;
} }
result->Attributes = p.attributes; result->Attributes = p.attributes;
result->Specs = p.specifiers;
result->ParentAccess = p.parent_access; result->ParentAccess = p.parent_access;
result->ParentType = p.parent; result->ParentType = p.parent;

View File

@ -264,7 +264,6 @@ s32 lex_preprocessor_define( LexContext* ctx )
} }
// TODO(Ed): We need to to attempt to recover from a lex failure? // TODO(Ed): We need to to attempt to recover from a lex failure?
forceinline
s32 lex_preprocessor_directive( LexContext* ctx ) s32 lex_preprocessor_directive( LexContext* ctx )
{ {
char const* hash = ctx->scanner; char const* hash = ctx->scanner;
@ -480,7 +479,6 @@ s32 lex_preprocessor_directive( LexContext* ctx )
return Lex_Continue; // Skip found token, its all handled here. return Lex_Continue; // Skip found token, its all handled here.
} }
forceinline
void lex_found_token( LexContext* ctx ) void lex_found_token( LexContext* ctx )
{ {
if ( ctx->token.Type != Tok_Invalid ) { if ( ctx->token.Type != Tok_Invalid ) {
@ -550,6 +548,9 @@ void lex_found_token( LexContext* ctx )
if ( bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Attribute) ) { if ( bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Attribute) ) {
ctx->token.Flags |= TF_Attribute; ctx->token.Flags |= TF_Attribute;
} }
if ( bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Specifier ) ) {
ctx->token.Flags |= TF_Specifier;
}
} }
else else
{ {

View File

@ -717,6 +717,13 @@ Code parse_class_struct( TokType which, bool inplace_def )
} }
// <ModuleFlags> <class/struct> <Attributes> <Name> // <ModuleFlags> <class/struct> <Attributes> <Name>
CodeSpecifiers specifiers = NullCode;
if ( check(Tok_Spec_Final)) {
specifiers = def_specifier(Spec_Final);
eat(Tok_Spec_Final);
}
// <ModuleFlags> <class/struct> <Attributes> <Name> <final>
local_persist local_persist
char interface_arr_mem[ kilobytes(4) ] = {0}; char interface_arr_mem[ kilobytes(4) ] = {0};
Array(CodeTypename) interfaces; { Array(CodeTypename) interfaces; {
@ -728,22 +735,22 @@ Code parse_class_struct( TokType which, bool inplace_def )
if ( check( Tok_Assign_Classifer ) ) if ( check( Tok_Assign_Classifer ) )
{ {
eat( Tok_Assign_Classifer ); eat( Tok_Assign_Classifer );
// <ModuleFlags> <class/struct> <Attributes> <Name> : // <ModuleFlags> <class/struct> <Attributes> <Name> <final> :
if ( tok_is_access_specifier(currtok) ) { if ( tok_is_access_specifier(currtok) ) {
access = tok_to_access_specifier(currtok); access = tok_to_access_specifier(currtok);
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> // <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier>
eat( currtok.Type ); eat( currtok.Type );
} }
Token parent_tok = parse_identifier(nullptr); Token parent_tok = parse_identifier(nullptr);
parent = def_type( parent_tok.Text ); parent = def_type( parent_tok.Text );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Parent/Interface Name> // <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Parent/Interface Name>
while ( check(Tok_Comma) ) while ( check(Tok_Comma) )
{ {
eat( Tok_Comma ); eat( Tok_Comma );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, // <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>,
if ( tok_is_access_specifier(currtok) ) { if ( tok_is_access_specifier(currtok) ) {
eat(currtok.Type); eat(currtok.Type);
@ -751,32 +758,32 @@ Code parse_class_struct( TokType which, bool inplace_def )
Token interface_tok = parse_identifier(nullptr); Token interface_tok = parse_identifier(nullptr);
array_append( interfaces, def_type( interface_tok.Text ) ); array_append( interfaces, def_type( interface_tok.Text ) );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... // <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ...
} }
} }
if ( check( Tok_BraceCurly_Open ) ) { if ( check( Tok_BraceCurly_Open ) ) {
body = parse_class_struct_body( which, name ); body = parse_class_struct_body( which, name );
} }
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... { <Body> } // <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> }
CodeComment inline_cmt = NullCode; CodeComment inline_cmt = NullCode;
if ( ! inplace_def ) if ( ! inplace_def )
{ {
Token stmt_end = currtok; Token stmt_end = currtok;
eat( Tok_Statement_End ); eat( Tok_Statement_End );
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... { <Body> }; // <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> };
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line ) if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
inline_cmt = parse_comment(); inline_cmt = parse_comment();
// <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>, ... { <Body> }; <InlineCmt> // <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, ... { <Body> }; <InlineCmt>
} }
if ( which == Tok_Decl_Class ) if ( which == Tok_Decl_Class )
result = cast(Code, def_class( name.Text, def_assign( body, parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) )); result = cast(Code, def_class( name.Text, def_assign( body, parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), specifiers, mflags ) ));
else else
result = cast(Code, def_struct( name.Text, def_assign( body, (CodeTypename)parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) )); result = cast(Code, def_struct( name.Text, def_assign( body, (CodeTypename)parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), specifiers, mflags ) ));
if ( inline_cmt ) if ( inline_cmt )
result->InlineCmt = cast(Code, inline_cmt); result->InlineCmt = cast(Code, inline_cmt);
@ -947,10 +954,6 @@ CodeBody parse_class_struct_body( TokType which, Token name )
member = cast(Code, parse_simple_preprocess( Tok_Preprocess_Macro_Stmt )); member = cast(Code, parse_simple_preprocess( Tok_Preprocess_Macro_Stmt ));
break; break;
} }
case Tok_Preprocess_Macro_Expr: {
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
// case Tok_Preprocess_Macro: // case Tok_Preprocess_Macro:
// // <Macro> // // <Macro>
@ -976,6 +979,15 @@ CodeBody parse_class_struct_body( TokType which, Token name )
break; break;
} }
case Tok_Preprocess_Macro_Expr:
{
if ( ! tok_is_attribute(currtok))
{
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
}
//! Fallthrough intended
case Tok_Attribute_Open: case Tok_Attribute_Open:
case Tok_Decl_GNU_Attribute: case Tok_Decl_GNU_Attribute:
case Tok_Decl_MSVC_Attribute: case Tok_Decl_MSVC_Attribute:
@ -1143,27 +1155,44 @@ Code parse_complicated_definition( TokType which )
{ {
push_scope(); push_scope();
bool is_inplace = false; b32 is_inplace = false;
b32 is_fn_def = false;
TokArray tokens = _ctx->parser.Tokens; TokArray tokens = _ctx->parser.Tokens;
s32 idx = tokens.Idx; s32 idx = tokens.Idx;
s32 level = 0; s32 level = 0;
b32 had_def = false;
b32 had_paren = false;
for ( ; idx < array_num(tokens.Arr); idx++ ) for ( ; idx < array_num(tokens.Arr); idx++ )
{ {
if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Open ) if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Open )
level++; level++;
if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Close ) if ( tokens.Arr[ idx ].Type == Tok_BraceCurly_Close ) {
level--; level--;
had_def = level == 0;
}
if ( level == 0 && tokens.Arr[ idx ].Type == Tok_Statement_End ) b32 found_fn_def = had_def && had_paren;
if ( level == 0 && (tokens.Arr[ idx ].Type == Tok_Statement_End || found_fn_def) )
break; break;
} }
is_fn_def = had_def && had_paren;
if (is_fn_def)
{
// Function definition with <which> on return type
Code result = parse_operator_function_or_variable(false, NullCode, NullCode);
// <which> <typename>(...) ... { ... }
parser_pop(& _ctx->parser);
return result;
}
if ( ( idx - 2 ) == tokens.Idx ) if ( ( idx - 2 ) == tokens.Idx )
{ {
// Its a forward declaration only // It's a forward declaration only
Code result = parse_forward_or_definition( which, is_inplace ); Code result = parse_forward_or_definition( which, is_inplace );
// <class, enum, struct, or union> <Name>; // <class, enum, struct, or union> <Name>;
parser_pop(& _ctx->parser); parser_pop(& _ctx->parser);
@ -1388,9 +1417,18 @@ CodeFn parse_function_after_name(
CodeParams params = parse_params(parser_use_parenthesis); CodeParams params = parse_params(parser_use_parenthesis);
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> ) // <Attributes> <Specifiers> <ReturnType> <Name> ( <Parameters> )
Code suffix_specs = NullCode;
// TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers. // TODO(Ed), Review old comment : These have to be kept separate from the return type's specifiers.
while ( left && tok_is_specifier(currtok) ) while ( left && tok_is_specifier(currtok) )
{ {
// For Unreal's PURE_VIRTUAL Support
Macro* macro = lookup_macro( currtok.Text );
if (macro && tok_is_specifier(currtok))
{
suffix_specs = parse_simple_preprocess(Tok_Preprocess_Macro_Expr);
continue;
}
if ( specifiers == nullptr ) if ( specifiers == nullptr )
{ {
specifiers = def_specifier( str_to_specifier( currtok.Text) ); specifiers = def_specifier( str_to_specifier( currtok.Text) );
@ -1418,12 +1456,26 @@ CodeFn parse_function_after_name(
else if ( check(Tok_Operator) && currtok.Text.Ptr[0] == '=' ) else if ( check(Tok_Operator) && currtok.Text.Ptr[0] == '=' )
{ {
eat(Tok_Operator); eat(Tok_Operator);
specifiers_append(specifiers, Spec_Pure ); if ( specifiers == nullptr )
{
specifiers = (CodeSpecifiers) make_code();
specifiers->Type = CT_Specifiers;
}
if ( str_are_equal(nexttok.Text, txt("delete")))
{
specifiers_append(specifiers, Spec_Delete);
eat(currtok.Type);
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> = delete
}
else
{
specifiers_append(specifiers, Spec_Pure );
eat( Tok_Number); eat( Tok_Number);
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> = 0
}
Token stmt_end = currtok; Token stmt_end = currtok;
eat( Tok_Statement_End ); eat( Tok_Statement_End );
// <Attributes> <Specifiers> <ReturnType> <Name> ( <Paraemters> ) <Specifiers> = 0;
if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line ) if ( currtok_noskip.Type == Tok_Comment && currtok_noskip.Line == stmt_end.Line )
inline_cmt = parse_comment(); inline_cmt = parse_comment();
@ -1479,6 +1531,9 @@ CodeFn parse_function_after_name(
if ( specifiers ) if ( specifiers )
result->Specs = specifiers; result->Specs = specifiers;
if ( suffix_specs )
result->SuffixSpecs = suffix_specs;
result->ReturnType = ret_type; result->ReturnType = ret_type;
if ( params ) if ( params )
@ -1672,10 +1727,6 @@ CodeBody parse_global_nspace( CodeType which )
member = cast(Code, parse_simple_preprocess( Tok_Preprocess_Macro_Stmt )); member = cast(Code, parse_simple_preprocess( Tok_Preprocess_Macro_Stmt ));
break; break;
} }
case Tok_Preprocess_Macro_Expr: {
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
case Tok_Preprocess_Pragma: { case Tok_Preprocess_Pragma: {
member = cast(Code, parse_pragma()); member = cast(Code, parse_pragma());
@ -1709,6 +1760,16 @@ CodeBody parse_global_nspace( CodeType which )
log_failure( "gen::%s: This function is not implemented" ); log_failure( "gen::%s: This function is not implemented" );
return InvalidCode; return InvalidCode;
} }
break;
case Tok_Preprocess_Macro_Expr:
{
if (tok_is_attribute(currtok))
{
log_failure("Unbounded macro expression residing in class/struct body\n%S", parser_to_strbuilder(_ctx->parser));
return InvalidCode;
}
}
//! Fallthrough intentional //! Fallthrough intentional
case Tok_Attribute_Open: case Tok_Attribute_Open:
case Tok_Decl_GNU_Attribute: case Tok_Decl_GNU_Attribute:
@ -1983,7 +2044,14 @@ Token parse_identifier( bool* possible_member_function )
Token name = currtok; Token name = currtok;
_ctx->parser.Scope->Name = name.Text; _ctx->parser.Scope->Name = name.Text;
eat( Tok_Identifier );
Macro* macro = lookup_macro(currtok.Text);
b32 accept_as_identifier = macro && bitfield_is_set(MacroFlags, macro->Flags, MF_Allow_As_Identifier );
// Typename can be: '::' <name>
// If that is the case first option will be Tok_Access_StaticSymbol below
if (check(Tok_Identifier) || accept_as_identifier)
eat( Tok_Identifier );
// <Name> // <Name>
parse_template_args( & name ); parse_template_args( & name );
@ -2404,6 +2472,25 @@ CodeOperator parse_operator_after_ret_type(
} }
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> // <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers>
// TODO(Ed): Add proper "delete" and "new" awareness
// We're dealing with either a "= delete" or operator deletion
if (check(Tok_Operator) && currtok.Text.Ptr[0] == '=')
{
eat(currtok.Type);
if ( ! str_are_equal(currtok.Text, txt("delete")))
{
log_failure("Expected delete after = in operator forward instead found \"%S\"\n%SB", currtok.Text, parser_to_strbuilder(_ctx->parser));
parser_pop(& _ctx->parser);
return InvalidCode;
}
if (specifiers == nullptr)
specifiers = def_specifier( Spec_Delete );
else
specifiers_append(specifiers, Spec_Delete);
eat(currtok.Type);
// <ExportFlag> <Attributes> <Specifiers> <ReturnType> <Qualifier::...> operator <Op> ( <Parameters> ) <Specifiers> = delete
}
// Parse Body // Parse Body
CodeBody body = { nullptr }; CodeBody body = { nullptr };
CodeComment inline_cmt = NullCode; CodeComment inline_cmt = NullCode;
@ -2454,6 +2541,24 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
CodeTypename type = parser_parse_type( parser_not_from_template, nullptr ); CodeTypename type = parser_parse_type( parser_not_from_template, nullptr );
// <Attributes> <Specifiers> <ReturnType/ValueType> // <Attributes> <Specifiers> <ReturnType/ValueType>
// Thanks Unreal
CodeAttributes post_rt_attributes = parse_attributes();
if (post_rt_attributes)
{
if (attributes)
{
StrBuilder merged = strbuilder_fmt_buf(_ctx->Allocator_Temp, "%S %S", attributes->Content, post_rt_attributes->Content);
attributes->Content = cache_str(strbuilder_to_str(merged));
}
else
{
attributes = post_rt_attributes;
}
// <Attributes> <Specifiers> <ReturnType/ValueType> <Attributes>
// CONVERTED TO:
// <Attributes> <Specifiers> <ReturnType/ValueType>
}
if ( type == InvalidCode ) { if ( type == InvalidCode ) {
parser_pop(& _ctx->parser); parser_pop(& _ctx->parser);
return InvalidCode; return InvalidCode;
@ -2701,10 +2806,8 @@ CodeParams parse_params( bool use_template_capture )
// ( <Macro> <ValueType> <Name> <PostNameMacro> // ( <Macro> <ValueType> <Name> <PostNameMacro>
} }
// In template captures you can have a typename have direct assignment without a name // C++ allows typename = expression... so anything goes....
// typename = typename ... if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
// Which would result in a static value type from a struct expansion (traditionally)
if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{ {
eat( Tok_Operator ); eat( Tok_Operator );
// ( <Macro> <ValueType> <Name> = // ( <Macro> <ValueType> <Name> =
@ -2812,10 +2915,8 @@ CodeParams parse_params( bool use_template_capture )
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <PostNameMacro> // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <PostNameMacro>
} }
// In template captures you can have a typename have direct assignment without a name /// C++ allows typename = expression... so anything goes....
// typename = typename ... if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
// Which would result in a static value type from a struct expansion (traditionally)
if ( ( name.Text.Ptr || use_template_capture ) && bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{ {
eat( Tok_Operator ); eat( Tok_Operator );
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> <PostNameMacro> = // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name> <PostNameMacro> =
@ -3439,6 +3540,7 @@ CodeConstructor parser_parse_constructor( CodeSpecifiers specifiers )
body = cast(CodeBody, parse_function_body()); body = cast(CodeBody, parse_function_body());
// <Name> ( <Parameters> ) { <Body> } // <Name> ( <Parameters> ) { <Body> }
} }
// TODO(Ed): Add support for detecting constructor deletion
else if ( check( Tok_Operator) && currtok.Text.Ptr[ 0 ] == '=' ) else if ( check( Tok_Operator) && currtok.Text.Ptr[ 0 ] == '=' )
{ {
body = cast(CodeBody, parse_assignment_expression()); body = cast(CodeBody, parse_assignment_expression());
@ -5426,7 +5528,10 @@ CodeUsing parser_parse_using()
if ( ! is_namespace ) if ( ! is_namespace )
{ {
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) attributes = parse_attributes();
// <ModuleFlags> using <Name> <Attributes>
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ))
{ {
attributes = parse_attributes(); attributes = parse_attributes();
// <ModuleFlags> using <Name> <Attributes> // <ModuleFlags> using <Name> <Attributes>

View File

@ -181,11 +181,13 @@ enum EMacroFlags : u16
// & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/variable definition // & it would allow UE_DEPRECATED, (UE_PROPERTY / UE_FUNCTION) to chain themselves as attributes of a resolved member function/variable definition
MF_Allow_As_Attribute = bit(3), MF_Allow_As_Attribute = bit(3),
// When a macro is encountered after attributs and specifiers while parsing a function, or variable: // When a macro is encountered after attributes and specifiers while parsing a function, or variable:
// It will consume the macro and treat it as resolving the definition. (Yes this is for Unreal Engine) // It will consume the macro and treat it as resolving the definition. (Yes this is for Unreal Engine)
// (MUST BE OF MT_Statement TYPE) // (MUST BE OF MT_Statement TYPE)
MF_Allow_As_Definition = bit(4), MF_Allow_As_Definition = bit(4),
MF_Allow_As_Specifier = bit(5), // Created for Unreal's PURE_VIRTUAL
MF_Null = 0, MF_Null = 0,
MF_UnderlyingType = GEN_U16_MAX, MF_UnderlyingType = GEN_U16_MAX,
}; };

View File

@ -4,87 +4,87 @@
#endif #endif
#pragma region StaticData #pragma region StaticData
global Context* _ctx; GEN_API global Context* _ctx;
global u32 context_counter; GEN_API global u32 context_counter;
#pragma region Constants #pragma region Constants
global Macro enum_underlying_macro; GEN_API global Macro enum_underlying_macro;
global Code Code_Global; GEN_API global Code Code_Global;
global Code Code_Invalid; GEN_API global Code Code_Invalid;
global Code access_public; GEN_API global Code access_public;
global Code access_protected; GEN_API global Code access_protected;
global Code access_private; GEN_API global Code access_private;
global CodeAttributes attrib_api_export; GEN_API global CodeAttributes attrib_api_export;
global CodeAttributes attrib_api_import; GEN_API global CodeAttributes attrib_api_import;
global Code module_global_fragment; GEN_API global Code module_global_fragment;
global Code module_private_fragment; GEN_API global Code module_private_fragment;
global Code fmt_newline; GEN_API global Code fmt_newline;
global CodeParams param_varadic; GEN_API global CodeParams param_varadic;
global CodePragma pragma_once; GEN_API global CodePragma pragma_once;
global CodePreprocessCond preprocess_else; GEN_API global CodePreprocessCond preprocess_else;
global CodePreprocessCond preprocess_endif; GEN_API global CodePreprocessCond preprocess_endif;
global CodeSpecifiers spec_const; GEN_API global CodeSpecifiers spec_const;
global CodeSpecifiers spec_consteval; GEN_API global CodeSpecifiers spec_consteval;
global CodeSpecifiers spec_constexpr; GEN_API global CodeSpecifiers spec_constexpr;
global CodeSpecifiers spec_constinit; GEN_API global CodeSpecifiers spec_constinit;
global CodeSpecifiers spec_extern_linkage; GEN_API global CodeSpecifiers spec_extern_linkage;
global CodeSpecifiers spec_final; GEN_API global CodeSpecifiers spec_final;
global CodeSpecifiers spec_forceinline; GEN_API global CodeSpecifiers spec_forceinline;
global CodeSpecifiers spec_global; GEN_API global CodeSpecifiers spec_global;
global CodeSpecifiers spec_inline; GEN_API global CodeSpecifiers spec_inline;
global CodeSpecifiers spec_internal_linkage; GEN_API global CodeSpecifiers spec_internal_linkage;
global CodeSpecifiers spec_local_persist; GEN_API global CodeSpecifiers spec_local_persist;
global CodeSpecifiers spec_mutable; GEN_API global CodeSpecifiers spec_mutable;
global CodeSpecifiers spec_noexcept; GEN_API global CodeSpecifiers spec_noexcept;
global CodeSpecifiers spec_neverinline; GEN_API global CodeSpecifiers spec_neverinline;
global CodeSpecifiers spec_override; GEN_API global CodeSpecifiers spec_override;
global CodeSpecifiers spec_ptr; GEN_API global CodeSpecifiers spec_ptr;
global CodeSpecifiers spec_pure; GEN_API global CodeSpecifiers spec_pure;
global CodeSpecifiers spec_ref; GEN_API global CodeSpecifiers spec_ref;
global CodeSpecifiers spec_register; GEN_API global CodeSpecifiers spec_register;
global CodeSpecifiers spec_rvalue; GEN_API global CodeSpecifiers spec_rvalue;
global CodeSpecifiers spec_static_member; GEN_API global CodeSpecifiers spec_static_member;
global CodeSpecifiers spec_thread_local; GEN_API global CodeSpecifiers spec_thread_local;
global CodeSpecifiers spec_virtual; GEN_API global CodeSpecifiers spec_virtual;
global CodeSpecifiers spec_volatile; GEN_API global CodeSpecifiers spec_volatile;
global CodeTypename t_empty; GEN_API global CodeTypename t_empty;
global CodeTypename t_auto; GEN_API global CodeTypename t_auto;
global CodeTypename t_void; GEN_API global CodeTypename t_void;
global CodeTypename t_int; GEN_API global CodeTypename t_int;
global CodeTypename t_bool; GEN_API global CodeTypename t_bool;
global CodeTypename t_char; GEN_API global CodeTypename t_char;
global CodeTypename t_wchar_t; GEN_API global CodeTypename t_wchar_t;
global CodeTypename t_class; GEN_API global CodeTypename t_class;
global CodeTypename t_typename; GEN_API global CodeTypename t_typename;
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS #ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
global CodeTypename t_b32; GEN_API global CodeTypename t_b32;
global CodeTypename t_s8; GEN_API global CodeTypename t_s8;
global CodeTypename t_s16; GEN_API global CodeTypename t_s16;
global CodeTypename t_s32; GEN_API global CodeTypename t_s32;
global CodeTypename t_s64; GEN_API global CodeTypename t_s64;
global CodeTypename t_u8; GEN_API global CodeTypename t_u8;
global CodeTypename t_u16; GEN_API global CodeTypename t_u16;
global CodeTypename t_u32; GEN_API global CodeTypename t_u32;
global CodeTypename t_u64; GEN_API global CodeTypename t_u64;
global CodeTypename t_ssize; GEN_API global CodeTypename t_ssize;
global CodeTypename t_usize; GEN_API global CodeTypename t_usize;
global CodeTypename t_f32; GEN_API global CodeTypename t_f32;
global CodeTypename t_f64; GEN_API global CodeTypename t_f64;
#endif #endif
#pragma endregion Constants #pragma endregion Constants

View File

@ -309,6 +309,7 @@ ArrayHeader* array_get_header(Array<Type> array) {
using NonConstType = TRemoveConst<Type>; using NonConstType = TRemoveConst<Type>;
return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1; return rcast(ArrayHeader*, const_cast<NonConstType*>(Data)) - 1;
} }
template<class Type> forceinline template<class Type> forceinline
bool array_grow(Array<Type>* array, usize min_capacity) bool array_grow(Array<Type>* array, usize min_capacity)
{ {

View File

@ -67,8 +67,8 @@
while (0) while (0)
#endif #endif
void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... ); GEN_API void assert_handler( char const* condition, char const* file, char const* function, s32 line, char const* msg, ... );
s32 assert_crash( char const* condition ); GEN_API s32 assert_crash( char const* condition );
void process_exit( u32 code ); GEN_API void process_exit( u32 code );
#pragma endregion Debug #pragma endregion Debug

View File

@ -121,20 +121,20 @@ enum FileStandardType
* @param std Check zpl_file_standard_type * @param std Check zpl_file_standard_type
* @return File handle to standard I/O * @return File handle to standard I/O
*/ */
FileInfo* file_get_standard( FileStandardType std ); GEN_API FileInfo* file_get_standard( FileStandardType std );
/** /**
* Closes the file * Closes the file
* @param file * @param file
*/ */
FileError file_close( FileInfo* file ); GEN_API FileError file_close( FileInfo* file );
/** /**
* Returns the currently opened file's name * Returns the currently opened file's name
* @param file * @param file
*/ */
inline inline
char const* file_name( FileInfo* file ) char const* file_name( FileInfo* file )
{ {
return file->filename ? file->filename : ""; return file->filename ? file->filename : "";
} }
@ -144,7 +144,7 @@ inline
* @param file * @param file
* @param filename * @param filename
*/ */
FileError file_open( FileInfo* file, char const* filename ); GEN_API FileError file_open( FileInfo* file, char const* filename );
/** /**
* Opens a file using a specified mode * Opens a file using a specified mode
@ -152,7 +152,7 @@ FileError file_open( FileInfo* file, char const* filename );
* @param mode Access mode to use * @param mode Access mode to use
* @param filename * @param filename
*/ */
FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename ); GEN_API FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename );
/** /**
* Reads from a file * Reads from a file
@ -200,14 +200,14 @@ constexpr b32 file_no_zero_terminate = false;
* @param filepath Path to the file * @param filepath Path to the file
* @return File contents data * @return File contents data
*/ */
FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const* filepath ); GEN_API FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const* filepath );
/** /**
* Returns a size of the file * Returns a size of the file
* @param file * @param file
* @return File size * @return File size
*/ */
s64 file_size( FileInfo* file ); GEN_API s64 file_size( FileInfo* file );
/** /**
* Seeks the file cursor from the beginning of file to a specific position * Seeks the file cursor from the beginning of file to a specific position
@ -274,7 +274,7 @@ enum FileStreamFlags : u32
* @param file * @param file
* @param allocator * @param allocator
*/ */
b8 file_stream_new( FileInfo* file, AllocatorInfo allocator ); GEN_API b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
/** /**
* Opens a memory stream over an existing buffer * Opens a memory stream over an existing buffer
@ -284,14 +284,14 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
* @param size Buffer's size * @param size Buffer's size
* @param flags * @param flags
*/ */
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags ); GEN_API b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags );
/** /**
* Retrieves the stream's underlying buffer and buffer size. * Retrieves the stream's underlying buffer and buffer size.
* @param file memory stream * @param file memory stream
* @param size (Optional) buffer size * @param size (Optional) buffer size
*/ */
u8* file_stream_buf( FileInfo* file, ssize* size ); GEN_API u8* file_stream_buf( FileInfo* file, ssize* size );
extern FileOperations const memory_file_operations; extern FileOperations const memory_file_operations;

View File

@ -5,7 +5,7 @@
#pragma region Hashing #pragma region Hashing
u32 crc32( void const* data, ssize len ); GEN_API u32 crc32( void const* data, ssize len );
u64 crc64( void const* data, ssize len ); GEN_API u64 crc64( void const* data, ssize len );
#pragma endregion Hashing #pragma endregion Hashing

View File

@ -5,6 +5,7 @@
#pragma region Macros #pragma region Macros
#ifndef GEN_API
#if GEN_COMPILER_MSVC #if GEN_COMPILER_MSVC
#ifdef GEN_DYN_LINK #ifdef GEN_DYN_LINK
#ifdef GEN_DYN_EXPORT #ifdef GEN_DYN_EXPORT
@ -22,9 +23,14 @@
#define GEN_API // Empty for static builds #define GEN_API // Empty for static builds
#endif #endif
#endif #endif
#endif // GEN_API
#ifndef global #ifndef global // Global variables
#define global static // Global variables # ifdef GEN_DYN_EXPORT
# define global
# else
# define global static
# endif
#endif #endif
#ifndef internal #ifndef internal
#define internal static // Internal linkage #define internal static // Internal linkage
@ -35,6 +41,9 @@
#ifndef bit #ifndef bit
#define bit( Value ) ( 1 << Value ) #define bit( Value ) ( 1 << Value )
#endif
#ifndef bitfield_is_set
#define bitfield_is_set( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) ) #define bitfield_is_set( Type, Field, Mask ) ( (scast(Type, Mask) & scast(Type, Field)) == scast(Type, Mask) )
#endif #endif

View File

@ -90,7 +90,7 @@ struct _heap_alloc_info
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ) void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
{ {
void* ptr = NULL; void* ptr = nullptr;
// unused( allocator_data ); // unused( allocator_data );
// unused( old_size ); // unused( old_size );
if ( ! alignment ) if ( ! alignment )

View File

@ -41,10 +41,10 @@ void const* pointer_add_const( void const* ptr, ssize bytes );
ssize pointer_diff( void const* begin, void const* end ); ssize pointer_diff( void const* begin, void const* end );
//! Copy non-overlapping memory from source to destination. //! Copy non-overlapping memory from source to destination.
void* mem_copy( void* dest, void const* source, ssize size ); GEN_API void* mem_copy( void* dest, void const* source, ssize size );
//! Search for a constant value within the size limit at memory location. //! Search for a constant value within the size limit at memory location.
void const* mem_find( void const* data, u8 byte_value, ssize size ); GEN_API void const* mem_find( void const* data, u8 byte_value, ssize size );
//! Copy memory from source to destination. //! Copy memory from source to destination.
void* mem_move( void* dest, void const* source, ssize size ); void* mem_move( void* dest, void const* source, ssize size );
@ -119,17 +119,17 @@ void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size,
/* define GEN_HEAP_ANALYSIS to enable this feature */ /* define GEN_HEAP_ANALYSIS to enable this feature */
/* call zpl_heap_stats_init at the beginning of the entry point */ /* call zpl_heap_stats_init at the beginning of the entry point */
/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */ /* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */
void heap_stats_init( void ); GEN_API void heap_stats_init( void );
ssize heap_stats_used_memory( void ); GEN_API ssize heap_stats_used_memory( void );
ssize heap_stats_alloc_count( void ); GEN_API ssize heap_stats_alloc_count( void );
void heap_stats_check( void ); GEN_API void heap_stats_check( void );
//! Allocate/Resize memory using default options. //! Allocate/Resize memory using default options.
//! Use this if you don't need a "fancy" resize allocation //! Use this if you don't need a "fancy" resize allocation
void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment ); void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment );
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags ); GEN_API void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
//! The heap allocator backed by operating system's memory manager. //! The heap allocator backed by operating system's memory manager.
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; } constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
@ -147,25 +147,25 @@ struct VirtualMemory
}; };
//! Initialize virtual memory from existing data. //! Initialize virtual memory from existing data.
VirtualMemory vm_from_memory( void* data, ssize size ); GEN_API VirtualMemory vm_from_memory( void* data, ssize size );
//! Allocate virtual memory at address with size. //! Allocate virtual memory at address with size.
//! @param addr The starting address of the region to reserve. If NULL, it lets operating system to decide where to allocate it. //! @param addr The starting address of the region to reserve. If NULL, it lets operating system to decide where to allocate it.
//! @param size The size to serve. //! @param size The size to serve.
VirtualMemory vm_alloc( void* addr, ssize size ); GEN_API VirtualMemory vm_alloc( void* addr, ssize size );
//! Release the virtual memory. //! Release the virtual memory.
b32 vm_free( VirtualMemory vm ); GEN_API b32 vm_free( VirtualMemory vm );
//! Trim virtual memory. //! Trim virtual memory.
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size ); GEN_API VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size );
//! Purge virtual memory. //! Purge virtual memory.
b32 vm_purge( VirtualMemory vm ); GEN_API b32 vm_purge( VirtualMemory vm );
//! Retrieve VM's page size and alignment. //! Retrieve VM's page size and alignment.
ssize virtual_memory_page_size( ssize* alignment_out ); GEN_API ssize virtual_memory_page_size( ssize* alignment_out );
#pragma region Arena #pragma region Arena
struct Arena; struct Arena;
@ -173,7 +173,7 @@ struct Arena;
AllocatorInfo arena_allocator_info( Arena* arena ); AllocatorInfo arena_allocator_info( Arena* arena );
// Remove static keyword and rename allocator_proc // Remove static keyword and rename allocator_proc
void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); GEN_API void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
// Add these declarations after the Arena struct // Add these declarations after the Arena struct
Arena arena_init_from_allocator(AllocatorInfo backing, ssize size); Arena arena_init_from_allocator(AllocatorInfo backing, ssize size);
@ -382,13 +382,13 @@ using FixedArena_4MB = FixedArena< megabytes( 4 ) >;
#pragma region Pool #pragma region Pool
struct Pool; struct Pool;
void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); GEN_API void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags);
Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size); Pool pool_init(AllocatorInfo backing, ssize num_blocks, ssize block_size);
Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align); Pool pool_init_align(AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align);
AllocatorInfo pool_allocator_info(Pool* pool); AllocatorInfo pool_allocator_info(Pool* pool);
void pool_clear(Pool* pool); GEN_API void pool_clear(Pool* pool);
void pool_free(Pool* pool); void pool_free(Pool* pool);
#if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP #if GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP
forceinline AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); } forceinline AllocatorInfo allocator_info(Pool& pool) { return pool_allocator_info(& pool); }

View File

@ -122,7 +122,7 @@ struct ADT_Node
* @param is_array * @param is_array
* @return error code * @return error code
*/ */
u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array ); GEN_API u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array );
/** /**
* @brief Destroy an ADT branch and its descendants * @brief Destroy an ADT branch and its descendants
@ -130,7 +130,7 @@ u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32
* @param node * @param node
* @return error code * @return error code
*/ */
u8 adt_destroy_branch( ADT_Node* node ); GEN_API u8 adt_destroy_branch( ADT_Node* node );
/** /**
* @brief Initialise an ADT leaf * @brief Initialise an ADT leaf
@ -140,7 +140,7 @@ u8 adt_destroy_branch( ADT_Node* node );
* @param type Node's type (use zpl_adt_make_branch for container nodes) * @param type Node's type (use zpl_adt_make_branch for container nodes)
* @return error code * @return error code
*/ */
u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type ); GEN_API u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
/** /**
@ -160,7 +160,7 @@ u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
* *
* @see code/apps/examples/json_get.c * @see code/apps/examples/json_get.c
*/ */
ADT_Node* adt_query( ADT_Node* node, char const* uri ); GEN_API ADT_Node* adt_query( ADT_Node* node, char const* uri );
/** /**
* @brief Find a field node within an object by the given name. * @brief Find a field node within an object by the given name.
@ -170,7 +170,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri );
* @param deep_search Perform search recursively * @param deep_search Perform search recursively
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ); GEN_API ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
/** /**
* @brief Allocate an unitialised node within a container at a specified index. * @brief Allocate an unitialised node within a container at a specified index.
@ -179,7 +179,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
* @param index * @param index
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ); GEN_API ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
/** /**
* @brief Allocate an unitialised node within a container. * @brief Allocate an unitialised node within a container.
@ -187,7 +187,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
* @param parent * @param parent
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
ADT_Node* adt_alloc( ADT_Node* parent ); GEN_API ADT_Node* adt_alloc( ADT_Node* parent );
/** /**
* @brief Move an existing node to a new container at a specified index. * @brief Move an existing node to a new container at a specified index.
@ -197,7 +197,7 @@ ADT_Node* adt_alloc( ADT_Node* parent );
* @param index * @param index
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index ); GEN_API ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
/** /**
* @brief Move an existing node to a new container. * @brief Move an existing node to a new container.
@ -206,7 +206,7 @@ ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
* @param new_parent * @param new_parent
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent ); GEN_API ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
/** /**
* @brief Swap two nodes. * @brief Swap two nodes.
@ -215,7 +215,7 @@ ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
* @param other_node * @param other_node
* @return * @return
*/ */
void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node ); GEN_API void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
/** /**
* @brief Remove node from container. * @brief Remove node from container.
@ -223,7 +223,7 @@ void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
* @param node * @param node
* @return * @return
*/ */
void adt_remove_node( ADT_Node* node ); GEN_API void adt_remove_node( ADT_Node* node );
/** /**
* @brief Initialise a node as an object * @brief Initialise a node as an object
@ -233,7 +233,7 @@ void adt_remove_node( ADT_Node* node );
* @param backing * @param backing
* @return * @return
*/ */
b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing ); GEN_API b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
/** /**
* @brief Initialise a node as an array * @brief Initialise a node as an array
@ -243,7 +243,7 @@ b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing );
* @param backing * @param backing
* @return * @return
*/ */
b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing ); GEN_API b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
/** /**
* @brief Initialise a node as a string * @brief Initialise a node as a string
@ -253,7 +253,7 @@ b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing );
* @param value * @param value
* @return * @return
*/ */
b8 adt_set_str( ADT_Node* obj, char const* name, char const* value ); GEN_API b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
/** /**
* @brief Initialise a node as a float * @brief Initialise a node as a float
@ -263,7 +263,7 @@ b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
* @param value * @param value
* @return * @return
*/ */
b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value ); GEN_API b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
/** /**
* @brief Initialise a node as a signed integer * @brief Initialise a node as a signed integer
@ -273,7 +273,7 @@ b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
* @param value * @param value
* @return * @return
*/ */
b8 adt_set_int( ADT_Node* obj, char const* name, s64 value ); GEN_API b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
/** /**
* @brief Append a new node to a container as an object * @brief Append a new node to a container as an object
@ -282,7 +282,7 @@ b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
* @param name * @param name
* @return* * @return*
*/ */
ADT_Node* adt_append_obj( ADT_Node* parent, char const* name ); GEN_API ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
/** /**
* @brief Append a new node to a container as an array * @brief Append a new node to a container as an array
@ -291,7 +291,7 @@ ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
* @param name * @param name
* @return* * @return*
*/ */
ADT_Node* adt_append_arr( ADT_Node* parent, char const* name ); GEN_API ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
/** /**
* @brief Append a new node to a container as a string * @brief Append a new node to a container as a string
@ -301,7 +301,7 @@ ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
* @param value * @param value
* @return* * @return*
*/ */
ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value ); GEN_API ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value );
/** /**
* @brief Append a new node to a container as a float * @brief Append a new node to a container as a float
@ -311,7 +311,7 @@ ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value
* @param value * @param value
* @return* * @return*
*/ */
ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value ); GEN_API ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
/** /**
* @brief Append a new node to a container as a signed integer * @brief Append a new node to a container as a signed integer
@ -321,7 +321,7 @@ ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value );
* @param value * @param value
* @return* * @return*
*/ */
ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value ); GEN_API ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
/* parser helpers */ /* parser helpers */
@ -332,7 +332,7 @@ ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
* @param base * @param base
* @return* * @return*
*/ */
char* adt_parse_number( ADT_Node* node, char* base ); GEN_API char* adt_parse_number( ADT_Node* node, char* base );
/** /**
* @brief Parses a text and stores the result into an unitialised node. * @brief Parses a text and stores the result into an unitialised node.
@ -342,7 +342,7 @@ char* adt_parse_number( ADT_Node* node, char* base );
* @param base * @param base
* @return* * @return*
*/ */
char* adt_parse_number_strict( ADT_Node* node, char* base_str ); GEN_API char* adt_parse_number_strict( ADT_Node* node, char* base_str );
/** /**
* @brief Parses and converts an existing string node into a number. * @brief Parses and converts an existing string node into a number.
@ -350,7 +350,7 @@ char* adt_parse_number_strict( ADT_Node* node, char* base_str );
* @param node * @param node
* @return * @return
*/ */
ADT_Error adt_c_str_to_number( ADT_Node* node ); GEN_API ADT_Error adt_c_str_to_number( ADT_Node* node );
/** /**
* @brief Parses and converts an existing string node into a number. * @brief Parses and converts an existing string node into a number.
@ -359,7 +359,7 @@ ADT_Error adt_c_str_to_number( ADT_Node* node );
* @param node * @param node
* @return * @return
*/ */
ADT_Error adt_c_str_to_number_strict( ADT_Node* node ); GEN_API ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
/** /**
* @brief Prints a number into a file stream. * @brief Prints a number into a file stream.
@ -371,7 +371,7 @@ ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
* @param node * @param node
* @return * @return
*/ */
ADT_Error adt_print_number( FileInfo* file, ADT_Node* node ); GEN_API ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
/** /**
* @brief Prints a string into a file stream. * @brief Prints a string into a file stream.
@ -385,7 +385,7 @@ ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
* @param escape_symbol * @param escape_symbol
* @return * @return
*/ */
ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol ); GEN_API ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol );
#pragma endregion ADT #pragma endregion ADT
@ -401,14 +401,14 @@ enum CSV_Error : u32
typedef ADT_Node CSV_Object; typedef ADT_Node CSV_Object;
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header ); u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim ); GEN_API u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
void csv_free( CSV_Object* obj ); void csv_free( CSV_Object* obj );
void csv_write( FileInfo* file, CSV_Object* obj ); void csv_write( FileInfo* file, CSV_Object* obj );
StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj ); StrBuilder csv_write_string( AllocatorInfo a, CSV_Object* obj );
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim ); GEN_API void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim ); GEN_API StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
/* inline */ /* inline */

View File

@ -13,15 +13,15 @@ typedef struct FileInfo FileInfo;
typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN]; typedef char PrintF_Buffer[GEN_PRINTF_MAXLEN];
// NOTE: A locally persisting buffer is used internally // NOTE: A locally persisting buffer is used internally
char* c_str_fmt_buf ( char const* fmt, ... ); GEN_API char* c_str_fmt_buf ( char const* fmt, ... );
char* c_str_fmt_buf_va ( char const* fmt, va_list va ); GEN_API char* c_str_fmt_buf_va ( char const* fmt, va_list va );
ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... ); GEN_API ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... );
ssize c_str_fmt_va ( char* str, ssize n, char const* fmt, va_list va ); GEN_API ssize c_str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
ssize c_str_fmt_out_va ( char const* fmt, va_list va ); GEN_API ssize c_str_fmt_out_va ( char const* fmt, va_list va );
ssize c_str_fmt_out_err ( char const* fmt, ... ); GEN_API ssize c_str_fmt_out_err ( char const* fmt, ... );
ssize c_str_fmt_out_err_va( char const* fmt, va_list va ); GEN_API ssize c_str_fmt_out_err_va( char const* fmt, va_list va );
ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... ); GEN_API ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... );
ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va ); GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
constexpr constexpr
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";

View File

@ -33,10 +33,10 @@ char const* c_str_trim( char const* str, b32 catch_newline );
void c_str_to_lower( char* str ); void c_str_to_lower( char* str );
void c_str_to_upper( char* str ); void c_str_to_upper( char* str );
s64 c_str_to_i64( const char* str, char** end_ptr, s32 base ); GEN_API s64 c_str_to_i64( const char* str, char** end_ptr, s32 base );
void i64_to_str( s64 value, char* string, s32 base ); GEN_API void i64_to_str( s64 value, char* string, s32 base );
void u64_to_str( u64 value, char* string, s32 base ); GEN_API void u64_to_str( u64 value, char* string, s32 base );
f64 c_str_to_f64( const char* str, char** end_ptr ); GEN_API f64 c_str_to_f64( const char* str, char** end_ptr );
inline inline
const char* char_first_occurence( const char* s, char c ) const char* char_first_occurence( const char* s, char c )

View File

@ -122,10 +122,11 @@ struct StrBuilder;
forceinline usize strbuilder_grow_formula(usize value); forceinline usize strbuilder_grow_formula(usize value);
GEN_API StrBuilder strbuilder_make_reserve (AllocatorInfo allocator, ssize capacity);
GEN_API StrBuilder strbuilder_make_length (AllocatorInfo allocator, char const* str, ssize length);
StrBuilder strbuilder_make_c_str (AllocatorInfo allocator, char const* str); StrBuilder strbuilder_make_c_str (AllocatorInfo allocator, char const* str);
StrBuilder strbuilder_make_str (AllocatorInfo allocator, Str str); StrBuilder strbuilder_make_str (AllocatorInfo allocator, Str str);
StrBuilder strbuilder_make_reserve (AllocatorInfo allocator, ssize capacity);
StrBuilder strbuilder_make_length (AllocatorInfo allocator, char const* str, ssize length);
StrBuilder strbuilder_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...); StrBuilder strbuilder_fmt (AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ...);
StrBuilder strbuilder_fmt_buf (AllocatorInfo allocator, char const* fmt, ...); StrBuilder strbuilder_fmt_buf (AllocatorInfo allocator, char const* fmt, ...);
StrBuilder strbuilder_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue); StrBuilder strbuilder_join (AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue);

View File

@ -7,13 +7,13 @@
#ifdef GEN_BENCHMARK #ifdef GEN_BENCHMARK
//! Return CPU timestamp. //! Return CPU timestamp.
u64 read_cpu_time_stamp_counter( void ); GEN_API u64 read_cpu_time_stamp_counter( void );
//! Return relative time (in seconds) since the application start. //! Return relative time (in seconds) since the application start.
f64 time_rel( void ); GEN_API f64 time_rel( void );
//! Return relative time since the application start. //! Return relative time since the application start.
u64 time_rel_ms( void ); GEN_API u64 time_rel_ms( void );
#endif #endif
#pragma endregion Timing #pragma endregion Timing

View File

@ -24,4 +24,5 @@ Final, final
NoExceptions, noexcept NoExceptions, noexcept
Override, override Override, override
Pure, = 0 Pure, = 0
Delete, = delete
Volatile, volatile Volatile, volatile

1 Invalid INVALID
24 NoExceptions noexcept
25 Override override
26 Pure = 0
27 Delete = delete
28 Volatile volatile

View File

@ -220,6 +220,7 @@ CodeBody gen_especifier( char const* path, bool use_c_definition = false )
case Spec_NoExceptions: case Spec_NoExceptions:
case Spec_Override: case Spec_Override:
case Spec_Pure: case Spec_Pure:
case Spec_Delete:
case Spec_Volatile: case Spec_Volatile:
return true; return true;

View File

@ -54,11 +54,13 @@ A simple `<container>_DefinitionCounter` is used to know how many instantiations
## Macro Usage ## Macro Usage
For the most part macros are kept minimal with exception to `_Generic`... For the most part macros are kept minimal with exception to `_Generic`...
*(I will be explaining this thing for the rest of this seciton along with gencpp c library's usage of it)*
The `_Generic` macro plays a key role in reducing direct need of the user to wrangle with mangled definition identifiers of 'templated' containers or for type coercion to map distinct data types to a common code path. The `_Generic` macro plays a key role in reducing direct need of the user to wrangle with mangled definition identifiers of 'templated' containers or for type coercion to map distinct data types to a common code path.
Because of its lack of use in many C11 libraries.. and, of those that do; they usually end up obfuscate it with excessive preprocessor abuse; Effort was put into minimizing how much of these macros are handled by the preprocessor vs gencpp itself. Many C11 libraries don't use it.. and, of those that do. they usually end up obfuscate it with excessive preprocessor abuse; Effort was put into minimizing how much of these macros are handled by the preprocessor vs gencpp itself.
*(I will be explaining this thing for the rest of this seciton along with gencpp c library's usage of it)*
The usual presentation (done bare) is the following: The usual presentation (done bare) is the following:
@ -95,7 +97,7 @@ For this library's purposes we'll be using the functional macro equivalent *(if
```c ```c
#define macro_that_uses_selector_arg_for_resolving_a_fucntion( selecting_exp) \ #define macro_that_uses_selector_arg_for_resolving_a_fucntion( selecting_exp) \
_Generic( (arg), \ _Generic( (selecting_exp), \
int : func_use_int, \ int : func_use_int, \
double : func_use_double, \ double : func_use_double, \
struct Whatnot : func_use_Whatnot, \ struct Whatnot : func_use_Whatnot, \

View File

@ -1256,63 +1256,6 @@ R"(#define <interface_name>( code ) _Generic( (code), \
break; break;
} }
CodeBody parsed_header_builder = parse_file( path_base "auxiliary/builder.hpp" );
CodeBody header_builder = def_body(CT_Global_Body);
for ( Code entry = parsed_header_builder.begin(); entry != parsed_header_builder.end(); ++ entry ) switch( entry->Type )
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder );
if (found) break;
header_builder.append(entry);
}
break;
case CT_Preprocess_If:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_header_builder, header_builder );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_builder, header_builder );
if (found) break;
header_builder.append(entry);
}
break;
case CT_Struct:
{
CodeBody body = cast(CodeBody, entry->Body);
CodeBody new_body = def_body(CT_Struct_Body);
for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch(body_entry->Type)
{
case CT_Preprocess_If:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body );
if (found) break;
new_body.append(body_entry);
}
break;
default:
new_body.append(body_entry);
break;
}
if ( new_body->NumEntries > 0 ) {
entry->Body = new_body;
}
header_builder.append(entry);
}
break;
default:
header_builder.append(entry);
break;
}
s32 idx = 0; s32 idx = 0;
CodeBody parsed_header_end = parse_file( path_base "components/header_end.hpp" ); CodeBody parsed_header_end = parse_file( path_base "components/header_end.hpp" );
CodeBody header_end = def_body(CT_Global_Body); CodeBody header_end = def_body(CT_Global_Body);
@ -1351,6 +1294,111 @@ R"(#define <interface_name>( code ) _Generic( (code), \
} }
#pragma endregion Resolve Components #pragma endregion Resolve Components
#pragma region Resolve Aux
CodeDefine gsel_builder_print = NullCode;
CodeBody parsed_header_builder = parse_file( path_base "auxiliary/builder.hpp" );
CodeBody header_builder = def_body(CT_Global_Body);
for ( Code entry = parsed_header_builder.begin(); entry != parsed_header_builder.end(); ++ entry ) switch( entry->Type )
{
case CT_Preprocess_IfDef:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_INTELLISENSE_DIRECTIVES"), entry, parsed_header_builder, header_builder );
if (found) break;
header_builder.append(entry);
}
break;
case CT_Preprocess_If:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP"), entry, parsed_header_builder, header_builder );
if (found) break;
found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), entry, parsed_header_builder, header_builder );
if (found) break;
header_builder.append(entry);
}
break;
case CT_Function_Fwd:
{
CodeFn fn = cast(CodeFn, entry);
if (! fn->Name.is_equal(txt("builder_print")) ) {
header_builder.append(fn);
continue;
}
fn->Name = cache_str(txt("builder__print"));
StrBuilder generic_selector = StrBuilder::make(_ctx->Allocator_Temp,
"#define builder_print(builder, code) _Generic( (code), \\\n"
);
// Append slots
for(Str type : code_typenames ) {
generic_selector.append_fmt("%S : %S,\\\n", type, fn->Name );
}
generic_selector.append(txt("default: gen_generic_selection_fail \\\n"));
generic_selector.append(txt("\t)\tGEN_RESOLVED_FUNCTION_CALL( builder, (Code)code )"));
// We need to register this as an identifier macro now sot that parsing the source wont break.
register_macro({ txt("builder_print"), MT_Statement, MF_Functional | MF_Allow_As_Identifier });
// We'll be adding this selector after builder_print_fmt
gsel_builder_print = parse_define(generic_selector);
header_builder.append(fn);
}
break;
case CT_Function:
{
CodeFn fn = cast(CodeFn, entry);
if ( fn->Name.is_equal(txt("builder_print_fmt")) ) {
header_builder.append(fn);
// Add the selector right after
header_builder.append(fmt_newline);
header_builder.append(gsel_builder_print);
}
}
break;
case CT_Struct:
{
CodeBody body = cast(CodeBody, entry->Body);
CodeBody new_body = def_body(CT_Struct_Body);
for ( Code body_entry = body.begin(); body_entry != body.end(); ++ body_entry ) switch(body_entry->Type)
{
case CT_Preprocess_If:
{
b32 found = ignore_preprocess_cond_block(txt("GEN_COMPILER_CPP && ! GEN_C_LIKE_CPP"), body_entry, body, new_body );
if (found) break;
new_body.append(body_entry);
}
break;
default:
new_body.append(body_entry);
break;
}
if ( new_body->NumEntries > 0 ) {
entry->Body = new_body;
}
header_builder.append(entry);
}
break;
default:
header_builder.append(entry);
break;
}
#pragma endregion Aux
// Source Content : Reflection and Generation // Source Content : Reflection and Generation
#pragma region Resolve Dependencies #pragma region Resolve Dependencies
@ -1559,6 +1607,26 @@ R"(#define <interface_name>( code ) _Generic( (code), \
} }
#pragma endregion Resolve Components #pragma endregion Resolve Components
#pragma region Resolve Aux
CodeBody parsed_src_builder = parse_file( path_base "auxiliary/builder.cpp" );
CodeBody src_builder = def_body(CT_Global_Body);
for ( Code entry = parsed_src_builder.begin(); entry != parsed_src_builder.end(); ++ entry ) switch( entry->Type )
{
case CT_Function:
{
if (entry->Name.is_equal(txt("builder_print"))) {
entry->Name = cache_str(txt("builder__print"));
}
src_builder.append(entry);
}
break;
default:
src_builder.append(entry);
break;
}
#pragma endregion ResolveAux
// THERE SHOULD BE NO NEW GENERIC CONTAINER DEFINITIONS PAST THIS POINT (It will not have slots for the generic selection generated macros) // THERE SHOULD BE NO NEW GENERIC CONTAINER DEFINITIONS PAST THIS POINT (It will not have slots for the generic selection generated macros)
CodeBody containers = def_body(CT_Global_Body); CodeBody containers = def_body(CT_Global_Body);
{ {
@ -1644,7 +1712,7 @@ R"(#define <interface_name>( code ) _Generic( (code), \
CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv", helper_use_c_definition ); CodeBody etoktype = gen_etoktype( path_base "enums/ETokType.csv", path_base "enums/AttributeTokens.csv", helper_use_c_definition );
Code rf_etoktype = refactor_and_format(etoktype); Code rf_etoktype = refactor_and_format(etoktype);
Code rf_src_builder = refactor_and_format( scan_file( path_base "auxiliary/builder.cpp" )); Code rf_src_builder = refactor_and_format( src_builder );
Code rf_src_scanner = refactor_and_format( scan_file( path_base "auxiliary/scanner.cpp" )); Code rf_src_scanner = refactor_and_format( scan_file( path_base "auxiliary/scanner.cpp" ));
#pragma endregion Refactored / Formatted #pragma endregion Refactored / Formatted

View File

@ -7,8 +7,19 @@ 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_strbuilder().to_str() : to_convert->Name; StrCached type;
CodeTypedef tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef enum <type> <name>; ))); CodeTypedef tdef;
if (to_convert->UnderlyingType)
{
type = to_convert->UnderlyingType.to_strbuilder().to_str();
tdef = parse_typedef(token_fmt("type", type, "name", to_convert->Name, stringize( typedef <type> <name>; )));
}
else
{
type = to_convert->Name;
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>))));

View File

@ -146,7 +146,7 @@ QualifierAlignment: Leave
ReferenceAlignment: Left ReferenceAlignment: Left
ReflowComments: true ReflowComments: false
# RequiresExpressionIndentation: OuterScope # RequiresExpressionIndentation: OuterScope
@ -164,7 +164,7 @@ SpaceAfterTemplateKeyword: false
SpaceAroundPointerQualifiers: Default SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: true SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true SpaceBeforeInheritanceColon: true
@ -182,7 +182,7 @@ SpacesInContainerLiterals: false
SpacesInLineCommentPrefix: SpacesInLineCommentPrefix:
Minimum: 1 Minimum: 1
Maximum: 20 Maximum: 20
SpacesInParentheses: true SpacesInParentheses: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
Standard: c++17 Standard: c++17

View File

@ -280,6 +280,7 @@ if ( $c_lib_dyn )
$compiler_args += $flag_c11 $compiler_args += $flag_c11
$compiler_args += ( $flag_define + 'GEN_DYN_LINK' ) $compiler_args += ( $flag_define + 'GEN_DYN_LINK' )
$compiler_args += ( $flag_define + 'GEN_DYN_EXPORT' ) $compiler_args += ( $flag_define + 'GEN_DYN_EXPORT' )
$compiler_args += ( $flag_define + 'GEN_DEFINE_LIBRARY_CODE_CONSTANTS' )
$linker_args = @() $linker_args = @()
$result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_dll $result = build-simple $path_build $includes $compiler_args $linker_args $unit $path_dll
@ -326,7 +327,7 @@ if ( $unreal )
} }
# C Library testing # C Library testing
if ( $test -and $false ) if ( $test -and $true )
{ {
$path_test_c = join-path $path_test c_library $path_test_c = join-path $path_test c_library
$path_build = join-path $path_test_c build $path_build = join-path $path_test_c build
@ -368,7 +369,7 @@ if ( $test -and $false )
Pop-Location Pop-Location
} }
if ( $test -and $true ) if ( $test -and $false )
{ {
$path_test_c = join-path $path_test c_library $path_test_c = join-path $path_test c_library
$path_build = join-path $path_test_c build $path_build = join-path $path_test_c build

Binary file not shown.

View File

@ -344,15 +344,17 @@ if ( $vendor -match "clang" )
} }
# Check if output is a static library # Check if output is a static library
# if ( $binary -match '\.lib$' ) if ( $binary -match '\.lib$' )
# { {
# $lib_args = @() $lib_args = @()
# $lib_args += $flag_nologo # $lib_args += $flag_nologo
# $lib_args += $flag_link_win_machine_64 # $lib_args += $flag_link_win_machine_64
# $lib_args += ( $flag_link_win_path_output + $binary ) # $lib_args += ( $flag_link_win_path_output + $binary )
# $lib_args += $object # $lib_args += '--format=windows'
# return run-archiver $archiver $binary $lib_args # $lib_args += '-X64'
# } $lib_args += $object
return run-archiver $archiver $binary $lib_args
}
$linker_args += $object $linker_args += $object
return run-linker $linker $binary $linker_args return run-linker $linker $binary $linker_args

90
scripts/uncrustify.cfg Normal file
View File

@ -0,0 +1,90 @@
# Basic indentation settings
indent_columns = 4
indent_with_tabs = 1
indent_case_brace = 0
indent_switch_case = 4
indent_col1_comment = true
indent_namespace = true
indent_class = true
indent_extern = true
# Alignment settings
align_assign_span = 1
align_assign_thresh = 0
align_enum_equ_span = 1
align_var_def_span = 1
align_var_def_thresh = 0
align_var_def_inline = true
align_right_cmt_span = 1
align_pp_define_span = 1
align_typedef_span = 1
align_typedef_gap = 0
# Spacing settings
sp_before_square = remove
sp_inside_square = remove
sp_after_comma = force
sp_before_comma = remove
sp_after_cast = remove
sp_inside_paren = remove
sp_inside_fparen = remove
sp_inside_sparen = remove
sp_before_sparen = force
sp_after_operator = remove
sp_after_operator_sym = remove
sp_after_ptr_star = remove
sp_before_ptr_star = force
sp_between_ptr_star = remove
# Code style settings
mod_full_brace_do = force
mod_full_brace_for = force
mod_full_brace_if = force
mod_full_brace_while = force
mod_paren_on_return = remove
mod_full_brace_nl = 1
mod_remove_extra_semicolon = true
# Line breaking
nl_after_brace_open = true
nl_after_brace_close = true
nl_after_return = true
nl_before_case = true
nl_fcall_brace = force
nl_enum_brace = force
nl_struct_brace = force
nl_union_brace = force
nl_if_brace = force
nl_brace_else = force
nl_elseif_brace = force
nl_else_brace = force
nl_else_if = remove
nl_while_brace = force
nl_do_brace = force
nl_for_brace = force
nl_max = 4
nl_after_func_proto = 2
nl_after_func_body = 2
# Template settings
sp_inside_angle = remove
sp_after_angle = force
sp_angle_paren = remove
sp_angle_word = force
# Other settings
cmt_indent_multi = true
cmt_c_group = false
cmt_cpp_group = false
indent_func_call_param = true
indent_func_def_param = true
indent_func_proto_param = true
indent_template_param = true
indent_relative_single_line_comments = true
# Preprocessor settings
pp_indent = remove
pp_space = remove
# Column limit
code_width = 160

View File

@ -1,3 +1,7 @@
#if GEN_INTELLISENSE_DIRECTIVES
#include "../../gen_c_library/gen/gen_singleheader.h"
#endif
#define GEN_IMPLEMENTATION #define GEN_IMPLEMENTATION
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS #define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
#include "gen_singleheader.h" #include "gen_singleheader.h"
@ -16,7 +20,7 @@ int main()
gen_CodeVar hello_var = gen_parse_variable(code( gen_CodeVar hello_var = gen_parse_variable(code(
char const* hello_gencpp_str = "HELLO GENCPP C11 !"; char const* hello_gencpp_str = "HELLO GENCPP C11 !";
)); ));
gen_builder_print( & src_hello, (gen_Code)hello_var ); gen_builder_print( & src_hello, hello_var );
gen_builder_write(& src_hello); gen_builder_write(& src_hello);
gen_CodeBody body = gen_parse_file("gen/hello.c"); gen_CodeBody body = gen_parse_file("gen/hello.c");