mirror of
https://github.com/Ed94/metadesk.git
synced 2026-07-20 23:46:48 +00:00
[expr parser] change the operator definition so that an MD_Node is not required
This commit is contained in:
+26
-19
@@ -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
|
||||
|
||||
+8
-5
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user