1
0
mirror of https://github.com/Ed94/gencpp.git synced 2025-05-11 18:06:46 -07:00

Compare commits

..

No commits in common. "13ebd105c44c0a4175232422e9ee36acab641aca" and "b6b246fb38f16a03e0a86f6afb8bb1fe8659a109" have entirely different histories.

35 changed files with 820 additions and 976 deletions

@ -21,11 +21,11 @@ using namespace gen;
struct Builder; struct Builder;
typedef struct Builder Builder; typedef struct Builder Builder;
GEN_API Builder builder_open ( char const* path ); Builder builder_open ( char const* path );
GEN_API void builder_pad_lines ( Builder* builder, s32 num ); void builder_pad_lines ( Builder* builder, s32 num );
GEN_API void builder_print ( Builder* builder, Code code ); void builder_print ( Builder* builder, Code code );
GEN_API void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va ); void builder_print_fmt_va( Builder* builder, char const* fmt, va_list va );
GEN_API void builder_write ( Builder* builder ); 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;

@ -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.
GEN_API Code scan_file( char const* path ); Code scan_file( char const* path );
GEN_API CodeBody parse_file( const char* path ); 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;
}; };
GEN_API CSV_Column parse_csv_one_column (AllocatorInfo allocator, char const* path); CSV_Column parse_csv_one_column(AllocatorInfo allocator, char const* path);
GEN_API CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path); CSV_Columns2 parse_csv_two_columns(AllocatorInfo allocator, char const* path);
#pragma endregion Scanner #pragma endregion Scanner

@ -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)
GEN_API extern Code Code_Global; extern Code Code_Global;
// Used to identify invalid generated code. // Used to identify invalid generated code.
GEN_API extern Code Code_Invalid; 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; // Class, Destructor, Function, Operator, Struct, Typename, Variable Code Specs; // Destructor, Function, Operator, 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; // Typename, Function (Thanks Unreal) Code SuffixSpecs; // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal) Code PostNameMacro; // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
}; };
}; };

@ -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;
CodeSpecifiers Specs; // Support for final char _PAD_SPECS_ [ sizeof(AST*) ];
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;
Code SuffixSpecs; // Thanks Unreal char _PAD_PROPERTIES_ [ sizeof(AST*) ];
}; };
}; };
StrCached Name; StrCached Name;
@ -970,7 +970,7 @@ struct AST_Struct
{ {
CodeComment InlineCmt; CodeComment InlineCmt;
CodeAttributes Attributes; CodeAttributes Attributes;
CodeSpecifiers Specs; // Support for final char _PAD_SPECS_ [ sizeof(AST*) ];
CodeTypename ParentType; CodeTypename ParentType;
char _PAD_PARAMS_[ sizeof(AST*) ]; char _PAD_PARAMS_[ sizeof(AST*) ];
CodeBody Body; CodeBody Body;

@ -186,16 +186,10 @@ 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 %SB", self->Name, access_level, typename_to_strbuilder(self->ParentType) ); strbuilder_append_fmt( result, "%S : %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 )
@ -207,6 +201,10 @@ 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 )
{ {
@ -591,10 +589,6 @@ 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) );
} }
@ -648,18 +642,11 @@ 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") );
} }
// This is bodged in for now SOLEY for Unreal's PURE_VIRTUAL functional macro (I kept it open ended for other jank) if ( self->Specs && specifiers_has(self->Specs, Spec_Pure ) >= 0 )
if ( self->SuffixSpecs ) strbuilder_append_str( result, txt(" = 0;") );
strbuilder_append_fmt( result, " %SB", code_to_strbuilder(self->SuffixSpecs) ); else if (self->Body)
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 )
@ -1100,17 +1087,11 @@ 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 %SB", access_level, typename_to_strbuilder(self->ParentType) ); strbuilder_append_fmt( result, "%S : %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 )
@ -1122,6 +1103,10 @@ 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 )
{ {

@ -33,7 +33,6 @@ 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
@ -68,7 +67,6 @@ inline Str spec_to_str(Specifier type)
{ "noexcept", sizeof( "noexcept" ) - 1 }, { "noexcept", sizeof( "noexcept" ) - 1 },
{ "override", sizeof( "override" ) - 1 }, { "override", sizeof( "override" ) - 1 },
{ "= 0", sizeof( "= 0" ) - 1 }, { "= 0", sizeof( "= 0" ) - 1 },
{ "= delete", sizeof("= delete") - 1 },
{ "volatile", sizeof( "volatile" ) - 1 }, { "volatile", sizeof( "volatile" ) - 1 },
}; };
return lookup[type]; return lookup[type];
@ -83,7 +81,6 @@ inline bool spec_is_trailing(Specifier specifier)
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;
default : default :

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

@ -156,7 +156,6 @@ 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 );

@ -532,7 +532,6 @@ 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 )
@ -1066,7 +1065,6 @@ 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;

@ -264,6 +264,7 @@ 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;
@ -479,6 +480,7 @@ 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 ) {
@ -548,9 +550,6 @@ 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
{ {

@ -717,13 +717,6 @@ 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; {
@ -735,22 +728,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> <final> : // <ModuleFlags> <class/struct> <Attributes> <Name> :
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> <final> : <Access Specifier> // <ModuleFlags> <class/struct> <Attributes> <Name> : <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> <final> : <Access Specifier> <Parent/Interface Name> // <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Parent/Interface Name>
while ( check(Tok_Comma) ) while ( check(Tok_Comma) )
{ {
eat( Tok_Comma ); eat( Tok_Comma );
// <ModuleFlags> <class/struct> <Attributes> <Name> <final> : <Access Specifier> <Name>, // <ModuleFlags> <class/struct> <Attributes> <Name> : <Access Specifier> <Name>,
if ( tok_is_access_specifier(currtok) ) { if ( tok_is_access_specifier(currtok) ) {
eat(currtok.Type); eat(currtok.Type);
@ -758,32 +751,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> <final> : <Access Specifier> <Name>, ... // <ModuleFlags> <class/struct> <Attributes> <Name> : <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> <final> : <Access Specifier> <Name>, ... { <Body> } // <ModuleFlags> <class/struct> <Attributes> <Name> : <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> <final> : <Access Specifier> <Name>, ... { <Body> }; // <ModuleFlags> <class/struct> <Attributes> <Name> : <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> <final> : <Access Specifier> <Name>, ... { <Body> }; <InlineCmt> // <ModuleFlags> <class/struct> <Attributes> <Name> : <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)), specifiers, mflags ) )); result = cast(Code, def_class( name.Text, def_assign( body, parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) ));
else else
result = cast(Code, def_struct( name.Text, def_assign( body, (CodeTypename)parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), specifiers, mflags ) )); result = cast(Code, def_struct( name.Text, def_assign( body, (CodeTypename)parent, access, attributes, interfaces, scast(s32, array_num(interfaces)), mflags ) ));
if ( inline_cmt ) if ( inline_cmt )
result->InlineCmt = cast(Code, inline_cmt); result->InlineCmt = cast(Code, inline_cmt);
@ -954,6 +947,10 @@ 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>
@ -979,15 +976,6 @@ 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:
@ -1155,44 +1143,27 @@ Code parse_complicated_definition( TokType which )
{ {
push_scope(); push_scope();
b32 is_inplace = false; bool 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;
}
b32 found_fn_def = had_def && had_paren; if ( level == 0 && tokens.Arr[ idx ].Type == Tok_Statement_End )
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 )
{ {
// It's a forward declaration only // Its 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);
@ -1417,18 +1388,9 @@ 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) );
@ -1456,26 +1418,12 @@ 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);
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 ); 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();
@ -1531,9 +1479,6 @@ 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 )
@ -1727,6 +1672,10 @@ 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());
@ -1760,16 +1709,6 @@ 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:
@ -2044,13 +1983,6 @@ 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;
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 ); eat( Tok_Identifier );
// <Name> // <Name>
@ -2472,25 +2404,6 @@ 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;
@ -2541,24 +2454,6 @@ 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;
@ -2806,8 +2701,10 @@ CodeParams parse_params( bool use_template_capture )
// ( <Macro> <ValueType> <Name> <PostNameMacro> // ( <Macro> <ValueType> <Name> <PostNameMacro>
} }
// C++ allows typename = expression... so anything goes.... // In template captures you can have a typename have direct assignment without a name
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) // typename = typename ...
// 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> =
@ -2915,8 +2812,10 @@ CodeParams parse_params( bool use_template_capture )
// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <PostNameMacro> // ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <PostNameMacro>
} }
/// C++ allows typename = expression... so anything goes.... // In template captures you can have a typename have direct assignment without a name
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) // typename = typename ...
// 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> =
@ -3540,7 +3439,6 @@ 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());
@ -5528,9 +5426,6 @@ CodeUsing parser_parse_using()
if ( ! is_namespace ) if ( ! is_namespace )
{ {
attributes = parse_attributes();
// <ModuleFlags> using <Name> <Attributes>
if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) ) if ( bitfield_is_set( u32, currtok.Flags, TF_Assign ) )
{ {
attributes = parse_attributes(); attributes = parse_attributes();

@ -181,13 +181,11 @@ 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 attributes and specifiers while parsing a function, or variable: // When a macro is encountered after attributs 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,
}; };

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

@ -309,7 +309,6 @@ 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)
{ {

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

@ -121,13 +121,13 @@ 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
*/ */
GEN_API FileInfo* file_get_standard( FileStandardType std ); FileInfo* file_get_standard( FileStandardType std );
/** /**
* Closes the file * Closes the file
* @param file * @param file
*/ */
GEN_API FileError file_close( FileInfo* file ); FileError file_close( FileInfo* file );
/** /**
* Returns the currently opened file's name * Returns the currently opened file's name
@ -144,7 +144,7 @@ char const* file_name( FileInfo* file )
* @param file * @param file
* @param filename * @param filename
*/ */
GEN_API FileError file_open( FileInfo* file, char const* filename ); 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 @@ GEN_API FileError file_open( FileInfo* file, char const* filename );
* @param mode Access mode to use * @param mode Access mode to use
* @param filename * @param filename
*/ */
GEN_API FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename ); 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
*/ */
GEN_API FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const* filepath ); 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
*/ */
GEN_API s64 file_size( FileInfo* file ); 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
*/ */
GEN_API b8 file_stream_new( FileInfo* file, AllocatorInfo allocator ); 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 @@ GEN_API b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
* @param size Buffer's size * @param size Buffer's size
* @param flags * @param flags
*/ */
GEN_API b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags ); 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
*/ */
GEN_API u8* file_stream_buf( FileInfo* file, ssize* size ); u8* file_stream_buf( FileInfo* file, ssize* size );
extern FileOperations const memory_file_operations; extern FileOperations const memory_file_operations;

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

@ -5,7 +5,6 @@
#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
@ -23,14 +22,9 @@
#define GEN_API // Empty for static builds #define GEN_API // Empty for static builds
#endif #endif
#endif #endif
#endif // GEN_API
#ifndef global // Global variables #ifndef global
# ifdef GEN_DYN_EXPORT #define global static // Global variables
# define global
# else
# define global static
# endif
#endif #endif
#ifndef internal #ifndef internal
#define internal static // Internal linkage #define internal static // Internal linkage
@ -41,9 +35,6 @@
#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

@ -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 = nullptr; void* ptr = NULL;
// unused( allocator_data ); // unused( allocator_data );
// unused( old_size ); // unused( old_size );
if ( ! alignment ) if ( ! alignment )

@ -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.
GEN_API void* mem_copy( void* dest, void const* source, ssize size ); 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.
GEN_API void const* mem_find( void const* data, u8 byte_value, ssize size ); 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 */
GEN_API void heap_stats_init( void ); void heap_stats_init( void );
GEN_API ssize heap_stats_used_memory( void ); ssize heap_stats_used_memory( void );
GEN_API ssize heap_stats_alloc_count( void ); ssize heap_stats_alloc_count( void );
GEN_API void heap_stats_check( void ); 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 );
GEN_API 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 );
//! 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.
GEN_API VirtualMemory vm_from_memory( void* data, ssize size ); 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.
GEN_API VirtualMemory vm_alloc( void* addr, ssize size ); VirtualMemory vm_alloc( void* addr, ssize size );
//! Release the virtual memory. //! Release the virtual memory.
GEN_API b32 vm_free( VirtualMemory vm ); b32 vm_free( VirtualMemory vm );
//! Trim virtual memory. //! Trim virtual memory.
GEN_API VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size ); VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size );
//! Purge virtual memory. //! Purge virtual memory.
GEN_API b32 vm_purge( VirtualMemory vm ); b32 vm_purge( VirtualMemory vm );
//! Retrieve VM's page size and alignment. //! Retrieve VM's page size and alignment.
GEN_API ssize virtual_memory_page_size( ssize* alignment_out ); 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
GEN_API void* arena_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); 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,12 +382,12 @@ using FixedArena_4MB = FixedArena< megabytes( 4 ) >;
#pragma region Pool #pragma region Pool
struct Pool; struct Pool;
GEN_API void* pool_allocator_proc(void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags); 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);
GEN_API void pool_clear(Pool* pool); 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

@ -122,7 +122,7 @@ struct ADT_Node
* @param is_array * @param is_array
* @return error code * @return error code
*/ */
GEN_API u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* name, b32 is_array ); 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 @@ GEN_API u8 adt_make_branch( ADT_Node* node, AllocatorInfo backing, char const* n
* @param node * @param node
* @return error code * @return error code
*/ */
GEN_API u8 adt_destroy_branch( ADT_Node* node ); u8 adt_destroy_branch( ADT_Node* node );
/** /**
* @brief Initialise an ADT leaf * @brief Initialise an ADT leaf
@ -140,7 +140,7 @@ GEN_API 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
*/ */
GEN_API u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type ); u8 adt_make_leaf( ADT_Node* node, char const* name, ADT_Type type );
/** /**
@ -160,7 +160,7 @@ GEN_API 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
*/ */
GEN_API ADT_Node* adt_query( ADT_Node* node, char const* uri ); 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 @@ GEN_API 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
*/ */
GEN_API ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search ); 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 @@ GEN_API 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
*/ */
GEN_API ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index ); 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 @@ GEN_API ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
* @param parent * @param parent
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
GEN_API ADT_Node* adt_alloc( ADT_Node* parent ); 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 @@ GEN_API ADT_Node* adt_alloc( ADT_Node* parent );
* @param index * @param index
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
GEN_API ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index ); 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 @@ GEN_API ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize
* @param new_parent * @param new_parent
* @return zpl_adt_node * node * @return zpl_adt_node * node
*/ */
GEN_API ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent ); ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
/** /**
* @brief Swap two nodes. * @brief Swap two nodes.
@ -215,7 +215,7 @@ GEN_API ADT_Node* adt_move_node( ADT_Node* node, ADT_Node* new_parent );
* @param other_node * @param other_node
* @return * @return
*/ */
GEN_API void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node ); 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 @@ GEN_API void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node );
* @param node * @param node
* @return * @return
*/ */
GEN_API void adt_remove_node( ADT_Node* node ); 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 @@ GEN_API void adt_remove_node( ADT_Node* node );
* @param backing * @param backing
* @return * @return
*/ */
GEN_API b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing ); 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 @@ GEN_API b8 adt_set_obj( ADT_Node* obj, char const* name, AllocatorInfo backing )
* @param backing * @param backing
* @return * @return
*/ */
GEN_API b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing ); 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 @@ GEN_API b8 adt_set_arr( ADT_Node* obj, char const* name, AllocatorInfo backing )
* @param value * @param value
* @return * @return
*/ */
GEN_API b8 adt_set_str( ADT_Node* obj, char const* name, char const* value ); 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 @@ GEN_API b8 adt_set_str( ADT_Node* obj, char const* name, char const* value );
* @param value * @param value
* @return * @return
*/ */
GEN_API b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value ); 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 @@ GEN_API b8 adt_set_flt( ADT_Node* obj, char const* name, f64 value );
* @param value * @param value
* @return * @return
*/ */
GEN_API b8 adt_set_int( ADT_Node* obj, char const* name, s64 value ); 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 @@ GEN_API b8 adt_set_int( ADT_Node* obj, char const* name, s64 value );
* @param name * @param name
* @return* * @return*
*/ */
GEN_API ADT_Node* adt_append_obj( ADT_Node* parent, char const* name ); 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 @@ GEN_API ADT_Node* adt_append_obj( ADT_Node* parent, char const* name );
* @param name * @param name
* @return* * @return*
*/ */
GEN_API ADT_Node* adt_append_arr( ADT_Node* parent, char const* name ); 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 @@ GEN_API ADT_Node* adt_append_arr( ADT_Node* parent, char const* name );
* @param value * @param value
* @return* * @return*
*/ */
GEN_API ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const* value ); 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 @@ GEN_API ADT_Node* adt_append_str( ADT_Node* parent, char const* name, char const
* @param value * @param value
* @return* * @return*
*/ */
GEN_API ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value ); 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 @@ GEN_API ADT_Node* adt_append_flt( ADT_Node* parent, char const* name, f64 value
* @param value * @param value
* @return* * @return*
*/ */
GEN_API ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value ); ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value );
/* parser helpers */ /* parser helpers */
@ -332,7 +332,7 @@ GEN_API ADT_Node* adt_append_int( ADT_Node* parent, char const* name, s64 value
* @param base * @param base
* @return* * @return*
*/ */
GEN_API char* adt_parse_number( ADT_Node* node, char* base ); 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 @@ GEN_API char* adt_parse_number( ADT_Node* node, char* base );
* @param base * @param base
* @return* * @return*
*/ */
GEN_API char* adt_parse_number_strict( ADT_Node* node, char* base_str ); 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 @@ GEN_API char* adt_parse_number_strict( ADT_Node* node, char* base_str );
* @param node * @param node
* @return * @return
*/ */
GEN_API ADT_Error adt_c_str_to_number( ADT_Node* node ); 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 @@ GEN_API ADT_Error adt_c_str_to_number( ADT_Node* node );
* @param node * @param node
* @return * @return
*/ */
GEN_API ADT_Error adt_c_str_to_number_strict( ADT_Node* node ); 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 @@ GEN_API ADT_Error adt_c_str_to_number_strict( ADT_Node* node );
* @param node * @param node
* @return * @return
*/ */
GEN_API ADT_Error adt_print_number( FileInfo* file, ADT_Node* node ); 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 @@ GEN_API ADT_Error adt_print_number( FileInfo* file, ADT_Node* node );
* @param escape_symbol * @param escape_symbol
* @return * @return
*/ */
GEN_API ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol ); ADT_Error adt_print_string( FileInfo* file, ADT_Node* node, char const* escaped_chars, char const* escape_symbol );
#pragma endregion ADT #pragma endregion ADT
@ -402,13 +402,13 @@ 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 );
GEN_API u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim ); 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 );
GEN_API void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim ); void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
GEN_API StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim ); StrBuilder csv_write_strbuilder_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
/* inline */ /* inline */

@ -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
GEN_API char* c_str_fmt_buf ( char const* fmt, ... ); char* c_str_fmt_buf ( char const* fmt, ... );
GEN_API char* c_str_fmt_buf_va ( char const* fmt, va_list va ); char* c_str_fmt_buf_va ( char const* fmt, va_list va );
GEN_API ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... ); ssize c_str_fmt ( char* str, ssize n, char const* fmt, ... );
GEN_API ssize c_str_fmt_va ( char* str, ssize n, char const* fmt, va_list va ); ssize c_str_fmt_va ( char* str, ssize n, 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_va ( char const* fmt, va_list va );
GEN_API ssize c_str_fmt_out_err ( char const* fmt, ... ); ssize c_str_fmt_out_err ( char const* fmt, ... );
GEN_API ssize c_str_fmt_out_err_va( char const* fmt, va_list va ); ssize c_str_fmt_out_err_va( char const* fmt, va_list va );
GEN_API ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... ); ssize c_str_fmt_file ( FileInfo* f, char const* fmt, ... );
GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va ); 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";

@ -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 );
GEN_API s64 c_str_to_i64( const char* str, char** end_ptr, s32 base ); s64 c_str_to_i64( const char* str, char** end_ptr, s32 base );
GEN_API void i64_to_str( s64 value, char* string, s32 base ); void i64_to_str( s64 value, char* string, s32 base );
GEN_API void u64_to_str( u64 value, char* string, s32 base ); void u64_to_str( u64 value, char* string, s32 base );
GEN_API f64 c_str_to_f64( const char* str, char** end_ptr ); 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 )

@ -122,11 +122,10 @@ 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);

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

@ -24,5 +24,4 @@ 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
Delete = delete
27 Volatile volatile

@ -220,7 +220,6 @@ 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;

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

@ -146,7 +146,7 @@ QualifierAlignment: Leave
ReferenceAlignment: Left ReferenceAlignment: Left
ReflowComments: false ReflowComments: true
# RequiresExpressionIndentation: OuterScope # RequiresExpressionIndentation: OuterScope
@ -164,7 +164,7 @@ SpaceAfterTemplateKeyword: false
SpaceAroundPointerQualifiers: Default SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false SpaceBeforeCaseColon: true
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: false SpacesInParentheses: true
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
Standard: c++17 Standard: c++17

@ -280,7 +280,6 @@ 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

@ -344,17 +344,15 @@ 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 += '--format=windows' # $lib_args += $object
# $lib_args += '-X64' # return run-archiver $archiver $binary $lib_args
$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