renamed parsed and upfront dirs to lowercase

This commit is contained in:
2023-07-29 16:27:36 -04:00
parent 4e8d6456cb
commit b9064fba9d
10 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,375 @@
#pragma once
#if GEN_TIME
#include "gen.hpp"
using namespace gen;
Code gen__array_base()
{
CodeType t_allocator_info = def_type( name(AllocatorInfo) );
CodeStruct header = def_struct( name(ArrayHeader),
def_struct_body( args(
def_variable( t_allocator_info, name(Allocator) )
, def_variable( t_uw, name(Capacity) )
, def_variable( t_uw, name(Num) )
)));
CodeFn grow_formula = def_function( name(array_grow_formula), def_param( t_uw, name(value)), t_uw
, def_execution( code( return 2 * value * 8; ) )
, def_specifiers( args( ESpecifier::Static, ESpecifier::Inline ) )
);
return def_global_body( args( header, grow_formula ) );
}
Code gen__array( StrC type )
{
static CodeType t_allocator_info = def_type( name(AllocatorInfo) );
static Code v_nullptr = code_str(nullptr);
static CodeSpecifiers spec_ct_member = def_specifiers( 2, ESpecifier::Constexpr, ESpecifier::Static );
static CodeSpecifiers spec_static_inline = def_specifiers( 2, ESpecifier::Static, ESpecifier::Inline );
static CodeSpecifiers spec_static = def_specifier( ESpecifier::Static );
static CodeUsing using_header = def_using( name(Header), def_type( name(ArrayHeader) ) );
static CodeVar ct_grow_formula = def_variable( t_auto, name(grow_formula), untyped_str( code( & array_grow_formula )), spec_ct_member );
StrC name;
{
char const* name_str = str_fmt_buf( "Array_%s\0", type.Ptr );
s32 name_len = str_len( name_str );
name = { name_len, name_str };
};
CodeType t_array_type = def_type( name );
CodeType t_type = def_type( type );
CodeType t_type_ptr = def_type( type, __, spec_ptr );
CodeType t_type_ref = def_type( type, __, spec_ref );
CodeType t_alias = def_type( name(Type) );
CodeType t_alias_ptr = def_type( name(Type), __, spec_ptr );
CodeType t_alias_ref = def_type( name(Type), __, spec_ref );
CodeType t_header = def_type( name(Header) );
CodeType t_header_ptr = def_type( name(Header), __, spec_ptr );
CodeType t_header_ref = def_type( name(Header), __, spec_ref );
CodeStruct array = {0};
{
CodeUsing using_type = def_using( name(Type), t_type );
CodeVar data = def_variable( t_alias_ptr, name(Data) );
CodeFn init = def_function( name(init), def_param( t_allocator_info, name(allocator) ), t_array_type
, def_execution( code(
return init_reserve( allocator, grow_formula(0) );
))
, spec_static
);
CodeFn init_reserve;
{
CodeParam params = def_params( args(
def_param( t_allocator_info, name(allocator) )
, def_param( t_sw, name(capacity) )
));
Code body = def_execution( code(
Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) ));
if ( header == nullptr )
return { nullptr };
header->Allocator = allocator;
header->Capacity = capacity;
header->Num = 0;
return { rcast( Type*, header + 1) };
));
init_reserve = def_function( name(init_reserve), params, t_array_type, body, spec_static );
}
CodeFn append = def_function( name(append), def_param(t_alias, name(value)), t_bool
, def_execution( code(
Header* header = get_header();
if ( header->Num == header->Capacity )
{
if ( ! grow( header->Capacity ))
return false;
header = get_header();
}
Data[ header->Num ] = value;
header->Num++;
return true;
))
);
CodeFn back = def_function( name(back), __, t_alias_ref
, def_execution( code(
Header& header = * get_header();
return Data[ header.Num - 1 ];
))
);
CodeFn clear = def_function( name(clear), __, t_void
, def_execution( code(
Header& header = * get_header();
header.Num = 0;
))
);
CodeFn fill;
{
CodeParam params = def_params( args(
def_param( t_uw, name(begin) )
, def_param( t_uw, name(end) )
, def_param( t_alias, name(value) )
));
Code body = untyped_str( code(
Header& header = * get_header();
if ( begin < 0 || end >= header.Num )
return false;
for ( sw idx = begin; idx < end; idx++ )
{
Data[ idx ] = value;
}
return true;
));
fill = def_function( name(fill), params, t_bool, body );
}
CodeFn free = def_function( name(free), __, t_void
, def_execution( code(
Header* header = get_header();
gen::free( header->Allocator, header );
))
);
CodeFn get_header = def_function( name(get_header), __, t_header_ptr
, def_execution( code(
return rcast( Header*, Data ) - 1;
))
);
CodeFn grow = def_function( name(grow), def_param( t_uw, name(min_capacity)), t_bool
, def_execution( code(
Header& header = * get_header();
uw new_capacity = grow_formula( header.Capacity );
if ( new_capacity < min_capacity )
new_capacity = 8;
return set_capacity( new_capacity );
))
);
CodeFn num = def_function( name(num), __, t_uw
, def_execution( code(
return get_header()->Num;
))
);
CodeFn pop = def_function( name(pop), __, t_bool
, def_execution( code(
Header& header = * get_header();
GEN_ASSERT( header.Num > 0 );
header.Num--;
))
);
CodeFn remove_at = def_function( name(remove_at), def_param( t_uw, name(idx)), t_void
, def_execution( code(
Header* header = get_header();
GEN_ASSERT( idx < header->Num );
mem_move( header + idx, header + idx + 1, sizeof( Type ) * ( header->Num - idx - 1 ) );
header->Num--;
))
);
CodeFn reserve = def_function( name(reserve), def_param( t_uw, name(new_capacity)), t_bool
, def_execution( code(
Header& header = * get_header();
if ( header.Capacity < new_capacity )
return set_capacity( new_capacity );
return true;
))
);
CodeFn resize = def_function( name(resize), def_param( t_uw, name(num)), t_bool
, def_execution( code(
Header* header = get_header();
if ( num > header->Capacity )
{
if ( ! grow( header->Capacity ))
return false;
header = get_header();
}
header->Num = num;
return true;
))
);
CodeFn set_capacity;
{
Code body = def_execution( code(
Header& header = * get_header();
if ( new_capacity == header.Capacity )
return true;
if ( new_capacity < header.Num )
header.Num = new_capacity;
sw size = sizeof(Header) + sizeof(Type) * new_capacity;
Header* new_header = rcast( Header*, alloc( header.Allocator, size ));
if ( new_header == nullptr )
return false;
mem_move( new_header, & header, sizeof( Header ) + sizeof(Type) * header.Num );
new_header->Capacity = new_capacity;
gen::free( header.Allocator, & header );
Data = rcast( Type*, new_header + 1);
return true;
));
set_capacity = def_function( name(set_capacity), def_param( t_uw, name(new_capacity)), t_bool, body );
}
CodeOpCast op_ptr = def_operator_cast( t_type_ptr, def_execution( code(
return Data;
)));
CodeBody body = def_struct_body( args(
using_header
, using_type
, ct_grow_formula
, init
, init_reserve
, append
, back
, clear
, fill
, free
, get_header
, grow
, num
, pop
, remove_at
, reserve
, resize
, set_capacity
, op_ptr
, data
));
array = def_struct( name, body );
}
return array;
}
struct GenArrayRequest
{
StrC Dependency;
StrC Type;
};
Array<GenArrayRequest> GenArrayRequests;
void gen__array_request( StrC type, StrC dep = {} )
{
do_once_start
GenArrayRequests = Array<GenArrayRequest>::init( GlobalAllocator );
do_once_end
// Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < GenArrayRequests.num(); ++idx )
{
StrC const reqest_type = GenArrayRequests[ idx ].Type;
if ( reqest_type.Len != type.Len )
continue;
if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 )
return;
}
GenArrayRequest request = { dep, type };
GenArrayRequests.append( request );
}
#define gen_array( type ) gen__array_request( code(type) )
u32 gen_array_file()
{
Builder
gen_array_file;
gen_array_file.open( "array.Upfront.gen.hpp" );
CodeInclude include_gen = def_include( txt_StrC("gen.hpp") );
gen_array_file.print( include_gen );
gen_array_file.print( def_using_namespace( name(gen)));
Code array_base = gen__array_base();
gen_array_file.print( array_base );
GenArrayRequest* current = GenArrayRequests;
s32 left = GenArrayRequests.num();
while (left--)
{
GenArrayRequest const& request = * current;
Code generated_array = gen__array( request.Type );
if ( request.Dependency )
{
char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type );
s32 cmt_len = str_len( cmt_str );
CodeComment cmt = def_comment( { cmt_len, cmt_str } );
CodeInclude include = def_include( request.Dependency );
gen_array_file.print( cmt );
gen_array_file.print( include );
}
gen_array_file.print( generated_array );
current++;
}
gen_array_file.write();
return 0;
}
#endif

View File

@ -0,0 +1,275 @@
#pragma once
#if GEN_TIME
#include "gen.hpp"
using namespace gen;
Code gen__buffer_base()
{
CodeType t_allocator_info = def_type( name(AllocatorInfo) );
Code header = def_struct( name(BufferHeader),
def_struct_body( args(
def_variable( t_allocator_info, name(Backing) )
, def_variable( t_uw, name(Capacity) )
, def_variable( t_uw, name(Num) )
)));
return def_global_body( 1, header );
}
Code gen__buffer( StrC type, sw type_size )
{
static CodeType t_allocator_info = def_type( name(AllocatorInfo));
static CodeUsing using_header = def_using( name(Header), def_type( name(BufferHeader) ) );
StrC name;
{
char const* name_str = str_fmt_buf( "Buffer_%s\0", type.Ptr );
s32 name_len = str_len( name_str );
name = { name_len, name_str };
};
CodeType t_buffer_type = def_type( name );
CodeType t_type = def_type( type );
CodeType t_type_ptr = def_type( type, __, spec_ptr );
CodeType t_type_ref = def_type( type, __, spec_ref );
CodeType t_header = def_type( name(Header) );
CodeType t_header_ptr = def_type( name(Header), __, spec_ptr );
CodeType t_header_ref = def_type( name(Header), __, spec_ref );
CodeStruct buffer = {0};
{
CodeUsing using_type = def_using( name(Type), t_type );
CodeVar data = def_variable( t_type_ptr, name(Data) );
CodeFn init;
{
CodeParam params = def_params( args(
def_param( t_allocator_info, name(allocator))
, def_param( t_sw, name(capacity))
));
Code body = def_execution( code(
Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + capacity * sizeof(Type) ) );
if ( header == nullptr )
return { nullptr };
header->Backing = allocator;
header->Capacity = capacity;
header->Num = 0;
return { rcast( Type*, header + 1) };
));
init = def_function( name(init), params, t_buffer_type, body, spec_static_member );
}
CodeFn init_copy;
{
CodeParam params = def_params( args(
def_param( t_allocator_info, name(allocator))
, def_param( t_buffer_type, name(other))
));
init_copy = def_function( name(init), params, t_buffer_type
, def_execution( code(
Header& other_header = other.get_header();
Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + other_header.Capacity * sizeof(Type) ) );
if ( header == nullptr )
return { nullptr };
header->Backing = allocator;
header->Capacity = other_header.Capacity;
header->Num = other_header.Num;
mem_copy( header + 1, other.Data, other_header.Num * sizeof(Type) );
return { rcast( Type*, header + 1) };
))
);
}
CodeFn append = def_function( name(append), def_param( t_type, name(value)), t_void
, def_execution( code(
Header& header = get_header();
Data[ header.Num ] = value;
header.Num++;
))
);
CodeFn appendv;
{
CodeParam params = def_params( args(
def_param( t_type_ptr, name( values))
, def_param( t_sw, name( num))
));
appendv = def_function( name(append), params, t_void
, def_execution( code(
Header& header = get_header();
GEN_ASSERT( header.Num + num <= header.Capacity);
mem_copy( Data + header.Num, values, num * sizeof( Type ) );
header.Num += num;
))
);
}
CodeFn clear = def_function( name(clear), __, t_void
, def_execution( code(
Header& header = get_header();
header.Num = 0;
))
);
CodeFn end = def_function( name(end), __, t_type_ref
, def_execution( code(
Header& header = get_header();
return Data[ header.Num - 1 ];
))
);
CodeFn free = def_function( name(free), __, t_void
, def_execution( code(
Header& header = get_header();
gen::free( header.Backing, & header );
))
);
CodeFn get_header = def_function( name(get_header), __, t_header_ref
, def_execution( code(
return * ( rcast( Header*, Data ) - 1 );
))
);
CodeFn num = def_function( name(num), __, t_sw
, def_execution( code(
return get_header().Num;
))
);
CodeFn pop = def_function( name(pop), __, t_type
, def_execution( code(
Header& header = get_header();
header.Num--;
return Data[ header.Num ];
))
);
CodeFn wipe = def_function( name(wipe), __, t_void
, def_execution( code(
Header& header = get_header();
header.Num = 0;
mem_set( Data, 0, header.Capacity * sizeof( Type ) );
))
);
CodeOpCast op_type_ptr = def_operator_cast( t_type_ptr, def_execution( code(
return Data;
)));
buffer = def_struct( name, def_struct_body( args(
using_header
, using_type
, init
, init_copy
, append
, appendv
, clear
, end
, free
, get_header
, num
, pop
, wipe
, op_type_ptr
, data
)));
}
return buffer;
}
struct GenBufferRequest
{
StrC Dependency;
StrC Type;
sw TypeSize;
};
Array<GenBufferRequest> GenBufferRequests;
void gen__buffer_request( StrC type, StrC dep = {} )
{
do_once_start
GenBufferRequests = Array<GenBufferRequest>::init( GlobalAllocator );
do_once_end
// Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < GenBufferRequests.num(); ++idx )
{
StrC const reqest_type = GenBufferRequests[ idx ].Type;
if ( reqest_type.Len != type.Len )
continue;
if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 )
return;
}
GenBufferRequest request = { dep, type};
GenBufferRequests.append( request );
}
#define gen_buffer( type ) gen__buffer_request( code(type))
u32 gen_buffer_file()
{
Builder
gen_buffer_file;
gen_buffer_file.open( "buffer.Upfront.gen.hpp" );
gen_buffer_file.print( def_include( txt_StrC("gen.hpp")) );
gen_buffer_file.print( def_using_namespace( name(gen)) );
gen_buffer_file.print( gen__buffer_base() );
GenBufferRequest* current = GenBufferRequests;
s32 left = GenBufferRequests.num();
while (left--)
{
GenBufferRequest const& request = * current;
Code generated_buffer = gen__buffer( current->Type, current->TypeSize );
if ( request.Dependency )
{
char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type );
s32 cmt_len = str_len( cmt_str );
Code cmt = def_comment( { cmt_len, cmt_str } );
Code include = def_include( request.Dependency );
gen_buffer_file.print( cmt );
gen_buffer_file.print( include );
}
gen_buffer_file.print( generated_buffer );
current++;
}
gen_buffer_file.write();
return 0;
}
#endif // GEN_TIME

View File

@ -0,0 +1,486 @@
#pragma once
#if GEN_TIME
#include "gen.hpp"
#include "Array.Upfront.hpp"
using namespace gen;
Code gen__hashtable_base()
{
CodeVar hashIndex = def_variable( t_sw, name(HashIndex) );
CodeVar entry_prev = def_variable( t_sw, name(PrevIndex) );
CodeVar entry_index = def_variable( t_sw, name(EntryIndex) );
CodeStruct find_result = def_struct( name(HashTable_FindResult), def_struct_body( 3
, hashIndex
, entry_prev
, entry_index
));
return find_result;
}
Code gen__hashtable( StrC type )
{
static CodeType t_allocator_info = def_type( name(AllocatorInfo) );
CodeType t_find_result = def_type( name(HashTable_FindResult) );
StringCached name;
{
char const* name_str = str_fmt_buf( "HashTable_%s", type.Ptr );
s32 len = str_len( name_str );
name = get_cached_string({ len, name_str });
}
CodeType t_ht_type = def_type( name );
CodeType t_type = def_type( type );
CodeType t_type_ptr = def_type( type, __, spec_ptr );
CodeType t_type_ref = def_type( type, __, spec_ref );
// Hash table depends on array container for its entry structure.
CodeType t_ht_entry, t_array_ht_entry;
CodeStruct ht_entry, array_ht_entry;
{
char const* name_str = str_fmt_buf( "HashTable_%s_Entry", type.Ptr );
s32 len = str_len( name_str );
StringCached ht_entry_name = get_cached_string({ len, name_str });
t_ht_entry = def_type( ht_entry_name );
ht_entry = def_struct( ht_entry_name, def_struct_body( args(
def_variable( t_u64, name(Key))
, def_variable( t_sw, name(Next))
, def_variable( t_type, name(Value))
)));
array_ht_entry = gen__array( ht_entry_name );
t_array_ht_entry = def_type( array_ht_entry->Name );
}
CodeStruct hashtable = {0};
{
CodeUsing using_entry = def_using( name(Entry), t_ht_entry );
CodeUsing using_array_entry = def_using( name(Array_Entry), t_array_ht_entry );
CodeUsing using_find_result = def_using( name(FindResult), t_find_result );
CodeType t_array_sw = def_type( name(Array_sw) );
CodeType t_array_entry = def_type( name(Array_Entry) );
CodeVar hashes = def_variable( t_array_sw, name(Hashes) );
CodeVar entries = def_variable( t_array_entry, name(Entries));
CodeFn init;
{
char const* tmpl = stringize(
<type> result = { 0 };
result.Hashes = Array_sw ::init( allocator );
result.Entries = Array_Entry::init( allocator );
return result;
);
Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) );
init = def_function( name(init), def_param( t_allocator_info, name(allocator)), t_ht_type, body, spec_static_member );
}
CodeFn init_reserve;
{
char const* tmpl = stringize(
<type> result = { { nullptr }, { nullptr } };
result.Hashes = Array_sw::init_reserve( allocator, num );
result.Hashes.get_header()->Num = num;
result.Entries = Array_Entry::init_reserve( allocator, num );
return result;
);
Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) );
CodeParam params = def_params( args( def_param( t_allocator_info, name(allocator)), def_param( t_sw, name(num))));
init_reserve = def_function( name(init_reserve), params, t_ht_type, body, spec_static_member );
}
CodeFn clear = def_function( name(clear), __, t_void
, def_execution( code(
for ( s32 idx = 0; idx < Hashes.num(); idx++ )
Hashes[ idx ] = -1;
Entries.clear();
))
);
CodeFn destroy = def_function( name(destroy), __, t_void
, def_execution( code(
if ( Hashes && Hashes.get_header()->Capacity )
Hashes.free();
if ( Entries && Hashes.get_header()->Capacity )
Entries.free();
))
);
CodeFn get = def_function( name(get), def_param( t_u64, name(key)), t_type_ptr
, def_execution( code(
sw idx = find( key ).EntryIndex;
if ( idx >= 0 )
return & Entries[ idx ].Value;
return nullptr;
))
);
CodeUsing using_map_proc;
{
char const* tmpl = stringize(
void (*) ( u64 key, <type> value )
);
CodeType value = def_type( token_fmt( "type", (StrC)t_type.to_string(), tmpl ) );
using_map_proc = def_using ( name(MapProc), value);
}
CodeFn map;
{
CodeType t_map_proc = def_type( name(MapProc) );
Code body = def_execution( code(
GEN_ASSERT_NOT_NULL( map_proc );
for ( sw idx = 0; idx < Entries.num(); idx++ )
{
map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
}
));
map = def_function( name(map), def_param( t_map_proc, name(map_proc) ), t_void, body );
}
CodeUsing using_map_mut_proc;
{
char const* tmpl = stringize(
void (*) ( u64 key, <type> value )
);
CodeType value = def_type( token_fmt( "type", (StrC)t_type_ptr.to_string(), tmpl ) );
using_map_mut_proc = def_using ( name(MapMutProc), value);
}
CodeFn map_mut;
{
CodeType t_map_mut_proc = def_type( name(MapMutProc));
Code body = def_execution( code(
GEN_ASSERT_NOT_NULL( map_proc );
for ( sw idx = 0; idx < Entries.num(); idx++ )
{
map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
}
));
map_mut = def_function( name(map_mut), def_param( t_map_mut_proc, name(map_proc)), t_void, body );
}
CodeFn grow = def_function( name(grow), __, t_void
, def_execution( code(
sw new_num = array_grow_formula( Entries.num() );
rehash( new_num );
))
);
CodeFn rehash;
{
char const* tmpl = stringize(
sw idx;
sw last_added_index;
<type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
Array_sw::Header* hash_header = new_ht.Hashes.get_header();
for ( idx = 0; idx < new_ht.Hashes.num(); ++idx )
new_ht.Hashes[ idx ] = -1;
for ( idx = 0; idx < Entries.num(); ++idx )
{
Entry& entry = Entries[ idx ];
FindResult find_result;
if ( new_ht.Hashes.num() == 0 )
new_ht.grow();
entry = Entries[ idx ];
find_result = new_ht.find( entry.Key );
last_added_index = new_ht.add_entry( entry.Key );
if ( find_result.PrevIndex < 0 )
new_ht.Hashes[ find_result.HashIndex ] = last_added_index;
else
new_ht.Entries[ find_result.PrevIndex ].Next = last_added_index;
new_ht.Entries[ last_added_index ].Next = find_result.EntryIndex;
new_ht.Entries[ last_added_index ].Value = entry.Value;
}
destroy();
*this = new_ht;
);
Code body = def_execution( token_fmt( "type", (StrC)name, tmpl ) );
rehash = def_function( name(rehash), def_param( t_sw, name(new_num)), t_void, body );
}
CodeFn rehash_fast;
{
char const* tmpl = stringize(
sw idx;
for ( idx = 0; idx < Entries.num(); idx++ )
Entries[ idx ].Next = -1;
for ( idx = 0; idx < Hashes.num(); idx++ )
Hashes[ idx ] = -1;
for ( idx = 0; idx < Entries.num(); idx++ )
{
Entry* entry;
FindResult find_result;
}
);
Code body = def_execution( token_fmt( "type", name, tmpl ) );
rehash_fast = def_function( name(rehash_fast), __, t_void, body );
}
CodeFn remove = def_function( name(remove), def_param( t_u64, name(key)), t_void
, def_execution( code(
FindResult find_result = find( key);
if ( find_result.EntryIndex >= 0 )
{
Entries.remove_at( find_result.EntryIndex );
rehash_fast();
}
))
);
CodeFn remove_entry = def_function( name(remove_entry), def_param( t_sw, name(idx)), t_void
, def_execution( code(
Entries.remove_at( idx );
))
);
CodeFn set;
{
CodeParam params = def_params( args(
def_param( t_u64, name(key))
, def_param( t_type, name(value))
));
Code body = def_execution( code(
sw idx;
FindResult find_result;
if ( Hashes.num() == 0 )
grow();
find_result = find( key );
if ( find_result.EntryIndex >= 0 )
{
idx = find_result.EntryIndex;
}
else
{
idx = add_entry( key );
if ( find_result.PrevIndex >= 0 )
{
Entries[ find_result.PrevIndex ].Next = idx;
}
else
{
Hashes[ find_result.HashIndex ] = idx;
}
}
Entries[ idx ].Value = value;
if ( full() )
grow();
));
set = def_function( name(set), params, t_void, body );
}
CodeFn slot = def_function( name(slot), def_param( t_u64, name(key)), t_sw
, def_execution( code(
for ( sw idx = 0; idx < Hashes.num(); ++idx )
if ( Hashes[ idx ] == key )
return idx;
return -1;
))
);
CodeFn add_entry = def_function( name(add_entry), def_param( t_u64, name(key)), t_sw
, def_execution( code(
sw idx;
Entry entry = { key, -1 };
idx = Entries.num();
Entries.append( entry );
return idx;
))
);
CodeFn find = def_function( name(find), def_param( t_u64, name(key)), t_find_result
, def_execution( code(
FindResult result = { -1, -1, -1 };
if ( Hashes.num() > 0 )
{
result.HashIndex = key % Hashes.num();
result.EntryIndex = Hashes[ result.HashIndex ];
while ( result.EntryIndex >= 0 )
{
if ( Entries[ result.EntryIndex ].Key == key )
break;
result.PrevIndex = result.EntryIndex;
result.EntryIndex = Entries[ result.EntryIndex ].Next;
}
}
return result;
))
);
CodeFn full = def_function( name(full), __, t_b32
, def_execution( code(
return 0.75f * Hashes.num() < Entries.num();
))
);
hashtable = def_struct( name, def_struct_body( args(
using_entry
, using_array_entry
, using_find_result
, using_map_proc
, using_map_mut_proc
, init
, init_reserve
, clear
, destroy
, get
, grow
, map
, map_mut
, rehash
, rehash_fast
, remove
, remove_entry
, set
, slot
, hashes
, entries
, access_protected
, add_entry
, find
, full
)));
}
return def_global_body( args( ht_entry, array_ht_entry, hashtable ));
}
struct GenHashTableRequest
{
StrC Dependency;
StrC Type;
};
Array<GenHashTableRequest> GenHashTableRequests;
void gen__hashtable_request( StrC type, StrC dep = {} )
{
do_once_start
GenHashTableRequests = Array<GenHashTableRequest>::init( GlobalAllocator );
gen_array( sw );
do_once_end
// Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < GenHashTableRequests.num(); ++idx )
{
StrC const reqest_type = GenHashTableRequests[ idx ].Type;
if ( reqest_type.Len != type.Len )
continue;
if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 )
return;
}
GenHashTableRequest request = { dep, type };
GenHashTableRequests.append( request );
}
#define gen_hashtable( type ) gen__hashtable_request( code(type))
u32 gen_hashtable_file()
{
Builder
gen_hashtable_file;
gen_hashtable_file.open( "hashtable.Upfront.gen.hpp" );
gen_hashtable_file.print( def_include( txt_StrC("gen.hpp")) );
gen_hashtable_file.print( def_include( txt_StrC("Array.Upfront.hpp")) );
gen_hashtable_file.print( def_include( txt_StrC("array.Upfront.gen.hpp")) );
gen_hashtable_file.print( def_using_namespace( name(gen)));
gen_hashtable_file.print( gen__hashtable_base());
GenHashTableRequest* current = GenHashTableRequests;
s32 left = GenHashTableRequests.num();
while (left--)
{
GenHashTableRequest const& request = * current;
Code generated_buffer = gen__hashtable( current->Type );
if ( request.Dependency )
{
char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type );
s32 cmt_len = str_len( cmt_str );
Code cmt = def_comment( { cmt_len, cmt_str } );
Code include = def_include( request.Dependency );
gen_hashtable_file.print( cmt );
gen_hashtable_file.print( include );
}
gen_hashtable_file.print( generated_buffer );
current++;
}
gen_hashtable_file.write();
return 0;
}
#endif // GEN_TIME

View File

@ -0,0 +1,228 @@
#pragma once
#if GEN_TIME
#include "gen.hpp"
#include "Buffer.Upfront.hpp"
using namespace gen;
Code gen__ring( StrC type )
{
static CodeType t_allocator_info = def_type( name(AllocatorInfo) );
String name;
{
char const* name_str = str_fmt_buf( "Ring_%s\0", type.Ptr );
s32 name_len = str_len( name_str );
name = get_cached_string({ name_len, name_str });
};
CodeType t_ring_type = def_type( name );
CodeType t_ring_type_ptr = def_type( name, __, spec_ptr );
CodeType t_type = def_type( type );
CodeType t_type_ptr = def_type( type, __, spec_ptr );
CodeType t_type_ref = def_type( type, __, spec_ref );
CodeType t_buffer_type;
{
char const* name_str = str_fmt_buf( "Buffer_%s\0", type.Ptr );
s32 len = str_len( name_str );
t_buffer_type = def_type( { len, name_str } );
}
CodeStruct ring = {0};
{
CodeUsing using_type = def_using( name(Type), t_type );
CodeVar backing = def_variable( t_allocator_info, name(Backing) );
CodeVar capacity = def_variable( t_uw, name(Capacity) );
CodeVar head = def_variable( t_uw, name(Head) );
CodeVar tail = def_variable( t_uw, name(Tail) );
CodeVar buffer = def_variable( t_buffer_type, name(Buffer) );
CodeFn init;
{
CodeParam params = def_params( args(
def_param( t_allocator_info, name(allocator) )
, def_param( t_uw, name(max_size) )
));
char const* tmpl = stringize(
<type> result = { 0 };
result.Backing = allocator;
result.Buffer = Buffer_<data_type>::init( allocator, max_size + 1 );
if ( result.Buffer == nullptr )
return { nullptr };
result.Capacity = max_size + 1;
return result;
);
Code body = def_execution( token_fmt( "type", (StrC)name, "data_type", type, tmpl ));
init = def_function( name(init), params, t_ring_type, body, spec_static_member );
}
CodeFn append = def_function( name(append), def_param( t_type, name(value)), t_void
, def_execution( code(
Buffer[ Head ] = value;
Head = ( Head + 1 ) % Capacity;
if ( Head == Tail )
Tail = ( Tail + 1 ) % Capacity;
))
);
CodeFn appendv;
{
CodeParam params = def_params( 2
, def_param( t_type_ptr, name(values))
, def_param( t_sw, name(num))
);
Code body = def_execution( code(
for ( sw idx = 0; idx < num; idx++ )
append( values[ idx ] );
));
appendv = def_function( name(append), params, t_void, body, spec_inline );
}
CodeFn empty = def_function( name(empty), __, t_bool
, def_execution( code(
return Head == Tail;
))
);
CodeFn free = def_function( name(free), __, t_void
, def_execution( code(
Buffer.free();
))
);
CodeFn full = def_function( name(full), __, t_bool
, def_execution( code(
return (Head + 1) % Capacity == Tail;
))
);
CodeFn get = def_function( name(get), __, t_type_ref
, def_execution( code(
Type& data = Buffer[ Tail ];
Tail = ( Tail + 1 ) % Capacity;
return data;
))
);
CodeFn wipe = def_function( name(wipe), __, t_void
, def_execution( code(
Head = 0;
Tail = 0;
Buffer.wipe();
))
);
ring = def_struct( name, def_struct_body( args(
using_type,
init,
append,
appendv,
empty,
free,
full,
get,
wipe,
backing,
capacity,
head,
tail,
buffer
)));
}
return ring;
}
struct GenRingRequest
{
StrC Dependency;
StrC Type;
};
Array<GenRingRequest> GenRingRequests;
void gen__ring_request( StrC type, StrC dep = {} )
{
do_once_start
GenRingRequests = Array<GenRingRequest>::init( GlobalAllocator );
do_once_end
// Make sure we don't already have a request for the type.
for ( sw idx = 0; idx < GenRingRequests.num(); ++idx )
{
StrC const reqest_type = GenRingRequests[ idx ].Type;
if ( reqest_type.Len != type.Len )
continue;
if ( str_compare( reqest_type.Ptr, type.Ptr, reqest_type.Len ) == 0 )
return;
}
// Ring definition depends on a array and buffer definition.
gen__buffer_request( type, dep );
GenRingRequest request = { dep, type };
GenRingRequests.append( request );
}
#define gen_ring( type ) gen__ring_request( code(type) )
u32 gen_ring_file()
{
Builder
gen_ring_file;
gen_ring_file.open( "ring.Upfront.gen.hpp" );
gen_ring_file.print( def_include( txt_StrC("gen.hpp")) );
gen_ring_file.print( def_include( txt_StrC("buffer.Upfront.gen.hpp")) );
gen_ring_file.print( def_using_namespace( name(gen)));
GenRingRequest* current = GenRingRequests;
s32 left = GenRingRequests.num();
while (left--)
{
GenRingRequest const& request = * current;
Code generated_ring = gen__ring( current->Type );
if ( request.Dependency )
{
char const* cmt_str = str_fmt_buf( "// Dependency for %s type", request.Type );
s32 cmt_len = str_len( cmt_str );
Code cmt = def_comment( { cmt_len, cmt_str } );
Code include = def_include( request.Dependency );
gen_ring_file.print( cmt );
gen_ring_file.print( include );
}
gen_ring_file.print( generated_ring );
current++;
}
gen_ring_file.write();
return 0;
}
#endif // GEN_TIME

View File

@ -0,0 +1,331 @@
#ifdef GEN_TIME
#include "gen.hpp"
using namespace gen;
u32 gen_sanity_upfront()
{
Builder
gen_sanity_file;
gen_sanity_file.open("./sanity.Upfront.gen.hpp");
// Comment
{
CodeComment comment_test = def_comment( txt_StrC("Sanity check: def_comment test") );
gen_sanity_file.print(comment_test);
}
gen_sanity_file.print_fmt("\n");
gen_sanity_file.print( def_comment( txt_StrC(
"The following will show a series of base cases for the gen api.\n"
)));
// Class
{
CodeClass fwd = def_class( name(TestEmptyClass) );
CodeClass empty_body;
{
CodeComment cmt = def_comment( txt_StrC("Empty class body") );
CodeBody body = def_class_body( args( cmt ) );
empty_body = def_class( name(TestEmptyClass), body );
}
gen_sanity_file.print(fwd);
gen_sanity_file.print(empty_body);
}
gen_sanity_file.print_fmt("\n");
// Typedef
{
CodeType t_unsigned_char = def_type( name(unsigned char) );
CodeTypedef u8_typedef = def_typedef( name(u8), t_unsigned_char );
gen_sanity_file.print(u8_typedef);
}
gen_sanity_file.print_fmt("\n");
// Enum
{
CodeEnum fwd = def_enum( name(ETestEnum), NoCode, t_u8 );
CodeEnum def;
{
Code body = untyped_str( code(
A,
B,
C
));
def = def_enum( name(ETestEnum), body, t_u8 );
}
CodeEnum fwd_enum_class = def_enum( name(ETestEnumClass), NoCode, t_u8, EnumClass );
gen_sanity_file.print(fwd);
gen_sanity_file.print(def);
gen_sanity_file.print(fwd_enum_class);
}
gen_sanity_file.print_fmt("\n");
// External Linkage
{
CodeBody body = def_extern_link_body( 1
, def_comment( txt_StrC("Empty extern body") )
);
CodeExtern c_extern = def_extern_link( name(C), body );
gen_sanity_file.print(c_extern);
}
gen_sanity_file.print_fmt("\n");
// Friend
{
CodeClass fwd = def_class( name(TestFriendFwd));
CodeBody body = def_class_body( args( def_friend( fwd ) ) );
gen_sanity_file.print( def_class( name(TestFriend), body ) );
}
gen_sanity_file.print_fmt("\n");
// Function
{
CodeFn fwd = def_function( name(test_function) );
CodeFn def;
{
CodeBody body = def_function_body( 1
, def_comment( txt_StrC("Empty function body") )
);
def = def_function( name(test_function), __, __, body );
}
gen_sanity_file.print(fwd);
gen_sanity_file.print(def);
}
gen_sanity_file.print_fmt("\n");
// Include
{
CodeInclude include = def_include( txt_StrC("../DummyInclude.hpp") );
gen_sanity_file.print(include);
}
gen_sanity_file.print_fmt("\n");
// Module
if (0)
{
CodeModule module_export = def_module( name(TestModule), ModuleFlag::Export );
CodeModule module_import = def_module( name(TestModule), ModuleFlag::Import );
CodeModule module_both = def_module( name(TestModule), ModuleFlag::Export | ModuleFlag::Import );
gen_sanity_file.print(module_global_fragment);
gen_sanity_file.print(module_private_fragment);
gen_sanity_file.print(module_export);
gen_sanity_file.print(module_import);
gen_sanity_file.print(module_both);
}
gen_sanity_file.print_fmt("\n");
// Namespace
{
CodeNamespace namespace_def;
{
CodeBody body = def_namespace_body( 1
, def_comment( txt_StrC("Empty namespace body") )
);
namespace_def = def_namespace( name(TestNamespace), body );
}
gen_sanity_file.print(namespace_def);
}
gen_sanity_file.print_fmt("\n");
// Operator
{
// Going to make a bit flag set of overloads for this.
CodeEnum bitflagtest;
{
CodeBody body = def_enum_body( 1, untyped_str( code(
A = 1 << 0,
B = 1 << 1,
C = 1 << 2
)));
bitflagtest = def_enum( name(EBitFlagtest), body, t_u8, EnumClass );
}
CodeType t_bitflag = def_type( name(EBitFlagtest) );
CodeOperator op_fwd, op_or;
{
CodeParam params = def_params( args(
def_param( t_bitflag, name(a) ),
def_param( t_bitflag, name(b) )
));
op_fwd = def_operator( EOperator::BOr, params, t_bitflag );
op_or = def_operator( EOperator::BOr, params, t_bitflag, untyped_str( code(
return EBitFlagtest( (u8)a | (u8)b );
)));
}
gen_sanity_file.print(bitflagtest);
gen_sanity_file.print(op_fwd);
gen_sanity_file.print(op_or);
}
gen_sanity_file.print_fmt("\n");
// Operator cast
{
CodeType t_u8_ptr = def_type( name(u8), __, spec_ptr );
CodeOpCast op_ptr = def_operator_cast( t_u8_ptr, __ );
CodeClass op_class = def_class( name(TestOperatorCast), def_class_body( args( op_ptr) ) );
gen_sanity_file.print(op_class);
}
gen_sanity_file.print_fmt("\n");
// Parameters
{
CodeFn fwd;
{
CodeParam params = def_param( t_u8, name(a) );
fwd = def_function( name(test_function_wparam), params );
}
CodeFn def, def2;
{
CodeBody body = def_function_body( 1
, def_comment( txt_StrC("Empty function body") )
);
CodeParam params = def_params( args(
def_param( t_u8, name(a) )
, def_param( t_u8, name(b) )
));
def = def_function( name(test_function_wparams), params, __, body );
CodeParam param_a = def_param( t_u8, name(a));
CodeParam param_b = def_param( t_u8, name(b));
CodeParam params_arr[2] = { param_a, param_b };
CodeParam params2 = def_params( 2, params_arr );
def2 = def_function( name(test_function_wparams2), params2, __, body );
}
gen_sanity_file.print(fwd);
gen_sanity_file.print(def);
gen_sanity_file.print(def2);
}
gen_sanity_file.print_fmt("\n");
// Specifiers
{
CodeFn fwd_fn = def_function( name(test_function_specifiers), __, __, __, spec_inline );
// TODO : Need an op overload here
CodeType u8_ptr = def_type( name(u8), __, spec_ptr );
CodeTypedef typedef_u8_ptr = def_typedef( name(ConstExprTest), u8_ptr );
gen_sanity_file.print(fwd_fn);
gen_sanity_file.print(typedef_u8_ptr);
}
gen_sanity_file.print_fmt("\n");
// Struct
{
CodeClass fwd = def_class( name(TestEmptyStruct) );
CodeClass empty_body;
{
CodeComment cmt = def_comment( txt_StrC("Empty struct body") );
CodeBody body = def_class_body( args( cmt ) );
empty_body = def_class( name(TestEmptyStruct), body );
}
gen_sanity_file.print(fwd);
gen_sanity_file.print(empty_body);
}
gen_sanity_file.print_fmt("\n");
// Union
{
CodeBody body = def_union_body( 1
, def_comment( txt_StrC("Empty union body") )
);
CodeUnion def = def_union( name(TestEmptyUnion), body );
gen_sanity_file.print(def);
}
gen_sanity_file.print_fmt("\n");
// Using
{
CodeUsing reg = def_using( name(TestUsing), t_u8 );
CodeUsing nspace = def_using_namespace( name(TestNamespace) );
gen_sanity_file.print(reg);
gen_sanity_file.print(nspace);
}
gen_sanity_file.print_fmt("\n");
// Variable
{
CodeVar bss = def_variable( t_u8, name(test_variable) );
CodeVar data = def_variable( t_u8, name(test_variable2), untyped_str( code( 0x12 )) );
gen_sanity_file.print(bss);
gen_sanity_file.print(data);
}
gen_sanity_file.print_fmt("\n");
// Template
{
CodeType t_Type = def_type( name(Type) );
CodeTemplate tmpl = def_template( def_param( t_class, name(Type) )
, def_function( name(test_template), def_param( t_Type, name(a) ), __
, def_function_body(1, def_comment( txt_StrC("Empty template function body")))
)
);
gen_sanity_file.print(tmpl);
}
gen_sanity_file.print_fmt("\n");
gen_sanity_file.print( def_comment( txt_StrC(
"End of base case tests.\n"
)));
gen_sanity_file.write();
return 0;
}
#endif