Bug fixes and updates to package_release.ps1

- Incrased size of the defines_map_arena to 256KB
- Various fixes for the parser
- Various fixes for code serialization
- Fix for is_equal member func in Code types
- Fixes for hasthable container
- Added are_equal static func to String type for use against StrC
- Added starts_with functions to String type
- package_release.ps1 now packages all docs (forgot to update it with last release)
This commit is contained in:
Edward R. Gonzalez 2024-05-05 21:53:22 -04:00
parent 4a2a93d41b
commit e1592ba410
12 changed files with 160 additions and 133 deletions

View File

@ -10,7 +10,9 @@ Its not meant to be a black box metaprogramming utility, it should be easy to in
## Notes ## Notes
**On Partial Hiatus: Working on handmade hero for now. Only fixes will be pushed as I come across them until I get what I want done from the series** **On Partial Hiatus: Life has got me tackling other issues..**
I will be passively updating the library with bug fixes and minor improvements as I use it for my personal projects.
There won't be any major reworks or features to this thing for a while.
This project is still in development (very much an alpha state), so expect bugs and missing features. This project is still in development (very much an alpha state), so expect bugs and missing features.
See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos. See [issues](https://github.com/Ed94/gencpp/issues) for a list of known bugs or todos.

View File

@ -1 +1,3 @@
#include "scanner.hpp" #ifdef GEN_INTELLISENSE_DIRECTIVES
# include "scanner.hpp"
#endif

View File

@ -139,7 +139,7 @@ void CodeConstructor::to_string_fwd( String& result )
if ( ast->InlineCmt ) if ( ast->InlineCmt )
result.append_fmt( "; // %S\n", ast->InlineCmt->Content ); result.append_fmt( "; // %S\n", ast->InlineCmt->Content );
else else
result.append( ";" ); result.append( ";\n" );
} }
String CodeClass::to_string() String CodeClass::to_string()
@ -183,7 +183,7 @@ void CodeClass::to_string_def( String& result )
while ( interface ) while ( interface )
{ {
result.append_fmt( ", %S", interface.to_string() ); result.append_fmt( ", %S", interface.to_string() );
interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; interface = interface->Next ? interface->Next->cast< CodeType >() : CodeType { nullptr };
} }
} }
else if ( ast->Name ) else if ( ast->Name )
@ -480,6 +480,7 @@ void CodeFn::to_string_def( String& result )
if ( ast->Attributes ) if ( ast->Attributes )
result.append_fmt( " %S ", ast->Attributes.to_string() ); result.append_fmt( " %S ", ast->Attributes.to_string() );
b32 prefix_specs = false;
if ( ast->Specs ) if ( ast->Specs )
{ {
for ( SpecifierT spec : ast->Specs ) for ( SpecifierT spec : ast->Specs )
@ -488,11 +489,13 @@ void CodeFn::to_string_def( String& result )
{ {
StrC spec_str = ESpecifier::to_str( spec ); StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
prefix_specs = true;
} }
} }
} }
if ( ast->Attributes || ast->Specs ) if ( ast->Attributes || prefix_specs )
result.append( "\n" ); result.append( "\n" );
if ( ast->ReturnType ) if ( ast->ReturnType )
@ -530,19 +533,22 @@ void CodeFn::to_string_fwd( String& result )
if ( ast->Attributes ) if ( ast->Attributes )
result.append_fmt( "%S ", ast->Attributes.to_string() ); result.append_fmt( "%S ", ast->Attributes.to_string() );
b32 prefix_specs = false;
if ( ast->Specs ) if ( ast->Specs )
{ {
for ( SpecifierT spec : ast->Specs ) for ( SpecifierT spec : ast->Specs )
{ {
if ( ESpecifier::is_trailing( spec ) && ! (spec != ESpecifier::Pure) ) if ( ! ESpecifier::is_trailing( spec ) || ! (spec != ESpecifier::Pure) )
{ {
StrC spec_str = ESpecifier::to_str( spec ); StrC spec_str = ESpecifier::to_str( spec );
result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr ); result.append_fmt( " %.*s", spec_str.Len, spec_str.Ptr );
prefix_specs = true;
} }
} }
} }
if ( ast->Attributes || ast->Specs ) if ( ast->Attributes || prefix_specs )
{ {
result.append("\n" ); result.append("\n" );
} }
@ -571,7 +577,7 @@ void CodeFn::to_string_fwd( String& result )
} }
} }
if ( ast->Specs.has( ESpecifier::Pure ) >= 0 ) if ( ast->Specs && ast->Specs.has( ESpecifier::Pure ) >= 0 )
result.append( " = 0;" ); result.append( " = 0;" );
else if (ast->Body) else if (ast->Body)
result.append_fmt( " = %S;", ast->Body.to_string() ); result.append_fmt( " = %S;", ast->Body.to_string() );
@ -983,7 +989,7 @@ void CodeStruct::to_string_def( String& result )
while ( interface ) while ( interface )
{ {
result.append_fmt( ", %S", interface.to_string() ); result.append_fmt( ", %S", interface.to_string() );
interface = interface->Next ? interface->Next->cast< CodeType >() : Code { nullptr }; interface = interface->Next ? interface->Next->cast< CodeType >() : CodeType { nullptr };
} }
} }
else if ( ast->Name ) else if ( ast->Name )
@ -1247,7 +1253,7 @@ void CodeVar::to_string( String& result )
result.append( ast->Name ); result.append( ast->Name );
if ( ast->ValueType->ArrExpr ) if ( ast->ValueType && ast->ValueType->ArrExpr )
{ {
result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() ); result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() );

View File

@ -28,8 +28,7 @@ bool Code::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -96,8 +95,7 @@ bool CodeBody::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -164,8 +162,7 @@ bool CodeAttributes::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -252,8 +249,7 @@ bool CodeComment::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -340,8 +336,7 @@ bool CodeConstructor::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -428,8 +423,7 @@ bool CodeClass::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -496,8 +490,7 @@ bool CodeDefine::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -584,8 +577,7 @@ bool CodeDestructor::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -672,8 +664,7 @@ bool CodeEnum::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -760,8 +751,7 @@ bool CodeExec::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -848,8 +838,7 @@ bool CodeExtern::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -936,8 +925,7 @@ bool CodeFriend::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1024,8 +1012,7 @@ bool CodeFn::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1112,8 +1099,7 @@ bool CodeInclude::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1200,8 +1186,7 @@ bool CodeModule::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1288,8 +1273,7 @@ bool CodeNS::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1376,8 +1360,7 @@ bool CodeOperator::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1464,8 +1447,7 @@ bool CodeOpCast::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1552,8 +1534,7 @@ bool CodeParam::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1620,8 +1601,7 @@ bool CodePragma::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1708,8 +1688,7 @@ bool CodePreprocessCond::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1796,8 +1775,7 @@ bool CodeSpecifiers::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1864,8 +1842,7 @@ bool CodeStruct::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -1932,8 +1909,7 @@ bool CodeTemplate::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -2020,8 +1996,7 @@ bool CodeType::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -2108,8 +2083,7 @@ bool CodeTypedef::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -2196,8 +2170,7 @@ bool CodeUnion::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -2284,8 +2257,7 @@ bool CodeUsing::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }
@ -2372,8 +2344,7 @@ bool CodeVar::is_equal( Code other )
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure( "Code::is_equal: Cannot compare code, AST is null!" ); return rcast( AST*, ast ) == other.ast;
return false;
} }
return rcast( AST*, ast )->is_equal( other.ast ); return rcast( AST*, ast )->is_equal( other.ast );
} }

View File

@ -88,17 +88,17 @@ void define_constants()
access_private = make_code(); access_private = make_code();
access_private->Type = ECode::Access_Private; access_private->Type = ECode::Access_Private;
access_private->Name = get_cached_string( txt("private:") ); access_private->Name = get_cached_string( txt("private:\n") );
access_private.set_global(); access_private.set_global();
access_protected = make_code(); access_protected = make_code();
access_protected->Type = ECode::Access_Protected; access_protected->Type = ECode::Access_Protected;
access_protected->Name = get_cached_string( txt("protected:") ); access_protected->Name = get_cached_string( txt("protected:\n") );
access_protected.set_global(); access_protected.set_global();
access_public = make_code(); access_public = make_code();
access_public->Type = ECode::Access_Public; access_public->Type = ECode::Access_Public;
access_public->Name = get_cached_string( txt("public:") ); access_public->Name = get_cached_string( txt("public:\n") );
access_public.set_global(); access_public.set_global();
attrib_api_export = def_attributes( code(GEN_API_Export_Code)); attrib_api_export = def_attributes( code(GEN_API_Export_Code));

View File

@ -159,7 +159,7 @@ struct TokArray
} }
}; };
global Arena_128KB defines_map_arena; global Arena_256KB defines_map_arena;
global HashTable<StrC> defines; global HashTable<StrC> defines;
global Array<Token> Tokens; global Array<Token> Tokens;
@ -374,6 +374,16 @@ s32 lex_preprocessor_directive(
move_forward(); move_forward();
preprocess_content.Length++; preprocess_content.Length++;
if ( current == '\r' && scanner[1] == '\n' )
{
move_forward();
move_forward();
}
else if ( current == '\n' )
{
move_forward();
}
Tokens.append( preprocess_content ); Tokens.append( preprocess_content );
return Lex_Continue; // Skip found token, its all handled here. return Lex_Continue; // Skip found token, its all handled here.
} }
@ -576,7 +586,7 @@ TokArray lex( StrC content )
{ {
s32 length = 0; s32 length = 0;
char const* scanner = entry.Data; char const* scanner = entry.Data;
while ( entry.length() > length && char_is_alphanumeric( *scanner ) || *scanner == '_' ) while ( entry.length() > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') )
{ {
scanner++; scanner++;
length ++; length ++;

View File

@ -136,8 +136,8 @@ void init()
, ( LexAllocator_Size - sizeof( Array<Token>::Header ) ) / sizeof(Token) , ( LexAllocator_Size - sizeof( Array<Token>::Header ) ) / sizeof(Token)
); );
defines_map_arena = Arena_128KB::init(); defines_map_arena = Arena_256KB::init();
defines = HashTable<StrC>::init( defines_map_arena ); defines = HashTable<StrC>::init_reserve( defines_map_arena, 256 );
} }
internal internal
@ -481,7 +481,7 @@ Code parse_array_decl()
if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' ) if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' )
{ {
Code array_expr = untyped_str( currtok ); Code array_expr = untyped_str( get_cached_string(txt(" ")) );
eat( TokType::Operator ); eat( TokType::Operator );
// [] // []
@ -574,6 +574,10 @@ Code parse_assignment_expression()
s32 level = 0; s32 level = 0;
while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) ) while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) )
{ {
if (currtok.Type == TokType::BraceCurly_Open )
level++;
if (currtok.Type == TokType::BraceCurly_Close )
level--;
if (currtok.Type == TokType::Capture_Start) if (currtok.Type == TokType::Capture_Start)
level++; level++;
else if (currtok.Type == TokType::Capture_End) else if (currtok.Type == TokType::Capture_End)
@ -1539,18 +1543,18 @@ Code parse_function_body()
result->Type = Function_Body; result->Type = Function_Body;
// TODO : Support actual parsing of function body // TODO : Support actual parsing of function body
Token start = currtok; Token start = currtok_noskip;
s32 level = 0; s32 level = 0;
while ( left && ( currtok.Type != TokType::BraceCurly_Close || level > 0 ) ) while ( left && ( currtok_noskip.Type != TokType::BraceCurly_Close || level > 0 ) )
{ {
if ( currtok.Type == TokType::BraceCurly_Open ) if ( currtok_noskip.Type == TokType::BraceCurly_Open )
level++; level++;
else if ( currtok.Type == TokType::BraceCurly_Close && level > 0 ) else if ( currtok_noskip.Type == TokType::BraceCurly_Close && level > 0 )
level--; level--;
eat( currtok.Type ); eat( currtok_noskip.Type );
} }
Token previous = prevtok; Token previous = prevtok;
@ -1751,6 +1755,7 @@ CodeBody parse_global_nspace( CodeT which )
case TokType::Spec_Internal_Linkage: case TokType::Spec_Internal_Linkage:
case TokType::Spec_NeverInline: case TokType::Spec_NeverInline:
case TokType::Spec_Static: case TokType::Spec_Static:
case TokType::Spec_ThreadLocal:
{ {
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers }; SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
s32 NumSpecifiers = 0; s32 NumSpecifiers = 0;
@ -1774,6 +1779,7 @@ CodeBody parse_global_nspace( CodeT which )
case ESpecifier::NeverInline: case ESpecifier::NeverInline:
case ESpecifier::Static: case ESpecifier::Static:
case ESpecifier::Volatile: case ESpecifier::Volatile:
case ESpecifier::Thread_Local:
break; break;
case ESpecifier::Consteval: case ESpecifier::Consteval:
@ -2294,7 +2300,7 @@ CodeOperator parse_operator_after_ret_type(
case '<': case '<':
{ {
if ( currtok.Text[1] == '=' ) if ( currtok.Text[1] == '=' )
op = LEqual; op = LesserEqual;
else if ( currtok.Text[1] == '<' ) else if ( currtok.Text[1] == '<' )
{ {
@ -2683,7 +2689,7 @@ CodeParam parse_params( bool use_template_capture )
s32 capture_level = 0; s32 capture_level = 0;
s32 template_level = 0; s32 template_level = 0;
while ( left && (currtok.Type != TokType::Comma) && template_level >= 0 && CheckEndParams() || capture_level > 0 || template_level > 0 ) while ( left && (currtok.Type != TokType::Comma) && template_level >= 0 && (CheckEndParams() || capture_level > 0 || template_level > 0) )
{ {
if (currtok.Text[ 0 ] == '<') if (currtok.Text[ 0 ] == '<')
++ template_level; ++ template_level;
@ -2789,8 +2795,7 @@ CodeParam parse_params( bool use_template_capture )
while ( left while ( left
&& currtok.Type != TokType::Comma && currtok.Type != TokType::Comma
&& template_level >= 0 && template_level >= 0
&& CheckEndParams() && (CheckEndParams() || capture_level > 0 || template_level > 0) )
|| capture_level > 0 || template_level > 0 )
{ {
if (currtok.Text[ 0 ] == '<') if (currtok.Text[ 0 ] == '<')
++ template_level; ++ template_level;
@ -2867,7 +2872,7 @@ CodePreprocessCond parse_preprocess_cond()
CodePreprocessCond CodePreprocessCond
cond = (CodePreprocessCond) make_code(); cond = (CodePreprocessCond) make_code();
cond->Type = scast(CodeT, currtok.Type - (ETokType::Preprocess_If - ECode::Preprocess_If) ); cond->Type = scast(CodeT, currtok.Type - (s32(ETokType::Preprocess_If) - s32(ECode::Preprocess_If)) );
eat( currtok.Type ); eat( currtok.Type );
// #<Conditional> // #<Conditional>
@ -3241,6 +3246,8 @@ CodeVar parse_variable_declaration_list()
break; break;
} }
eat(currtok.Type);
if ( specifiers ) if ( specifiers )
specifiers.append( spec ); specifiers.append( spec );
else else
@ -3642,6 +3649,13 @@ CodeEnum parse_enum( bool inplace_def )
// <Name> = <Expression> <Macro>, // <Name> = <Expression> <Macro>,
} }
// Consume inline comments
if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line )
{
eat( TokType::Comment );
// <Name> = <Expression> <Macro>, // <Inline Comment>
}
entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text; entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text;
member = untyped_str( entry ); member = untyped_str( entry );
@ -4385,10 +4399,13 @@ CodeType parse_type( bool from_template, bool* typedef_is_function )
else if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct else if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct
|| currtok.Type == TokType::Decl_Union ) || currtok.Type == TokType::Decl_Union )
{ {
Token fwd_key = currtok;
eat( currtok.Type ); eat( currtok.Type );
// <Attributes> <Specifiers> <class, enum, struct, union> // <Attributes> <Specifiers> <class, enum, struct, union>
name = parse_identifier(); name = parse_identifier();
fwd_key.Length = sptr(name.Text + name.Length) - sptr(fwd_key.Text);
name = fwd_key;
// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text; // name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text;
// eat( TokType::Identifier ); // eat( TokType::Identifier );

View File

@ -155,7 +155,7 @@ struct Array
{ {
Header& header = * get_header(); Header& header = * get_header();
if ( begin < 0 || end >= header.Num ) if ( begin < 0 || end > header.Num )
return false; return false;
for ( sw idx = begin; idx < end; idx++ ) for ( sw idx = begin; idx < end; idx++ )
@ -312,14 +312,12 @@ struct HashTable
Type Value; Type Value;
}; };
static constexpr f32 CriticalLoadScale = 0.7f;
static static
HashTable init( AllocatorInfo allocator ) HashTable init( AllocatorInfo allocator )
{ {
HashTable<Type> result = { { nullptr }, { nullptr } }; HashTable<Type> result = init_reserve(allocator, 8);
result.Hashes = Array<sw>::init( allocator );
result.Entries = Array<Entry>::init( allocator );
return result; return result;
} }
@ -330,19 +328,17 @@ struct HashTable
result.Hashes = Array<sw>::init_reserve( allocator, num ); result.Hashes = Array<sw>::init_reserve( allocator, num );
result.Hashes.get_header()->Num = num; result.Hashes.get_header()->Num = num;
result.Hashes.resize( num );
result.Hashes.fill( 0, num, -1);
result.Entries = Array<Entry>::init_reserve( allocator, num ); result.Entries = Array<Entry>::init_reserve( allocator, num );
return result; return result;
} }
void clear( void ) void clear( void )
{ {
for ( sw idx = 0; idx < Hashes.num(); idx++ )
Hashes[ idx ] = -1;
Hashes.clear();
Entries.clear(); Entries.clear();
Hashes.fill( 0, Hashes.num(), -1);
} }
void destroy( void ) void destroy( void )
@ -395,32 +391,19 @@ struct HashTable
void rehash( sw new_num ) void rehash( sw new_num )
{ {
sw idx;
sw last_added_index; sw last_added_index;
HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num ); HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
for ( sw idx = 0; idx < Entries.num(); ++idx )
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; FindResult find_result;
if ( new_ht.Hashes.num() == 0 ) Entry& entry = Entries[ idx ];
new_ht.grow();
entry = Entries[ idx ];
find_result = new_ht.find( entry.Key ); find_result = new_ht.find( entry.Key );
last_added_index = new_ht.add_entry( entry.Key ); last_added_index = new_ht.add_entry( entry.Key );
if ( find_result.PrevIndex < 0 ) if ( find_result.PrevIndex < 0 )
new_ht.Hashes[ find_result.HashIndex ] = last_added_index; new_ht.Hashes[ find_result.HashIndex ] = last_added_index;
else else
new_ht.Entries[ find_result.PrevIndex ].Next = last_added_index; new_ht.Entries[ find_result.PrevIndex ].Next = last_added_index;
@ -478,11 +461,10 @@ struct HashTable
sw idx; sw idx;
FindResult find_result; FindResult find_result;
if ( Hashes.num() == 0 ) if ( full() )
grow(); grow();
find_result = find( key ); find_result = find( key );
if ( find_result.EntryIndex >= 0 ) if ( find_result.EntryIndex >= 0 )
{ {
idx = find_result.EntryIndex; idx = find_result.EntryIndex;
@ -555,7 +537,9 @@ protected:
b32 full() b32 full()
{ {
return 0.75f * Hashes.num() < Entries.num(); uw critical_load = uw( CriticalLoadScale * f32(Hashes.num()) );
b32 result = Entries.num() > critical_load;
return result;
} }
}; };

View File

@ -11,14 +11,12 @@ struct StrC
sw Len; sw Len;
char const* Ptr; char const* Ptr;
operator char const* () const operator char const* () const { return Ptr; }
{ char const& operator[]( sw index ) const { return Ptr[index]; }
return Ptr;
}
}; };
#define cast_to_strc( str ) * rcast( StrC*, str - sizeof(sw) ) #define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(sw) )
#define txt( text ) StrC { sizeof( text ) - 1, text } #define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
StrC to_str( char const* str ) StrC to_str( char const* str )
{ {
@ -99,6 +97,19 @@ struct String
return true; return true;
} }
static
bool are_equal( String lhs, StrC rhs )
{
if ( lhs.length() != (rhs.Len) )
return false;
for ( sw idx = 0; idx < lhs.length(); ++idx )
if ( lhs[idx] != rhs[idx] )
return false;
return true;
}
bool make_space_for( char const* str, sw add_len ); bool make_space_for( char const* str, sw add_len );
bool append( char c ) bool append( char c )
@ -197,6 +208,24 @@ struct String
return header.Length; return header.Length;
} }
b32 starts_with( StrC substring ) const
{
if (substring.Len > length())
return false;
b32 result = str_compare(Data, substring.Ptr, substring.Len ) == 0;
return result;
}
b32 starts_with( String substring ) const
{
if (substring.length() > length())
return false;
b32 result = str_compare(Data, substring, substring.length() - 1 ) == 0;
return result;
}
void skip_line() void skip_line()
{ {
#define current (*scanner) #define current (*scanner)

View File

@ -360,10 +360,9 @@ CodeBody gen_ast_inlines()
{ {
if ( ast == nullptr || other.ast == nullptr ) if ( ast == nullptr || other.ast == nullptr )
{ {
log_failure("Code::is_equal: Cannot compare code, AST is null!"); // Just check if they're both null.
return false; return rcast(AST*, ast) == other.ast;
} }
return rcast(AST*, ast)->is_equal( other.ast ); return rcast(AST*, ast)->is_equal( other.ast );
} }
bool <typename>::is_valid() bool <typename>::is_valid()

View File

@ -1,6 +1,7 @@
#if __clang__ #if __clang__
# pragma clang diagnostic push # pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunused-const-variable" # pragma clang diagnostic ignored "-Wunused-const-variable"
# pragma clang diagnostic ignored "-Wunused-but-set-variable"
# pragma clang diagnostic ignored "-Wswitch" # pragma clang diagnostic ignored "-Wswitch"
# pragma clang diagnostic ignored "-Wunused-variable" # pragma clang diagnostic ignored "-Wunused-variable"
# pragma clang diagnostic ignored "-Wunknown-pragmas" # pragma clang diagnostic ignored "-Wunknown-pragmas"

View File

@ -26,15 +26,21 @@ if ( -not(Test-Path $path_release_content) ) {
New-Item -ItemType Directory -Path $path_release_content New-Item -ItemType Directory -Path $path_release_content
} }
$license = Join-Path $path_root LICENSE $license = Join-Path $path_root LICENSE
$readme_root = Join-Path $path_root Readme.md $readme_root = Join-Path $path_root Readme.md
$readme_docs = Join-Path $path_docs Readme.md $readme_docs = Join-Path $path_docs Readme.md
$readme_parsing = Join-Path $path_docs Parsing.md $readme_ast_design = Join-Path $path_docs AST_Design.md
$readme_ast_types = Join-Path $path_docs AST_Types.md
$readme_parsing = Join-Path $path_docs Parsing.md
$readme_parser_algo = Join-Path $path_docs Parser_Algo.md
Copy-Item $license -Destination (Join-Path $path_release_content "LICENSE") Copy-Item $license -Destination (Join-Path $path_release_content "LICENSE")
Copy-Item $readme_root -Destination (Join-Path $path_release_content "Readme.md") Copy-Item $readme_root -Destination (Join-Path $path_release_content "Readme.md")
Copy-Item $readme_docs -Destination (Join-Path $path_release_content "Readme_Docs.md") Copy-Item $readme_docs -Destination (Join-Path $path_release_content "Readme_Docs.md")
Copy-Item $readme_parsing -Destination (Join-Path $path_release_content "Parsing.md") Copy-Item $readme_ast_design -Destination (Join-Path $path_release_content "AST_Design.md")
Copy-Item $readme_ast_types -Destination (Join-Path $path_release_content "AST_Types.md")
Copy-Item $readme_parsing -Destination (Join-Path $path_release_content "Parsing.md")
Copy-Item $readme_parser_algo -Destination (Join-Path $path_release_content "Parser_Algo.md")
# Singleheader # Singleheader
Copy-Item -Path $path_singleheader_gen\gen.hpp -Destination $path_release_content\gen.hpp Copy-Item -Path $path_singleheader_gen\gen.hpp -Destination $path_release_content\gen.hpp