mirror of
https://github.com/Ed94/metadesk.git
synced 2026-08-07 16:18:49 +00:00
Pipe error location through error->node.
This commit is contained in:
+1
-1
@@ -301,6 +301,7 @@ typedef enum MD_NodeKind
|
|||||||
MD_NodeKind_Namespace,
|
MD_NodeKind_Namespace,
|
||||||
MD_NodeKind_Label,
|
MD_NodeKind_Label,
|
||||||
MD_NodeKind_Tag,
|
MD_NodeKind_Tag,
|
||||||
|
MD_NodeKind_ErrorMarker,
|
||||||
MD_NodeKind_MAX,
|
MD_NodeKind_MAX,
|
||||||
}
|
}
|
||||||
MD_NodeKind;
|
MD_NodeKind;
|
||||||
@@ -487,7 +488,6 @@ struct MD_Error
|
|||||||
MD_String8 filename;
|
MD_String8 filename;
|
||||||
MD_Node *node;
|
MD_Node *node;
|
||||||
MD_b32 catastrophic;
|
MD_b32 catastrophic;
|
||||||
MD_CodeLoc location;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct MD_ParseCtx MD_ParseCtx;
|
typedef struct MD_ParseCtx MD_ParseCtx;
|
||||||
|
|||||||
+23
-25
@@ -1546,17 +1546,14 @@ _MD_CodeLocFromFileOffset(MD_String8 filename, MD_u8 * file_contents, MD_u8 *at)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MD_PRIVATE_FUNCTION_IMPL void
|
MD_PRIVATE_FUNCTION_IMPL void
|
||||||
_MD_Error(MD_ParseCtx *ctx, MD_Node *node, MD_u8 *at, MD_b32 catastrophic, char *fmt, ...)
|
_MD_Error(MD_ParseCtx *ctx, MD_Node *node, MD_b32 catastrophic, char *fmt, ...)
|
||||||
{
|
{
|
||||||
MD_CodeLoc error_loc = _MD_CodeLocFromFileOffset(ctx->filename, ctx->file_contents.str, at);
|
// NOTE(mal): Sort errors. Traverse the whole list assuming it will be short.
|
||||||
|
// The alternative is to drop a prev pointer into MD_Error and traverse it backwards
|
||||||
// NOTE(mal): Sort errors. We traverse the whole list assuming there won't be many of them.
|
|
||||||
// We could drop a prev pointer into MD_Error and start from ctx->last_error to make it faster
|
|
||||||
MD_Error *prev_error = 0;
|
MD_Error *prev_error = 0;
|
||||||
for(MD_Error *e = ctx->first_error; e; e = e->next)
|
for(MD_Error *e = ctx->first_error; e; e = e->next)
|
||||||
{
|
{
|
||||||
if(e->location.line < error_loc.line ||
|
if(e->node->at < node->at)
|
||||||
(e->location.line == error_loc.line && e->location.column < error_loc.column))
|
|
||||||
{
|
{
|
||||||
prev_error = e;
|
prev_error = e;
|
||||||
}
|
}
|
||||||
@@ -1572,7 +1569,6 @@ _MD_Error(MD_ParseCtx *ctx, MD_Node *node, MD_u8 *at, MD_b32 catastrophic, char
|
|||||||
MD_Error *error = _MD_PushArray(_MD_GetCtx(), MD_Error, 1);
|
MD_Error *error = _MD_PushArray(_MD_GetCtx(), MD_Error, 1);
|
||||||
error->node = node ? node : MD_NilNode();
|
error->node = node ? node : MD_NilNode();
|
||||||
error->catastrophic = catastrophic;
|
error->catastrophic = catastrophic;
|
||||||
error->location = error_loc;
|
|
||||||
error->filename = ctx->filename;
|
error->filename = ctx->filename;
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@@ -1601,6 +1597,8 @@ _MD_Error(MD_ParseCtx *ctx, MD_Node *node, MD_u8 *at, MD_b32 catastrophic, char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#define _MD_TokenError(ctx, token, catastrophic, fmt, ...) \
|
||||||
|
_MD_Error(ctx, _MD_MakeNodeFromToken_Ctx(ctx, MD_NodeKind_ErrorMarker, token), catastrophic, fmt, __VA_ARGS__)
|
||||||
|
|
||||||
MD_PRIVATE_FUNCTION_IMPL MD_Node *
|
MD_PRIVATE_FUNCTION_IMPL MD_Node *
|
||||||
_MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 whole_string, MD_String8 filename,
|
_MD_MakeNode(MD_NodeKind kind, MD_String8 string, MD_String8 whole_string, MD_String8 filename,
|
||||||
@@ -1738,7 +1736,7 @@ _MD_ParseOneNode(MD_ParseCtx *ctx)
|
|||||||
comment_before = comment_token.string;
|
comment_before = comment_token.string;
|
||||||
if(!_MD_CommentIsSyntacticallyCorrect(comment_token))
|
if(!_MD_CommentIsSyntacticallyCorrect(comment_token))
|
||||||
{
|
{
|
||||||
_MD_Error(ctx, result.node, ctx->at-comment_token.outer_string.size, 1, "Unterminated comment \"%.*s\"",
|
_MD_TokenError(ctx, comment_token, 1, "Unterminated comment \"%.*s\"",
|
||||||
MD_StringExpand(MD_StringPrefix(comment_token.outer_string, _MD_MAX_UNTERMINATED_TOKEN_ERROR_LEN)));
|
MD_StringExpand(MD_StringPrefix(comment_token.outer_string, _MD_MAX_UNTERMINATED_TOKEN_ERROR_LEN)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1746,6 +1744,8 @@ _MD_ParseOneNode(MD_ParseCtx *ctx)
|
|||||||
MD_TokenGroups skip_groups = MD_TokenGroup_Whitespace|MD_TokenGroup_Comment;
|
MD_TokenGroups skip_groups = MD_TokenGroup_Whitespace|MD_TokenGroup_Comment;
|
||||||
MD_Token next_token = MD_Parse_PeekSkipSome(ctx, skip_groups);
|
MD_Token next_token = MD_Parse_PeekSkipSome(ctx, skip_groups);
|
||||||
|
|
||||||
|
retry:
|
||||||
|
|
||||||
// NOTE(rjf): Unnamed Sets
|
// NOTE(rjf): Unnamed Sets
|
||||||
if((MD_Parse_TokenMatch(next_token, MD_S8Lit("("), 0) ||
|
if((MD_Parse_TokenMatch(next_token, MD_S8Lit("("), 0) ||
|
||||||
MD_Parse_TokenMatch(next_token, MD_S8Lit("{"), 0) ||
|
MD_Parse_TokenMatch(next_token, MD_S8Lit("{"), 0) ||
|
||||||
@@ -1778,7 +1778,7 @@ _MD_ParseOneNode(MD_ParseCtx *ctx)
|
|||||||
{
|
{
|
||||||
if(!_MD_StringLiteralIsBalanced(token))
|
if(!_MD_StringLiteralIsBalanced(token))
|
||||||
{
|
{
|
||||||
_MD_Error(ctx, result.node, ctx->at-token.outer_string.size, 1, "Unterminated text literal \"%.*s\"",
|
_MD_Error(ctx, result.node, 1, "Unterminated text literal \"%.*s\"",
|
||||||
MD_StringExpand(MD_StringPrefix(token.outer_string, _MD_MAX_UNTERMINATED_TOKEN_ERROR_LEN)));
|
MD_StringExpand(MD_StringPrefix(token.outer_string, _MD_MAX_UNTERMINATED_TOKEN_ERROR_LEN)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1787,11 +1787,11 @@ _MD_ParseOneNode(MD_ParseCtx *ctx)
|
|||||||
MD_u8 c = token.string.str[0];
|
MD_u8 c = token.string.str[0];
|
||||||
if(c == '}' || c == ']' || c == ')')
|
if(c == '}' || c == ']' || c == ')')
|
||||||
{
|
{
|
||||||
_MD_Error(ctx, result.node, ctx->at-token.outer_string.size, 1, "Unbalanced \"%c\"", c);
|
_MD_TokenError(ctx, token, 1, "Unbalanced \"%c\"", c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_MD_Error(ctx, result.node, ctx->at-token.outer_string.size, 0, "Unexpected reserved symbol \"%c\"", c);
|
_MD_TokenError(ctx, token, 0, "Unexpected reserved symbol \"%c\"", c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1811,11 +1811,10 @@ _MD_ParseOneNode(MD_ParseCtx *ctx)
|
|||||||
if(fc == result.node->last_child && !MD_NodeIsNil(fc->first_tag) && // NOTE(mal): One child. Tagged.
|
if(fc == result.node->last_child && !MD_NodeIsNil(fc->first_tag) && // NOTE(mal): One child. Tagged.
|
||||||
fc->kind == MD_NodeKind_Label && fc->whole_string.size == 0) // NOTE(mal): Unlabeled set
|
fc->kind == MD_NodeKind_Label && fc->whole_string.size == 0) // NOTE(mal): Unlabeled set
|
||||||
{
|
{
|
||||||
MD_Node *tag = fc->first_tag;
|
for(MD_EachNode(tag, fc->first_tag))
|
||||||
// NOTE(mal): @rjf: I'm assuming that tag->string falls inside the ctx->file_contents string
|
{
|
||||||
// Can I do that? It's the easiest way to get the error offset.
|
_MD_Error(ctx, tag, 0, "Invalid position for tag \"%.*s\"", MD_StringExpand(tag->string));
|
||||||
MD_u8 *tag_at = tag->string.str;
|
}
|
||||||
_MD_Error(ctx, tag, tag_at, 0, "Invalid position for tag \"%.*s\"", MD_StringExpand(tag->string));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto end_parse;
|
goto end_parse;
|
||||||
@@ -1823,15 +1822,14 @@ _MD_ParseOneNode(MD_ParseCtx *ctx)
|
|||||||
|
|
||||||
else if(MD_Parse_RequireKind(ctx, MD_TokenKind_BadCharacter, &token))
|
else if(MD_Parse_RequireKind(ctx, MD_TokenKind_BadCharacter, &token))
|
||||||
{
|
{
|
||||||
result.node = MD_MakeNodeFromToken(MD_NodeKind_Label, ctx->filename, ctx->file_contents.str, ctx->at, token);
|
|
||||||
|
|
||||||
MD_String8List bytes = {0};
|
MD_String8List bytes = {0};
|
||||||
for(int i_byte = 0; i_byte < token.outer_string.size; ++i_byte)
|
for(int i_byte = 0; i_byte < token.outer_string.size; ++i_byte)
|
||||||
{
|
{
|
||||||
MD_PushStringToList(&bytes, MD_PushStringF("0x%02X", token.outer_string.str[i_byte]));
|
MD_PushStringToList(&bytes, MD_PushStringF("0x%02X", token.outer_string.str[i_byte]));
|
||||||
}
|
}
|
||||||
MD_String8 byte_string = MD_JoinStringListWithSeparator(bytes, MD_S8Lit(" "));
|
MD_String8 byte_string = MD_JoinStringListWithSeparator(bytes, MD_S8Lit(" "));
|
||||||
_MD_Error(ctx, result.node, ctx->at-1, 0, "Non-ASCII character \"%.*s\"", MD_StringExpand(byte_string));
|
_MD_TokenError(ctx, token, 0, "Non-ASCII character \"%.*s\"", MD_StringExpand(byte_string));
|
||||||
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
end_parse:;
|
end_parse:;
|
||||||
@@ -1865,7 +1863,7 @@ _MD_ParseOneNode(MD_ParseCtx *ctx)
|
|||||||
comment_after = comment_token.string;
|
comment_after = comment_token.string;
|
||||||
if(!_MD_CommentIsSyntacticallyCorrect(comment_token))
|
if(!_MD_CommentIsSyntacticallyCorrect(comment_token))
|
||||||
{
|
{
|
||||||
_MD_Error(ctx, result.node, ctx->at-comment_token.outer_string.size, 1, "Unterminated comment \"%.*s\"",
|
_MD_TokenError(ctx, comment_token, 1, "Unterminated comment \"%.*s\"",
|
||||||
MD_StringExpand(MD_StringPrefix(comment_token.outer_string, _MD_MAX_UNTERMINATED_TOKEN_ERROR_LEN)));
|
MD_StringExpand(MD_StringPrefix(comment_token.outer_string, _MD_MAX_UNTERMINATED_TOKEN_ERROR_LEN)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1969,7 +1967,7 @@ _MD_ParseSet(MD_ParseCtx *ctx, MD_Node *parent, _MD_ParseSetFlags flags,
|
|||||||
if(brace) delimiter_char = '{';
|
if(brace) delimiter_char = '{';
|
||||||
else if(paren) delimiter_char = '(';
|
else if(paren) delimiter_char = '(';
|
||||||
else if(bracket) delimiter_char = '[';
|
else if(bracket) delimiter_char = '[';
|
||||||
_MD_Error(ctx, parse.node, at_before_children-1, 1, "Unbalanced \"%c\"", delimiter_char);
|
_MD_Error(ctx, parent, 1, "Unbalanced \"%c\"", delimiter_char);
|
||||||
}
|
}
|
||||||
goto end_parse;
|
goto end_parse;
|
||||||
}
|
}
|
||||||
@@ -2044,8 +2042,8 @@ _MD_ParseTagList(MD_ParseCtx *ctx, MD_Node **first_out, MD_Node **last_out)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
MD_Token token = MD_Parse_PeekSkipSome(ctx, 0);
|
MD_Token token = MD_Parse_PeekSkipSome(ctx, 0);
|
||||||
_MD_Error(ctx, 0, token.outer_string.str, 0,
|
_MD_TokenError(ctx, token, 0, "\"%.*s\" is not a proper tag identifier",
|
||||||
"Tag \"%.*s\" is not a proper identifier", MD_StringExpand(token.outer_string));
|
MD_StringExpand(token.outer_string));
|
||||||
// NOTE(mal): There are reasons to consume the non-tag token, but also to leave it.
|
// NOTE(mal): There are reasons to consume the non-tag token, but also to leave it.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2114,7 +2112,7 @@ MD_ParseWholeString(MD_String8 filename, MD_String8 contents)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
MD_Token token = MD_Parse_PeekSkipSome(&ctx, 0);
|
MD_Token token = MD_Parse_PeekSkipSome(&ctx, 0);
|
||||||
_MD_Error(&ctx, 0, ctx.at, 0, "Invalid hash directive \"%.*s\"",
|
_MD_TokenError(&ctx, token, 0, "Invalid hash directive \"%.*s\"",
|
||||||
MD_StringExpand(token.outer_string));
|
MD_StringExpand(token.outer_string));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -6,7 +6,8 @@
|
|||||||
#define DEBUG_PRINT_GENERATED_TESTS 1
|
#define DEBUG_PRINT_GENERATED_TESTS 1
|
||||||
|
|
||||||
// NOTE: https://www.pcg-random.org/download.html
|
// NOTE: https://www.pcg-random.org/download.html
|
||||||
typedef struct RandomSeries{
|
typedef struct RandomSeries
|
||||||
|
{
|
||||||
MD_u64 state; // NOTE: RNG state. All values are possible.
|
MD_u64 state; // NOTE: RNG state. All values are possible.
|
||||||
MD_u64 inc; // Controls which RNG sequence (stream) is selected. Odd at all times.
|
MD_u64 inc; // Controls which RNG sequence (stream) is selected. Odd at all times.
|
||||||
} RandomSeries;
|
} RandomSeries;
|
||||||
|
|||||||
@@ -471,7 +471,7 @@ int main(void)
|
|||||||
MD_Error *e = parse.first_error;
|
MD_Error *e = parse.first_error;
|
||||||
for(int i_error = 0; i_error < max_error_count && tests[i_test].columns[i_error]; ++i_error)
|
for(int i_error = 0; i_error < max_error_count && tests[i_test].columns[i_error]; ++i_error)
|
||||||
{
|
{
|
||||||
if(!e || e->location.column != tests[i_test].columns[i_error])
|
if(!e || MD_CodeLocFromNode(e->node).column != tests[i_test].columns[i_error])
|
||||||
{
|
{
|
||||||
columns_match = 0;
|
columns_match = 0;
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user