From 9ac946cf0799d3a439c7ba10022ff7b615e6be10 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 1 Oct 2021 20:31:06 -0700 Subject: [PATCH] [expr parser] change the operator definition so that an MD_Node is not required --- source/md.c | 45 +++++++++++++++++++++++----------------- source/md.h | 13 +++++++----- tests/expression_tests.c | 25 ++++++++++++++-------- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/source/md.c b/source/md.c index f67d41d..0c2b935 100644 --- a/source/md.c +++ b/source/md.c @@ -3313,8 +3313,8 @@ MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) MD_FUNCTION void MD_ExprOprPush(MD_Arena *arena, MD_ExprOprList *list, - MD_u32 op_id, MD_ExprOprKind kind, - MD_u64 precedence, MD_Node *md_node) + MD_ExprOprKind kind, MD_u64 precedence, MD_String8 string, + MD_u32 op_id, void *op_ptr) { MD_ExprOprNode *node = MD_PushArrayZero(arena, MD_ExprOprNode, 1); MD_QueuePush(list->first, list->last, node); @@ -3322,7 +3322,8 @@ MD_ExprOprPush(MD_Arena *arena, MD_ExprOprList *list, node->op.op_id = op_id; node->op.kind = kind; node->op.precedence = precedence; - node->op.md_node__ = md_node; + node->op.string = string; + node->op.op_ptr = op_ptr; } MD_FUNCTION MD_ExprOprTable @@ -3335,7 +3336,7 @@ MD_ExprBakeOperatorTableFromList(MD_Arena *arena, MD_ExprOprList *list) op_node = op_node->next) { MD_ExprOpr op = op_node->op; - MD_String8 op_s = op.md_node__->string; + MD_String8 op_s = op.string; // TODO(allen): @upgrade_potential(minor) @@ -3353,13 +3354,16 @@ MD_ExprBakeOperatorTableFromList(MD_Arena *arena, MD_ExprOprList *list) op_node2 = op_node2->next) { // NOTE(mal): O(n^2) MD_ExprOpr op2 = op_node2->op; - MD_String8 op2_s = op2.md_node__->string; + MD_String8 op2_s = op2.string; if(op.precedence == op2.precedence && - ((op.kind == MD_ExprOprKind_Binary && op2.kind == MD_ExprOprKind_BinaryRightAssociative) || - (op.kind == MD_ExprOprKind_BinaryRightAssociative && op2.kind == MD_ExprOprKind_Binary))) + ((op.kind == MD_ExprOprKind_Binary && + op2.kind == MD_ExprOprKind_BinaryRightAssociative) || + (op.kind == MD_ExprOprKind_BinaryRightAssociative && + op2.kind == MD_ExprOprKind_Binary))) { - error_str = MD_S8Fmt(arena, "Ignored binary operator \"%.*s\" because another binary operator" - "has the same precedence and different associativity", MD_S8VArg(op_s)); + error_str = + MD_S8Fmt(arena, "Ignored binary operator \"%.*s\" because another binary operator" + "has the same precedence and different associativity", MD_S8VArg(op_s)); } else if(MD_S8Match(op_s, op2_s, 0)) { @@ -3381,7 +3385,9 @@ MD_ExprBakeOperatorTableFromList(MD_Arena *arena, MD_ExprOprList *list) // save error if(error_str.size != 0) { - MD_Message *error = MD_MakeNodeError(arena, op.md_node__, MD_MessageKind_Warning, error_str); + // 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, error_str, 0); MD_MessageListPush(&result.errors, error); } @@ -3409,7 +3415,7 @@ _MD_Expr_Make(MD_Arena *arena, MD_ExprOpr *op, MD_Node *op_node, MD_ExprNode *result = MD_PushArrayZero(arena, MD_ExprNode, 1); result->is_op = 1; result->op_id = op->op_id; - result->md_op_node = op->md_node__; + result->op_ptr = op->op_ptr; result->md_node = op_node; result->left = left; result->right = right; @@ -3470,13 +3476,6 @@ _MD_ExprParse_MakeSubcontext(MD_ExprParseCtx *ctx, MD_Node *first, MD_Node *one_ return result; } -MD_FUNCTION MD_Message* -MD_MakeExprParseError(MD_Arena *arena, MD_String8 str, MD_u64 offset) -{ - MD_Node *err_node = MD_MakeNode(arena, MD_NodeKind_ErrorMarker, MD_S8Lit(""), MD_S8Lit(""), offset); - return MD_MakeNodeError(arena, err_node, MD_MessageKind_FatalError, str); -} - MD_FUNCTION MD_ExprParseResult _MD_ExprParse_Atom(MD_Arena *arena, MD_ExprParseCtx *ctx) { @@ -3652,7 +3651,7 @@ MD_ExprOprFromKindString(MD_ExprOprTable *table, MD_ExprOprKind kind, MD_String8 MD_ExprOprList *op_list = table->table+cur_kind; for(MD_ExprOprNode *op_node = op_list->first; !result && op_node; op_node = op_node->next) { - if(MD_S8Match(op_node->op.md_node__->string, s, 0)) + if(MD_S8Match(op_node->op.string, s, 0)) { result = &op_node->op; } @@ -3662,6 +3661,14 @@ MD_ExprOprFromKindString(MD_ExprOprTable *table, MD_ExprOprKind kind, MD_String8 return result; } +MD_FUNCTION MD_Message* +MD_MakeExprParseError(MD_Arena *arena, MD_String8 str, MD_u64 offset) +{ + MD_Node *err_node = MD_MakeNode(arena, MD_NodeKind_ErrorMarker, MD_S8Lit(""), MD_S8Lit(""), offset); + return MD_MakeNodeError(arena, err_node, MD_MessageKind_FatalError, str); +} + + //~ String Generation MD_FUNCTION void diff --git a/source/md.h b/source/md.h index 71086ee..480ddef 100644 --- a/source/md.h +++ b/source/md.h @@ -728,13 +728,15 @@ typedef enum MD_ExprOprKind MD_ExprOprKind_COUNT, } MD_ExprOprKind; +// TODO(allen): can we lego-brick the node and opr? typedef struct MD_ExprOpr MD_ExprOpr; struct MD_ExprOpr { MD_u32 op_id; MD_ExprOprKind kind; MD_u32 precedence; - MD_Node *md_node__; + MD_String8 string; + void *op_ptr; }; typedef struct MD_ExprOprNode MD_ExprOprNode; @@ -767,9 +769,8 @@ struct MD_ExprNode struct MD_ExprNode *right; MD_b32 is_op; MD_u32 op_id; + void *op_ptr; MD_Node *md_node; - // TODO(allen): could md_op_node actually be void* ? - MD_Node *md_op_node; }; typedef struct MD_ExprParseResult MD_ExprParseResult; @@ -1105,8 +1106,9 @@ MD_FUNCTION MD_b32 MD_NodeDeepMatch(MD_Node *a, MD_Node *b, MD_MatchFlags flags) //~ Expression Parsing MD_FUNCTION void MD_ExprOprPush(MD_Arena *arena, MD_ExprOprList *list, - MD_u32 op_id, MD_ExprOprKind kind, - MD_u64 precedence, MD_Node *md_node); + MD_ExprOprKind kind, MD_u64 precedence, + MD_String8 op_string, + MD_u32 op_id, void *op_ptr); MD_FUNCTION MD_ExprOprTable MD_ExprBakeOperatorTableFromList(MD_Arena *arena, MD_ExprOprList *list); @@ -1117,6 +1119,7 @@ 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_String8 str, MD_u64 offset); //~ String Generation diff --git a/tests/expression_tests.c b/tests/expression_tests.c index a247ad7..9bb7eb6 100644 --- a/tests/expression_tests.c +++ b/tests/expression_tests.c @@ -242,32 +242,38 @@ operator_array[Op_##name].op = (MD_ExprOpr){ .op_id = Op_##name, .kind = MD_Expr // NOTE: Wrong operator kind operator_list = (MD_ExprOprList){0}; - MD_ExprOprPush(arena, &operator_list, Op_Addition, MD_ExprOprKind_Null, 1, plus_node); + MD_ExprOprPush(arena, &operator_list, MD_ExprOprKind_Null, 1, MD_S8Lit("+"), + Op_Addition, plus_node); op_table = MD_ExprBakeOperatorTableFromList(arena, &operator_list); MD_Assert(op_table.errors.max_message_kind = MD_MessageKind_Warning && op_table.errors.node_count == 1 && op_table.errors.first->node == plus_node); // NOTE: Repeat operator operator_list = (MD_ExprOprList){0}; - MD_ExprOprPush(arena, &operator_list, Op_Addition, MD_ExprOprKind_Binary, 1, plus_node); - MD_ExprOprPush(arena, &operator_list, Op_Addition, MD_ExprOprKind_Binary, 1, plus_node_bis); + MD_ExprOprPush(arena, &operator_list, MD_ExprOprKind_Binary, 1, MD_S8Lit("+"), + Op_Addition, plus_node); + MD_ExprOprPush(arena, &operator_list, MD_ExprOprKind_Binary, 1, MD_S8Lit("+"), + Op_Addition, plus_node_bis); op_table = MD_ExprBakeOperatorTableFromList(arena, &operator_list); MD_Assert(op_table.errors.max_message_kind = MD_MessageKind_Warning && op_table.errors.node_count == 1 && op_table.errors.first->node == plus_node_bis); operator_list = (MD_ExprOprList){0}; // NOTE: Binary-postfix operator conflict - MD_ExprOprPush(arena, &operator_list, Op_Addition, MD_ExprOprKind_Binary, 1, plus_node); - MD_ExprOprPush(arena, &operator_list, Op_Addition, MD_ExprOprKind_Postfix, 1, plus_node_bis); + MD_ExprOprPush(arena, &operator_list, MD_ExprOprKind_Binary, 1, MD_S8Lit("+"), + Op_Addition, plus_node); + MD_ExprOprPush(arena, &operator_list, MD_ExprOprKind_Postfix, 1, MD_S8Lit("+"), + Op_Addition, plus_node_bis); op_table = MD_ExprBakeOperatorTableFromList(arena, &operator_list); MD_Assert(op_table.errors.max_message_kind = MD_MessageKind_Warning && op_table.errors.node_count == 1 && op_table.errors.first->node == plus_node_bis); operator_list = (MD_ExprOprList){0}; // NOTE: Same precedence difference associativity conflict - MD_ExprOprPush(arena, &operator_list, Op_Addition, MD_ExprOprKind_Binary, 1, plus_node); - MD_ExprOprPush(arena, &operator_list, Op_Addition, MD_ExprOprKind_BinaryRightAssociative, - 1, minus_node); + MD_ExprOprPush(arena, &operator_list, MD_ExprOprKind_Binary, 1, MD_S8Lit("+"), + Op_Addition, plus_node); + MD_ExprOprPush(arena, &operator_list, MD_ExprOprKind_BinaryRightAssociative, 1, MD_S8Lit("-"), + Op_Addition, minus_node); op_table = MD_ExprBakeOperatorTableFromList(arena, &operator_list); MD_Assert(op_table.errors.max_message_kind = MD_MessageKind_Warning && op_table.errors.node_count == 1 && op_table.errors.first->node == minus_node); @@ -280,7 +286,8 @@ operator_array[Op_##name].op = (MD_ExprOpr){ .op_id = Op_##name, .kind = MD_Expr { OperatorDescription *desc = operator_array + op; MD_Node *node = MD_MakeNode(arena, MD_NodeKind_Main, desc->s, desc->s, 0); - MD_ExprOprPush(arena, &operator_list, op, desc->op.kind, desc->op.precedence, node); + MD_ExprOprPush(arena, &operator_list, desc->op.kind, desc->op.precedence, desc->s, + op, node); } MD_ExprOprTable op_table = MD_ExprBakeOperatorTableFromList(arena, &operator_list);