eval2: fix parsing task popping rules, still give chance to rhs when popping tasks in all cases

This commit is contained in:
Ryan Fleury
2026-06-27 04:25:05 -07:00
parent b704e797e2
commit cae9754099
5 changed files with 217 additions and 224 deletions
+15 -27
View File
@@ -1571,6 +1571,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
for(B32 done = 0; !done;) for(B32 done = 0; !done;)
{ {
U64 start_off = off; U64 start_off = off;
E2_ParseTask *start_task = state->top_task;
S64 max_precedence = state->top_task->max_precedence; S64 max_precedence = state->top_task->max_precedence;
B32 type_ancestors = state->top_task->do_type_ancestors; B32 type_ancestors = state->top_task->do_type_ancestors;
B32 need_new_expr = (expr == &e2_expr_nil && !type_ancestors && !state->caller_info_completes_task); B32 need_new_expr = (expr == &e2_expr_nil && !type_ancestors && !state->caller_info_completes_task);
@@ -1615,17 +1616,21 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
//- rjf: symbols (possible prefix unaries, *or* unexpected) //- rjf: symbols (possible prefix unaries, *or* unexpected)
else if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_Symbol, s(""), &off, &token)) else if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_Symbol, s(""), &off, &token))
{ {
String8 token_string = str8_substr(string, token.range);
// rjf: string -> operator kind // rjf: string -> operator kind
B32 unexpected = !str8_match(token_string, state->top_task->expected_closer, 0);
E2_ExprKind expr_kind = E2_ExprKind_Null; E2_ExprKind expr_kind = E2_ExprKind_Null;
String8 closer = {0}; String8 closer = {0};
S64 precedence = 0; S64 precedence = 0;
{ {
String8 token_string = str8_substr(string, token.range);
for EachIndex(idx, lang_info->expr_kind_parse_infos_count) for EachIndex(idx, lang_info->expr_kind_parse_infos_count)
{ {
if(lang_info->expr_kind_parse_infos[idx].parse_kind == E2_ExprParseKind_Prefix && if(lang_info->expr_kind_parse_infos[idx].parse_kind == E2_ExprParseKind_Prefix &&
lang_info->expr_kind_parse_infos[idx].precedence <= max_precedence &&
str8_match(token_string, lang_info->expr_kind_parse_infos[idx].pre, 0)) str8_match(token_string, lang_info->expr_kind_parse_infos[idx].pre, 0))
{
unexpected = 0;
if(lang_info->expr_kind_parse_infos[idx].precedence <= max_precedence)
{ {
expr_kind = lang_info->expr_kind_parse_infos[idx].expr_kind; expr_kind = lang_info->expr_kind_parse_infos[idx].expr_kind;
closer = lang_info->expr_kind_parse_infos[idx].post; closer = lang_info->expr_kind_parse_infos[idx].post;
@@ -1634,6 +1639,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
} }
} }
} }
}
// rjf: push task for operand // rjf: push task for operand
if(expr_kind != E2_ExprKind_Null) if(expr_kind != E2_ExprKind_Null)
@@ -1657,9 +1663,8 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
} }
// rjf: report unexpected symbols // rjf: report unexpected symbols
if(expr_kind == E2_ExprKind_Null) if(expr_kind == E2_ExprKind_Null && unexpected)
{ {
String8 token_string = str8_substr(string, token.range);
e2_msgf(arena, &parse.msgs, token.range, "Unexpected `%S`.", token_string); e2_msgf(arena, &parse.msgs, token.range, "Unexpected `%S`.", token_string);
} }
} }
@@ -1935,7 +1940,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
//- rjf: if we're parsing a type, and we see a C-style type info recursion (to //- rjf: if we're parsing a type, and we see a C-style type info recursion (to
// express ancestors of the current type), then we need to generate a task to // express ancestors of the current type), then we need to generate a task to
// descend and parse the ancestor type // descend and parse the ancestor type
if(!state->caller_info_completes_task && expr != &e2_expr_nil) if(!state->caller_info_completes_task && expr != &e2_expr_nil && (state->top_task->next_type_ancestor == 0 || state->top_task->next_type_ancestor == &e2_expr_nil))
{ {
B32 parent_looking_for_type = (state->top_task->expr_kind != E2_ExprKind_Null && B32 parent_looking_for_type = (state->top_task->expr_kind != E2_ExprKind_Null &&
state->top_task->child_count == 0 && state->top_task->child_count == 0 &&
@@ -2031,12 +2036,8 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
} }
} }
//- rjf: attach formed expressions to parent task exprs; pop tasks when they're done. //- rjf: attach formed expressions to parent task; pop task if done.
// if we have no parent task, then we just fill the result, and we're done with the parse.
if(state->caller_info_completes_task || expr != &e2_expr_nil) if(state->caller_info_completes_task || expr != &e2_expr_nil)
{
//- rjf: pop finished expressions
for(B32 task_pushed = 0; state->top_task != 0 && !done && !task_pushed;)
{ {
//- rjf: if this task has a type ancestor: our finished expression is //- rjf: if this task has a type ancestor: our finished expression is
// actually a descendant of that. we want to push our finished expression // actually a descendant of that. we want to push our finished expression
@@ -2156,7 +2157,6 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
E2_ExprNode *child_n = push_array(arena, E2_ExprNode, 1); E2_ExprNode *child_n = push_array(arena, E2_ExprNode, 1);
SLLQueuePush(task->first_child, task->last_child, child_n); SLLQueuePush(task->first_child, task->last_child, child_n);
child_n->v = type_expr; child_n->v = type_expr;
task_pushed = 1;
} }
} }
@@ -2216,33 +2216,21 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type,
SLLStackPop(state->top_task); SLLStackPop(state->top_task);
SLLStackPush(state->free_task, completed_task); SLLStackPush(state->free_task, completed_task);
} }
//- rjf: if this task still has potential right-hand-sides, then we need to
// break out of the pop-loop and keep parsing at this level.
if(state->top_task->expr_kind == E2_ExprKind_Null || completed_task->do_type_ancestors)
{
break;
}
} }
//- rjf: if the top task is not done -> break & continue. //- rjf: if the top task is not done -> continue parsing.
// //
// if we have an active op kind, reset expression, because we need to parse another. // if we have an active op kind, reset expression, because we need to parse another.
// if we don't, we need to look for extensions of our current expression instead. // if we don't, we need to look for extensions of our current expression instead.
// //
else else if(state->top_task->expr_kind != E2_ExprKind_Null)
{
if(state->top_task->expr_kind != E2_ExprKind_Null)
{ {
expr = &e2_expr_nil; expr = &e2_expr_nil;
} }
break;
}
}
} }
//- rjf: we're always done if there's nothing left to parse, *or* if we made no progress. //- rjf: we're done if we couldn't make any more progress.
if(off >= string.size || (off == start_off && !e2_parse_status_is_caller_request(parse.status))) if(start_task == state->top_task && (off >= string.size || (off == start_off && !e2_parse_status_is_caller_request(parse.status))))
{ {
done = 1; done = 1;
if(expr != &e2_expr_nil) if(expr != &e2_expr_nil)
+2 -1
View File
@@ -9,12 +9,13 @@ E2_ExprKindTable:
{TypeIdentifier 0 1 0 0 } {TypeIdentifier 0 1 0 0 }
{Ptr 1 1 1 1 } {Ptr 1 1 1 1 }
{Array 1 1 1 2 } {Array 1 1 1 2 }
{Function 1 1 1 0xffffffffffffffffull}
{Numeric 0 0 0 0 } {Numeric 0 0 0 0 }
{StringLiteral 0 0 0 0 } {StringLiteral 0 0 0 0 }
{CharLiteral 0 0 0 0 } {CharLiteral 0 0 0 0 }
{Dot 1 0 0 1 } {Dot 1 0 0 1 }
{Index 0 0 0 2 } {Index 0 0 0 2 }
{Call 1 0 0 0xffffffffffffffffull} {Call 0 0 0 0xffffffffffffffffull}
{DerefAsm 1 0 0 1 } {DerefAsm 1 0 0 1 }
{SizeOf 1 0 1 1 } {SizeOf 1 0 1 1 }
{TypeOf 1 1 1 1 } {TypeOf 1 1 1 1 }
+9 -5
View File
@@ -4,7 +4,7 @@
//- GENERATED CODE //- GENERATED CODE
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
B8 e2_expr_kind_allow_type_operands_table[43] = B8 e2_expr_kind_allow_type_operands_table[44] =
{ {
0, 0,
0, 0,
@@ -12,12 +12,13 @@ B8 e2_expr_kind_allow_type_operands_table[43] =
0, 0,
1, 1,
1, 1,
1,
0, 0,
0, 0,
0, 0,
1, 1,
0, 0,
1, 0,
1, 1,
1, 1,
1, 1,
@@ -51,7 +52,7 @@ B8 e2_expr_kind_allow_type_operands_table[43] =
1, 1,
}; };
B8 e2_expr_kind_is_type_expr_table[43] = B8 e2_expr_kind_is_type_expr_table[44] =
{ {
0, 0,
0, 0,
@@ -59,6 +60,7 @@ B8 e2_expr_kind_is_type_expr_table[43] =
1, 1,
1, 1,
1, 1,
1,
0, 0,
0, 0,
0, 0,
@@ -98,7 +100,7 @@ B8 e2_expr_kind_is_type_expr_table[43] =
0, 0,
}; };
B8 e2_expr_kind_is_first_operand_type_maybe_table[43] = B8 e2_expr_kind_is_first_operand_type_maybe_table[44] =
{ {
0, 0,
0, 0,
@@ -106,6 +108,7 @@ B8 e2_expr_kind_is_first_operand_type_maybe_table[43] =
0, 0,
1, 1,
1, 1,
1,
0, 0,
0, 0,
0, 0,
@@ -145,7 +148,7 @@ B8 e2_expr_kind_is_first_operand_type_maybe_table[43] =
0, 0,
}; };
U64 e2_expr_kind_target_operand_count_table[43] = U64 e2_expr_kind_target_operand_count_table[44] =
{ {
0, 0,
0, 0,
@@ -153,6 +156,7 @@ U64 e2_expr_kind_target_operand_count_table[43] =
0, 0,
1, 1,
2, 2,
0xffffffffffffffffull,
0, 0,
0, 0,
0, 0,
+5 -4
View File
@@ -14,6 +14,7 @@ E2_ExprKind_MacroArg,
E2_ExprKind_TypeIdentifier, E2_ExprKind_TypeIdentifier,
E2_ExprKind_Ptr, E2_ExprKind_Ptr,
E2_ExprKind_Array, E2_ExprKind_Array,
E2_ExprKind_Function,
E2_ExprKind_Numeric, E2_ExprKind_Numeric,
E2_ExprKind_StringLiteral, E2_ExprKind_StringLiteral,
E2_ExprKind_CharLiteral, E2_ExprKind_CharLiteral,
@@ -158,10 +159,10 @@ E2_ExprKindParseInfo *expr_kind_parse_infos;
}; };
C_LINKAGE_BEGIN C_LINKAGE_BEGIN
extern B8 e2_expr_kind_allow_type_operands_table[43]; extern B8 e2_expr_kind_allow_type_operands_table[44];
extern B8 e2_expr_kind_is_type_expr_table[43]; extern B8 e2_expr_kind_is_type_expr_table[44];
extern B8 e2_expr_kind_is_first_operand_type_maybe_table[43]; extern B8 e2_expr_kind_is_first_operand_type_maybe_table[44];
extern U64 e2_expr_kind_target_operand_count_table[43]; extern U64 e2_expr_kind_target_operand_count_table[44];
extern E2_LangInfo e2_lang_kind_info_table[1]; extern E2_LangInfo e2_lang_kind_info_table[1];
extern E2_ExprKindParseInfo e2_expr_kind_parse_info_table__clike[38]; extern E2_ExprKindParseInfo e2_expr_kind_parse_info_table__clike[38];
extern U8 e2_type_kind_basic_byte_size_table[61]; extern U8 e2_type_kind_basic_byte_size_table[61];
+3 -4
View File
@@ -43,8 +43,9 @@ entry_point(CmdLine *cmdline)
// (A) // (A)
// int & B // int & B
// (1 + (int)&B) // (1 + (int)&B)
s("int32 *"),
// TODO(rjf): this is now busted, `mul` root comes out - related to always having a top task maybe? s("int32[100]"),
s("int32 (*) [100]"),
s("3 * 4 + 2"), s("3 * 4 + 2"),
s("(3 * 4) + 2"), s("(3 * 4) + 2"),
s("3 * 4"), s("3 * 4"),
@@ -57,8 +58,6 @@ entry_point(CmdLine *cmdline)
s("123, 456"), s("123, 456"),
s("222.f"), s("222.f"),
s("123 as float32"), s("123 as float32"),
s("int32 (*) [100]"),
s("int32[100]"),
s("cast float32 123"), s("cast float32 123"),
s("cast (float32) 123"), s("cast (float32) 123"),
s("(int32 *)123"), s("(int32 *)123"),