[expr parsing] handle the 'errors' monad through the parse context instead of through return composition

This commit is contained in:
Allen Webster
2021-10-01 23:11:05 -07:00
parent ed377ebd33
commit 2f6ada618a
3 changed files with 48 additions and 43 deletions
+42 -39
View File
@@ -3462,20 +3462,27 @@ MD_ExprParse_MakeContext(MD_ExprOprTable *op_table, MD_Node *first)
MD_FUNCTION MD_ExprParseResult MD_FUNCTION MD_ExprParseResult
MD_ExprParse(MD_Arena *arena, MD_ExprOprTable *op_table, MD_Node *first, MD_Node *opl) MD_ExprParse(MD_Arena *arena, MD_ExprOprTable *op_table, MD_Node *first, MD_Node *opl)
{ {
// parse the node range
MD_ExprParseCtx ctx = MD_ExprParse_MakeContext(op_table, first); MD_ExprParseCtx ctx = MD_ExprParse_MakeContext(op_table, first);
MD_Node *iter = first; MD_Node *iter = first;
MD_ExprParseResult result = MD_ExprParse_Ctx_MinPrecedence(arena, &ctx, &iter, opl, 0); MD_Expr *expr = MD_ExprParse_Ctx_MinPrecedence(arena, &ctx, &iter, opl, 0);
if(result.errors.max_message_kind == MD_MessageKind_Null)
// check for failed-to-reach-end error
if(ctx.errors.max_message_kind == MD_MessageKind_Null)
{ {
MD_Node *stop_node = iter; MD_Node *stop_node = iter;
if(!MD_NodeIsNil(stop_node)) if(!MD_NodeIsNil(stop_node))
{ {
MD_String8 error_str=MD_S8Lit("Expected binary or unary postfix operator."); MD_String8 error_str = MD_S8Lit("Expected binary or unary postfix operator.");
MD_Message *error = MD_MakeNodeError(arena,stop_node,MD_MessageKind_FatalError,error_str); MD_Message *error = MD_MakeNodeError(arena,stop_node,MD_MessageKind_FatalError,error_str);
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&ctx.errors, error);
} }
} }
// fill result
MD_ExprParseResult result = {0};
result.expr = expr;
result.errors = ctx.errors;
return(result); return(result);
} }
@@ -3541,10 +3548,11 @@ MD_ExprParse_OprConsume(MD_ExprParseCtx *ctx, MD_Node **iter, MD_Node *opl,
return result; return result;
} }
MD_FUNCTION MD_ExprParseResult MD_FUNCTION MD_Expr*
MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_Node **iter, MD_Node *opl) MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_Node **iter, MD_Node *opl)
{ {
MD_ExprParseResult result = MD_ZERO_STRUCT; // TODO(allen): nil
MD_Expr* result = 0;
MD_Node *node = *iter; MD_Node *node = *iter;
MD_ExprOpr *op = 0; MD_ExprOpr *op = 0;
@@ -3566,7 +3574,7 @@ MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_Node **iter, MD_Node
MD_String8 error_str = MD_S8Lit("Unexpected end of expression."); MD_String8 error_str = MD_S8Lit("Unexpected end of expression.");
MD_Message *error = MD_MakeNodeError(arena, error_node, MD_MessageKind_FatalError, MD_Message *error = MD_MakeNodeError(arena, error_node, MD_MessageKind_FatalError,
error_str); error_str);
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&ctx->errors, error);
} }
else if((node->flags & MD_NodeFlag_HasParenLeft) && else if((node->flags & MD_NodeFlag_HasParenLeft) &&
(node->flags & MD_NodeFlag_HasParenRight)) (node->flags & MD_NodeFlag_HasParenRight))
@@ -3583,20 +3591,17 @@ MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_Node **iter, MD_Node
{ {
*iter = MD_NodeNextWithLimit(*iter, opl); *iter = MD_NodeNextWithLimit(*iter, opl);
// NOTE(mal): Unparsed leaf sets ({ ... }, [ ... ]) // NOTE(mal): Unparsed leaf sets ({ ... }, [ ... ])
result.node = MD_PushArrayZero(arena, MD_Expr, 1); result = MD_PushArrayZero(arena, MD_Expr, 1);
result.node->md_node = node; result->md_node = node;
} }
else if(MD_ExprParse_OprConsume(ctx, iter, opl, MD_ExprOprKind_Prefix, 1, &op)) else if(MD_ExprParse_OprConsume(ctx, iter, opl, MD_ExprOprKind_Prefix, 1, &op))
{ {
MD_u32 min_precedence = op->precedence + 1; MD_u32 min_precedence = op->precedence + 1;
MD_ExprParseResult sub_parse_result = MD_Expr *sub_expr =
MD_ExprParse_Ctx_MinPrecedence(arena, ctx, iter, opl, min_precedence); MD_ExprParse_Ctx_MinPrecedence(arena, ctx, iter, opl, min_precedence);
if(sub_parse_result.errors.max_message_kind == MD_MessageKind_Null) if(ctx->errors.max_message_kind == MD_MessageKind_Null)
{ {
result.node = MD_Expr_Alloc(arena, op, node, sub_parse_result.node, 0); result = MD_Expr_Alloc(arena, op, node, sub_expr, 0);
}
else{
result.errors = sub_parse_result.errors;
} }
} }
else if(MD_ExprParse_OprConsume(ctx, iter, opl, MD_ExprOprKind_Null, 1, &op)) else if(MD_ExprParse_OprConsume(ctx, iter, opl, MD_ExprOprKind_Null, 1, &op))
@@ -3605,7 +3610,7 @@ MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_Node **iter, MD_Node
MD_u64 error_offset = node->offset - ctx->original_first->offset; MD_u64 error_offset = node->offset - ctx->original_first->offset;
MD_Message *error = MD_MakeNodeError(arena, node, MD_MessageKind_FatalError, error_str); MD_Message *error = MD_MakeNodeError(arena, node, MD_MessageKind_FatalError, error_str);
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&ctx->errors, error);
} }
else if(node->flags & (MD_NodeFlag_HasParenLeft | MD_NodeFlag_HasParenRight | MD_NodeFlag_HasBracketLeft | else if(node->flags & (MD_NodeFlag_HasParenLeft | MD_NodeFlag_HasParenRight | MD_NodeFlag_HasBracketLeft |
MD_NodeFlag_HasBracketRight | MD_NodeFlag_HasBraceLeft | MD_NodeFlag_HasBraceRight)) MD_NodeFlag_HasBracketRight | MD_NodeFlag_HasBraceLeft | MD_NodeFlag_HasBraceRight))
@@ -3614,50 +3619,49 @@ MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_Node **iter, MD_Node
MD_u64 error_offset = node->offset - ctx->original_first->offset; MD_u64 error_offset = node->offset - ctx->original_first->offset;
MD_Message *error = MD_MakeNodeError(arena, node, MD_MessageKind_FatalError, error_str); MD_Message *error = MD_MakeNodeError(arena, node, MD_MessageKind_FatalError, error_str);
MD_MessageListPush(&result.errors, error); MD_MessageListPush(&ctx->errors, error);
} }
else{ // NOTE(mal): leaf else{ // NOTE(mal): leaf
*iter = MD_NodeNextWithLimit(*iter, opl); *iter = MD_NodeNextWithLimit(*iter, opl);
result.node = MD_PushArrayZero(arena, MD_Expr, 1); result = MD_PushArrayZero(arena, MD_Expr, 1);
result.node->md_node = node; result->md_node = node;
} }
return result; return(result);
} }
MD_FUNCTION MD_ExprParseResult MD_FUNCTION MD_Expr*
MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx,
MD_Node **iter, MD_Node *opl, MD_Node **iter, MD_Node *opl,
MD_u32 min_precedence) MD_u32 min_precedence)
{ {
MD_ExprParseResult result = MD_ZERO_STRUCT; // TODO(allen): nil
MD_Expr* result = 0;
MD_ExprOpr *subscript_op = ctx->accel.subscript_op; MD_ExprOpr *subscript_op = ctx->accel.subscript_op;
result = MD_ExprParse_Atom(arena, ctx, iter, opl); result = MD_ExprParse_Atom(arena, ctx, iter, opl);
if(result.errors.max_message_kind == MD_MessageKind_Null) if(ctx->errors.max_message_kind == MD_MessageKind_Null)
{ {
for (;!MD_NodeIsNil(*iter);) for (;!MD_NodeIsNil(*iter);)
{ {
MD_Node *node = *iter; MD_Node *node = *iter;
MD_ExprOpr *op; MD_ExprOpr *op = 0;
if(subscript_op && subscript_op->precedence >= min_precedence && if(subscript_op != 0 && subscript_op->precedence >= min_precedence &&
node->flags & MD_NodeFlag_HasBracketLeft && node->flags & MD_NodeFlag_HasBracketRight) (node->flags & MD_NodeFlag_HasBracketLeft) &&
(node->flags & MD_NodeFlag_HasBracketRight))
{ {
*iter = MD_NodeNextWithLimit(*iter, opl); *iter = MD_NodeNextWithLimit(*iter, opl);
// NOTE(mal): Array subscript // NOTE(mal): Array subscript
MD_Node *sub_iter = node->first_child; MD_Node *sub_iter = node->first_child;
MD_ExprParseResult sub_parse_result = MD_ExprParse_Ctx_MinPrecedence(arena, ctx, MD_Expr* sub_expr = MD_ExprParse_Ctx_MinPrecedence(arena, ctx, &sub_iter, MD_NilNode(), 0);
&sub_iter,MD_NilNode(), if(ctx->errors.max_message_kind == MD_MessageKind_Null)
0);
if(sub_parse_result.errors.max_message_kind == MD_MessageKind_Null)
{ {
result.node = MD_Expr_Alloc(arena, subscript_op, node, result.node, sub_parse_result.node); result = MD_Expr_Alloc(arena, subscript_op, node, result, sub_expr);
} }
else{ else{
result.errors = sub_parse_result.errors;
break; break;
} }
} }
@@ -3667,14 +3671,13 @@ MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx,
min_precedence, &op)) min_precedence, &op))
{ {
MD_u32 next_min_precedence = op->precedence + (op->kind == MD_ExprOprKind_Binary); MD_u32 next_min_precedence = op->precedence + (op->kind == MD_ExprOprKind_Binary);
MD_ExprParseResult sub_parse_result = MD_Expr *sub_expr =
MD_ExprParse_Ctx_MinPrecedence(arena, ctx, iter, opl, next_min_precedence); MD_ExprParse_Ctx_MinPrecedence(arena, ctx, iter, opl, next_min_precedence);
if(sub_parse_result.errors.max_message_kind == MD_MessageKind_Null) if(ctx->errors.max_message_kind == MD_MessageKind_Null)
{ {
result.node = MD_Expr_Alloc(arena, op, node, result.node, sub_parse_result.node); result = MD_Expr_Alloc(arena, op, node, result, sub_expr);
} }
else{ else{
result.errors = sub_parse_result.errors;
break; break;
} }
} }
@@ -3682,12 +3685,12 @@ MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx,
node->flags & MD_NodeFlag_HasParenLeft && node->flags & MD_NodeFlag_HasParenRight) node->flags & MD_NodeFlag_HasParenLeft && node->flags & MD_NodeFlag_HasParenRight)
{ // NOTE: call { // NOTE: call
*iter = MD_NodeNextWithLimit(*iter, opl); *iter = MD_NodeNextWithLimit(*iter, opl);
result.node = MD_Expr_Alloc(arena, ctx->accel.call_op, node, result.node, 0); result = MD_Expr_Alloc(arena, ctx->accel.call_op, node, result, 0);
} }
else if(MD_ExprParse_OprConsume(ctx, iter, opl, MD_ExprOprKind_Postfix, else if(MD_ExprParse_OprConsume(ctx, iter, opl, MD_ExprOprKind_Postfix,
min_precedence, &op)) min_precedence, &op))
{ {
result.node = MD_Expr_Alloc(arena, op, node, result.node, 0); result = MD_Expr_Alloc(arena, op, node, result, 0);
} }
else else
{ {
@@ -3696,7 +3699,7 @@ MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena, MD_ExprParseCtx *ctx,
} }
} }
return result; return(result);
} }
+5 -3
View File
@@ -770,7 +770,7 @@ struct MD_Expr
typedef struct MD_ExprParseResult MD_ExprParseResult; typedef struct MD_ExprParseResult MD_ExprParseResult;
struct MD_ExprParseResult struct MD_ExprParseResult
{ {
MD_Expr *node; MD_Expr *expr;
MD_MessageList errors; MD_MessageList errors;
}; };
@@ -789,6 +789,8 @@ struct MD_ExprParseCtx
MD_ExprOpr *bracket_set_op; MD_ExprOpr *bracket_set_op;
MD_ExprOpr *brace_set_op; MD_ExprOpr *brace_set_op;
} accel; } accel;
MD_MessageList errors;
}; };
//~ String Generation Types //~ String Generation Types
@@ -1135,9 +1137,9 @@ MD_FUNCTION MD_b32 MD_ExprParse_OprConsume(MD_ExprParseCtx *ctx, MD_
MD_ExprOprKind kind, MD_ExprOprKind kind,
MD_u32 min_precedence, MD_u32 min_precedence,
MD_ExprOpr **op_out); MD_ExprOpr **op_out);
MD_FUNCTION MD_ExprParseResult MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx, MD_FUNCTION MD_Expr* MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx,
MD_Node **iter, MD_Node *opl); MD_Node **iter, MD_Node *opl);
MD_FUNCTION MD_ExprParseResult MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena, MD_FUNCTION MD_Expr* MD_ExprParse_Ctx_MinPrecedence(MD_Arena *arena,
MD_ExprParseCtx *ctx, MD_ExprParseCtx *ctx,
MD_Node **iter, MD_Node *node, MD_Node **iter, MD_Node *node,
MD_u32 min_precedence); MD_u32 min_precedence);
+1 -1
View File
@@ -369,7 +369,7 @@ operator_array[Op_##name].op = (MD_ExprOpr){ .op_id = Op_##name, .kind = MD_Expr
MD_ExprParseResult expr_parse = MD_ExprParse(arena, &op_table, parse.node->first_child, MD_NilNode()); MD_ExprParseResult expr_parse = MD_ExprParse(arena, &op_table, parse.node->first_child, MD_NilNode());
if(expr_parse.errors.max_message_kind == MD_MessageKind_Null) if(expr_parse.errors.max_message_kind == MD_MessageKind_Null)
{ {
MD_String8 parser_answer = parenthesize(arena, operator_array, expr_parse.node); MD_String8 parser_answer = parenthesize(arena, operator_array, expr_parse.expr);
if(!MD_S8Match(parser_answer, a, 0)) if(!MD_S8Match(parser_answer, a, 0))
{ {
printf("Example %d : Expected answer for %.*s is %.*s. Got %.*s\n", printf("Example %d : Expected answer for %.*s is %.*s. Got %.*s\n",