Started to move over zpl depndencies and use templated containers.

Still have a ways to go.
This commit is contained in:
Edward R. Gonzalez 2023-07-11 18:29:45 -04:00
parent 661630a88f
commit 20d307759b
15 changed files with 2485 additions and 1340 deletions

47
.vscode/gencpp.natvis vendored
View File

@ -1,11 +1,33 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="StrC"> <Type Name="gen::AllocatorInfo">
<DisplayString>Data:{Data} Proc:{Proc}</DisplayString>
</Type>
<Type Name="gen::Array&lt;*&gt;">
<DisplayString>Num:{((Header*)((char*)Data - sizeof(Header)))->Num}, Capacity:{((Header*)((char*)Data - sizeof(Header)))->Capacity}</DisplayString>
<Expand>
<Synthetic Name="Header">
<DisplayString>{(Header*)((char*)Data - sizeof(Header))}</DisplayString>
<Expand>
<Item Name="Allocator">((Header*)((char*)Data - sizeof(Header)))->Allocator</Item>
<Item Name="Capacity">((Header*)((char*)Data - sizeof(Header)))->Capacity</Item>
<Item Name="Num">((Header*)((char*)Data - sizeof(Header)))->Num</Item>
</Expand>
</Synthetic>
<ArrayItems>
<Size>((Header*)((char*)Data - sizeof(Header)))->Capacity</Size>
<ValuePointer>Data</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="gen::StrC">
<DisplayString>Len:{Len} Ptr:{Ptr, [Len]s}</DisplayString> <DisplayString>Len:{Len} Ptr:{Ptr, [Len]s}</DisplayString>
</Type> </Type>
<Type Name="String"> <Type Name="gen::String">
<DisplayString Condition="Data == nullptr">null</DisplayString> <DisplayString Condition="Data == nullptr">null</DisplayString>
<DisplayString>{Data,na}</DisplayString> <DisplayString>{Data,na}</DisplayString>
<Expand> <Expand>
@ -20,7 +42,7 @@
</Expand> </Expand>
</Type> </Type>
<Type Name="String::Header"> <Type Name="gen::String::Header">
<DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString> <DisplayString>Length: {Length}, Capacity: {Capacity}</DisplayString>
<Expand> <Expand>
<Item Name="Allocator">Allocator</Item> <Item Name="Allocator">Allocator</Item>
@ -41,7 +63,7 @@
<Item Name="ArrStatic" Condition="DynamicEntries == false">ArrStatic</Item> <Item Name="ArrStatic" Condition="DynamicEntries == false">ArrStatic</Item>
<Item Name="Index" Condition="DynamicEntries == false">StaticIndex</Item> <Item Name="Index" Condition="DynamicEntries == false">StaticIndex</Item>
<Item Name="ArrDyn" Condition="DynamicEntries == true">ArrDyn</Item> <Item Name="ArrDyn" Condition="DynamicEntries == true">ArrDyn</Item>
<Item Name="Index" Condition="DynamicEntries == true">((ArrayHeader*)((char*)ArrDyn - sizeof(ArrayHeader)))->count</Item> <Item Name="Index" Condition="DynamicEntries == true">ArrDyn.num()</Item>
</Expand> </Expand>
</Type> </Type>
@ -57,7 +79,7 @@
<Item Name="ArrStatic" Condition="ast->DynamicEntries == false">ast->ArrStatic</Item> <Item Name="ArrStatic" Condition="ast->DynamicEntries == false">ast->ArrStatic</Item>
<Item Name="Index" Condition="ast->DynamicEntries == false">ast->StaticIndex</Item> <Item Name="Index" Condition="ast->DynamicEntries == false">ast->StaticIndex</Item>
<Item Name="ArrDyn" Condition="ast->DynamicEntries == true">ast->ArrDyn</Item> <Item Name="ArrDyn" Condition="ast->DynamicEntries == true">ast->ArrDyn</Item>
<Item Name="Index" Condition="ast->DynamicEntries == true">((ArrayHeader*)((char*)ast->ArrDyn - sizeof(ArrayHeader)))->count</Item> <Item Name="Index" Condition="ast->DynamicEntries == true">ast->ArrDyn.num()</Item>
</Expand> </Expand>
</Type> </Type>
@ -71,21 +93,6 @@
<Type Name="gen::Parser::TokArray"> <Type Name="gen::Parser::TokArray">
<DisplayString>Current[ { Arr[Idx] } ] Idx:{ Idx }</DisplayString> <DisplayString>Current[ { Arr[Idx] } ] Idx:{ Idx }</DisplayString>
<Expand>
<Synthetic Name="Header">
<DisplayString>{(ArrayHeader*)((char*)Arr - sizeof(ArrayHeader))}</DisplayString>
<Expand>
<Item Name="elem_size">((ArrayHeader*)((char*)Arr - sizeof(ArrayHeader)))->elem_size</Item>
<Item Name="count">((ArrayHeader*)((char*)Arr - sizeof(ArrayHeader)))->count</Item>
<Item Name="capacity">((ArrayHeader*)((char*)Arr - sizeof(ArrayHeader)))->capacity</Item>
<Item Name="allocator">((ArrayHeader*)((char*)Arr - sizeof(ArrayHeader)))->allocator</Item>
</Expand>
</Synthetic>
<ArrayItems>
<Size>((ArrayHeader*)((char*)Arr - sizeof(ArrayHeader)))->count</Size>
<ValuePointer>Arr</ValuePointer>
</ArrayItems>
</Expand>
</Type> </Type>
</AutoVisualizer> </AutoVisualizer>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,15 +7,15 @@
namespace gen namespace gen
{ {
ZPL_TABLE_DEFINE( StringTable, str_tbl_, String ); // ZPL_TABLE_DEFINE( StringTable, str_tbl_, String );
namespace StaticData namespace StaticData
{ {
global Array(Pool) CodePools = nullptr; global Array< Pool > CodePools = { nullptr };
global Array(Arena) CodeEntriesArenas = nullptr; global Array< Arena > CodeEntriesArenas = { nullptr };
global Array(Arena) StringArenas = nullptr; global Array< Arena > StringArenas = { nullptr };
global StringTable StringMap; global StringTable StringCache;
global AllocatorInfo Allocator_DataArrays = heap(); global AllocatorInfo Allocator_DataArrays = heap();
global AllocatorInfo Allocator_CodePool = heap(); global AllocatorInfo Allocator_CodePool = heap();
@ -837,13 +837,28 @@ namespace gen
result.append_fmt( "%s %s", entry( 0 )->to_string(), Name ); result.append_fmt( "%s %s", entry( 0 )->to_string(), Name );
AST* type = entry( 0);
AST* type_arr = type->entry( 0 );
// TODO : This problably needs to be an iteration for all entries of type.
if ( type->num_entries() && type_arr->Type == ECode::Untyped )
result.append_fmt( "[%s]", type_arr->to_string() );
if ( entry( idx ) ) if ( entry( idx ) )
result.append_fmt( " = %s;", entry( idx )->to_string() ); result.append_fmt( " = %s;", entry( idx )->to_string() );
break; break;
} }
result.append_fmt( "%s %s;", entry( 0 )->to_string(), Name ); AST* type = entry( 0);
AST* type_arr = type->entry( 0 );
// TODO : This problably needs to be an iteration for all entries of type.
if ( type->num_entries() && type_arr->Type == ECode::Untyped )
result.append_fmt( "%s %s[%s];", type->to_string(), Name, type_arr->to_string() );
else
result.append_fmt( "%s %s;", entry( 0 )->to_string(), Name );
} }
break; break;
@ -1033,48 +1048,52 @@ namespace gen
// Setup the arrays // Setup the arrays
{ {
if (! array_init_reserve( CodePools, Allocator_DataArrays, InitSize_DataArrays ) ) CodePools = Array<Pool>::init_reserve( Allocator_DataArrays, InitSize_DataArrays );
if ( CodePools == nullptr )
fatal( "gen::init: Failed to initialize the CodePools array" ); fatal( "gen::init: Failed to initialize the CodePools array" );
if ( ! array_init_reserve( CodeEntriesArenas, Allocator_DataArrays, InitSize_DataArrays ) ) CodeEntriesArenas = Array<Arena>::init_reserve( Allocator_DataArrays, InitSize_DataArrays );
if ( CodeEntriesArenas == nullptr )
fatal( "gen::init: Failed to initialize the CodeEntriesPools array" ); fatal( "gen::init: Failed to initialize the CodeEntriesPools array" );
if ( ! array_init_reserve( StringArenas, Allocator_DataArrays, InitSize_DataArrays ) ) StringArenas = Array<Arena>::init_reserve( Allocator_DataArrays, InitSize_DataArrays );
if ( StringArenas == nullptr )
fatal( "gen::init: Failed to initialize the StringArenas array" ); fatal( "gen::init: Failed to initialize the StringArenas array" );
} }
// Setup the code pool and code entries arena. // Setup the code pool and code entries arena.
{ {
Pool code_pool; Pool code_pool = Pool::init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
pool_init( & code_pool, Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
if ( code_pool.physical_start == nullptr ) if ( code_pool.PhysicalStart == nullptr )
fatal( "gen::init: Failed to initialize the code pool" ); fatal( "gen::init: Failed to initialize the code pool" );
array_append( CodePools, code_pool ); CodePools.append( code_pool );
Arena code_entires_arena; Arena code_entires_arena = Arena::init_from_allocator( Allocator_CodeEntriesArena, SizePer_CodeEntriresArena );
arena_init_from_allocator( & code_entires_arena, Allocator_CodeEntriesArena, SizePer_CodeEntriresArena );
if ( code_entires_arena.physical_start == nullptr ) if ( code_entires_arena.PhysicalStart == nullptr )
fatal( "gen::init: Failed to initialize the code entries arena" ); fatal( "gen::init: Failed to initialize the code entries arena" );
array_append( CodeEntriesArenas, code_entires_arena ); CodeEntriesArenas.append( code_entires_arena );
Arena string_arena; Arena string_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
arena_init_from_allocator( & string_arena, Allocator_StringArena, SizePer_StringArena );
if ( string_arena.physical_start == nullptr ) if ( string_arena.PhysicalStart == nullptr )
fatal( "gen::init: Failed to initialize the string arena" ); fatal( "gen::init: Failed to initialize the string arena" );
array_append( StringArenas, string_arena ); StringArenas.append( string_arena );
} }
// Setup the hash tables // Setup the hash tables
{ {
str_tbl_init ( & StringMap, Allocator_StringTable ); StringCache = StringTable::init( Allocator_StringTable );
if ( StringMap.entries == nullptr )
fatal( "gen::init: Failed to initialize the StringMap"); if ( StringCache.Entries == nullptr )
fatal( "gen::init: Failed to initialize the StringCache");
} }
Code::Global = make_code(); Code::Global = make_code();
@ -1195,41 +1214,40 @@ namespace gen
using namespace StaticData; using namespace StaticData;
s32 index = 0; s32 index = 0;
s32 left = array_count( CodePools ); s32 left = CodePools.num();
do do
{ {
Pool* code_pool = & CodePools[index]; Pool* code_pool = & CodePools[index];
pool_free( code_pool ); code_pool->free();
index++; index++;
} }
while ( left--, left ); while ( left--, left );
index = 0; index = 0;
left = array_count( CodeEntriesArenas ); left = CodeEntriesArenas.num();
do do
{ {
Arena* code_entries_arena = & CodeEntriesArenas[index]; Arena* code_entries_arena = & CodeEntriesArenas[index];
arena_free( code_entries_arena ); code_entries_arena->free();
index++; index++;
} }
while ( left--, left ); while ( left--, left );
index = 0; index = 0;
left = array_count( StringArenas ); left = StringArenas.num();
do do
{ {
Arena* string_arena = & StringArenas[index]; Arena* string_arena = & StringArenas[index];
arena_free( string_arena ); string_arena->free();
index++; index++;
} }
while ( left--, left ); while ( left--, left );
str_tbl_destroy( & StringMap ); StringCache.destroy();
// type_tbl_destroy( & TypeMap );
array_free( CodePools ); CodePools.free();
array_free( CodeEntriesArenas ); CodeEntriesArenas.free();
array_free( StringArenas ); StringArenas.free();
} }
inline inline
@ -1237,29 +1255,30 @@ namespace gen
{ {
using namespace StaticData; using namespace StaticData;
Arena* last = & array_back( StringArenas ); Arena& last = StringArenas.back();
if ( last->total_allocated + str_length > last->total_size ) if ( last.TotalUsed + str_length > last.TotalSize )
{ {
Arena new_arena; Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
arena_init_from_allocator( & new_arena, Allocator_StringArena, SizePer_StringArena );
if ( ! array_append( StringArenas, new_arena ) ) if ( ! StringArenas.append( new_arena ) )
fatal( "gen::get_string_allocator: Failed to allocate a new string arena" ); fatal( "gen::get_string_allocator: Failed to allocate a new string arena" );
last = & array_back( StringArenas ); last = StringArenas.back();
} }
return arena_allocator( last ); return last;
} }
// Will either make or retrive a code string. // Will either make or retrive a code string.
StringCached get_cached_string( StrC str ) StringCached get_cached_string( StrC str )
{ {
using namespace StaticData;
s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len; s32 hash_length = str.Len > kilobytes(1) ? kilobytes(1) : str.Len;
u32 key = crc32( str.Ptr, hash_length ); u32 key = crc32( str.Ptr, hash_length );
{ {
String* result = str_tbl_get( & StaticData::StringMap, key ); StringCached* result = StringCache.get( key );
if ( result ) if ( result )
return * result; return * result;
@ -1267,7 +1286,7 @@ namespace gen
String result = String::make( get_string_allocator( str.Len ), str ); String result = String::make( get_string_allocator( str.Len ), str );
str_tbl_set( & StaticData::StringMap, key, result ); StringCache.set( key, result );
return result; return result;
} }
@ -1279,33 +1298,32 @@ namespace gen
{ {
using namespace StaticData; using namespace StaticData;
AllocatorInfo allocator = { nullptr, nullptr }; AllocatorInfo allocator = CodePools.back();
s32 index = 0; s32 index = 0;
s32 left = array_count( CodePools ); s32 left = CodePools.num();
do do
{ {
if ( CodePools[index].free_list != nullptr ) if ( CodePools[index].FreeList != nullptr )
{ {
allocator = zpl::pool_allocator( & CodePools[index] ); allocator = CodePools[index];
break; break;
} }
index++; index++;
} }
while ( left--, left ); while ( left--, left );
if ( allocator.data == nullptr ) if ( allocator.Data == nullptr )
{ {
Pool code_pool; Pool code_pool = Pool::init( Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
pool_init( & code_pool, Allocator_CodePool, CodePool_NumBlocks, sizeof(AST) );
if ( code_pool.physical_start == nullptr ) if ( code_pool.PhysicalStart == nullptr )
fatal( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." ); fatal( "gen::make_code: Failed to allocate a new code pool - CodePool allcoator returned nullptr." );
if ( ! array_append( CodePools, code_pool ) ) if ( ! CodePools.append( code_pool ) )
fatal( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." ); fatal( "gen::make_code: Failed to allocate a new code pool - CodePools failed to append new pool." );
allocator = pool_allocator( CodePools ); allocator = * CodePools;
} }
Code result { rcast( AST*, alloc( allocator, sizeof(AST) )) }; Code result { rcast( AST*, alloc( allocator, sizeof(AST) )) };
@ -1323,37 +1341,34 @@ namespace gen
return result; return result;
} }
Array(AST*) make_code_entries() Array< AST* > make_code_entries()
{ {
using namespace StaticData; using namespace StaticData;
AllocatorInfo allocator = { nullptr, nullptr }; AllocatorInfo allocator = { nullptr, nullptr };
s32 index = 0; s32 index = 0;
s32 left = array_count( CodeEntriesArenas ); s32 left = CodeEntriesArenas.num();
do do
{ {
if ( arena_size_remaining( & CodeEntriesArenas[index], ZPL_DEFAULT_MEMORY_ALIGNMENT) >= InitSize_CodeEntiresArray ) if ( CodeEntriesArenas[index].size_remaining( ZPL_DEFAULT_MEMORY_ALIGNMENT) >= InitSize_CodeEntiresArray )
allocator = arena_allocator( & CodeEntriesArenas[index] ); allocator = CodeEntriesArenas[index];
index++; index++;
} }
while( left--, left ); while( left--, left );
if ( allocator.data == nullptr ) if ( allocator.Data == nullptr )
{ {
Arena arena; Arena arena = Arena::init_from_allocator( Allocator_CodeEntriesArena, SizePer_CodeEntriresArena );
arena_init_from_allocator( & arena, Allocator_CodeEntriesArena, SizePer_CodeEntriresArena );
if ( arena.physical_start == nullptr ) if ( arena.PhysicalStart == nullptr )
fatal( "gen::make_code: Failed to allocate a new code entries arena - CodeEntriesArena allcoator returned nullptr." ); fatal( "gen::make_code: Failed to allocate a new code entries arena - CodeEntriesArena allcoator returned nullptr." );
allocator = arena_allocator( & arena ); allocator = arena;
array_append( CodeEntriesArenas, arena ); CodeEntriesArenas.append( arena );
} }
Array(AST*) entry_array; Array< AST* > entry_array = Array< AST* >::init( allocator );
array_init( entry_array, allocator );
return entry_array; return entry_array;
} }
@ -3357,12 +3372,12 @@ namespace gen
struct TokArray struct TokArray
{ {
Array(Token) Arr; Array<Token> Arr;
s32 Idx; s32 Idx;
bool __eat( TokType type, char const* context ) bool __eat( TokType type, char const* context )
{ {
if ( array_count(Arr) - Idx <= 0 ) if ( Arr.num() - Idx <= 0 )
{ {
log_failure( "gen::%s: No tokens left", context ); log_failure( "gen::%s: No tokens left", context );
return Code::Invalid; return Code::Invalid;
@ -3393,7 +3408,7 @@ namespace gen
Token* next() Token* next()
{ {
return Idx + 1 < array_count(Arr) ? &Arr[Idx + 1] : nullptr; return Idx + 1 < Arr.num() ? &Arr[Idx + 1] : nullptr;
} }
}; };
@ -3423,17 +3438,18 @@ namespace gen
} }
do_once_start do_once_start
arena_init_from_allocator( & LexAllocator, heap(), megabytes(10) ); // TODO : Use the global memory allocator for this...
LexAllocator = Arena::init_from_allocator( heap(), megabytes(10) );
if ( LexAllocator.physical_start == nullptr ) if ( LexAllocator.PhysicalStart == nullptr )
{ {
log_failure( "gen::lex: failed to allocate memory for parsing constructor's lexer"); log_failure( "gen::lex: failed to allocate memory for parsing constructor's lexer");
return { nullptr, 0 }; return { { nullptr }, 0 };
} }
do_once_end do_once_end
local_persist thread_local local_persist thread_local
Array(Token) Tokens = nullptr; Array<Token> Tokens = { nullptr };
s32 left = content.Len -1; s32 left = content.Len -1;
char const* scanner = content.Ptr; char const* scanner = content.Ptr;
@ -3445,13 +3461,13 @@ namespace gen
if ( left <= 0 ) if ( left <= 0 )
{ {
log_failure( "gen::lex: no tokens found (only whitespace provided)" ); log_failure( "gen::lex: no tokens found (only whitespace provided)" );
return { nullptr, 0 }; return { { nullptr }, 0 };
} }
if ( Tokens ) if ( Tokens )
array_clear( Tokens ); Tokens.clear();
array_init_reserve( Tokens, arena_allocator( & LexAllocator), content.Len / 8 ); Tokens = Array<Token>::init_reserve( LexAllocator, content.Len / 8 );
while (left ) while (left )
{ {
@ -3851,7 +3867,7 @@ namespace gen
if ( token.Type != TokType::Invalid ) if ( token.Type != TokType::Invalid )
{ {
array_append( Tokens, token ); Tokens.append( token );
continue; continue;
} }
@ -3864,13 +3880,13 @@ namespace gen
} }
token.Type = type; token.Type = type;
array_append( Tokens, token ); Tokens.append( token );
} }
if ( array_count(Tokens) == 0 ) if ( Tokens.num() == 0 )
{ {
log_failure( "Failed to lex any tokens" ); log_failure( "Failed to lex any tokens" );
return { nullptr, 0 }; return { { nullptr }, 0 };
} }
return { Tokens, 0 }; return { Tokens, 0 };
@ -3898,7 +3914,7 @@ namespace gen
# define currtok toks.current() # define currtok toks.current()
# define prevtok toks.previous() # define prevtok toks.previous()
# define eat( Type_ ) toks.__eat( Type_, context ) # define eat( Type_ ) toks.__eat( Type_, context )
# define left ( array_count(toks.Arr) - toks.Idx ) # define left ( toks.Arr.num() - toks.Idx )
# define check( Type_ ) ( left && currtok.Type == Type_ ) # define check( Type_ ) ( left && currtok.Type == Type_ )
#pragma endregion Helper Macros #pragma endregion Helper Macros
@ -3948,9 +3964,11 @@ namespace gen
while ( left && currtok.Type != TokType::BraceSquare_Close ) while ( left && currtok.Type != TokType::BraceSquare_Close )
{ {
untyped_tok.Length = ( (sptr)currtok.Text + currtok.Length ) - (sptr)untyped_tok.Text; eat( currtok.Type );
} }
untyped_tok.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)untyped_tok.Text;
Code array_expr = untyped_str( untyped_tok ); Code array_expr = untyped_str( untyped_tok );
if ( left == 0 ) if ( left == 0 )
@ -5729,8 +5747,8 @@ namespace gen
SpecifierT specs_found[16] { ESpecifier::Num_Specifiers }; SpecifierT specs_found[16] { ESpecifier::Num_Specifiers };
s32 num_specifiers = 0; s32 num_specifiers = 0;
Token name = { nullptr, 0, TokType::Invalid }; Token name = { nullptr, 0, TokType::Invalid };
Token func_sig = { currtok.Text, 0, TokType::Invalid }; Token brute_sig = { currtok.Text, 0, TokType::Invalid };
while ( left && tok_is_specifier( currtok ) ) while ( left && tok_is_specifier( currtok ) )
{ {
@ -5779,6 +5797,29 @@ namespace gen
name = parse_identifier( toks, context ); name = parse_identifier( toks, context );
if ( ! name ) if ( ! name )
return Code::Invalid; return Code::Invalid;
// Problably dealing with a templated symbol
if ( currtok.Type == TokType::Operator && currtok.Text[0] == '<' && currtok.Length == 1 )
{
eat( TokType::Operator );
s32 level = 0;
while ( left && ( currtok.Text[0] != '>' || level > 0 ))
{
if ( currtok.Text[0] == '<' )
level++;
if ( currtok.Text[0] == '>' )
level--;
eat( currtok.Type );
}
eat( TokType::Operator );
// Extend length of name to last token
name.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)name.Text;
}
} }
while ( left && tok_is_specifier( currtok ) ) while ( left && tok_is_specifier( currtok ) )
@ -5837,7 +5878,7 @@ namespace gen
eat(TokType::Capture_End); eat(TokType::Capture_End);
func_sig.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)func_sig.Text; brute_sig.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)brute_sig.Text;
} }
using namespace ECode; using namespace ECode;
@ -5846,10 +5887,10 @@ namespace gen
result = make_code(); result = make_code();
result->Type = Typename; result->Type = Typename;
if ( func_sig.Length > 0 ) if ( brute_sig.Length > 0 )
{ {
// Bruteforce all tokens together. // Bruteforce all tokens together.
name = func_sig; name = brute_sig;
} }
else else
{ {
@ -6162,17 +6203,15 @@ namespace gen
sw Length; sw Length;
}; };
ZPL_TABLE( static, TokMap, tokmap_, TokEntry )
sw token_fmt_va( char* buf, uw buf_size, char const* fmt, s32 num_tokens, va_list va ) sw token_fmt_va( char* buf, uw buf_size, char const* fmt, s32 num_tokens, va_list va )
{ {
char const* buf_begin = buf; char const* buf_begin = buf;
sw remaining = buf_size; sw remaining = buf_size;
TokMap tok_map; HashTable<TokEntry> tok_map;
{ {
// TODO : Switch this to use an arena that makes use of the stack (cap the size of the token table to around 4096 bytes) // TODO : Switch this to use an arena that makes use of the stack (cap the size of the token table to around 4096 bytes)
tokmap_init( & tok_map, Memory::GlobalAllocator ); tok_map = HashTable<TokEntry>::init( Memory::GlobalAllocator );
s32 left = num_tokens; s32 left = num_tokens;
@ -6189,7 +6228,7 @@ namespace gen
u32 key = crc32( token, str_len(token, 32) ); u32 key = crc32( token, str_len(token, 32) );
tokmap_set( & tok_map, key, entry ); tok_map.set( key, entry );
} }
} }
@ -6224,7 +6263,7 @@ namespace gen
char const* token = fmt + 1; char const* token = fmt + 1;
u32 key = crc32( token, tok_len ); u32 key = crc32( token, tok_len );
TokEntry* value = tokmap_get( & tok_map, key ); TokEntry* value = tok_map.get( key );
if ( value ) if ( value )
{ {
@ -6254,7 +6293,7 @@ namespace gen
} }
} }
tokmap_clear( & tok_map ); tok_map.clear();
sw result = buf_size - remaining + 1; sw result = buf_size - remaining + 1;

View File

@ -378,7 +378,7 @@ namespace gen
#pragma region Data Structures #pragma region Data Structures
// Implements basic string interning. Data structure is based off the ZPL Hashtable. // Implements basic string interning. Data structure is based off the ZPL Hashtable.
ZPL_TABLE_DECLARE( ZPL_EXTERN, StringTable, str_tbl_, String ); using StringTable = HashTable<String const>;
// Represents strings cached with the string table. // Represents strings cached with the string table.
// Should never be modified, if changed string is desired, cache_string( str ) another. // Should never be modified, if changed string is desired, cache_string( str ) another.
@ -428,7 +428,7 @@ namespace gen
s32 num_entries() s32 num_entries()
{ {
return DynamicEntries ? array_count( ArrDyn ) : StaticIndex; return DynamicEntries ? ArrDyn.num() : StaticIndex;
} }
// Parameter // Parameter
@ -548,7 +548,7 @@ namespace gen
# define Using_AST_POD \ # define Using_AST_POD \
union { \ union { \
AST* ArrStatic[AST::ArrS_Cap]; \ AST* ArrStatic[AST::ArrS_Cap]; \
Array(AST*) ArrDyn; \ Array< AST* > ArrDyn; \
StringCached Content; \ StringCached Content; \
SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; \ SpecifierT ArrSpecs[AST::ArrSpecs_Cap]; \
}; \ }; \
@ -699,7 +699,7 @@ namespace gen
// This provides a fresh Code AST array for the entries field of the AST. // This provides a fresh Code AST array for the entries field of the AST.
// This is done separately from the regular CodePool allocator. // This is done separately from the regular CodePool allocator.
Array(AST*) make_code_entries(); Array< AST* > make_code_entries();
// Set these before calling gen's init() procedure. // Set these before calling gen's init() procedure.
// Data // Data
@ -1071,7 +1071,7 @@ namespace gen
other->duplicate() : other; other->duplicate() : other;
if (DynamicEntries) if (DynamicEntries)
array_append( ArrDyn, to_add ); ArrDyn.append( to_add );
else else
{ {
@ -1087,11 +1087,11 @@ namespace gen
s32 index = 0; s32 index = 0;
do do
{ {
array_append( ArrDyn, ArrStatic[index] ); ArrDyn.append( ArrStatic[index] );
} }
while ( StaticIndex--, StaticIndex ); while ( StaticIndex--, StaticIndex );
array_append( ArrDyn, to_add ); ArrDyn.append( to_add );
} }
} }

View File

@ -300,16 +300,16 @@ struct GenArrayRequest
StrC Dependency; StrC Dependency;
StrC Type; StrC Type;
}; };
Array(GenArrayRequest) GenArrayRequests; Array<GenArrayRequest> GenArrayRequests;
void gen__array_request( StrC type, StrC dep = {} ) void gen__array_request( StrC type, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenArrayRequests, Memory::GlobalAllocator ); GenArrayRequests = Array<GenArrayRequest>::init( Memory::GlobalAllocator );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenArrayRequests ); ++idx ) for ( sw idx = 0; idx < GenArrayRequests.num(); ++idx )
{ {
StrC const reqest_type = GenArrayRequests[ idx ].Type; StrC const reqest_type = GenArrayRequests[ idx ].Type;
@ -321,7 +321,7 @@ void gen__array_request( StrC type, StrC dep = {} )
} }
GenArrayRequest request = { dep, type }; GenArrayRequest request = { dep, type };
array_append( GenArrayRequests, request ); GenArrayRequests.append( request );
} }
#define gen_array( type ) gen__array_request( { txt_to_StrC(type) } ) #define gen_array( type ) gen__array_request( { txt_to_StrC(type) } )
@ -338,7 +338,7 @@ u32 gen_array_file()
gen_array_file.print( array_base ); gen_array_file.print( array_base );
GenArrayRequest* current = GenArrayRequests; GenArrayRequest* current = GenArrayRequests;
s32 left = array_count( GenArrayRequests ); s32 left = GenArrayRequests.num();
while (left--) while (left--)
{ {
GenArrayRequest const& request = * current; GenArrayRequest const& request = * current;

View File

@ -206,16 +206,16 @@ struct GenBufferRequest
StrC Type; StrC Type;
sw TypeSize; sw TypeSize;
}; };
Array(GenBufferRequest) GenBufferRequests; Array<GenBufferRequest> GenBufferRequests;
void gen__buffer_request( StrC type, sw size, StrC dep = {} ) void gen__buffer_request( StrC type, sw size, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenBufferRequests, Memory::GlobalAllocator ); GenBufferRequests = Array<GenBufferRequest>::init( Memory::GlobalAllocator );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenBufferRequests ); ++idx ) for ( sw idx = 0; idx < GenBufferRequests.num(); ++idx )
{ {
StrC const reqest_type = GenBufferRequests[ idx ].Type; StrC const reqest_type = GenBufferRequests[ idx ].Type;
@ -227,7 +227,7 @@ void gen__buffer_request( StrC type, sw size, StrC dep = {} )
} }
GenBufferRequest request = { dep, type, size}; GenBufferRequest request = { dep, type, size};
array_append( GenBufferRequests, request ); GenBufferRequests.append( request );
} }
#define gen_buffer( type ) gen__buffer_request( { txt_to_StrC(type) }, sizeof( type )) #define gen_buffer( type ) gen__buffer_request( { txt_to_StrC(type) }, sizeof( type ))
@ -241,7 +241,7 @@ u32 gen_buffer_file()
gen_buffer_file.print( gen__buffer_base() ); gen_buffer_file.print( gen__buffer_base() );
GenBufferRequest* current = GenBufferRequests; GenBufferRequest* current = GenBufferRequests;
s32 left = array_count( GenBufferRequests ); s32 left = GenBufferRequests.num();
while (left--) while (left--)
{ {
GenBufferRequest const& request = * current; GenBufferRequest const& request = * current;

View File

@ -21,7 +21,7 @@ Code gen__hashtable_base()
return find_result; return find_result;
} }
Code gen__hashtable( StrC type, sw type_size ) Code gen__hashtable( StrC type )
{ {
static Code t_allocator_info = def_type( name(AllocatorInfo) ); static Code t_allocator_info = def_type( name(AllocatorInfo) );
@ -397,20 +397,19 @@ struct GenHashTableRequest
{ {
StrC Dependency; StrC Dependency;
StrC Type; StrC Type;
sw TypeSize;
}; };
Array(GenHashTableRequest) GenHashTableRequests; Array<GenHashTableRequest> GenHashTableRequests;
void gen__hashtable_request( StrC type, sw size, StrC dep = {} ) void gen__hashtable_request( StrC type, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenHashTableRequests, Memory::GlobalAllocator ); GenHashTableRequests = Array<GenHashTableRequest>::init( Memory::GlobalAllocator );
gen_array( sw ); gen_array( sw );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenHashTableRequests ); ++idx ) for ( sw idx = 0; idx < GenHashTableRequests.num(); ++idx )
{ {
StrC const reqest_type = GenHashTableRequests[ idx ].Type; StrC const reqest_type = GenHashTableRequests[ idx ].Type;
@ -421,10 +420,10 @@ void gen__hashtable_request( StrC type, sw size, StrC dep = {} )
return; return;
} }
GenHashTableRequest request = { dep, type, size}; GenHashTableRequest request = { dep, type };
array_append( GenHashTableRequests, request ); GenHashTableRequests.append( request );
} }
#define gen_hashtable( type ) gen__hashtable_request( { txt_to_StrC(type) }, sizeof( type )) #define gen_hashtable( type ) gen__hashtable_request( { txt_to_StrC(type) } )
u32 gen_hashtable_file() u32 gen_hashtable_file()
{ {
@ -439,12 +438,12 @@ u32 gen_hashtable_file()
gen_buffer_file.print( gen__hashtable_base()); gen_buffer_file.print( gen__hashtable_base());
GenHashTableRequest* current = GenHashTableRequests; GenHashTableRequest* current = GenHashTableRequests;
s32 left = array_count( GenHashTableRequests ); s32 left = GenHashTableRequests.num();
while (left--) while (left--)
{ {
GenHashTableRequest const& request = * current; GenHashTableRequest const& request = * current;
Code generated_buffer = gen__hashtable( current->Type, current->TypeSize ); Code generated_buffer = gen__hashtable( current->Type );
if ( request.Dependency ) if ( request.Dependency )
{ {

View File

@ -162,16 +162,16 @@ struct GenRingRequest
StrC Type; StrC Type;
sw TypeSize; sw TypeSize;
}; };
Array(GenRingRequest) GenRingRequests; Array<GenRingRequest> GenRingRequests;
void gen__ring_request( StrC type, sw size, StrC dep = {} ) void gen__ring_request( StrC type, sw size, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenRingRequests, Memory::GlobalAllocator ); GenRingRequests = Array<GenRingRequest>::init( Memory::GlobalAllocator );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenRingRequests ); ++idx ) for ( sw idx = 0; idx < GenRingRequests.num(); ++idx )
{ {
StrC const reqest_type = GenRingRequests[ idx ].Type; StrC const reqest_type = GenRingRequests[ idx ].Type;
@ -186,7 +186,7 @@ void gen__ring_request( StrC type, sw size, StrC dep = {} )
gen__buffer_request( type, size, dep ); gen__buffer_request( type, size, dep );
GenRingRequest request = { dep, type, size}; GenRingRequest request = { dep, type, size};
array_append( GenRingRequests, request ); GenRingRequests.append( request );
} }
#define gen_ring( type ) gen__ring_request( { txt_to_StrC(type) }, sizeof( type )) #define gen_ring( type ) gen__ring_request( { txt_to_StrC(type) }, sizeof( type ))
@ -201,7 +201,7 @@ u32 gen_ring_file()
// gen_ring_file.print( gen__ring_base() ); // gen_ring_file.print( gen__ring_base() );
GenRingRequest* current = GenRingRequests; GenRingRequest* current = GenRingRequests;
s32 left = array_count( GenRingRequests ); s32 left = GenRingRequests.num();
while (left--) while (left--)
{ {
GenRingRequest const& request = * current; GenRingRequest const& request = * current;

View File

@ -224,16 +224,16 @@ struct GenArrayRequest
StrC Dependency; StrC Dependency;
StrC Type; StrC Type;
}; };
Array(GenArrayRequest) GenArrayRequests; Array<GenArrayRequest> GenArrayRequests;
void gen__array_request( StrC type, sw size, StrC dep = {} ) void gen__array_request( StrC type, sw size, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenArrayRequests, Memory::GlobalAllocator ); GenArrayRequests = Array<GenArrayRequest>::init( Memory::GlobalAllocator );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenArrayRequests ); ++idx ) for ( sw idx = 0; idx < GenArrayRequests.num(); ++idx )
{ {
StrC const reqest_type = GenArrayRequests[ idx ].Type; StrC const reqest_type = GenArrayRequests[ idx ].Type;
@ -245,7 +245,7 @@ void gen__array_request( StrC type, sw size, StrC dep = {} )
} }
GenArrayRequest request = { dep, type }; GenArrayRequest request = { dep, type };
array_append( GenArrayRequests, request ); GenArrayRequests.append( request );
} }
#define gen_array( type ) gen__array_request( { txt_to_StrC(type) }, sizeof(type) ) #define gen_array( type ) gen__array_request( { txt_to_StrC(type) }, sizeof(type) )
@ -262,7 +262,7 @@ u32 gen_array_file()
gen_array_file.print( array_base ); gen_array_file.print( array_base );
GenArrayRequest* current = GenArrayRequests; GenArrayRequest* current = GenArrayRequests;
s32 left = array_count( GenArrayRequests ); s32 left = GenArrayRequests.num();
while (left--) while (left--)
{ {
GenArrayRequest const& request = * current; GenArrayRequest const& request = * current;

View File

@ -137,16 +137,16 @@ struct GenBufferRequest
StrC Dependency; StrC Dependency;
StrC Type; StrC Type;
}; };
Array(GenBufferRequest) GenBufferRequests; Array<GenBufferRequest> GenBufferRequests;
void gen__buffer_request( StrC type, StrC dep = {} ) void gen__buffer_request( StrC type, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenBufferRequests, Memory::GlobalAllocator ); GenBufferRequests = Array<GenBufferRequest>::init( Memory::GlobalAllocator );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenBufferRequests ); ++idx ) for ( sw idx = 0; idx < GenBufferRequests.num(); ++idx )
{ {
StrC const reqest_type = GenBufferRequests[ idx ].Type; StrC const reqest_type = GenBufferRequests[ idx ].Type;
@ -158,7 +158,7 @@ void gen__buffer_request( StrC type, StrC dep = {} )
} }
GenBufferRequest request = { dep, type }; GenBufferRequest request = { dep, type };
array_append( GenBufferRequests, request ); GenBufferRequests.append( request );
} }
#define gen_buffer( type ) gen__buffer_request( { txt_to_StrC(type) } ) #define gen_buffer( type ) gen__buffer_request( { txt_to_StrC(type) } )
@ -172,7 +172,7 @@ u32 gen_buffer_file()
gen_buffer_file.print( gen__buffer_base() ); gen_buffer_file.print( gen__buffer_base() );
GenBufferRequest* current = GenBufferRequests; GenBufferRequest* current = GenBufferRequests;
s32 left = array_count( GenBufferRequests ); s32 left = GenBufferRequests.num();
while (left--) while (left--)
{ {
GenBufferRequest const& request = * current; GenBufferRequest const& request = * current;

View File

@ -290,18 +290,18 @@ struct GenHashTableRequest
StrC Type; StrC Type;
sw TypeSize; sw TypeSize;
}; };
Array(GenHashTableRequest) GenHashTableRequests; Array<GenHashTableRequest> GenHashTableRequests;
void gen__hashtable_request( StrC type, sw size, StrC dep = {} ) void gen__hashtable_request( StrC type, sw size, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenHashTableRequests, Memory::GlobalAllocator ); GenHashTableRequests = Array<GenHashTableRequest>::init( Memory::GlobalAllocator );
gen_array( sw ); gen_array( sw );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenHashTableRequests ); ++idx ) for ( sw idx = 0; idx < GenHashTableRequests.num(); ++idx )
{ {
StrC const reqest_type = GenHashTableRequests[ idx ].Type; StrC const reqest_type = GenHashTableRequests[ idx ].Type;
@ -313,7 +313,7 @@ void gen__hashtable_request( StrC type, sw size, StrC dep = {} )
} }
GenHashTableRequest request = { dep, type, size}; GenHashTableRequest request = { dep, type, size};
array_append( GenHashTableRequests, request ); GenHashTableRequests.append( request );
} }
#define gen_hashtable( type ) gen__hashtable_request( { txt_to_StrC(type) }, sizeof( type )) #define gen_hashtable( type ) gen__hashtable_request( { txt_to_StrC(type) }, sizeof( type ))
@ -329,7 +329,7 @@ u32 gen_hashtable_file()
gen_buffer_file.print( gen__hashtable_base()); gen_buffer_file.print( gen__hashtable_base());
GenHashTableRequest* current = GenHashTableRequests; GenHashTableRequest* current = GenHashTableRequests;
s32 left = array_count( GenHashTableRequests ); s32 left = GenHashTableRequests.num();
while (left--) while (left--)
{ {
GenHashTableRequest const& request = * current; GenHashTableRequest const& request = * current;

View File

@ -102,16 +102,16 @@ struct GenRingRequest
StrC Dependency; StrC Dependency;
StrC Type; StrC Type;
}; };
Array(GenRingRequest) GenRingRequests; Array<GenRingRequest> GenRingRequests;
void gen__ring_request( StrC type, sw size, StrC dep = {} ) void gen__ring_request( StrC type, sw size, StrC dep = {} )
{ {
do_once_start do_once_start
array_init( GenRingRequests, Memory::GlobalAllocator ); GenRingRequests = Array<GenRingRequest>::init( Memory::GlobalAllocator );
do_once_end do_once_end
// Make sure we don't already have a request for the type. // Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < array_count( GenRingRequests ); ++idx ) for ( sw idx = 0; idx < GenRingRequests.num(); ++idx )
{ {
StrC const reqest_type = GenRingRequests[ idx ].Type; StrC const reqest_type = GenRingRequests[ idx ].Type;
@ -126,7 +126,7 @@ void gen__ring_request( StrC type, sw size, StrC dep = {} )
gen__buffer_request( type, dep ); gen__buffer_request( type, dep );
GenRingRequest request = { dep, type }; GenRingRequest request = { dep, type };
array_append( GenRingRequests, request ); GenRingRequests.append( request );
} }
#define gen_ring( type ) gen__ring_request( { txt_to_StrC(type) }, sizeof( type )) #define gen_ring( type ) gen__ring_request( { txt_to_StrC(type) }, sizeof( type ))
@ -141,7 +141,7 @@ u32 gen_ring_file()
// gen_ring_file.print( gen__ring_base() ); // gen_ring_file.print( gen__ring_base() );
GenRingRequest* current = GenRingRequests; GenRingRequest* current = GenRingRequests;
s32 left = array_count( GenRingRequests ); s32 left = GenRingRequests.num();
while (left--) while (left--)
{ {
GenRingRequest const& request = * current; GenRingRequest const& request = * current;

113
test/SOA.hpp Normal file
View File

@ -0,0 +1,113 @@
#pragma once
#ifdef gen_time
#include "gen.hpp"
using namespace gen;
Code gen_SOA( Code struct_def, bool use_dynamic = false )
{
StrC name;
name.Ptr = str_fmt_buf( "SOA_%s", (char const*) struct_def->Name );
name.Len = str_len( name );
Code
soa_entry = { struct_def->duplicate() };
soa_entry->Name = get_cached_string( name(Entry) );
Array<Code> vars = Array<Code>::init( Memory::GlobalAllocator );;
Code soa = def_struct( name, def_struct_body( 1, soa_entry ) );
{
Code body = struct_def.body();
for ( s32 idx = 0; idx < body->num_entries(); idx++ )
{
Code struct_mem = { body->entry( idx ) };
if ( struct_mem->Type == ECode::Variable )
{
Code var_type = { struct_mem->entry(0) };
Code entry_arr = { nullptr };
if ( use_dynamic)
{
entry_arr = parse_variable( token_fmt( "Array<<type>> <name>;", 2
, "type", (char const*)var_type->Name
, "name", (char const*)struct_mem->Name )
);
}
else
{
entry_arr = parse_variable( token_fmt( "<type> <name>[100];", 2
, "type", (char const*)var_type->Name
, "name", (char const*)struct_mem->Name )
);
}
vars.append( entry_arr );
soa.body()->add_entry( entry_arr );
}
}
}
Code make;
{
make = parse_function( token_fmt(
txt(
static
<SOA_Type> make( AllocatorInfo allocator )
{
<SOA_Type> soa = {};
}
),
1, "SOA_Type", (char const*)name
));
if ( use_dynamic )
{
for ( s32 idx = 0; idx < vars.num(); idx++ )
{
Code member = vars[idx];
Code arr_init = def_execution( token_fmt( "soa.<var_name> = <var_type>::init( allocator );", 2
, "var_name", (char const*)member->Name
, "var_type", (char const*)member->entry(0)->Name
));
make.body()->add_entry( arr_init );
}
}
make.body()->add_entry( def_execution( code( return soa; ) ));
}
Code get;
{
get = parse_function( code(
Entry get( s32 idx )
{
}
));
String content = String::make( Memory::GlobalAllocator, "return\n{\n" );
for ( s32 idx = 0; idx < vars.num(); idx ++ )
{
Code member = vars[idx];
content.append_fmt( token_fmt( "<var_name>[idx],", 1
, "var_name", (char const*)member->Name
));
}
content.append( "};" );
Code ret = def_execution( content );
get.body()->add_entry( ret );
}
soa.body()->add_entry( make );
soa.body()->add_entry( get );
return soa;
}
#endif

View File

@ -4,6 +4,7 @@
#include "Parsed\HashTable.Parsed.hpp" #include "Parsed\HashTable.Parsed.hpp"
#include "Parsed\Ring.Parsed.hpp" #include "Parsed\Ring.Parsed.hpp"
#include "Parsed\Sanity.Parsed.hpp" #include "Parsed\Sanity.Parsed.hpp"
#include "SOA.hpp"
#ifdef gen_time #ifdef gen_time
@ -34,6 +35,31 @@ int gen_main()
gen_hashtable_file(); gen_hashtable_file();
gen_ring_file(); gen_ring_file();
Builder soa_test; soa_test.open( "SOA.gen.hpp" );
soa_test.print( parse_using( code(
using u16 = unsigned short;
)));
soa_test.print( def_include( StrC::from("Bloat.hpp")));
soa_test.print( def_using_namespace( name(gen) ) );
soa_test.print( gen_SOA(
parse_struct( code(
struct TestStruct
{
u8 A;
u16 B;
u32 C;
u64 D;
};
)),
true
));
soa_test.write();
gen::deinit(); gen::deinit();
Memory::cleanup(); Memory::cleanup();
return 0; return 0;