Singleheader validation test got through ast reconstruction, failed to validate the reconstructed AST.

This commit is contained in:
Edward R. Gonzalez 2023-08-23 18:16:45 -04:00
parent 8635b0fd1b
commit a6766cf0b1
4 changed files with 535 additions and 553 deletions

View File

@ -351,7 +351,7 @@ String AST::to_string()
result.append_fmt( "%S)", Params->to_string() ); result.append_fmt( "%S)", Params->to_string() );
else else
result.append( "void)" ); result.append( ")" );
if ( Specs ) if ( Specs )
{ {
@ -390,7 +390,7 @@ String AST::to_string()
result.append_fmt( "%S)", Params->to_string() ); result.append_fmt( "%S)", Params->to_string() );
else else
result.append( "void)" ); result.append( ")" );
if ( Specs ) if ( Specs )
{ {
@ -447,7 +447,7 @@ String AST::to_string()
result.append_fmt( "%S)", Params->to_string() ); result.append_fmt( "%S)", Params->to_string() );
else else
result.append( "void)" ); result.append( ")" );
if ( Specs ) if ( Specs )
{ {
@ -485,7 +485,7 @@ String AST::to_string()
result.append_fmt( "%S)", Params->to_string() ); result.append_fmt( "%S)", Params->to_string() );
else else
result.append_fmt( "void)" ); result.append_fmt( ")" );
if ( Specs ) if ( Specs )
{ {
@ -930,15 +930,87 @@ bool AST::is_equal( AST* other )
AST nodes are compared with AST::is_equal. AST nodes are compared with AST::is_equal.
*/ */
if ( other == nullptr ) if ( other == nullptr )
{
log_fmt( "AST::is_equal: other is null\nAST: %S", debug_str() );
return false; return false;
}
if ( Type != other->Type ) if ( Type != other->Type )
{
log_fmt("AST::is_equal: Type check failure with other\nAST: %S\nOther: %S"
, debug_str()
, other->debug_str()
);
return false; return false;
}
switch ( Type ) switch ( Type )
{ {
using namespace ECode; using namespace ECode;
#define check_member_val( val ) \
if ( val != other->val ) \
{ \
log_fmt("AST::is_equal: Member - " #val "\n failed" \
"AST : %S\n" \
"Other: %S\n" \
"For val member: " #val \
, debug_str() \
, other->debug_str() \
); \
\
return false; \
}
#define check_member_str( str ) \
if ( str != other->str ) \
{ \
log_fmt("AST::is_equal: Member string check failure with other\n" \
"AST : %S\n" \
"Other: %S\n" \
"For str member: " #str \
, debug_str() \
, other->debug_str() \
); \
\
return false; \
}
#define check_member_ast( ast ) \
if ( ast ) \
{ \
if ( other->ast == nullptr ) \
{ \
log_fmt("AST::is_equal: Failed for member " #ast " other equivalent param is null\n" \
"AST : %S\n" \
"Other: %S\n" \
"For ast member: %S\n" \
, debug_str() \
, other->debug_str() \
, ast->debug_str() \
); \
\
return false; \
} \
\
if ( ! ast->is_equal( other->ast ) ) \
{ \
log_fmt( "AST::is_equal: Failed for " #ast"\n" \
"AST : %S\n" \
"Other: %S\n" \
"For ast member: %S\n" \
"other's ast member: %S\n" \
, debug_str() \
, other->debug_str() \
, ast->debug_str() \
, other->ast->debug_str() \
); \
} \
\
return false; \
}
case NewLine: case NewLine:
case Access_Public: case Access_Public:
case Access_Protected: case Access_Protected:
@ -952,29 +1024,20 @@ bool AST::is_equal( AST* other )
case PlatformAttributes: case PlatformAttributes:
case Untyped: case Untyped:
{ {
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr ) check_member_str( Content );
return false; check_member_ast( Prev );
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr ) check_member_ast( Next );
return false;
return Content == other->Content;
} }
case Class_Fwd: case Class_Fwd:
case Struct_Fwd: case Struct_Fwd:
{ {
if ( Name != other->Name ) check_member_str( Name );
return false; check_member_ast( ParentType );
if ( ParentType != other->ParentType ) check_member_val( ParentAccess );
return false; check_member_ast( Attributes );
if ( ParentAccess != other->ParentAccess ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -982,76 +1045,54 @@ bool AST::is_equal( AST* other )
case Class: case Class:
case Struct: case Struct:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( ParentType );
return false; check_member_val( ParentAccess );
if ( ParentType != other->ParentType ) check_member_ast( Attributes );
return false; check_member_ast( Body );
if ( ParentAccess != other->ParentAccess ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr )
return false;
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
return true; return true;
} }
case Constructor: case Constructor:
{ {
if ( InitializerList ? ! InitializerList->is_equal( other->InitializerList ) : other->InitializerList != nullptr ) check_member_ast( InitializerList );
return false; check_member_ast( Params );
if ( Params ? ! Params->is_equal( other->Params ) : other->Params != nullptr ) check_member_ast( Body );
return false; check_member_ast( Prev );
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr ) check_member_ast( Next );
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Constructor_Fwd: case Constructor_Fwd:
{ {
if ( InitializerList ? ! InitializerList->is_equal( other->InitializerList ) : other->InitializerList != nullptr ) check_member_ast( InitializerList );
return false; check_member_ast( Params );
if ( Params ? ! Params->is_equal( other->Params ) : other->Params != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Destructor: case Destructor:
{ {
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( Specs );
return false; check_member_ast( Body );
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Destructor_Fwd: case Destructor_Fwd:
{ {
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( Specs );
return false; check_member_ast( Prev );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr ) check_member_ast( Next );
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1059,20 +1100,13 @@ bool AST::is_equal( AST* other )
case Enum: case Enum:
case Enum_Class: case Enum_Class:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( Attributes );
return false; check_member_ast( UnderlyingType );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Body );
return false; check_member_ast( Prev );
if ( UnderlyingType ? ! UnderlyingType->is_equal( other->UnderlyingType ) : other->UnderlyingType != nullptr ) check_member_ast( Next );
return false;
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1080,122 +1114,82 @@ bool AST::is_equal( AST* other )
case Enum_Fwd: case Enum_Fwd:
case Enum_Class_Fwd: case Enum_Class_Fwd:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( Attributes );
return false; check_member_ast( UnderlyingType );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( UnderlyingType ? ! UnderlyingType->is_equal( other->UnderlyingType ) : other->UnderlyingType != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Extern_Linkage: case Extern_Linkage:
{ {
if ( Name != other->Name ) check_member_str( Name );
return false; check_member_ast( Body );
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Friend: case Friend:
{ {
if ( Name != other->Name ) check_member_str( Name );
return false; check_member_ast( Declaration );
if ( Declaration ? ! Declaration->is_equal( other->Declaration ) : other->Declaration != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Function: case Function:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( ReturnType );
return false; check_member_ast( Attributes );
if ( ReturnType ? ! ReturnType->is_equal( other->ReturnType ) : other->ReturnType != nullptr ) check_member_ast( Specs );
return false; check_member_ast( Params );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Body );
return false; check_member_ast( Prev );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( Next );
return false;
if ( Params ? ! Params->is_equal( other->Params ) : other->Params != nullptr )
return false;
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Function_Fwd: case Function_Fwd:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( ReturnType );
return false; check_member_ast( Attributes );
if ( ReturnType ? ! ReturnType->is_equal( other->ReturnType ) : other->ReturnType != nullptr ) check_member_ast( Specs );
return false; check_member_ast( Params );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr )
return false;
if ( Params ? ! Params->is_equal( other->Params ) : other->Params != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Module: case Module:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Namespace: case Namespace:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( Body );
return false; check_member_ast( Prev );
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr ) check_member_ast( Next );
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1203,24 +1197,15 @@ bool AST::is_equal( AST* other )
case Operator: case Operator:
case Operator_Member: case Operator_Member:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( ReturnType );
return false; check_member_ast( Attributes );
if ( ReturnType ? ! ReturnType->is_equal( other->ReturnType ) : other->ReturnType != nullptr ) check_member_ast( Specs );
return false; check_member_ast( Params );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Body );
return false; check_member_ast( Prev );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( Next );
return false;
if ( Params ? ! Params->is_equal( other->Params ) : other->Params != nullptr )
return false;
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1228,56 +1213,37 @@ bool AST::is_equal( AST* other )
case Operator_Fwd: case Operator_Fwd:
case Operator_Member_Fwd: case Operator_Member_Fwd:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( ReturnType );
return false; check_member_ast( Attributes );
if ( ReturnType ? ! ReturnType->is_equal( other->ReturnType ) : other->ReturnType != nullptr ) check_member_ast( Specs );
return false; check_member_ast( Params );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr )
return false;
if ( Params ? ! Params->is_equal( other->Params ) : other->Params != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Operator_Cast: case Operator_Cast:
{ {
if ( Name != other->Name ) check_member_str( Name );
return false; check_member_ast( Specs );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( ValueType );
return false; check_member_ast( Body );
if ( ValueType ? ! ValueType->is_equal( other->ValueType ) : other->ValueType != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Operator_Cast_Fwd: case Operator_Cast_Fwd:
{ {
if ( Name != other->Name ) check_member_str( Name );
return false; check_member_ast( Specs );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( ValueType );
return false; check_member_ast( Prev );
if ( ValueType ? ! ValueType->is_equal( other->ValueType ) : other->ValueType != nullptr ) check_member_ast( Next );
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1286,15 +1252,42 @@ bool AST::is_equal( AST* other )
{ {
if ( NumEntries > 1 ) if ( NumEntries > 1 )
{ {
if ( NumEntries != other->NumEntries ) check_member_val( NumEntries );
return false;
AST* curr = this; AST* curr = this;
AST* curr_other = other; AST* curr_other = other;
while ( curr != nullptr ) while ( curr != nullptr )
{ {
if ( ! curr->is_equal( curr_other ) ) if ( curr )
{
if ( curr_other == nullptr )
{
log_fmt("AST::is_equal: Failed for parameter, other equivalent param is null\n"
"AST : %S\n"
"Other: %S\n"
"For ast member: %S\n"
, curr->debug_str()
);
return false; return false;
}
if ( ! curr->is_equal( curr_other ) )
{
log_fmt( "AST::is_equal: Failed for parameter\n"
"AST : %S\n"
"Other: %S\n"
"For ast member: %S\n"
"other's ast member: %S\n"
, debug_str()
, other->debug_str()
, curr->debug_str()
, curr_other->debug_str()
);
}
return false;
}
curr = curr->Next; curr = curr->Next;
curr_other = curr_other->Next; curr_other = curr_other->Next;
@ -1303,28 +1296,20 @@ bool AST::is_equal( AST* other )
return true; return true;
} }
if ( Name != other->Name ) check_member_str( Name );
return false; check_member_ast( ValueType );
if ( ValueType ? ! ValueType->is_equal( other->ValueType ) : other->ValueType != nullptr ) check_member_ast( Value );
return false; check_member_ast( ArrExpr );
if ( Value ? ! Value->is_equal( other->Value ) : other->Value != nullptr )
return false;
if ( ArrExpr ? ! ArrExpr->is_equal( other->ArrExpr ) : other->ArrExpr != nullptr )
return false;
return true; return true;
} }
case Preprocess_Define: case Preprocess_Define:
{ {
if ( Name != other->Name ) check_member_str( Name );
return false; check_member_str( Content );
if ( Content != other->Content ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1334,12 +1319,9 @@ bool AST::is_equal( AST* other )
case Preprocess_IfNotDef: case Preprocess_IfNotDef:
case Preprocess_ElIf: case Preprocess_ElIf:
{ {
if ( Content != other->Content ) check_member_str( Content );
return false; check_member_ast( Prev );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr ) check_member_ast( Next );
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1347,100 +1329,70 @@ bool AST::is_equal( AST* other )
case Preprocess_Include: case Preprocess_Include:
case Preprocess_Pragma: case Preprocess_Pragma:
{ {
if ( Content != other->Content ) check_member_str( Content );
return false; check_member_ast( Prev );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr ) check_member_ast( Next );
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Specifiers: case Specifiers:
{ {
if ( NumEntries != other->NumEntries ) check_member_val( NumEntries );
return false; check_member_str( Name );
if ( Name != other->Name )
return false;
for ( s32 idx = 0; idx < NumEntries; ++idx ) for ( s32 idx = 0; idx < NumEntries; ++idx )
{ {
if ( ArrSpecs[ idx ] != other->ArrSpecs[ idx ] ) check_member_val( ArrSpecs[ idx ] );
return false;
} }
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Template: case Template:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( Params );
return false; check_member_ast( Declaration );
if ( Params ? ! Params->is_equal( other->Params ) : other->Params != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Declaration ? ! Declaration->is_equal( other->Declaration ) : other->Declaration != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Typedef: case Typedef:
{ {
if ( IsFunction != other->IsFunction ) check_member_val( IsFunction );
return false; check_member_val( ModuleFlags );
if ( ModuleFlags != other->ModuleFlags ) check_member_str( Name );
return false; check_member_ast( Specs );
if ( Name != other->Name ) check_member_ast( UnderlyingType );
return false; check_member_ast( Prev );
if ( UnderlyingType != other->UnderlyingType ) check_member_ast( Next );
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Typename: case Typename:
{ {
if ( Name != other->Name ) check_member_val( IsParamPack );
return false; check_member_str( Name );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( Specs );
return false; check_member_ast( ArrExpr );
if ( ArrExpr ? ! ArrExpr->is_equal( other->ArrExpr ) : other->ArrExpr != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Union: case Union:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( Attributes );
return false; check_member_ast( Body );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( Body ? ! Body->is_equal( other->Body ) : other->Body != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1448,42 +1400,27 @@ bool AST::is_equal( AST* other )
case Using: case Using:
case Using_Namespace: case Using_Namespace:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( UnderlyingType );
return false; check_member_ast( Attributes );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Prev );
return false; check_member_ast( Next );
if ( UnderlyingType ? ! UnderlyingType->is_equal( other->UnderlyingType ) : other->UnderlyingType != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
case Variable: case Variable:
{ {
if ( ModuleFlags != other->ModuleFlags ) check_member_val( ModuleFlags );
return false; check_member_str( Name );
if ( Name != other->Name ) check_member_ast( ValueType );
return false; check_member_ast( BitfieldSize );
if ( Attributes ? ! Attributes->is_equal( other->Attributes ) : other->Attributes != nullptr ) check_member_ast( Value );
return false; check_member_ast( Attributes );
if ( Specs ? ! Specs->is_equal( other->Specs ) : other->Specs != nullptr ) check_member_ast( Specs );
return false; check_member_ast( Prev );
if ( ValueType ? ! ValueType->is_equal( other->ValueType ) : other->ValueType != nullptr ) check_member_ast( Next );
return false;
if ( BitfieldSize ? ! BitfieldSize->is_equal( other->BitfieldSize ) : other->BitfieldSize != nullptr )
return false;
if ( Value ? ! Value->is_equal( other->Value ) : other->Value != nullptr )
return false;
if ( Prev ? ! Prev->is_equal( other->Prev ) : other->Prev != nullptr )
return false;
if ( Next ? ! Next->is_equal( other->Next ) : other->Next != nullptr )
return false;
return true; return true;
} }
@ -1496,21 +1433,41 @@ bool AST::is_equal( AST* other )
case Struct_Body: case Struct_Body:
case Union_Body: case Union_Body:
{ {
if ( NumEntries != other->NumEntries ) check_member_val( NumEntries );
return false; check_member_ast( Front );
check_member_ast( Back );
if ( Front != other->Front )
return false;
if ( Back != other->Back )
return false;
AST* curr = Front; AST* curr = Front;
AST* curr_other = other->Front; AST* curr_other = other->Front;
while ( curr != nullptr ) while ( curr != nullptr )
{ {
if ( ! curr->is_equal( curr_other ) ) if ( curr_other == nullptr )
{
log_fmt("AST::is_equal: Failed for body, other equivalent param is null\n"
"AST : %S\n"
"Other: %S\n"
"For ast member: %S\n"
, curr->debug_str()
);
return false; return false;
}
if ( ! curr->is_equal( curr_other ) )
{
log_fmt( "AST::is_equal: Failed for body\n"
"AST : %S\n"
"Other: %S\n"
"For ast member: %S\n"
"other's ast member: %S\n"
, debug_str()
, other->debug_str()
, curr->debug_str()
, curr_other->debug_str()
);
return false;
}
curr = curr->Next; curr = curr->Next;
curr_other = curr_other->Next; curr_other = curr_other->Next;
@ -1518,6 +1475,10 @@ bool AST::is_equal( AST* other )
return true; return true;
} }
#undef check_member_val
#undef check_member_str
#undef check_member_ast
} }
return true; return true;

File diff suppressed because it is too large Load Diff

View File

@ -149,10 +149,17 @@ namespace Parser
{ {
node->Prev = Scope; node->Prev = Scope;
Scope = node; Scope = node;
#if 0 && Build_Debug
log_fmt("\tEntering Context: %.*s\n", Scope->ProcName.Len, Scope->ProcName.Ptr );
#endif
} }
void pop() void pop()
{ {
#if 0 && Build_Debug
log_fmt("\tPopping Context: %.*s\n", Scope->ProcName.Len, Scope->ProcName.Ptr );
#endif
Scope = Scope->Prev; Scope = Scope->Prev;
} }
@ -234,6 +241,10 @@ namespace Parser
return false; return false;
} }
#if 0 && Build_Debug
log_fmt("Ate: %S\n", Arr[Idx].to_string() );
#endif
Idx++; Idx++;
return true; return true;
} }
@ -1027,8 +1038,18 @@ namespace Parser
} }
else else
{ {
String context_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 100, left ), scanner ); s32 start = max( 0, Tokens.num() - 100 );
log_fmt("\n%d\n", start);
for ( s32 idx = start; idx < Tokens.num(); idx++ )
{
log_fmt( "Token %d Type: %s : %.*s\n"
, idx
, ETokType::to_str( Tokens[ idx ].Type ).Ptr
, Tokens[ idx ].Length, Tokens[ idx ].Text
);
}
String context_str = String::fmt_buf( GlobalAllocator, "%.*s", min( 100, left ), scanner );
log_failure( "Failed to lex token '%c' (%d, %d)\n%s", current, line, column, context_str ); log_failure( "Failed to lex token '%c' (%d, %d)\n%s", current, line, column, context_str );
// Skip to next whitespace since we can't know if anything else is valid until then. // Skip to next whitespace since we can't know if anything else is valid until then.
@ -4761,7 +4782,7 @@ CodeUnion parse_union( bool inplace_def )
while ( ! check_noskip( TokType::BraceCurly_Close ) ) while ( ! check_noskip( TokType::BraceCurly_Close ) )
{ {
if ( currtok.Type == TokType::Preprocess_Hash ) if ( currtok_noskip.Type == TokType::Preprocess_Hash )
eat( TokType::Preprocess_Hash ); eat( TokType::Preprocess_Hash );
Code member = { nullptr }; Code member = { nullptr };

View File

@ -40,9 +40,9 @@ void check_singleheader_ast()
time_start = time_rel_ms(); time_start = time_rel_ms();
if ( ast.is_equal( ast_gen ) ) if ( ast.is_equal( ast_gen ) )
log_fmt( "Passed!: AST passed validation!\n" ); log_fmt( "\nPassed!: AST passed validation!\n" );
else else
log_fmt( "Failed: AST did not pass validation\n" ); log_fmt( "\nFailed: AST did not pass validation\n" );
log_fmt( "Time taken: %llu ms\n", time_rel_ms() - time_start ); log_fmt( "Time taken: %llu ms\n", time_rel_ms() - time_start );