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
**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.
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 )
result.append_fmt( "; // %S\n", ast->InlineCmt->Content );
else
result.append( ";" );
result.append( ";\n" );
}
String CodeClass::to_string()
@ -183,7 +183,7 @@ void CodeClass::to_string_def( String& result )
while ( interface )
{
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 )
@ -480,6 +480,7 @@ void CodeFn::to_string_def( String& result )
if ( ast->Attributes )
result.append_fmt( " %S ", ast->Attributes.to_string() );
b32 prefix_specs = false;
if ( 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 );
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" );
if ( ast->ReturnType )
@ -530,19 +533,22 @@ void CodeFn::to_string_fwd( String& result )
if ( ast->Attributes )
result.append_fmt( "%S ", ast->Attributes.to_string() );
b32 prefix_specs = false;
if ( 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 );
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" );
}
@ -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;" );
else if (ast->Body)
result.append_fmt( " = %S;", ast->Body.to_string() );
@ -983,7 +989,7 @@ void CodeStruct::to_string_def( String& result )
while ( interface )
{
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 )
@ -1247,7 +1253,7 @@ void CodeVar::to_string( String& result )
result.append( ast->Name );
if ( ast->ValueType->ArrExpr )
if ( ast->ValueType && ast->ValueType->ArrExpr )
{
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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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 )
{
log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
return false;
return rcast( AST*, ast ) == 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->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_protected = make_code();
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_public = make_code();
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();
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 Array<Token> Tokens;
@ -374,6 +374,16 @@ s32 lex_preprocessor_directive(
move_forward();
preprocess_content.Length++;
if ( current == '\r' && scanner[1] == '\n' )
{
move_forward();
move_forward();
}
else if ( current == '\n' )
{
move_forward();
}
Tokens.append( preprocess_content );
return Lex_Continue; // Skip found token, its all handled here.
}
@ -576,7 +586,7 @@ TokArray lex( StrC content )
{
s32 length = 0;
char const* scanner = entry.Data;
while ( entry.length() > length && char_is_alphanumeric( *scanner ) || *scanner == '_' )
while ( entry.length() > length && (char_is_alphanumeric( *scanner ) || *scanner == '_') )
{
scanner++;
length ++;

View File

@ -136,8 +136,8 @@ void init()
, ( LexAllocator_Size - sizeof( Array<Token>::Header ) ) / sizeof(Token)
);
defines_map_arena = Arena_128KB::init();
defines = HashTable<StrC>::init( defines_map_arena );
defines_map_arena = Arena_256KB::init();
defines = HashTable<StrC>::init_reserve( defines_map_arena, 256 );
}
internal
@ -481,7 +481,7 @@ Code parse_array_decl()
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 );
// []
@ -574,6 +574,10 @@ Code parse_assignment_expression()
s32 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)
level++;
else if (currtok.Type == TokType::Capture_End)
@ -1539,18 +1543,18 @@ Code parse_function_body()
result->Type = Function_Body;
// TODO : Support actual parsing of function body
Token start = currtok;
Token start = currtok_noskip;
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++;
else if ( currtok.Type == TokType::BraceCurly_Close && level > 0 )
else if ( currtok_noskip.Type == TokType::BraceCurly_Close && level > 0 )
level--;
eat( currtok.Type );
eat( currtok_noskip.Type );
}
Token previous = prevtok;
@ -1751,6 +1755,7 @@ CodeBody parse_global_nspace( CodeT which )
case TokType::Spec_Internal_Linkage:
case TokType::Spec_NeverInline:
case TokType::Spec_Static:
case TokType::Spec_ThreadLocal:
{
SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
s32 NumSpecifiers = 0;
@ -1774,6 +1779,7 @@ CodeBody parse_global_nspace( CodeT which )
case ESpecifier::NeverInline:
case ESpecifier::Static:
case ESpecifier::Volatile:
case ESpecifier::Thread_Local:
break;
case ESpecifier::Consteval:
@ -2294,7 +2300,7 @@ CodeOperator parse_operator_after_ret_type(
case '<':
{
if ( currtok.Text[1] == '=' )
op = LEqual;
op = LesserEqual;
else if ( currtok.Text[1] == '<' )
{
@ -2683,7 +2689,7 @@ CodeParam parse_params( bool use_template_capture )
s32 capture_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 ] == '<')
++ template_level;
@ -2789,8 +2795,7 @@ CodeParam parse_params( bool use_template_capture )
while ( left
&& currtok.Type != TokType::Comma
&& template_level >= 0
&& CheckEndParams()
|| capture_level > 0 || template_level > 0 )
&& (CheckEndParams() || capture_level > 0 || template_level > 0) )
{
if (currtok.Text[ 0 ] == '<')
++ template_level;
@ -2867,7 +2872,7 @@ CodePreprocessCond parse_preprocess_cond()
CodePreprocessCond
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 );
// #<Conditional>
@ -3241,6 +3246,8 @@ CodeVar parse_variable_declaration_list()
break;
}
eat(currtok.Type);
if ( specifiers )
specifiers.append( spec );
else
@ -3642,6 +3649,13 @@ CodeEnum parse_enum( bool inplace_def )
// <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;
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
|| currtok.Type == TokType::Decl_Union )
{
Token fwd_key = currtok;
eat( currtok.Type );
// <Attributes> <Specifiers> <class, enum, struct, union>
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;
// eat( TokType::Identifier );

View File

@ -155,7 +155,7 @@ struct Array
{
Header& header = * get_header();
if ( begin < 0 || end >= header.Num )
if ( begin < 0 || end > header.Num )
return false;
for ( sw idx = begin; idx < end; idx++ )
@ -312,14 +312,12 @@ struct HashTable
Type Value;
};
static constexpr f32 CriticalLoadScale = 0.7f;
static
HashTable init( AllocatorInfo allocator )
{
HashTable<Type> result = { { nullptr }, { nullptr } };
result.Hashes = Array<sw>::init( allocator );
result.Entries = Array<Entry>::init( allocator );
HashTable<Type> result = init_reserve(allocator, 8);
return result;
}
@ -330,19 +328,17 @@ struct HashTable
result.Hashes = Array<sw>::init_reserve( allocator, 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 );
return result;
}
void clear( void )
{
for ( sw idx = 0; idx < Hashes.num(); idx++ )
Hashes[ idx ] = -1;
Hashes.clear();
Entries.clear();
Hashes.fill( 0, Hashes.num(), -1);
}
void destroy( void )
@ -395,32 +391,19 @@ struct HashTable
void rehash( sw new_num )
{
sw idx;
sw last_added_index;
HashTable<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 )
for ( sw 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 ];
Entry& 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;
@ -478,11 +461,10 @@ struct HashTable
sw idx;
FindResult find_result;
if ( Hashes.num() == 0 )
if ( full() )
grow();
find_result = find( key );
if ( find_result.EntryIndex >= 0 )
{
idx = find_result.EntryIndex;
@ -555,7 +537,9 @@ protected:
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;
char const* Ptr;
operator char const* () const
{
return Ptr;
}
operator char const* () const { return Ptr; }
char const& operator[]( sw index ) const { return Ptr[index]; }
};
#define cast_to_strc( str ) * rcast( StrC*, str - sizeof(sw) )
#define txt( text ) StrC { sizeof( text ) - 1, text }
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(sw) )
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
StrC to_str( char const* str )
{
@ -99,6 +97,19 @@ struct String
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 append( char c )
@ -197,6 +208,24 @@ struct String
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()
{
#define current (*scanner)

View File

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

View File

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

View File

@ -29,12 +29,18 @@ if ( -not(Test-Path $path_release_content) ) {
$license = Join-Path $path_root LICENSE
$readme_root = Join-Path $path_root Readme.md
$readme_docs = Join-Path $path_docs Readme.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 $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_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
Copy-Item -Path $path_singleheader_gen\gen.hpp -Destination $path_release_content\gen.hpp