mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-11-03 23:36:12 -08:00 
			
		
		
		
	Introduced the general context struct for gencpp
This commit is contained in:
		@@ -9,9 +9,11 @@ internal void parser_deinit();
 | 
			
		||||
GEN_NS_PARSER_END
 | 
			
		||||
 | 
			
		||||
internal
 | 
			
		||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
			
		||||
void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
			
		||||
{
 | 
			
		||||
	Arena* last = array_back(Global_AllocatorBuckets);
 | 
			
		||||
	GEN_ASSERT(_ctx);
 | 
			
		||||
	GEN_ASSERT(_ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
	Arena* last = array_back(_ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
 | 
			
		||||
	switch ( type )
 | 
			
		||||
	{
 | 
			
		||||
@@ -19,15 +21,15 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
 | 
			
		||||
		{
 | 
			
		||||
			if ( ( last->TotalUsed + size ) > last->TotalSize )
 | 
			
		||||
			{
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), _ctx->InitSize_Fallback_Allocator_Bucket_Size );
 | 
			
		||||
 | 
			
		||||
				if ( bucket.PhysicalStart == nullptr )
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				if ( ! array_append( Global_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
 | 
			
		||||
				if ( ! array_append( _ctx->Fallback_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				last = array_back(Global_AllocatorBuckets);
 | 
			
		||||
				last = array_back(_ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return alloc_align( arena_allocator_info(last), size, alignment );
 | 
			
		||||
@@ -46,15 +48,15 @@ void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, s
 | 
			
		||||
		{
 | 
			
		||||
			if ( last->TotalUsed + size > last->TotalSize )
 | 
			
		||||
			{
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
 | 
			
		||||
				Arena bucket = arena_init_from_allocator( heap(), _ctx->InitSize_Fallback_Allocator_Bucket_Size );
 | 
			
		||||
 | 
			
		||||
				if ( bucket.PhysicalStart == nullptr )
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Global_AllocatorBuckets");
 | 
			
		||||
					GEN_FATAL( "Failed to create bucket for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				if ( ! array_append( Global_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Global_AllocatorBuckets");
 | 
			
		||||
				if ( ! array_append( _ctx->Fallback_AllocatorBuckets, bucket ) )
 | 
			
		||||
					GEN_FATAL( "Failed to append bucket to Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
				last = array_back(Global_AllocatorBuckets);
 | 
			
		||||
				last = array_back( _ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			void* result = alloc_align( last->Backing, size, alignment );
 | 
			
		||||
@@ -75,7 +77,7 @@ internal
 | 
			
		||||
void define_constants()
 | 
			
		||||
{
 | 
			
		||||
	Code_Global          = make_code();
 | 
			
		||||
	Code_Global->Name    = get_cached_string( txt("Global Code") );
 | 
			
		||||
	Code_Global->Name    = cache_str( txt("Global Code") );
 | 
			
		||||
	Code_Global->Content = Code_Global->Name;
 | 
			
		||||
 | 
			
		||||
	Code_Invalid = make_code();
 | 
			
		||||
@@ -83,22 +85,22 @@ void define_constants()
 | 
			
		||||
 | 
			
		||||
	t_empty       = (CodeTypename) make_code();
 | 
			
		||||
	t_empty->Type = CT_Typename;
 | 
			
		||||
	t_empty->Name = get_cached_string( txt("") );
 | 
			
		||||
	t_empty->Name = cache_str( txt("") );
 | 
			
		||||
	code_set_global(cast(Code, t_empty));
 | 
			
		||||
 | 
			
		||||
	access_private       = make_code();
 | 
			
		||||
	access_private->Type = CT_Access_Private;
 | 
			
		||||
	access_private->Name = get_cached_string( txt("private:\n") );
 | 
			
		||||
	access_private->Name = cache_str( txt("private:\n") );
 | 
			
		||||
	code_set_global(cast(Code, access_private));
 | 
			
		||||
 | 
			
		||||
	access_protected       = make_code();
 | 
			
		||||
	access_protected->Type = CT_Access_Protected;
 | 
			
		||||
	access_protected->Name = get_cached_string( txt("protected:\n") );
 | 
			
		||||
	access_protected->Name = cache_str( txt("protected:\n") );
 | 
			
		||||
	code_set_global(access_protected);
 | 
			
		||||
 | 
			
		||||
	access_public       = make_code();
 | 
			
		||||
	access_public->Type = CT_Access_Public;
 | 
			
		||||
	access_public->Name = get_cached_string( txt("public:\n") );
 | 
			
		||||
	access_public->Name = cache_str( txt("public:\n") );
 | 
			
		||||
	code_set_global(access_public);
 | 
			
		||||
 | 
			
		||||
	Str api_export_str = code(GEN_API_Export_Code);
 | 
			
		||||
@@ -111,13 +113,13 @@ void define_constants()
 | 
			
		||||
 | 
			
		||||
	module_global_fragment          = make_code();
 | 
			
		||||
	module_global_fragment->Type    = CT_Untyped;
 | 
			
		||||
	module_global_fragment->Name    = get_cached_string( txt("module;") );
 | 
			
		||||
	module_global_fragment->Name    = cache_str( txt("module;") );
 | 
			
		||||
	module_global_fragment->Content = module_global_fragment->Name;
 | 
			
		||||
	code_set_global(cast(Code, module_global_fragment));
 | 
			
		||||
 | 
			
		||||
	module_private_fragment          = make_code();
 | 
			
		||||
	module_private_fragment->Type    = CT_Untyped;
 | 
			
		||||
	module_private_fragment->Name    = get_cached_string( txt("module : private;") );
 | 
			
		||||
	module_private_fragment->Name    = cache_str( txt("module : private;") );
 | 
			
		||||
	module_private_fragment->Content = module_private_fragment->Name;
 | 
			
		||||
	code_set_global(cast(Code, module_private_fragment));
 | 
			
		||||
 | 
			
		||||
@@ -127,13 +129,13 @@ void define_constants()
 | 
			
		||||
 | 
			
		||||
	pragma_once          = (CodePragma) make_code();
 | 
			
		||||
	pragma_once->Type    = CT_Preprocess_Pragma;
 | 
			
		||||
	pragma_once->Name    = get_cached_string( txt("once") );
 | 
			
		||||
	pragma_once->Name    = cache_str( txt("once") );
 | 
			
		||||
	pragma_once->Content = pragma_once->Name;
 | 
			
		||||
	code_set_global((Code)pragma_once);
 | 
			
		||||
 | 
			
		||||
	param_varadic            = (CodeParams) make_code();
 | 
			
		||||
	param_varadic->Type      = CT_Parameters;
 | 
			
		||||
	param_varadic->Name      = get_cached_string( txt("...") );
 | 
			
		||||
	param_varadic->Name      = cache_str( txt("...") );
 | 
			
		||||
	param_varadic->ValueType = t_empty;
 | 
			
		||||
	code_set_global((Code)param_varadic);
 | 
			
		||||
 | 
			
		||||
@@ -205,221 +207,249 @@ void define_constants()
 | 
			
		||||
	if (enum_underlying_sig.Len == 0) {
 | 
			
		||||
		enum_underlying_sig = txt("enum_underlying(");
 | 
			
		||||
	}
 | 
			
		||||
	array_append(PreprocessorDefines, enum_underlying_sig);
 | 
			
		||||
	array_append( _ctx->PreprocessorDefines, enum_underlying_sig);
 | 
			
		||||
 | 
			
		||||
#	undef def_constant_spec
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init()
 | 
			
		||||
void init(Context* ctx)
 | 
			
		||||
{
 | 
			
		||||
	// Setup global allocator
 | 
			
		||||
	AllocatorInfo fallback_allocator = { & fallback_allocator_proc, nullptr };
 | 
			
		||||
	
 | 
			
		||||
	b32 using_fallback_allocator = false;
 | 
			
		||||
	if (ctx->Allocator_DyanmicContainers.Proc == nullptr) {
 | 
			
		||||
		ctx->Allocator_DyanmicContainers = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->Allocator_Pool.Proc == nullptr ) {
 | 
			
		||||
		ctx->Allocator_Pool = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->Allocator_StrCache.Proc == nullptr) {
 | 
			
		||||
		ctx->Allocator_StrCache = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->Allocator_Temp.Proc == nullptr) {
 | 
			
		||||
		ctx->Allocator_Temp = fallback_allocator;
 | 
			
		||||
		using_fallback_allocator = true;
 | 
			
		||||
	}
 | 
			
		||||
	// Setup fallback allocator
 | 
			
		||||
	if (using_fallback_allocator)
 | 
			
		||||
	{
 | 
			
		||||
		AllocatorInfo becasue_C = { & Global_Allocator_Proc, nullptr };
 | 
			
		||||
		GlobalAllocator = becasue_C;
 | 
			
		||||
 | 
			
		||||
		Global_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
 | 
			
		||||
 | 
			
		||||
		if ( Global_AllocatorBuckets == nullptr )
 | 
			
		||||
			GEN_FATAL( "Failed to reserve memory for Global_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
		Arena bucket = arena_init_from_allocator( heap(), Global_BucketSize );
 | 
			
		||||
		ctx->Fallback_AllocatorBuckets = array_init_reserve(Arena, heap(), 128 );
 | 
			
		||||
		if ( ctx->Fallback_AllocatorBuckets == nullptr )
 | 
			
		||||
			GEN_FATAL( "Failed to reserve memory for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
		Arena bucket = arena_init_from_allocator( heap(), ctx->InitSize_Fallback_Allocator_Bucket_Size );
 | 
			
		||||
		if ( bucket.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "Failed to create first bucket for Global_AllocatorBuckets");
 | 
			
		||||
			GEN_FATAL( "Failed to create first bucket for Fallback_AllocatorBuckets");
 | 
			
		||||
 | 
			
		||||
		array_append( Global_AllocatorBuckets, bucket );
 | 
			
		||||
		array_append( ctx->Fallback_AllocatorBuckets, bucket );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Allocator_DataArrays.Proc == nullptr) {
 | 
			
		||||
		Allocator_DataArrays = GlobalAllocator;
 | 
			
		||||
	if (ctx->Max_CommentLineLength == 0) {
 | 
			
		||||
		ctx->Max_CommentLineLength = 1024;
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_CodePool.Proc == nullptr ) {
 | 
			
		||||
		Allocator_CodePool = GlobalAllocator;
 | 
			
		||||
	if (ctx->Max_StrCacheLength == 0) {
 | 
			
		||||
		ctx->Max_StrCacheLength = kilobytes(512);
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_Lexer.Proc == nullptr) {
 | 
			
		||||
		Allocator_Lexer = GlobalAllocator;
 | 
			
		||||
 | 
			
		||||
	if (ctx->InitSize_BuilderBuffer == 0) {
 | 
			
		||||
		ctx->InitSize_BuilderBuffer = megabytes(2);
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_StringArena.Proc == nullptr) {
 | 
			
		||||
		Allocator_StringArena = GlobalAllocator;
 | 
			
		||||
	if (ctx->InitSize_CodePoolsArray == 0) { 
 | 
			
		||||
		ctx->InitSize_CodePoolsArray = 16; 
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_StringTable.Proc == nullptr) {
 | 
			
		||||
		Allocator_StringTable = GlobalAllocator;
 | 
			
		||||
	if (ctx->InitSize_StringArenasArray == 0) {
 | 
			
		||||
		ctx->InitSize_StringArenasArray = 16; 
 | 
			
		||||
	}
 | 
			
		||||
	if (Allocator_TypeTable.Proc == nullptr) {
 | 
			
		||||
		Allocator_TypeTable = GlobalAllocator;
 | 
			
		||||
	if (ctx->CodePool_NumBlocks == 0) {
 | 
			
		||||
		ctx->CodePool_NumBlocks = kilobytes(16);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ctx->InitSize_LexArena == 0 ) {
 | 
			
		||||
		ctx->InitSize_LexArena = megabytes(4);
 | 
			
		||||
	}
 | 
			
		||||
	if (ctx->SizePer_StringArena == 0) {
 | 
			
		||||
		ctx->SizePer_StringArena = megabytes(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ctx->InitSize_Fallback_Allocator_Bucket_Size == 0) { 
 | 
			
		||||
		ctx->InitSize_Fallback_Allocator_Bucket_Size = megabytes(8);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Override the current context (user has to put it back if unwanted).
 | 
			
		||||
	_ctx = ctx;
 | 
			
		||||
 | 
			
		||||
	// Setup the arrays
 | 
			
		||||
	{
 | 
			
		||||
		CodePools = array_init_reserve(Pool, Allocator_DataArrays, InitSize_DataArrays );
 | 
			
		||||
 | 
			
		||||
		if ( CodePools == nullptr )
 | 
			
		||||
		ctx->CodePools = array_init_reserve(Pool, ctx->Allocator_DyanmicContainers, ctx->InitSize_CodePoolsArray );
 | 
			
		||||
		if ( ctx->CodePools == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the CodePools array" );
 | 
			
		||||
 | 
			
		||||
		StringArenas = array_init_reserve(Arena, Allocator_DataArrays, InitSize_DataArrays );
 | 
			
		||||
 | 
			
		||||
		if ( StringArenas == nullptr )
 | 
			
		||||
		ctx->StringArenas = array_init_reserve(Arena, ctx->Allocator_DyanmicContainers, ctx->InitSize_StringArenasArray );
 | 
			
		||||
		if ( ctx->StringArenas == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the StringArenas array" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Setup the code pool and code entries arena.
 | 
			
		||||
	{
 | 
			
		||||
		Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
 | 
			
		||||
		Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
		if ( code_pool.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the code pool" );
 | 
			
		||||
		array_append( ctx->CodePools, code_pool );
 | 
			
		||||
 | 
			
		||||
		array_append( CodePools, code_pool );
 | 
			
		||||
 | 
			
		||||
		LexArena = arena_init_from_allocator( Allocator_Lexer, LexAllocator_Size );
 | 
			
		||||
 | 
			
		||||
		Arena strbuilder_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
 | 
			
		||||
		// TODO(Ed): This is going to be phased out most likely.
 | 
			
		||||
		ctx->LexArena = arena_init_from_allocator( ctx->Allocator_DyanmicContainers, ctx->InitSize_LexArena );
 | 
			
		||||
 | 
			
		||||
		// TODO(Ed): Eventually the string arenas needs to be phased out for a dedicated string slab allocator
 | 
			
		||||
		Arena strbuilder_arena = arena_init_from_allocator( ctx->Allocator_StrCache, ctx->SizePer_StringArena );
 | 
			
		||||
		if ( strbuilder_arena.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the string arena" );
 | 
			
		||||
 | 
			
		||||
		array_append( StringArenas, strbuilder_arena );
 | 
			
		||||
		array_append( ctx->StringArenas, strbuilder_arena );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Setup the hash tables
 | 
			
		||||
	{
 | 
			
		||||
		StringCache = hashtable_init(StringCached, Allocator_StringTable);
 | 
			
		||||
 | 
			
		||||
		if ( StringCache.Entries == nullptr )
 | 
			
		||||
		ctx->StrCache = hashtable_init(StrCached, ctx->Allocator_DyanmicContainers);
 | 
			
		||||
		if ( ctx->StrCache.Entries == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::init: Failed to initialize the StringCache");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Preprocessor Defines
 | 
			
		||||
	PreprocessorDefines = array_init_reserve(StringCached, GlobalAllocator, kilobytes(1) );
 | 
			
		||||
	ctx->PreprocessorDefines = array_init_reserve(StrCached, ctx->Allocator_DyanmicContainers, kilobytes(1) );
 | 
			
		||||
 | 
			
		||||
	define_constants();
 | 
			
		||||
	GEN_NS_PARSER parser_init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void deinit()
 | 
			
		||||
void deinit(Context* ctx)
 | 
			
		||||
{
 | 
			
		||||
	usize index = 0;
 | 
			
		||||
	usize left  = array_num(CodePools);
 | 
			
		||||
	usize left  = array_num(ctx->CodePools);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Pool* code_pool = & CodePools[index];
 | 
			
		||||
		Pool* code_pool = & ctx->CodePools[index];
 | 
			
		||||
		pool_free(code_pool);
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	index = 0;
 | 
			
		||||
	left  = array_num(StringArenas);
 | 
			
		||||
	left  = array_num(ctx->StringArenas);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Arena* strbuilder_arena = & StringArenas[index];
 | 
			
		||||
		Arena* strbuilder_arena = & ctx->StringArenas[index];
 | 
			
		||||
		arena_free(strbuilder_arena);
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	hashtable_destroy(StringCache);
 | 
			
		||||
	hashtable_destroy(ctx->StrCache);
 | 
			
		||||
 | 
			
		||||
	array_free( CodePools);
 | 
			
		||||
	array_free( StringArenas);
 | 
			
		||||
	array_free( ctx->CodePools);
 | 
			
		||||
	array_free( ctx->StringArenas);
 | 
			
		||||
 | 
			
		||||
	arena_free(& LexArena);
 | 
			
		||||
	arena_free(& ctx->LexArena);
 | 
			
		||||
 | 
			
		||||
	array_free(PreprocessorDefines);
 | 
			
		||||
	array_free(ctx->PreprocessorDefines);
 | 
			
		||||
 | 
			
		||||
	index = 0;
 | 
			
		||||
	left  = array_num(Global_AllocatorBuckets);
 | 
			
		||||
	left  = array_num( ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Arena* bucket = & Global_AllocatorBuckets[ index ];
 | 
			
		||||
		Arena* bucket = & ctx->Fallback_AllocatorBuckets[ index ];
 | 
			
		||||
		arena_free(bucket);
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	array_free(Global_AllocatorBuckets);
 | 
			
		||||
	array_free( ctx->Fallback_AllocatorBuckets);
 | 
			
		||||
	GEN_NS_PARSER parser_deinit();
 | 
			
		||||
 | 
			
		||||
	if (_ctx == ctx) 
 | 
			
		||||
		_ctx = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void reset()
 | 
			
		||||
void reset(Context* ctx)
 | 
			
		||||
{
 | 
			
		||||
	s32 index = 0;
 | 
			
		||||
	s32 left  = array_num(CodePools);
 | 
			
		||||
	s32 left  = array_num(ctx->CodePools);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Pool* code_pool = & CodePools[index];
 | 
			
		||||
		Pool* code_pool = & ctx->CodePools[index];
 | 
			
		||||
		pool_clear(code_pool);
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	index = 0;
 | 
			
		||||
	left  = array_num(StringArenas);
 | 
			
		||||
	left  = array_num(ctx->StringArenas);
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		Arena* strbuilder_arena = & StringArenas[index];
 | 
			
		||||
		Arena* strbuilder_arena = & ctx->StringArenas[index];
 | 
			
		||||
		strbuilder_arena->TotalUsed = 0;;
 | 
			
		||||
		index++;
 | 
			
		||||
	}
 | 
			
		||||
	while ( left--, left );
 | 
			
		||||
 | 
			
		||||
	hashtable_clear(StringCache);
 | 
			
		||||
 | 
			
		||||
	hashtable_clear(ctx->StrCache);
 | 
			
		||||
	define_constants();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AllocatorInfo get_strbuilder_allocator( s32 c_str_length )
 | 
			
		||||
void set_context(Context* new_ctx) {
 | 
			
		||||
	GEN_ASSERT(new_ctx);
 | 
			
		||||
	_ctx = new_ctx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AllocatorInfo get_cached_str_allocator( s32 str_length )
 | 
			
		||||
{
 | 
			
		||||
	Arena* last = array_back(StringArenas);
 | 
			
		||||
 | 
			
		||||
	usize size_req = c_str_length + sizeof(StrBuilderHeader) + sizeof(char*);
 | 
			
		||||
 | 
			
		||||
	Arena* last     = array_back(_ctx->StringArenas);
 | 
			
		||||
	usize  size_req = str_length + sizeof(StrBuilderHeader) + sizeof(char*);
 | 
			
		||||
	if ( last->TotalUsed + scast(ssize, size_req) > last->TotalSize )
 | 
			
		||||
	{
 | 
			
		||||
		Arena new_arena = arena_init_from_allocator( Allocator_StringArena, SizePer_StringArena );
 | 
			
		||||
		Arena new_arena = arena_init_from_allocator( _ctx->Allocator_StrCache, _ctx->SizePer_StringArena );
 | 
			
		||||
		if ( ! array_append( _ctx->StringArenas, new_arena ) )
 | 
			
		||||
			GEN_FATAL( "gen::get_cached_str_allocator: Failed to allocate a new string arena" );
 | 
			
		||||
 | 
			
		||||
		if ( ! array_append( StringArenas, new_arena ) )
 | 
			
		||||
			GEN_FATAL( "gen::get_strbuilder_allocator: Failed to allocate a new string arena" );
 | 
			
		||||
 | 
			
		||||
		last = array_back(StringArenas);
 | 
			
		||||
		last = array_back( _ctx->StringArenas);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return arena_allocator_info(last);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Will either make or retrive a code string.
 | 
			
		||||
StringCached get_cached_string( Str str )
 | 
			
		||||
StrCached cache_str( Str str )
 | 
			
		||||
{
 | 
			
		||||
	s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
 | 
			
		||||
	u64 key         = crc32( str.Ptr, hash_length );
 | 
			
		||||
	{
 | 
			
		||||
		StringCached* result = hashtable_get(StringCache, key );
 | 
			
		||||
 | 
			
		||||
	if (str.Len > _ctx->Max_StrCacheLength) {
 | 
			
		||||
		// Do not cache the string, just shove into the arena and and return it.
 | 
			
		||||
		Str result = strbuilder_to_str( strbuilder_make_str( get_cached_str_allocator( str.Len ), str ));
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	u64 key = crc32( str.Ptr, str.Len ); {
 | 
			
		||||
		StrCached* result = hashtable_get( _ctx->StrCache, key );
 | 
			
		||||
		if ( result )
 | 
			
		||||
			return * result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Str result = strbuilder_to_str( strbuilder_make_str( get_strbuilder_allocator( str.Len ), str ));
 | 
			
		||||
	hashtable_set(StringCache, key, result );
 | 
			
		||||
 | 
			
		||||
	Str result = strbuilder_to_str( strbuilder_make_str( get_cached_str_allocator( str.Len ), str ));
 | 
			
		||||
	hashtable_set( _ctx->StrCache, key, result );
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Used internally to retireve a Code object form the CodePool.
 | 
			
		||||
Code make_code()
 | 
			
		||||
{
 | 
			
		||||
	Pool* allocator = array_back( CodePools);
 | 
			
		||||
	Pool* allocator = array_back( _ctx->CodePools);
 | 
			
		||||
	if ( allocator->FreeList == nullptr )
 | 
			
		||||
	{
 | 
			
		||||
		Pool code_pool = pool_init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
		Pool code_pool = pool_init( _ctx->Allocator_Pool, _ctx->CodePool_NumBlocks, sizeof(AST) );
 | 
			
		||||
 | 
			
		||||
		if ( code_pool.PhysicalStart == nullptr )
 | 
			
		||||
			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
 | 
			
		||||
 | 
			
		||||
		if ( ! array_append( CodePools, code_pool ) )
 | 
			
		||||
		if ( ! array_append( _ctx->CodePools, code_pool ) )
 | 
			
		||||
			GEN_FATAL( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
 | 
			
		||||
 | 
			
		||||
		allocator = array_back( CodePools);
 | 
			
		||||
		allocator = array_back( _ctx->CodePools);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Code result = { rcast( AST*, alloc( pool_allocator_info(allocator), sizeof(AST) )) };
 | 
			
		||||
@@ -427,27 +457,10 @@ Code make_code()
 | 
			
		||||
	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_strbuilder_arena( AllocatorInfo allocator )
 | 
			
		||||
{
 | 
			
		||||
	Allocator_StringArena = allocator;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_allocator_strbuilder_table( AllocatorInfo allocator )
 | 
			
		||||
{
 | 
			
		||||
	Allocator_StringArena = allocator;
 | 
			
		||||
void set_preprocess_define( Str id, b32 is_functional ) {
 | 
			
		||||
	StrBuilder builder = strbuilder_make_str( _ctx->Allocator_Temp, id );
 | 
			
		||||
	if (is_functional) {
 | 
			
		||||
		strbuilder_append_char( & builder, '(' );
 | 
			
		||||
	}
 | 
			
		||||
	array_append( _ctx->PreprocessorDefines, cache_str(builder) ); 
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user