From f521e01d6e8d2b7c68d7dfe0641e5768779c5b1d Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 29 Apr 2025 15:26:40 -0700 Subject: [PATCH] dynamic ternaries in ir tree evaluation, fixes to over-ambitious parsing of identifier qualifiers --- src/eval/eval_ir.c | 32 ++++++++++++++++++++++++++++---- src/eval/eval_parse.c | 2 +- src/eval/eval_types.c | 9 ++++++++- src/mule/mule_main.cpp | 7 +++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 56a3b45c..5066136b 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1232,7 +1232,6 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 E_TypeKind c_type_kind = e_type_kind_from_key(c_type); E_TypeKind l_type_kind = e_type_kind_from_key(l_type); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - E_TypeKey result_type = l_type; // rjf: bad conditions? -> error if applicable, exit if(c_tree.root->op == 0 || l_tree.root->op == 0 || r_tree.root->op == 0) @@ -1243,12 +1242,37 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Conditional term must be an integer or boolean type."); } - else if(!e_type_match(l_type, r_type)) + + // rjf: determine the resultant type - if the left/right types match, then we + // can just pick the left type, and defer 100% of our interpretation. however, + // if the types do *not* match, then we need to pre-emptively evaluate the + // condition, and pick the result based on that. + B32 ternary_is_dynamic = 0; + E_TypeKey result_type = l_type; + if(!e_type_match(l_type, r_type)) { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left and right terms must have matching types."); + ternary_is_dynamic = 1; } - // rjf: generate + // rjf: generate dynamic ternary + if(ternary_is_dynamic) + { + E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, c_value_tree); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interpretation = e_interpret(bytecode); + if(interpretation.value.u64 != 0) + { + result = l_tree; + } + else + { + result = r_tree; + } + } + + // rjf: generate static ternary + else { E_IRNode *c_value_tree = e_irtree_resolve_to_value(arena, c_tree.mode, c_tree.root, c_type); E_IRNode *l_value_tree = e_irtree_resolve_to_value(arena, l_tree.mode, l_tree.root, l_type); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index c437c23d..a2b2f1a0 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -945,7 +945,7 @@ e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray t { E_Token next_token = e_token_at_it(it+1, &tokens); String8 next_token_string = str8_substr(text, next_token.range); - if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) + if(next_token.range.min == token.range.max && next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) { it += 2; resolution_qualifier = token_string; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index d59f999b..6264c1e7 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1516,7 +1516,14 @@ e_type_match(E_TypeKey l, E_TypeKey r) { default: { - result = 1; + if(e_type_kind_is_basic_or_enum(luk)) + { + result = 1; + } + else + { + result = 0; + } }break; case E_TypeKind_Ptr: diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index f42810ba..b9276f41 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -249,6 +249,13 @@ struct Discriminated_Union }; }; +raddbg_auto_view_rule(Discriminated_Union, + kind == Kind.First ? first : + kind == Kind.Second ? second : + kind == Kind.Third ? third : + kind == Kind.Fourth ? fourth : + $); + struct Linked_List{ Linked_List *next; Linked_List *prev;