mirror of
https://github.com/Ed94/metadesk.git
synced 2026-06-13 07:52:22 -07:00
[expr parser] rearrange expression errors to point right at the original metadesk nodes as much as possible
This commit is contained in:
@@ -11,4 +11,3 @@ Some changes I made to `MD_MakeExprParseError` (I'm not obsessed I swear):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+100
-84
@@ -2304,59 +2304,6 @@ MD_LexAdvanceFromSkips(MD_String8 string, MD_TokenKind skip_kinds)
|
||||
return(result);
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_Message*
|
||||
MD_MakeNodeError(MD_Arena *arena, MD_Node *node, MD_MessageKind kind, MD_String8 str)
|
||||
{
|
||||
MD_Message *error = MD_PushArrayZero(arena, MD_Message, 1);
|
||||
error->node = node;
|
||||
error->kind = kind;
|
||||
error->string = str;
|
||||
return error;
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_Message *
|
||||
MD_MakeTokenError(MD_Arena *arena, MD_String8 parse_contents, MD_Token token,
|
||||
MD_MessageKind kind, MD_String8 str)
|
||||
{
|
||||
MD_Node *err_node = MD_MakeNode(arena, MD_NodeKind_ErrorMarker, MD_S8Lit(""), parse_contents,
|
||||
token.raw_string.str - parse_contents.str);
|
||||
return MD_MakeNodeError(arena, err_node, kind, str);
|
||||
}
|
||||
|
||||
MD_FUNCTION void
|
||||
MD_MessageListPush(MD_MessageList *list, MD_Message *message)
|
||||
{
|
||||
MD_QueuePush(list->first, list->last, message);
|
||||
if(message->kind > list->max_message_kind)
|
||||
{
|
||||
list->max_message_kind = message->kind;
|
||||
}
|
||||
list->node_count += 1;
|
||||
}
|
||||
|
||||
MD_FUNCTION void
|
||||
MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push)
|
||||
{
|
||||
if(list->last)
|
||||
{
|
||||
if(to_push->node_count != 0)
|
||||
{
|
||||
list->last->next = to_push->first;
|
||||
list->last = to_push->last;
|
||||
list->node_count += to_push->node_count;
|
||||
if(to_push->max_message_kind > list->max_message_kind)
|
||||
{
|
||||
list->max_message_kind = to_push->max_message_kind;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*list = *to_push;
|
||||
}
|
||||
MD_MemoryZeroStruct(to_push);
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_ParseResult
|
||||
MD_ParseResultZero(void)
|
||||
{
|
||||
@@ -2915,6 +2862,78 @@ MD_ParseWholeFile(MD_Arena *arena, MD_String8 filename)
|
||||
return parse;
|
||||
}
|
||||
|
||||
//~ Messages (Errors/Warnings)
|
||||
|
||||
MD_FUNCTION MD_Node*
|
||||
MD_MakeErrorMarkerNode(MD_Arena *arena, MD_String8 parse_contents, MD_u64 offset)
|
||||
{
|
||||
MD_Node *result = MD_MakeNode(arena, MD_NodeKind_ErrorMarker, MD_S8Lit(""), parse_contents,
|
||||
offset);
|
||||
return(result);
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_Message*
|
||||
MD_MakeNodeError(MD_Arena *arena, MD_Node *node, MD_MessageKind kind, MD_String8 str)
|
||||
{
|
||||
MD_Message *error = MD_PushArrayZero(arena, MD_Message, 1);
|
||||
error->node = node;
|
||||
error->kind = kind;
|
||||
error->string = str;
|
||||
return error;
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_Message*
|
||||
MD_MakeDetachedError(MD_Arena *arena, MD_MessageKind kind, MD_String8 str, void *user_ptr)
|
||||
{
|
||||
MD_Node *err_node = MD_MakeErrorMarkerNode(arena, MD_S8Lit(""), 0);
|
||||
MD_Message *result = MD_MakeNodeError(arena, err_node, kind, str);
|
||||
result->user_ptr = user_ptr;
|
||||
return(result);
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_Message *
|
||||
MD_MakeTokenError(MD_Arena *arena, MD_String8 parse_contents, MD_Token token,
|
||||
MD_MessageKind kind, MD_String8 str)
|
||||
{
|
||||
MD_u64 offset = token.raw_string.str - parse_contents.str;
|
||||
MD_Node *err_node = MD_MakeErrorMarkerNode(arena, parse_contents, offset);
|
||||
return MD_MakeNodeError(arena, err_node, kind, str);
|
||||
}
|
||||
|
||||
MD_FUNCTION void
|
||||
MD_MessageListPush(MD_MessageList *list, MD_Message *message)
|
||||
{
|
||||
MD_QueuePush(list->first, list->last, message);
|
||||
if(message->kind > list->max_message_kind)
|
||||
{
|
||||
list->max_message_kind = message->kind;
|
||||
}
|
||||
list->node_count += 1;
|
||||
}
|
||||
|
||||
MD_FUNCTION void
|
||||
MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push)
|
||||
{
|
||||
if(list->last)
|
||||
{
|
||||
if(to_push->node_count != 0)
|
||||
{
|
||||
list->last->next = to_push->first;
|
||||
list->last = to_push->last;
|
||||
list->node_count += to_push->node_count;
|
||||
if(to_push->max_message_kind > list->max_message_kind)
|
||||
{
|
||||
list->max_message_kind = to_push->max_message_kind;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*list = *to_push;
|
||||
}
|
||||
MD_MemoryZeroStruct(to_push);
|
||||
}
|
||||
|
||||
//~ Location Conversions
|
||||
|
||||
MD_FUNCTION MD_CodeLoc
|
||||
@@ -3387,8 +3406,8 @@ MD_ExprBakeOperatorTableFromList(MD_Arena *arena, MD_ExprOprList *list)
|
||||
{
|
||||
// TODO(allen): review: does it make sense to use these kinds of errors
|
||||
// for *this* which isn't derived from metadesk at all?
|
||||
MD_Message *error = MD_MakeExprParseError(arena, MD_MessageKind_Warning, error_str, 0,
|
||||
op->op_ptr);
|
||||
MD_Message *error = MD_MakeDetachedError(arena, MD_MessageKind_Warning,
|
||||
error_str, op->op_ptr);
|
||||
MD_MessageListPush(&result.errors, error);
|
||||
}
|
||||
|
||||
@@ -3431,7 +3450,12 @@ _MD_Expr_Make(MD_Arena *arena, MD_ExprOpr *op, MD_Node *op_node,
|
||||
MD_FUNCTION void
|
||||
_MD_CtxAdvance(MD_ExprParseCtx *ctx)
|
||||
{
|
||||
ctx->first = ctx->first->next;
|
||||
MD_Node *node = ctx->first->next;
|
||||
if (node == ctx->one_past_last__)
|
||||
{
|
||||
node = MD_NilNode();
|
||||
}
|
||||
ctx->first = node;
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_b32
|
||||
@@ -3460,7 +3484,7 @@ _MD_ExprParse_MakeContext(MD_ExprOprTable *op_table, MD_Node *first, MD_Node *on
|
||||
result.op_table = op_table;
|
||||
result.original_first = first;
|
||||
result.first = first;
|
||||
result.one_past_last = one_past_last;
|
||||
result.one_past_last__ = one_past_last;
|
||||
|
||||
result.accel.bracket_set_op = MD_ExprOprFromKindString(op_table, MD_ExprOprKind_Prefix, MD_S8Lit("[]"));
|
||||
result.accel.brace_set_op = MD_ExprOprFromKindString(op_table, MD_ExprOprKind_Prefix, MD_S8Lit("{}"));
|
||||
@@ -3475,7 +3499,7 @@ _MD_ExprParse_MakeSubcontext(MD_ExprParseCtx *ctx, MD_Node *first, MD_Node *one_
|
||||
{
|
||||
MD_ExprParseCtx result = *ctx;
|
||||
result.first = first;
|
||||
result.one_past_last = one_past_last;
|
||||
result.one_past_last__ = one_past_last;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3489,16 +3513,21 @@ _MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx)
|
||||
|
||||
if(MD_NodeIsNil(node))
|
||||
{
|
||||
MD_Node *last_non_null = ctx->original_first;
|
||||
while(!MD_NodeIsNil(last_non_null->next))
|
||||
MD_Node *last = ctx->original_first;
|
||||
for (;last->next != ctx->one_past_last__; last = last->next);
|
||||
|
||||
MD_Node *error_node = last->next;
|
||||
if (MD_NodeIsNil(error_node))
|
||||
{
|
||||
last_non_null = last_non_null->next;
|
||||
MD_Node *root = MD_RootFromNode(node);
|
||||
MD_String8 parse_contents = root->raw_string;
|
||||
MD_u64 offset = last->offset + last->raw_string.size;
|
||||
error_node = MD_MakeErrorMarkerNode(arena, parse_contents, offset);
|
||||
}
|
||||
|
||||
MD_String8 error_str = MD_S8Lit("Unexpected end of expression.");
|
||||
MD_u64 error_offset = last_non_null->offset + last_non_null->raw_string.size - ctx->original_first->offset;
|
||||
MD_Message *error = MD_MakeExprParseError(arena, MD_MessageKind_FatalError,
|
||||
error_str, error_offset, last_non_null);
|
||||
MD_Message *error = MD_MakeNodeError(arena, error_node, MD_MessageKind_FatalError,
|
||||
error_str);
|
||||
MD_MessageListPush(&result.errors, error);
|
||||
}
|
||||
else if(node->flags & MD_NodeFlag_HasParenLeft && node->flags & MD_NodeFlag_HasParenRight)
|
||||
@@ -3533,8 +3562,8 @@ _MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx)
|
||||
{
|
||||
MD_String8 error_str = MD_S8Fmt(arena, "Expected leaf. Got operator \"%.*s\".", MD_S8VArg(node->string));
|
||||
MD_u64 error_offset = node->offset - ctx->original_first->offset;
|
||||
MD_Message *error = MD_MakeExprParseError(arena, MD_MessageKind_FatalError,
|
||||
error_str, error_offset, node);
|
||||
|
||||
MD_Message *error = MD_MakeNodeError(arena, node, MD_MessageKind_FatalError, error_str);
|
||||
MD_MessageListPush(&result.errors, error);
|
||||
}
|
||||
else if(node->flags & (MD_NodeFlag_HasParenLeft | MD_NodeFlag_HasParenRight | MD_NodeFlag_HasBracketLeft |
|
||||
@@ -3542,8 +3571,8 @@ _MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx)
|
||||
{
|
||||
MD_String8 error_str = MD_S8Fmt(arena, "Unexpected set.", MD_S8VArg(node->string));
|
||||
MD_u64 error_offset = node->offset - ctx->original_first->offset;
|
||||
MD_Message *error = MD_MakeExprParseError(arena, MD_MessageKind_FatalError,
|
||||
error_str, error_offset, node);
|
||||
|
||||
MD_Message *error = MD_MakeNodeError(arena, node, MD_MessageKind_FatalError, error_str);
|
||||
MD_MessageListPush(&result.errors, error);
|
||||
}
|
||||
else{ // NOTE(mal): leaf
|
||||
@@ -3565,7 +3594,7 @@ _MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_u32 mi
|
||||
result = _MD_ExprParse_Atom(arena, ctx);
|
||||
if(result.errors.max_message_kind == MD_MessageKind_Null)
|
||||
{
|
||||
while(!MD_NodeIsNil(ctx->first) && ctx->first != ctx->one_past_last)
|
||||
for (;!MD_NodeIsNil(ctx->first);)
|
||||
{
|
||||
MD_Node *node = ctx->first;
|
||||
MD_ExprOpr *op;
|
||||
@@ -3630,13 +3659,11 @@ MD_ExprParse(MD_Arena *arena, MD_ExprOprTable *op_table,
|
||||
result = _MD_ExprParse_Ctx_MinPrecedence(arena, &ctx, 0);
|
||||
if(result.errors.max_message_kind == MD_MessageKind_Null)
|
||||
{
|
||||
if(ctx.first != ctx.one_past_last)
|
||||
if(!MD_NodeIsNil(ctx.first))
|
||||
{
|
||||
MD_String8 error_str =
|
||||
MD_S8Lit("Partial parse. Expected binary or unary postfix operator.");
|
||||
MD_u64 error_offset = ctx.first->offset - first->offset;
|
||||
MD_Message *error = MD_MakeExprParseError(arena, MD_MessageKind_FatalError,
|
||||
error_str, error_offset, ctx.first);
|
||||
MD_Message *error = MD_MakeNodeError(arena,ctx.first,MD_MessageKind_FatalError,error_str);
|
||||
MD_MessageListPush(&result.errors, error);
|
||||
}
|
||||
}
|
||||
@@ -3672,17 +3699,6 @@ MD_ExprOprFromKindString(MD_ExprOprTable *table, MD_ExprOprKind kind, MD_String8
|
||||
return result;
|
||||
}
|
||||
|
||||
MD_FUNCTION MD_Message*
|
||||
MD_MakeExprParseError(MD_Arena *arena, MD_MessageKind kind, MD_String8 str, MD_u64 offset,
|
||||
void *user_ptr)
|
||||
{
|
||||
MD_Node *err_node = MD_MakeNode(arena, MD_NodeKind_ErrorMarker,
|
||||
MD_S8Lit(""), MD_S8Lit(""), offset);
|
||||
MD_Message *result = MD_MakeNodeError(arena, err_node, kind, str);
|
||||
result->user_ptr = user_ptr;
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
//~ String Generation
|
||||
|
||||
|
||||
+17
-10
@@ -782,7 +782,7 @@ struct MD_ExprParseCtx
|
||||
MD_ExprOprTable *op_table;
|
||||
MD_Node *original_first;
|
||||
MD_Node *first;
|
||||
MD_Node *one_past_last;
|
||||
MD_Node *one_past_last__;
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -1013,13 +1013,6 @@ MD_FUNCTION MD_MapSlot* MD_MapOverwrite(MD_Arena *arena, MD_Map *map, MD_MapKey
|
||||
MD_FUNCTION MD_b32 MD_TokenGroupContainsKind(MD_TokenGroups groups, MD_TokenKind kind);
|
||||
MD_FUNCTION MD_Token MD_TokenFromString(MD_String8 string);
|
||||
MD_FUNCTION MD_u64 MD_LexAdvanceFromSkips(MD_String8 string, MD_TokenKind skip_kinds);
|
||||
MD_FUNCTION MD_Message* MD_MakeNodeError(MD_Arena *arena, MD_Node *node,
|
||||
MD_MessageKind kind, MD_String8 str);
|
||||
MD_FUNCTION MD_Message* MD_MakeTokenError(MD_Arena *arena, MD_String8 parse_contents,
|
||||
MD_Token token, MD_MessageKind kind,
|
||||
MD_String8 str);
|
||||
MD_FUNCTION void MD_MessageListPush(MD_MessageList *list, MD_Message *message);
|
||||
MD_FUNCTION void MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push);
|
||||
MD_FUNCTION MD_ParseResult MD_ParseResultZero(void);
|
||||
MD_FUNCTION MD_ParseResult MD_ParseNodeSet(MD_Arena *arena, MD_String8 string, MD_u64 offset, MD_Node *parent,
|
||||
MD_ParseSetRule rule);
|
||||
@@ -1028,6 +1021,22 @@ MD_FUNCTION MD_ParseResult MD_ParseWholeString(MD_Arena *arena, MD_String8 filen
|
||||
|
||||
MD_FUNCTION MD_ParseResult MD_ParseWholeFile(MD_Arena *arena, MD_String8 filename);
|
||||
|
||||
//~ Messages (Errors/Warnings)
|
||||
|
||||
MD_FUNCTION MD_Node* MD_MakeErrorMarkerNode(MD_Arena *arena, MD_String8 parse_contents,
|
||||
MD_u64 offset);
|
||||
|
||||
MD_FUNCTION MD_Message*MD_MakeNodeError(MD_Arena *arena, MD_Node *node,
|
||||
MD_MessageKind kind, MD_String8 str);
|
||||
MD_FUNCTION MD_Message*MD_MakeDetachedError(MD_Arena *arena, MD_MessageKind kind,
|
||||
MD_String8 str, void *ptr);
|
||||
MD_FUNCTION MD_Message*MD_MakeTokenError(MD_Arena *arena, MD_String8 parse_contents,
|
||||
MD_Token token, MD_MessageKind kind,
|
||||
MD_String8 str);
|
||||
|
||||
MD_FUNCTION void MD_MessageListPush(MD_MessageList *list, MD_Message *message);
|
||||
MD_FUNCTION void MD_MessageListConcat(MD_MessageList *list, MD_MessageList *to_push);
|
||||
|
||||
//~ Location Conversion
|
||||
|
||||
MD_FUNCTION MD_CodeLoc MD_CodeLocFromFileOffset(MD_String8 filename, MD_u8 *base, MD_u64 offset);
|
||||
@@ -1114,8 +1123,6 @@ MD_FUNCTION MD_ExprParseResult MD_ExprParse(MD_Arena *arena, MD_ExprOprTable *op
|
||||
|
||||
MD_FUNCTION MD_ExprOpr* MD_ExprOprFromKindString(MD_ExprOprTable *table,
|
||||
MD_ExprOprKind kind, MD_String8 s);
|
||||
MD_FUNCTION MD_Message* MD_MakeExprParseError(MD_Arena *arena, MD_MessageKind kind,
|
||||
MD_String8 str, MD_u64 offset, void *ptr);
|
||||
|
||||
//~ String Generation
|
||||
|
||||
|
||||
@@ -302,6 +302,8 @@ operator_array[Op_##name].op = (MD_ExprOpr){ .op_id = Op_##name, .kind = MD_Expr
|
||||
// adding some extra parens, we can then compare it to the expected parenthisation of the
|
||||
// original input string. We get most of the topological comparison with a simpler test interface.
|
||||
Expression_QA tests[] = {
|
||||
{ .q = "a+", .a = "", ExpressionErrorKind_Expr, 2},
|
||||
|
||||
{ .q = "a + b + c", .a = "(a + b) + c" },
|
||||
{ .q = "a + (b + c)", .a = "a + (b + c)" },
|
||||
{ .q = "a + b + c + d", .a = "((a + b) + c) + d" },
|
||||
@@ -351,7 +353,7 @@ operator_array[Op_##name].op = (MD_ExprOpr){ .op_id = Op_##name, .kind = MD_Expr
|
||||
{ .q = "a)", .a = "", ExpressionErrorKind_MD, 1},
|
||||
{ .q = "/a", .a = "", ExpressionErrorKind_Expr, 0},
|
||||
{ .q = "+ /a", .a = "", ExpressionErrorKind_Expr, 2},
|
||||
{ .q = "a+", .a = "", ExpressionErrorKind_Expr, 2},
|
||||
//{ .q = "a+", .a = "", ExpressionErrorKind_Expr, 2},
|
||||
{ .q = "a 1", .a = "", ExpressionErrorKind_Expr, 2},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user