2023-08-28 20:46:50 -07:00
|
|
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
2023-08-21 17:30:13 -07:00
|
|
|
#pragma once
|
2023-11-19 17:34:46 -08:00
|
|
|
#include "code_serialization.cpp"
|
2023-08-28 20:46:50 -07:00
|
|
|
#endif
|
2023-08-21 17:30:13 -07:00
|
|
|
|
2024-12-07 14:17:02 -08:00
|
|
|
GEN_NS_PARSER_BEGIN
|
2024-12-09 11:55:02 -08:00
|
|
|
internal void parser_init();
|
|
|
|
internal void parser_deinit();
|
2024-12-07 14:17:02 -08:00
|
|
|
GEN_NS_PARSER_END
|
2023-07-30 15:55:57 -07:00
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
internal
|
2024-10-27 15:58:37 -07:00
|
|
|
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2024-12-04 21:40:51 -08:00
|
|
|
Arena* last = array_back(Global_AllocatorBuckets);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
switch ( type )
|
|
|
|
{
|
|
|
|
case EAllocation_ALLOC:
|
|
|
|
{
|
|
|
|
if ( ( last->TotalUsed + size ) > last->TotalSize )
|
|
|
|
{
|
2024-11-30 14:18:49 -08:00
|
|
|
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( bucket.PhysicalStart == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-05 14:04:17 -08:00
|
|
|
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
last = array_back(Global_AllocatorBuckets);
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2024-12-04 08:01:53 -08:00
|
|
|
return alloc_align( arena_allocator_info(last), size, alignment );
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
case EAllocation_FREE:
|
|
|
|
{
|
|
|
|
// Doesn't recycle.
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EAllocation_FREE_ALL:
|
|
|
|
{
|
|
|
|
// Memory::cleanup instead.
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EAllocation_RESIZE:
|
|
|
|
{
|
|
|
|
if ( last->TotalUsed + size > last->TotalSize )
|
|
|
|
{
|
2024-11-30 14:18:49 -08:00
|
|
|
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( bucket.PhysicalStart == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-05 14:04:17 -08:00
|
|
|
if ( ! array_append( Global_AllocatorBuckets, bucket ) )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
last = array_back(Global_AllocatorBuckets);
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void* result = alloc_align( last->Backing, size, alignment );
|
|
|
|
|
|
|
|
if ( result != nullptr && old_memory != nullptr )
|
|
|
|
{
|
|
|
|
mem_copy( result, old_memory, old_size );
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal
|
2023-07-24 17:59:20 -07:00
|
|
|
void define_constants()
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2024-12-03 15:47:12 -08:00
|
|
|
Code_Global = make_code();
|
|
|
|
Code_Global->Name = get_cached_string( txt("Global Code") );
|
|
|
|
Code_Global->Content = Code_Global->Name;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-01 21:03:38 -08:00
|
|
|
Code_Invalid = make_code();
|
2024-12-06 02:29:17 -08:00
|
|
|
code_set_global(Code_Invalid);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-03 12:19:39 -08:00
|
|
|
t_empty = (CodeTypename) make_code();
|
|
|
|
t_empty->Type = CT_Typename;
|
2024-12-01 02:30:37 -08:00
|
|
|
t_empty->Name = get_cached_string( txt("") );
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global(cast(Code, t_empty));
|
2023-08-01 13:07:47 -07:00
|
|
|
|
2024-12-01 02:30:37 -08:00
|
|
|
access_private = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
access_private->Type = CT_Access_Private;
|
2024-12-01 02:30:37 -08:00
|
|
|
access_private->Name = get_cached_string( txt("private:\n") );
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global(cast(Code, access_private));
|
2023-07-29 22:21:04 -07:00
|
|
|
|
2024-12-01 02:30:37 -08:00
|
|
|
access_protected = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
access_protected->Type = CT_Access_Protected;
|
2024-12-01 02:30:37 -08:00
|
|
|
access_protected->Name = get_cached_string( txt("protected:\n") );
|
2024-12-06 02:29:17 -08:00
|
|
|
code_set_global(access_protected);
|
2023-07-29 22:21:04 -07:00
|
|
|
|
|
|
|
access_public = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
access_public->Type = CT_Access_Public;
|
2024-05-05 18:53:22 -07:00
|
|
|
access_public->Name = get_cached_string( txt("public:\n") );
|
2024-12-06 02:29:17 -08:00
|
|
|
code_set_global(access_public);
|
2023-07-29 22:21:04 -07:00
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
StrC api_export_str = code(GEN_API_Export_Code);
|
|
|
|
attrib_api_export = def_attributes( api_export_str );
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global(cast(Code, attrib_api_export));
|
2023-07-29 22:21:04 -07:00
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
StrC api_import_str = code(GEN_API_Import_Code);
|
|
|
|
attrib_api_import = def_attributes( api_import_str );
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global(cast(Code, attrib_api_import));
|
2023-07-29 22:21:04 -07:00
|
|
|
|
|
|
|
module_global_fragment = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
module_global_fragment->Type = CT_Untyped;
|
2023-08-09 15:47:59 -07:00
|
|
|
module_global_fragment->Name = get_cached_string( txt("module;") );
|
2023-07-29 22:21:04 -07:00
|
|
|
module_global_fragment->Content = module_global_fragment->Name;
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global(cast(Code, module_global_fragment));
|
2023-07-29 22:21:04 -07:00
|
|
|
|
|
|
|
module_private_fragment = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
module_private_fragment->Type = CT_Untyped;
|
2023-08-09 15:47:59 -07:00
|
|
|
module_private_fragment->Name = get_cached_string( txt("module : private;") );
|
2023-07-29 22:21:04 -07:00
|
|
|
module_private_fragment->Content = module_private_fragment->Name;
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global(cast(Code, module_private_fragment));
|
2023-07-29 22:21:04 -07:00
|
|
|
|
2023-08-04 13:12:13 -07:00
|
|
|
fmt_newline = make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
fmt_newline->Type = CT_NewLine;
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global((Code)fmt_newline);
|
|
|
|
|
2023-07-29 22:21:04 -07:00
|
|
|
pragma_once = (CodePragma) make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
pragma_once->Type = CT_Preprocess_Pragma;
|
2023-08-09 15:47:59 -07:00
|
|
|
pragma_once->Name = get_cached_string( txt("once") );
|
2023-07-29 22:21:04 -07:00
|
|
|
pragma_once->Content = pragma_once->Name;
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global((Code)pragma_once);
|
2023-07-29 22:21:04 -07:00
|
|
|
|
2024-12-06 21:21:09 -08:00
|
|
|
param_varadic = (CodeParam) make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
param_varadic->Type = CT_Parameters;
|
2023-08-09 15:47:59 -07:00
|
|
|
param_varadic->Name = get_cached_string( txt("...") );
|
2023-07-29 22:21:04 -07:00
|
|
|
param_varadic->ValueType = t_empty;
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global((Code)param_varadic);
|
2023-07-29 22:21:04 -07:00
|
|
|
|
|
|
|
preprocess_else = (CodePreprocessCond) make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
preprocess_else->Type = CT_Preprocess_Else;
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global((Code)preprocess_else);
|
2023-07-29 22:21:04 -07:00
|
|
|
|
|
|
|
preprocess_endif = (CodePreprocessCond) make_code();
|
2024-12-03 12:19:39 -08:00
|
|
|
preprocess_endif->Type = CT_Preprocess_EndIf;
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global((Code)preprocess_endif);
|
2023-07-29 22:21:04 -07:00
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
# define def_constant_code_type( Type_ ) \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
StrC name_str = name(Type_); \
|
2024-12-09 11:55:02 -08:00
|
|
|
t_##Type_ = def_type( name_str ); \
|
2024-12-08 22:33:37 -08:00
|
|
|
code_set_global( cast(Code, t_##Type_)); \
|
|
|
|
} while(0)
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
def_constant_code_type( auto );
|
|
|
|
def_constant_code_type( void );
|
|
|
|
def_constant_code_type( int );
|
|
|
|
def_constant_code_type( bool );
|
|
|
|
def_constant_code_type( char );
|
|
|
|
def_constant_code_type( wchar_t );
|
|
|
|
def_constant_code_type( class );
|
|
|
|
def_constant_code_type( typename );
|
|
|
|
|
|
|
|
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
|
|
|
|
t_b32 = def_type( name(b32) );
|
|
|
|
|
|
|
|
def_constant_code_type( s8 );
|
|
|
|
def_constant_code_type( s16 );
|
|
|
|
def_constant_code_type( s32 );
|
|
|
|
def_constant_code_type( s64 );
|
|
|
|
|
|
|
|
def_constant_code_type( u8 );
|
|
|
|
def_constant_code_type( u16 );
|
|
|
|
def_constant_code_type( u32 );
|
|
|
|
def_constant_code_type( u64 );
|
|
|
|
|
2024-10-27 15:58:37 -07:00
|
|
|
def_constant_code_type( ssize );
|
|
|
|
def_constant_code_type( usize );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
def_constant_code_type( f32 );
|
|
|
|
def_constant_code_type( f64 );
|
|
|
|
#endif
|
|
|
|
# undef def_constant_code_type
|
|
|
|
|
|
|
|
|
2023-07-24 17:59:20 -07:00
|
|
|
# define def_constant_spec( Type_, ... ) \
|
|
|
|
spec_##Type_ = def_specifiers( num_args(__VA_ARGS__), __VA_ARGS__); \
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global( cast(Code, spec_##Type_));
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-10-22 18:41:36 -07:00
|
|
|
# pragma push_macro("forceinline")
|
|
|
|
# pragma push_macro("global")
|
|
|
|
# pragma push_macro("internal")
|
|
|
|
# pragma push_macro("local_persist")
|
|
|
|
# pragma push_macro("neverinline")
|
|
|
|
# undef forceinline
|
|
|
|
# undef global
|
|
|
|
# undef internal
|
|
|
|
# undef local_persist
|
|
|
|
# undef neverinline
|
2024-12-03 10:14:14 -08:00
|
|
|
def_constant_spec( const, Spec_Const );
|
|
|
|
def_constant_spec( consteval, Spec_Consteval );
|
|
|
|
def_constant_spec( constexpr, Spec_Constexpr );
|
|
|
|
def_constant_spec( constinit, Spec_Constinit );
|
|
|
|
def_constant_spec( extern_linkage, Spec_External_Linkage );
|
|
|
|
def_constant_spec( final, Spec_Final );
|
|
|
|
def_constant_spec( forceinline, Spec_ForceInline );
|
|
|
|
def_constant_spec( global, Spec_Global );
|
|
|
|
def_constant_spec( inline, Spec_Inline );
|
|
|
|
def_constant_spec( internal_linkage, Spec_Internal_Linkage );
|
|
|
|
def_constant_spec( local_persist, Spec_Local_Persist );
|
|
|
|
def_constant_spec( mutable, Spec_Mutable );
|
|
|
|
def_constant_spec( neverinline, Spec_NeverInline );
|
|
|
|
def_constant_spec( noexcept, Spec_NoExceptions );
|
|
|
|
def_constant_spec( override, Spec_Override );
|
|
|
|
def_constant_spec( ptr, Spec_Ptr );
|
|
|
|
def_constant_spec( pure, Spec_Pure )
|
|
|
|
def_constant_spec( ref, Spec_Ref );
|
|
|
|
def_constant_spec( register, Spec_Register );
|
|
|
|
def_constant_spec( rvalue, Spec_RValue );
|
|
|
|
def_constant_spec( static_member, Spec_Static );
|
|
|
|
def_constant_spec( thread_local, Spec_Thread_Local );
|
|
|
|
def_constant_spec( virtual, Spec_Virtual );
|
|
|
|
def_constant_spec( volatile, Spec_Volatile)
|
|
|
|
|
|
|
|
spec_local_persist = def_specifiers( 1, Spec_Local_Persist );
|
2024-12-06 21:21:09 -08:00
|
|
|
code_set_global(cast(Code, spec_local_persist));
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2023-10-22 18:41:36 -07:00
|
|
|
# pragma pop_macro("forceinline")
|
|
|
|
# pragma pop_macro("global")
|
|
|
|
# pragma pop_macro("internal")
|
|
|
|
# pragma pop_macro("local_persist")
|
|
|
|
# pragma pop_macro("neverinline")
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-01 02:30:37 -08:00
|
|
|
# pragma push_macro("enum_underlying")
|
2024-12-05 21:33:53 -08:00
|
|
|
array_append(PreprocessorDefines, txt("enum_underlying("));
|
2024-12-01 02:30:37 -08:00
|
|
|
# pragma pop_macro("enum_underlying")
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
# undef def_constant_spec
|
|
|
|
}
|
|
|
|
|
|
|
|
void init()
|
|
|
|
{
|
|
|
|
// Setup global allocator
|
|
|
|
{
|
2024-12-08 22:33:37 -08:00
|
|
|
AllocatorInfo becasue_C = { & Global_Allocator_Proc, nullptr };
|
|
|
|
GlobalAllocator = becasue_C;
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
Global_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( Global_AllocatorBuckets == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets");
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-11-30 14:18:49 -08:00
|
|
|
Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( bucket.PhysicalStart == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-05 14:04:17 -08:00
|
|
|
array_append( Global_AllocatorBuckets, bucket );
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2024-12-08 20:10:10 -08:00
|
|
|
if (Allocator_DataArrays.Proc == nullptr) {
|
|
|
|
Allocator_DataArrays = heap();
|
|
|
|
}
|
|
|
|
if (Allocator_CodePool.Proc == nullptr ) {
|
|
|
|
Allocator_CodePool = heap();
|
|
|
|
}
|
|
|
|
if (Allocator_Lexer.Proc == nullptr) {
|
|
|
|
Allocator_Lexer = heap();
|
|
|
|
}
|
|
|
|
if (Allocator_StringArena.Proc == nullptr) {
|
|
|
|
Allocator_StringArena = heap();
|
|
|
|
}
|
|
|
|
if (Allocator_StringTable.Proc == nullptr) {
|
|
|
|
Allocator_StringTable = heap();
|
|
|
|
}
|
|
|
|
if (Allocator_TypeTable.Proc == nullptr) {
|
|
|
|
Allocator_TypeTable = heap();
|
|
|
|
}
|
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
// Setup the arrays
|
|
|
|
{
|
2024-12-08 22:33:37 -08:00
|
|
|
CodePools = array_init_reserve(Pool, Allocator_DataArrays, InitSize_DataArrays );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( CodePools == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::init: Failed to initialize the CodePools array" );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
StringArenas = array_init_reserve(Arena, Allocator_DataArrays, InitSize_DataArrays );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( StringArenas == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" );
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Setup the code pool and code entries arena.
|
|
|
|
{
|
2024-11-30 14:18:49 -08:00
|
|
|
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( code_pool.PhysicalStart == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::init: Failed to initialize the code pool" );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-05 14:04:17 -08:00
|
|
|
array_append( CodePools, code_pool );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-11-30 14:18:49 -08:00
|
|
|
LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-11-30 14:18:49 -08:00
|
|
|
Arena string_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( string_arena.PhysicalStart == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::init: Failed to initialize the string arena" );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-05 14:04:17 -08:00
|
|
|
array_append( StringArenas, string_arena );
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Setup the hash tables
|
|
|
|
{
|
2024-12-08 22:33:37 -08:00
|
|
|
StringCache = hashtable_init(StringCached, Allocator_StringTable);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( StringCache.Entries == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::init: Failed to initialize the StringCache");
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2023-11-21 17:09:14 -08:00
|
|
|
// Preprocessor Defines
|
2024-12-08 22:33:37 -08:00
|
|
|
PreprocessorDefines = array_init_reserve(StringCached, GlobalAllocator, kilobytes(1) );
|
2023-11-21 17:09:14 -08:00
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
define_constants();
|
2024-12-09 11:55:02 -08:00
|
|
|
GEN_NS_PARSER parser_init();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void deinit()
|
|
|
|
{
|
2024-10-27 15:58:37 -07:00
|
|
|
usize index = 0;
|
2024-12-04 08:01:53 -08:00
|
|
|
usize left = array_num(CodePools);
|
2023-07-24 14:45:27 -07:00
|
|
|
do
|
|
|
|
{
|
|
|
|
Pool* code_pool = & CodePools[index];
|
2024-12-04 08:01:53 -08:00
|
|
|
pool_free(code_pool);
|
2023-07-24 14:45:27 -07:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
while ( left--, left );
|
|
|
|
|
|
|
|
index = 0;
|
2024-12-04 08:01:53 -08:00
|
|
|
left = array_num(StringArenas);
|
2023-07-24 14:45:27 -07:00
|
|
|
do
|
|
|
|
{
|
|
|
|
Arena* string_arena = & StringArenas[index];
|
2024-12-04 08:01:53 -08:00
|
|
|
arena_free(string_arena);
|
2023-07-24 14:45:27 -07:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
while ( left--, left );
|
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
hashtable_destroy(StringCache);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
array_free( CodePools);
|
|
|
|
array_free( StringArenas);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-04 08:01:53 -08:00
|
|
|
arena_free(& LexArena);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
array_free(PreprocessorDefines);
|
2023-11-22 11:23:21 -08:00
|
|
|
|
2023-07-24 14:45:27 -07:00
|
|
|
index = 0;
|
2024-12-04 08:01:53 -08:00
|
|
|
left = array_num(Global_AllocatorBuckets);
|
2023-07-24 14:45:27 -07:00
|
|
|
do
|
|
|
|
{
|
|
|
|
Arena* bucket = & Global_AllocatorBuckets[ index ];
|
2024-12-04 08:01:53 -08:00
|
|
|
arena_free(bucket);
|
2023-07-24 14:45:27 -07:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
while ( left--, left );
|
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
array_free(Global_AllocatorBuckets);
|
2024-12-09 11:55:02 -08:00
|
|
|
GEN_NS_PARSER parser_deinit();
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void reset()
|
|
|
|
{
|
|
|
|
s32 index = 0;
|
2024-12-04 08:01:53 -08:00
|
|
|
s32 left = array_num(CodePools);
|
2023-07-24 14:45:27 -07:00
|
|
|
do
|
|
|
|
{
|
|
|
|
Pool* code_pool = & CodePools[index];
|
2024-12-04 08:30:54 -08:00
|
|
|
pool_clear(code_pool);
|
2023-07-24 14:45:27 -07:00
|
|
|
index++;
|
|
|
|
}
|
|
|
|
while ( left--, left );
|
|
|
|
|
|
|
|
index = 0;
|
2024-12-04 08:01:53 -08:00
|
|
|
left = array_num(StringArenas);
|
2023-07-24 14:45:27 -07:00
|
|
|
do
|
|
|
|
{
|
|
|
|
Arena* string_arena = & StringArenas[index];
|
|
|
|
string_arena->TotalUsed = 0;;
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
while ( left--, left );
|
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
hashtable_clear(StringCache);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
define_constants();
|
|
|
|
}
|
|
|
|
|
|
|
|
AllocatorInfo get_string_allocator( s32 str_length )
|
|
|
|
{
|
2024-12-04 21:40:51 -08:00
|
|
|
Arena* last = array_back(StringArenas);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-11-30 11:13:30 -08:00
|
|
|
usize size_req = str_length + sizeof(StringHeader) + sizeof(char*);
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize )
|
2023-07-24 14:45:27 -07:00
|
|
|
{
|
2024-11-30 14:18:49 -08:00
|
|
|
Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-05 14:04:17 -08:00
|
|
|
if ( ! array_append( StringArenas, new_arena ) )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::get_string_allocator: Failed to allocate a new string arena" );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
last = array_back(StringArenas);
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2024-12-04 08:01:53 -08:00
|
|
|
return arena_allocator_info(last);
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Will either make or retrive a code string.
|
|
|
|
StringCached get_cached_string( StrC str )
|
|
|
|
{
|
|
|
|
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
|
|
|
|
u64 key = crc32( str.Ptr, hash_length );
|
|
|
|
{
|
2024-12-04 21:40:51 -08:00
|
|
|
StringCached* result = hashtable_get(StringCache, key );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( result )
|
|
|
|
return * result;
|
|
|
|
}
|
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
StrC result = string_to_strc( string_make_strc( get_string_allocator( str.Len ), str ));
|
|
|
|
hashtable_set(StringCache, key, result );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
return result;
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2023-08-03 20:18:33 -07:00
|
|
|
// Used internally to retireve a Code object form the CodePool.
|
2023-07-24 14:45:27 -07:00
|
|
|
Code make_code()
|
|
|
|
{
|
2024-12-04 21:40:51 -08:00
|
|
|
Pool* allocator = array_back( CodePools);
|
2023-07-24 14:45:27 -07:00
|
|
|
if ( allocator->FreeList == nullptr )
|
|
|
|
{
|
2024-11-30 14:18:49 -08:00
|
|
|
Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
|
|
|
if ( code_pool.PhysicalStart == nullptr )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-05 14:04:17 -08:00
|
|
|
if ( ! array_append( CodePools, code_pool ) )
|
2023-08-09 15:47:59 -07:00
|
|
|
GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
|
2023-07-24 14:45:27 -07:00
|
|
|
|
2024-12-04 21:40:51 -08:00
|
|
|
allocator = array_back( CodePools);
|
2023-07-24 14:45:27 -07:00
|
|
|
}
|
|
|
|
|
2024-12-08 22:33:37 -08:00
|
|
|
Code result = { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
|
2024-12-06 21:21:09 -08:00
|
|
|
mem_set( rcast(void*, cast(AST*, result)), 0, sizeof(AST) );
|
2023-07-24 14:45:27 -07:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_allocator_data_arrays( AllocatorInfo allocator )
|
|
|
|
{
|
|
|
|
Allocator_DataArrays = allocator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_allocator_code_pool( AllocatorInfo allocator )
|
|
|
|
{
|
|
|
|
Allocator_CodePool = allocator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_allocator_lexer( AllocatorInfo allocator )
|
|
|
|
{
|
|
|
|
Allocator_Lexer = allocator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_allocator_string_arena( AllocatorInfo allocator )
|
|
|
|
{
|
|
|
|
Allocator_StringArena = allocator;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_allocator_string_table( AllocatorInfo allocator )
|
|
|
|
{
|
|
|
|
Allocator_StringArena = allocator;
|
|
|
|
}
|