mirror of
https://github.com/Ed94/gencpp.git
synced 2025-06-15 11:11:46 -07:00
Improved parser scope errors.
Added the caret for indicating where the error is.
This commit is contained in:
@ -33,8 +33,8 @@ namespace Parser
|
||||
Entry( BraceSquare_Close, "]" ) \
|
||||
Entry( Capture_Start, "(" ) \
|
||||
Entry( Capture_End, ")" ) \
|
||||
Entry( Comment, "__comment__" ) \
|
||||
Entry( Char, "__char__" ) \
|
||||
Entry( Comment, "comment" ) \
|
||||
Entry( Char, "character" ) \
|
||||
Entry( Comma, "," ) \
|
||||
Entry( Decl_Class, "class" ) \
|
||||
Entry( Decl_GNU_Attribute, "__attribute__" ) \
|
||||
@ -50,7 +50,7 @@ namespace Parser
|
||||
Entry( Decl_Typedef, "typedef" ) \
|
||||
Entry( Decl_Using, "using" ) \
|
||||
Entry( Decl_Union, "union" ) \
|
||||
Entry( Identifier, "__identifier__" ) \
|
||||
Entry( Identifier, "identifier" ) \
|
||||
Entry( Module_Import, "import" ) \
|
||||
Entry( Module_Export, "export" ) \
|
||||
Entry( Number, "number" ) \
|
||||
@ -80,7 +80,7 @@ namespace Parser
|
||||
Entry( Spec_Volatile, "volatile") \
|
||||
Entry( Star, "*" ) \
|
||||
Entry( Statement_End, ";" ) \
|
||||
Entry( String, "__string__" ) \
|
||||
Entry( String, "string" ) \
|
||||
Entry( Type_Unsigned, "unsigned" ) \
|
||||
Entry( Type_Signed, "signed" ) \
|
||||
Entry( Type_Short, "short" ) \
|
||||
|
@ -82,6 +82,7 @@ namespace Parser
|
||||
{
|
||||
StackNode* Prev;
|
||||
|
||||
Token Start;
|
||||
Token Name; // The name of the AST node (if parsed)
|
||||
StrC ProcName; // The name of the procedure
|
||||
};
|
||||
@ -91,44 +92,6 @@ namespace Parser
|
||||
TokArray Tokens;
|
||||
StackNode* Scope;
|
||||
|
||||
String to_string()
|
||||
{
|
||||
String result = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
|
||||
result.append_fmt("\tContext:\n");
|
||||
|
||||
Token last_valid = Tokens.Idx >= Tokens.Arr.num() ? Tokens.Arr[Tokens.Arr.num() -1] : Tokens.current();
|
||||
|
||||
char const* current = last_valid.Text;
|
||||
sptr length = last_valid.Length;
|
||||
while ( current <= Tokens.Arr.back().Text && *current != '\n' )
|
||||
{
|
||||
current++;
|
||||
length++;
|
||||
}
|
||||
|
||||
String line = String::make( GlobalAllocator, { length, last_valid.Text } );
|
||||
result.append_fmt("\t(%d, %d): %s\n", last_valid.Line, last_valid.Column, line );
|
||||
line.free();
|
||||
|
||||
StackNode* curr_scope = Scope;
|
||||
do
|
||||
{
|
||||
if ( curr_scope->Name )
|
||||
{
|
||||
result.append_fmt("\tProcedure: %s, AST Name: %s\n", curr_scope->ProcName.Ptr, (StrC)curr_scope->Name );
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append_fmt("\tProcedure: %s\n", curr_scope->ProcName.Ptr );
|
||||
}
|
||||
|
||||
curr_scope = curr_scope->Prev;
|
||||
}
|
||||
while ( curr_scope );
|
||||
return result;
|
||||
}
|
||||
|
||||
void push( StackNode* node )
|
||||
{
|
||||
node->Prev = Scope;
|
||||
@ -139,6 +102,51 @@ namespace Parser
|
||||
{
|
||||
Scope = Scope->Prev;
|
||||
}
|
||||
|
||||
String to_string()
|
||||
{
|
||||
String result = String::make_reserve( GlobalAllocator, kilobytes(4) );
|
||||
|
||||
Token scope_start = Scope->Start;
|
||||
Token last_valid = Tokens.Idx >= Tokens.Arr.num() ? Tokens.Arr[Tokens.Arr.num() -1] : Tokens.current();
|
||||
|
||||
sptr length = scope_start.Length;
|
||||
char const* current = scope_start.Text + length;
|
||||
while ( current <= Tokens.Arr.back().Text && *current != '\n' && length < 74 )
|
||||
{
|
||||
current++;
|
||||
length++;
|
||||
}
|
||||
|
||||
String line = String::make( GlobalAllocator, { length, scope_start.Text } );
|
||||
result.append_fmt("\tScope: %s\n", line );
|
||||
line.free();
|
||||
|
||||
sptr dist = (sptr)last_valid.Text - (sptr)scope_start.Text;
|
||||
sptr length_from_err = dist;
|
||||
String line_from_err = String::make( GlobalAllocator, { length_from_err, last_valid.Text } );
|
||||
|
||||
result.append_fmt("\t(%d, %d):%*c\n", last_valid.Line, last_valid.Column, length_from_err, '^' );
|
||||
|
||||
StackNode* curr_scope = Scope;
|
||||
s32 level = 0;
|
||||
do
|
||||
{
|
||||
if ( curr_scope->Name )
|
||||
{
|
||||
result.append_fmt("\t%d: %s, AST Name: %s\n", level, curr_scope->ProcName.Ptr, (StrC)curr_scope->Name );
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append_fmt("\t%d: %s\n", level, curr_scope->ProcName.Ptr );
|
||||
}
|
||||
|
||||
curr_scope = curr_scope->Prev;
|
||||
level++;
|
||||
}
|
||||
while ( curr_scope );
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
global ParseContext Context;
|
||||
@ -155,7 +163,7 @@ namespace Parser
|
||||
{
|
||||
String token_str = String::make( GlobalAllocator, { Arr[Idx].Length, Arr[Idx].Text } );
|
||||
|
||||
log_failure( "Parse Error, TokArray::eat, Expected: %s, not %s (%d, %d)`\n%s", ETokType::to_str(type), token_str, Context.to_string() );
|
||||
log_failure( "Parse Error, TokArray::eat, Expected: %s, not '%s' (%d, %d)`\n%s", ETokType::to_str(type), token_str, current().Line, current().Column, Context.to_string() );
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -727,7 +735,7 @@ if ( def.Ptr == nullptr )
|
||||
# define check( Type_ ) ( left && currtok.Type == Type_ )
|
||||
|
||||
# define push_scope() \
|
||||
StackNode scope { nullptr, NullToken, txt_StrC( __func__ ) }; \
|
||||
StackNode scope { nullptr, currtok, NullToken, txt_StrC( __func__ ) }; \
|
||||
Context.push( & scope )
|
||||
|
||||
#pragma endregion Helper Macros
|
||||
@ -1796,8 +1804,7 @@ Code parse_class_struct( Parser::TokType which )
|
||||
|
||||
attributes = parse_attributes();
|
||||
|
||||
if ( check( TokType::Identifier ) )
|
||||
name = parse_identifier();
|
||||
name = parse_identifier();
|
||||
|
||||
local_persist
|
||||
char interface_arr_mem[ kilobytes(4) ] {0};
|
||||
@ -2649,7 +2656,10 @@ CodeStruct parse_struct( StrC def )
|
||||
return CodeInvalid;
|
||||
|
||||
Context.Tokens = toks;
|
||||
return (CodeStruct) parse_class_struct( TokType::Decl_Struct );
|
||||
push_scope();
|
||||
CodeStruct result = (CodeStruct) parse_class_struct( TokType::Decl_Struct );
|
||||
Context.pop();
|
||||
return result;
|
||||
}
|
||||
|
||||
internal
|
||||
|
Reference in New Issue
Block a user