mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-11-03 23:36:12 -08:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
			b6b246fb38
			...
			13ebd105c4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 13ebd105c4 | |||
| bdd9c9bcdf | |||
| 16bc66c80e | |||
| f8c42a53c6 | |||
| eca538c6af | |||
| ce2be411d7 | |||
| 16fc3fa379 | |||
| 62b36ec8bb | 
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,7 @@ 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
 | 
				
			||||||
@@ -67,6 +68,7 @@ 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];
 | 
				
			||||||
@@ -81,6 +83,7 @@ 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -156,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 );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 | 
							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();
 | 
				
			||||||
@@ -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,6 +2044,13 @@ 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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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,6 +5528,9 @@ 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,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,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
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
 | 
				
			||||||
@@ -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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,12 +382,12 @@ 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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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 );
 | 
				
			||||||
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 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,4 +24,5 @@ Final,            final
 | 
				
			|||||||
NoExceptions,     noexcept
 | 
					NoExceptions,     noexcept
 | 
				
			||||||
Override,         override
 | 
					Override,         override
 | 
				
			||||||
Pure,             = 0
 | 
					Pure,             = 0
 | 
				
			||||||
 | 
					Delete,           = delete
 | 
				
			||||||
Volatile,         volatile
 | 
					Volatile,         volatile
 | 
				
			||||||
 
 | 
				
			|||||||
		
		
			
  | 
@@ -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;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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>))));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user