Removed the DSL macros, More fixes related to memory.

I commented out stuff related to type caching, I may not be using it. Depends on whether I want to keep the parent member in the ast.

DSL macros were removed, I want to keep the macros minimum for the api.
The varadic macros for the body may be problomatic if there is some bs vendor's are doing with memory layouts of structs that are not necessarily POD but only have the assignment operator overloaded.
Worst case I'll have to remove them.

Memory should be fine now to start doing iterations on the array test.

Parser constructors have been on hold for a while. They'll problably not be done until sometime in June.
This commit is contained in:
Edward R. Gonzalez 2023-05-09 21:54:54 -04:00
parent d00de42969
commit e74b498686
2 changed files with 143 additions and 149 deletions

View File

@ -6,7 +6,7 @@
namespace gen namespace gen
{ {
ZPL_TABLE_DEFINE( StringTable, str_tbl_, String ); ZPL_TABLE_DEFINE( StringTable, str_tbl_, String );
ZPL_TABLE_DEFINE( TypeTable, type_tbl_ , Code ); // ZPL_TABLE_DEFINE( TypeTable, type_tbl_ , Code );
namespace StaticData namespace StaticData
{ {
@ -15,7 +15,7 @@ namespace gen
static Array(Arena) StringArenas = nullptr; static Array(Arena) StringArenas = nullptr;
static StringTable StringMap; static StringTable StringMap;
static TypeTable TypeMap; // static TypeTable TypeMap;
static AllocatorInfo Allocator_DataArrays = heap(); static AllocatorInfo Allocator_DataArrays = heap();
static AllocatorInfo Allocator_CodePool = heap(); static AllocatorInfo Allocator_CodePool = heap();
@ -54,11 +54,26 @@ namespace gen
Code access_protected; Code access_protected;
Code access_private; Code access_private;
Code spec_constexpr;
Code spec_const; Code spec_const;
Code spec_consteval;
Code spec_constexpr;
Code spec_constinit;
Code spec_extern_linkage;
Code spec_inline; Code spec_inline;
Code sepc_ptr; Code spec_internal_linkage;
Code spec_local_persist;
Code spec_mutable;
Code spec_ptr;
Code spec_ref; Code spec_ref;
Code spec_register;
Code spec_rvalue;
Code spec_static_member;
Code spec_thread_local;
Code spec_volatile;
Code spec_type_signed;
Code spec_type_unsigned;
Code spec_type_short;
Code spec_type_long;
#pragma endregion Constants #pragma endregion Constants
#pragma region AST Body Case Macros #pragma region AST Body Case Macros
@ -1201,15 +1216,14 @@ namespace gen
if ( StringMap.entries == nullptr ) if ( StringMap.entries == nullptr )
fatal( "gen::init: Failed to initialize the StringMap"); fatal( "gen::init: Failed to initialize the StringMap");
type_tbl_init( & TypeMap, Allocator_TypeTable ); //type_tbl_init( & TypeMap, Allocator_TypeTable );
if ( TypeMap.entries == nullptr ) //if ( TypeMap.entries == nullptr )
fatal( "gen::init: Failed to initialize the TypeMap" ); // fatal( "gen::init: Failed to initialize the TypeMap" );
} }
Code::Invalid = make_code(); Code::Invalid = make_code();
Code::Invalid.lock(); Code::Invalid.lock();
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
Code& Code&
t_void_write = ccast( Code, t_void ); t_void_write = ccast( Code, t_void );
t_void_write = def_type( name(void) ); t_void_write = def_type( name(void) );
@ -1224,6 +1238,7 @@ namespace gen
def_constant_code_type( char ); def_constant_code_type( char );
def_constant_code_type( wchar_t ); def_constant_code_type( wchar_t );
#ifdef GEN_DEFINE_LIBRARY_CODE_CONSTANTS
def_constant_code_type( s8 ); def_constant_code_type( s8 );
def_constant_code_type( s16 ); def_constant_code_type( s16 );
def_constant_code_type( s32 ); def_constant_code_type( s32 );
@ -1239,20 +1254,58 @@ namespace gen
def_constant_code_type( f32 ); def_constant_code_type( f32 );
def_constant_code_type( f64 ); def_constant_code_type( f64 );
# undef def_constant_code_type
#endif #endif
# undef def_constant_code_type
Code& Code&
spec_constexpr_write = ccast( Code, spec_constexpr ); access_private_write = ccast( Code, access_private );
spec_constexpr_write = def_specifiers( 1, ESpecifier::Constexpr ); access_private_write = make_code();
access_private_write->Type = ECode::Access_Private;
access_private_write->Name = get_cached_string( { sizeof("private"), "private" } );
access_private_write.lock();
Code&
access_protected_write = ccast( Code, access_protected );
access_protected_write = make_code();
access_protected_write->Type = ECode::Access_Protected;
access_protected_write->Name = get_cached_string( { sizeof("protected"), "protected" } );
access_protected_write.lock();
Code&
access_public_write = ccast( Code, access_public );
access_public_write = make_code();
access_public_write->Type = ECode::Access_Public;
access_public_write->Name = get_cached_string( { sizeof("public"), "public" } );
access_public_write.lock();
Code&
spec_local_persist_write = ccast( Code, spec_local_persist );
spec_local_persist_write = def_specifiers( 1, ESpecifier::Local_Persist );
# define def_constant_spec( Type_, ... ) \ # define def_constant_spec( Type_, ... ) \
Code& \ Code& \
spec_##Type_##_write = ccast( Code, spec_##Type_); \ spec_##Type_##_write = ccast( Code, spec_##Type_); \
spec_##Type_##_write = def_specifiers( macro_num_args(__VA_ARGS__), __VA_ARGS__); \ spec_##Type_##_write = def_specifiers( macro_num_args(__VA_ARGS__), __VA_ARGS__); \
def_constant_spec( const, ESpecifier::Const ); def_constant_spec( consteval, ESpecifier::Consteval );
def_constant_spec( inline, ESpecifier::Inline ); def_constant_spec( constexpr, ESpecifier::Constexpr );
def_constant_spec( constinit, ESpecifier::Constinit );
def_constant_spec( extern_linkage, ESpecifier::External_Linkage );
def_constant_spec( const, ESpecifier::Const );
def_constant_spec( inline, ESpecifier::Inline );
def_constant_spec( internal_linkage, ESpecifier::Internal_Linkage );
def_constant_spec( mutable, ESpecifier::Mutable );
def_constant_spec( ptr, ESpecifier::Ptr );
def_constant_spec( ref, ESpecifier::Ref );
def_constant_spec( register, ESpecifier::Register );
def_constant_spec( rvalue, ESpecifier::RValue );
def_constant_spec( static_member, ESpecifier::Static_Member );
def_constant_spec( thread_local, ESpecifier::Thread_Local );
def_constant_spec( volatile, ESpecifier::Volatile)
def_constant_spec( type_signed, ESpecifier::Type_Signed );
def_constant_spec( type_unsigned, ESpecifier::Type_Unsigned );
def_constant_spec( type_short, ESpecifier::Type_Short );
def_constant_spec( type_long, ESpecifier::Type_Long );
# undef def_constant_spec # undef def_constant_spec
} }
@ -1260,35 +1313,42 @@ namespace gen
{ {
using namespace StaticData; using namespace StaticData;
s32 left = array_count( CodePools ); s32 index = 0;
s32 left = array_count( CodePools );
do do
{ {
Pool* code_pool = & CodePools[left]; Pool* code_pool = & CodePools[index];
pool_free( code_pool ); pool_free( code_pool );
index++;
} }
while ( left--, left ); while ( left--, left );
left = array_count( CodeEntriesArenas ); index = 0;
left = array_count( CodeEntriesArenas );
do do
{ {
Arena* code_entries_arena = & CodeEntriesArenas[left]; Arena* code_entries_arena = & CodeEntriesArenas[index];
arena_free( code_entries_arena ); arena_free( code_entries_arena );
index++;
} }
while ( left--, left ); while ( left--, left );
left = array_count( StringArenas ); index = 0;
left = array_count( StringArenas );
do do
{ {
Arena* string_arena = & StringArenas[left]; Arena* string_arena = & StringArenas[index];
arena_free( string_arena ); arena_free( string_arena );
index++;
} }
while ( left--, left ); while ( left--, left );
str_tbl_destroy( & StringMap ); str_tbl_destroy( & StringMap );
type_tbl_destroy( & TypeMap ); // type_tbl_destroy( & TypeMap );
array_free( CodePools ); array_free( CodePools );
array_free( CodeEntriesArenas ); array_free( CodeEntriesArenas );
array_free( StringArenas );
} }
void clear_code_memory() void clear_code_memory()
@ -1323,7 +1383,7 @@ namespace gen
array_clear( CodeEntriesArenas ); array_clear( CodeEntriesArenas );
} }
type_tbl_clear( & StaticData::TypeMap ); // type_tbl_clear( & StaticData::TypeMap );
} }
inline inline
@ -1364,6 +1424,20 @@ namespace gen
return result; return result;
} }
// Code get_cached_type( StrC name )
// {
// s32 hash_length = name.Len > kilobytes(1) ? kilobytes(1) : name.Len;
// s32 key = crc32( name.Ptr, hash_length );
// {
// Code* result = type_tbl_get( & StaticData::TypeMap, key );
// if ( result )
// return * result;
// }
// return Code::Invalid;
// }
/* /*
Used internally to retireve a Code object form the CodePool. Used internally to retireve a Code object form the CodePool.
*/ */
@ -1373,11 +1447,16 @@ namespace gen
AllocatorInfo allocator = { nullptr, nullptr }; AllocatorInfo allocator = { nullptr, nullptr };
s32 left = array_count( CodePools ); s32 index = 0;
s32 left = array_count( CodePools );
do do
{ {
if ( CodePools[left].free_list != nullptr ) if ( CodePools[index].free_list != nullptr )
allocator = zpl::pool_allocator( & CodePools[left] ); {
allocator = zpl::pool_allocator( & CodePools[index] );
break;
}
index++;
} }
while ( left--, left ); while ( left--, left );
@ -1417,11 +1496,13 @@ namespace gen
AllocatorInfo allocator = { nullptr, nullptr }; AllocatorInfo allocator = { nullptr, nullptr };
s32 left = array_count( CodeEntriesArenas ); s32 index = 0;
s32 left = array_count( CodeEntriesArenas );
do do
{ {
if ( arena_size_remaining(CodeEntriesArenas, ZPL_DEFAULT_MEMORY_ALIGNMENT) >= InitSize_CodeEntiresArray ) if ( arena_size_remaining( & CodeEntriesArenas[index], ZPL_DEFAULT_MEMORY_ALIGNMENT) >= InitSize_CodeEntiresArray )
allocator = arena_allocator( & CodeEntriesArenas[left] ); allocator = arena_allocator( & CodeEntriesArenas[index] );
index++;
} }
while( left--, left ); while( left--, left );
@ -1433,7 +1514,8 @@ namespace gen
if ( arena.physical_start == nullptr ) if ( arena.physical_start == 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( CodeEntriesArenas ); allocator = arena_allocator( & arena );
array_append( CodeEntriesArenas, arena );
} }
Array(AST*) entry_array; Array(AST*) entry_array;
@ -2399,6 +2481,10 @@ namespace gen
return Code::Invalid; return Code::Invalid;
} }
// Code cached = get_cached_type( name );
// if ( cached )
// return cached;
Code Code
result = make_code(); result = make_code();
result->Name = get_cached_string( name ); result->Name = get_cached_string( name );
@ -2411,6 +2497,12 @@ namespace gen
result->add_entry( ArrayExpr ); result->add_entry( ArrayExpr );
result.lock(); result.lock();
// s32 hash_length = name.Len > kilobytes(1) ? kilobytes(1) : name.Len;
// s32 key = crc32( name.Ptr, hash_length );
// type_tbl_set( & StaticData::TypeMap, key, result );
return result; return result;
} }

View File

@ -723,8 +723,13 @@ namespace gen
Provides interning specific to Typename ASTs. Provides interning specific to Typename ASTs.
Interning for other types should be possible (specifiers) with this, so long as they Interning for other types should be possible (specifiers) with this, so long as they
don't have an set of child AST entries (Use the content field). don't have an set of child AST entries (Use the content field).
TODO: I'm not sure if this is viable.
ASTs are duplicated when added (parent is unique),
Parent is currently used for debug and serialization.
If these features are considered unnecessary, then caching would be fine.
*/ */
ZPL_TABLE_DECLARE( ZPL_EXTERN, TypeTable, type_tbl_, Code ); // ZPL_TABLE_DECLARE( ZPL_EXTERN, TypeTable, type_tbl_, Code );
#pragma endregion Data Structures #pragma endregion Data Structures
#pragma region Gen Interface #pragma region Gen Interface
@ -1058,131 +1063,13 @@ namespace gen
// Used by the DSL but can also be used without it. // Used by the DSL but can also be used without it.
# define type_ns( Name_ ) t_##Name_ # define type_ns( Name_ ) t_##Name_
// Convienence for defining any name used with the gen interface. // Convienence for defining any name used with the gen api.
// Lets you provide the length and string literal to the functions without the need for the DSL. // Lets you provide the length and string literal to the functions without the need for the DSL.
# define name( Id_ ) { txt_n_len( Id_ ) } # define name( Id_ ) { txt_n_len( Id_ ) }
// Same as name just used to indicate intention of literal for code instead of names. // Same as name just used to indicate intention of literal for code instead of names.
# define code( Code_ ) { txt_n_len( Code_ ) } # define code( Code_ ) { txt_n_len( Code_ ) }
/*
gen's Domain Specific Langauge.
Completely optional, makes the code gen syntax less verbose and cumbersome...
Since its C macros ends up looking like a lisp dialect...
Longforms auto-define the variable.
Shorthands are just the function call.
Anything below the make() macro is intended to be syntactically used in the follwing format:
make( <type>, <name> )
{
...
}
Where ... are whatever is deemed necessary to produce the definition for the def( <name> ).
The code macros are used to embed c/c++ to insert into the desired lcoation.
*/
#ifdef GEN_DEFINE_DSL
// Boilerplate
/*
In order to provide some convient syntax sugar this polymoprhic macro boilerplate is needed for:
* function( ... )
* operator( ... )
* params( ... )
macrofn based off of: https://stackoverflow.com/questions/3046889/optional-parameters-with-c-macros
specifically: https://stackoverflow.com/a/56038661
*/
# define macrofn_chooser(_f0, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10, _f11, _f12, _f13, _f14, _f15, _f16, ...) _f16
# define macrofn_recomposer(ArgsWithParentheses_) macrofn_chooser ArgsWithParentheses_
# define macrofn_chose_from_arg_num(F, ...) macrofn_recomposer((__VA_ARGS__, F##_16, F##_15, F##_14, F##_13, F##_12, F##_11, F##_10, F##_9, F##_8, F##_7, F##_6, F##_5, F##_4, F##_3, F##_2, F##_1, ))
# define marcofn_no_arg_expander(Func_) ,,,,,,,,,,,,,,,,Func_ ## _0
# define macrofn_finder(Func_, ...) macrofn_chose_from_arg_num(Func_, marcofn_no_arg_expander __VA_ARGS__ (Func_))
# define macrofn_polymorphic(Func_, ...) macrofn_finder(Func_, __VA_ARGS__)(__VA_ARGS__)
# define function_5( Name_, Params_, RetType_, Specifiers_, Body_ ) gen::def_function( txt_n_len( Name_ ), macro_expand( Params_ ), type_ns(RetType_), Specifiers_, Body_ )
# define function_4( Name_, Params_, RetType_, Specifiers_ ) gen::def_function( txt_n_len( Name_ ), macro_expand( Params_ ), type_ns(RetType_), Specifiers_ )
# define function_3( Name_, Params_, RetType_ ) gen::def_function( txt_n_len( Name_ ), macro_expand( Params_ ), type_ns(RetType_) )
# define function_2( Name_, Params_ ) gen::def_function( txt_n_len( Name_ ), macro_expand( Params_ ) )
# define function_1( Name_ ) gen::def_function( txt_n_len( Name_ ) )
# define params_12( T_1, V_1, T_2, V_2, T_3, V_3, T_4, V_4, T_5, V_5, T_6, V_6 ) gen::def_params( 12, type_ns(T_1), txt_n_len( V_1), type_ns(T_2), txt_n_len( V_2), type_ns(T_3), txt_n_len( V_3), type_ns(T_4), txt_n_len( V_4), type_ns(T_5), txt_n_len( V_5), type_ns(T_6), txt_n_len(V_6))
# define params_10( T_1, V_1, T_2, V_2, T_3, V_3, T_4, V_4, T_5, V_5 ) gen::def_params( 10, type_ns(T_1), txt_n_len( V_1), type_ns(T_2), txt_n_len( V_2), type_ns(T_3), txt_n_len( V_3), type_ns(T_4), txt_n_len( V_4), type_ns(T_5), txt_n_len( V_5))
# define params_8( T_1, V_1, T_2, V_2, T_3, V_3, T_4, V_4 ) gen::def_params( 8, type_ns(T_1), txt_n_len( V_1), type_ns(T_2), txt_n_len( V_2), type_ns(T_3), txt_n_len( V_3), type_ns(T_4), txt_n_len( V_4) )
# define params_6( T_1, V_1, T_2, V_2, T_3, V_3 ) gen::def_params( 6, type_ns(T_1), txt_n_len( V_1), type_ns(T_2), txt_n_len( V_2), type_ns(T_3), txt_n_len( V_3))
# define params_4( T_1, V_1, T_2, V_2 ) gen::def_params( 4, type_ns(T_1), txt_n_len( V_1), type_ns(T_2), txt_n_len( V_2))
# define params_2( T_1, V_1 ) gen::def_param ( type_ns(T_1), txt_n_len( V_1))
# define params_bad static_assert("params(...): Invalid number of parameters provided.")
# define params_11 params_bad
# define params_9 params_bad
# define params_7 params_bad
# define params_5 params_bad
# define params_3 params_bad
# define params_1 params_bad
// Upfront
# define comment( Value_ ) gen::def_comment( sizeof(Value), Value_ )
# define attribute( Value_ ) gen::def_attribute( txt_n_len(Value_) )
# define class( Name_, ... ) gen::def_class( txt_n_len(Name_), __VA_ARGS__ )
# define enum( Name_, Type_, Body_ ) gen::def_enum ( txt_n_len(Name_), type_ns(Type_), Body_ )
# define extern_linkage( Name_, Body_ ) gen::def_extern_linkage( txt_n_len(Name_), Body_ )
# define function( ... ) macrofn_polymorphic( function, __VA_ARGS__ )
# define namespace( Name_, Body_ ) gen::def_namespace ( txt_n_len(Name_), Body_ )
# define operator( Op_, ... ) macrofn_polymorphic( operator, __VA_ARGS__ )
# define params( ... ) macrofn_polymorphic( params, __VA_ARGS__ )
# define specifiers( ... ) gen::def_specifiers ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define struct( Name_, ... ) gen::def_struct ( txt_n_len(Name_), __VA_ARGS__ )
# define variable( Type_, Name_, ... ) gen::def_variable ( type_ns(Type_), txt_n_len(Name_), __VA_ARGS__ )
# define type( Value_, ... ) gen::def_type ( txt_n_len(Value_), __VA_ARGS__ )
# define type_fmt( Fmt_, ... ) gen::def_type ( bprintf( Fmt_, __VA_ARGS__ ) )
# define union( Name_, ... ) gen::def_union ( txt_n_len(Name_), __VA_ARGS__ )
# define using( Name_, ... ) gen::def_using ( txt_n_len(Name_), __VA_ARGS__ )
# define class_body( ... ) gen::def_class_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define enum_body( ... ) gen::def_enum_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define extern_linkage_body( ... ) gen::def_extern_linkage_body( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define global_body( ... ) gen::def_global_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define function_body( ... ) gen::def_function_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define namespace_body( ... ) gen::def_namespace_body( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define operator_body( ... ) gen::def_operator_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define struct_body( ... ) gen::def_struct_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# define union_body( ... ) gen::def_union_body ( macro_num_args( __VA_ARGS__ ), __VA_ARGS__ )
# ifdef GEN_FEATURE_INCREMENTAL
// Incremental
# define make( ConstructType_, Name_, ... ) Code Name_ = make_##ConstructType_( txt_n_len(Name_), __VA_ARGS__ );
# endif
# ifdef GEN_FEATURE_PARSING
// Parsing
# define class_code( ... ) gen::parse_class ( txt_n_len( __VA_ARGS__ ))
# define enum_code( ... ) gen::parse_enum ( txt_n_len( __VA_ARGS__ ))
# define function_code( ... ) gen::parse_function ( txt_n_len( __VA_ARGS__ ))
# define global_body_code( ... ) gen::parse_global_body( txt_n_len( __VA_ARGS__ ))
# define operator_code( ... ) gen::parse_operator ( txt_n_len( __VA_ARGS__ ))
# define namespace_code( ... ) gen::parse_namespace ( txt_n_len( __VA_ARGS__ ))
# define struct_code( ... ) gen::parse_struct ( txt_n_len( __VA_ARGS__ ))
# define variable_code( ... ) gen::parse_variable ( txt_n_len( __VA_ARGS__ ))
# define type_code( ... ) gen::parse_type ( txt_n_len( __VA_ARGS__ ))
# define typedef_code( ... ) gen::parse_typedef ( txt_n_len( __VA_ARGS__ ))
# define union_code( ... ) gen::parse_union ( txt_n_len( __VA_ARGS__ ))
# define using_code( ... ) gen::parse_code ( txt_n_len( __VA_ARGS__ ))
# endif
// Untyped
# define code_str( ... ) gen::untyped_str ( txt_n_len(__VA_ARGS__) )
# define code_fmt( Fmt_, ... ) gen::untyped_fmt ( Fmt_, __VA_ARGS__ )
# define code_token( Fmt_, ... ) gen::untyped_token_fmt( Fmt_, macro_num_args( __VA_ARGS__) / 2, __VA_ARGS__ )
#endif
#pragma endregion Macros #pragma endregion Macros
#pragma region Constants #pragma region Constants
@ -1241,11 +1128,26 @@ namespace gen
extern Code access_protected; extern Code access_protected;
extern Code access_private; extern Code access_private;
extern Code spec_constexpr;
extern Code spec_const; extern Code spec_const;
extern Code spec_consteval;
extern Code spec_constexpr;
extern Code spec_constinit;
extern Code spec_extern_linkage;
extern Code spec_inline; extern Code spec_inline;
extern Code spec_internal_linkage;
extern Code spec_local_persist;
extern Code spec_mutable;
extern Code spec_ptr; extern Code spec_ptr;
extern Code spec_ref; extern Code spec_ref;
extern Code spec_register;
extern Code spec_rvalue;
extern Code spec_static_member;
extern Code spec_thread_local;
extern Code spec_volatile;
extern Code spec_type_signed;
extern Code spec_type_unsigned;
extern Code spec_type_short;
extern Code spec_type_long;
} }
#pragma endregion Constants #pragma endregion Constants