diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 4e056cb1..3acca27f 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -35,7 +35,7 @@ e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens); - E_Eval eval = e_eval_from_expr(arena, parse.exprs.first); + E_Eval eval = e_eval_from_expr(arena, parse.expr); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; } @@ -337,7 +337,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) S32 indent; }; str8_list_pushf(scratch.arena, &strings, " expr:\n"); - Task start_task = {0, parse.exprs.first, 2}; + Task start_task = {0, parse.expr, 2}; Task *first_task = &start_task; for(Task *t = first_task; t != 0; t = t->next) { @@ -370,7 +370,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.first); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 483a9409..a1078495 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -514,7 +514,7 @@ struct E_AutoHookNode E_AutoHookNode *pattern_order_next; String8 type_string; String8List type_pattern_parts; - E_ExprChain tag_exprs; + E_Expr *expr; }; typedef struct E_AutoHookSlot E_AutoHookSlot; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 9838c363..902a90f0 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -123,14 +123,14 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * { E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, tokens); - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); type_key = irtree.type_key; } E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key)); U8 pattern_split = '?'; node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties); - node->tag_exprs = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).exprs; + node->expr = e_parse_expr_from_text(arena, push_str8_copy(arena, params->tag_expr_string)).expr; if(!e_type_key_match(e_type_key_zero(), type_key)) { U64 hash = e_hash_from_string(5381, node->type_string); @@ -164,10 +164,7 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { if(str8_match(n->type_string, type_string, 0)) { - for(E_Expr *e = n->tag_exprs.first; e != &e_expr_nil; e = e->next) - { - e_expr_list_push(arena, &exprs, e); - } + e_expr_list_push(arena, &exprs, n->expr); } } } @@ -197,10 +194,7 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } if(fits_this_type_string) { - for(E_Expr *e = auto_hook_node->tag_exprs.first; e != &e_expr_nil; e = e->next) - { - e_expr_list_push(arena, &exprs, e); - } + e_expr_list_push(arena, &exprs, auto_hook_node->expr); } } } @@ -2253,6 +2247,58 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) }break; } + //- rjf: check chained expressions for simple wrappers + { + struct + { + String8 shorthand; + String8 full_name; + } + shorthand_lens_pair_table[] = + { + {str8_lit("x"), str8_lit("hex")}, + {str8_lit("b"), str8_lit("bin")}, + {str8_lit("o"), str8_lit("oct")}, + {str8_lit("d"), str8_lit("dec")}, + }; + for(E_Expr *chained_expr = expr->next; + chained_expr != &e_expr_nil; + chained_expr = chained_expr->next) + { + B32 matches_shorthand = 0; + if(chained_expr->kind == E_ExprKind_LeafIdentifier) + { + for EachElement(shorthand_idx, shorthand_lens_pair_table) + { + if(str8_match(chained_expr->string, shorthand_lens_pair_table[shorthand_idx].shorthand, 0)) + { + String8 full_name = shorthand_lens_pair_table[shorthand_idx].full_name; + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .direct_key = result.type_key, + .name = full_name); + matches_shorthand = 1; + break; + } + } + } + if(!matches_shorthand && e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_AllDecorative)))) + { + E_Expr *lens_spec_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, str8_lit("array")); + E_TypeKey lens_spec_type_key = lens_spec_expr->type_key; + E_Type *lens_spec_type = e_type_from_key__cached(lens_spec_type_key); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .flags = lens_spec_type->flags, + .count = 1, + .args = &chained_expr, + .direct_key = result.type_key, + .name = lens_spec_type->name, + .irext = lens_spec_type->irext, + .access = lens_spec_type->access, + .expand = lens_spec_type->expand); + } + } + } + //- rjf: if the evaluated type has a hook for an extra layer of ir extension, // call into it E_Type *type = e_type_from_key__cached(result.type_key); diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index fbbae582..7c9bf0cc 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -798,14 +798,14 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) } // rjf: construct leaf type - parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); - parse.exprs.first->type_key = type_key; + parse.expr = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str); + parse.expr->type_key = type_key; } } } //- rjf: parse extensions - if(parse.exprs.first != &e_expr_nil) + if(parse.expr != &e_expr_nil) { for(;;) { @@ -818,9 +818,9 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) if(str8_match(token_string, str8_lit("*"), 0)) { token_it += 1; - E_Expr *ptee = parse.exprs.first; - parse.exprs.first = parse.exprs.last = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); - e_expr_push_child(parse.exprs.first, ptee); + E_Expr *ptee = parse.expr; + parse.expr = e_push_expr(arena, E_ExprKind_Ptr, token_string.str); + e_expr_push_child(parse.expr, ptee); } else { @@ -941,7 +941,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse type expr E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it, it_opl)); - E_Expr *type = type_parse.exprs.last; + E_Expr *type = type_parse.expr; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; location = token_string.str; @@ -1029,7 +1029,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse () contents E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.exprs.last; + atom = nested_parse.expr; it = nested_parse.last_token; // rjf: expect ) @@ -1058,11 +1058,11 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse [] contents E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); - atom = nested_parse.exprs.last; + atom = nested_parse.expr; it = nested_parse.last_token; // rjf: build cast-to-U64*, and dereference operators - if(nested_parse.exprs.last == &e_expr_nil) + if(nested_parse.expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression following `[`."); } @@ -1253,10 +1253,10 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok it = idx_expr_parse.last_token; // rjf: valid indexing expression => produce index expr - if(idx_expr_parse.exprs.last != &e_expr_nil) + if(idx_expr_parse.expr != &e_expr_nil) { E_Expr *array_expr = atom; - E_Expr *index_expr = idx_expr_parse.exprs.last; + E_Expr *index_expr = idx_expr_parse.expr; atom = e_push_expr(arena, E_ExprKind_ArrayIndex, token_string.str); e_expr_push_child(atom, array_expr); e_expr_push_child(atom, index_expr); @@ -1294,11 +1294,14 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); it = args_parse.last_token; - if(args_parse.exprs.first != &e_expr_nil) + if(args_parse.expr != &e_expr_nil) { - call_expr->last->next = args_parse.exprs.first; - args_parse.exprs.first->prev = call_expr->last; - call_expr->last = args_parse.exprs.last; + call_expr->last->next = args_parse.expr; + args_parse.expr->prev = call_expr->last; + for(E_Expr *arg = args_parse.expr; arg != &e_expr_nil; arg = arg->next) + { + call_expr->last = arg; + } } atom = call_expr; @@ -1388,7 +1391,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok { E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - E_Expr *rhs = rhs_expr_parse.exprs.last; + E_Expr *rhs = rhs_expr_parse.expr; it = rhs_expr_parse.last_token; if(rhs == &e_expr_nil) { @@ -1413,9 +1416,9 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: parse middle expression E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); it = middle_expr_parse.last_token; - E_Expr *middle_expr = middle_expr_parse.exprs.last; + E_Expr *middle_expr = middle_expr_parse.expr; e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); - if(middle_expr_parse.exprs.last == &e_expr_nil) + if(middle_expr_parse.expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected expression after `?`."); } @@ -1446,7 +1449,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok { it = rhs_expr_parse.last_token; e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); - if(rhs_expr_parse.exprs.last == &e_expr_nil) + if(rhs_expr_parse.expr == &e_expr_nil) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, colon_token_string.str, "Expected expression after `:`."); } @@ -1454,12 +1457,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: build ternary if(atom != &e_expr_nil && - middle_expr_parse.exprs.last != &e_expr_nil && - rhs_expr_parse.exprs.last != &e_expr_nil) + middle_expr_parse.expr != &e_expr_nil && + rhs_expr_parse.expr != &e_expr_nil) { E_Expr *lhs = atom; - E_Expr *mhs = middle_expr_parse.exprs.last; - E_Expr *rhs = rhs_expr_parse.exprs.last; + E_Expr *mhs = middle_expr_parse.expr; + E_Expr *rhs = rhs_expr_parse.expr; atom = e_push_expr(arena, E_ExprKind_Ternary, token_string.str); e_expr_push_child(atom, lhs); e_expr_push_child(atom, mhs); @@ -1478,7 +1481,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok //- rjf: store parsed atom to expression chain - if we didn't get an expression, break if(atom != &e_expr_nil) { - DLLPushBack_NPZ(&e_expr_nil, result.exprs.first, result.exprs.last, atom, next, prev); + DLLPushBack_NPZ(&e_expr_nil, result.expr, result.last_expr, atom, next, prev); chain_count += 1; } else diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 493dbad7..84f26343 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -11,7 +11,8 @@ typedef struct E_Parse E_Parse; struct E_Parse { E_Token *last_token; - E_ExprChain exprs; + E_Expr *expr; + E_Expr *last_expr; E_MsgList msgs; }; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 3be74495..7c211371 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1942,7 +1942,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) type_kind == E_TypeKind_Enum)) { got_commit_data = 1; - E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; + E_Expr *src_expr = e_parse_expr_from_text(scratch.arena, string).expr; E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); @@ -2096,7 +2096,7 @@ rd_query_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).expr; if(expr->kind == E_ExprKind_LeafIdentifier && str8_match(expr->qualifier, str8_lit("query"), 0)) { @@ -12045,7 +12045,7 @@ rd_frame(void) //- rjf: add macro for 'call_stack' -> 'query:current_thread.callstack' { - E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).exprs.first; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, str8_lit("query:current_thread.call_stack")).expr; e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("call_stack"), expr); } @@ -12247,7 +12247,7 @@ rd_frame(void) E_Parse parse = e_parse_expr_from_text(scratch.arena, expr); if(parse.msgs.max_kind == E_MsgKind_Null) { - for(E_Expr *expr = parse.exprs.first; expr != &e_expr_nil; expr = expr->next) + for(E_Expr *expr = parse.expr; expr != &e_expr_nil; expr = expr->next) { e_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ctx->macro_map, expr); } @@ -15707,7 +15707,7 @@ Z(getting_started) ExprWalkTask *next; E_Expr *expr; }; - E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd).exprs.last; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, src_bp_cnd).expr; ExprWalkTask start_task = {0, expr}; ExprWalkTask *first_task = &start_task; for(ExprWalkTask *t = first_task; t != 0; t = t->next) diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 51095516..5c61ffa4 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -136,7 +136,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(watches) if(cfg_idx < cfgs->count) { String8 expr_string = rd_cfg_child_from_string(cfgs->v[cfg_idx], str8_lit("expression"))->first->string; - exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).exprs.first; + exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).expr; exprs_strings_out[idx] = push_str8_copy(arena, expr_string); } } @@ -218,7 +218,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(locals) for(U64 idx = 0; idx < read_range_count; idx += 1) { String8 expr_string = accel->v[read_range.min + idx]; - exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).exprs.last; + exprs_out[idx] = e_parse_expr_from_text(arena, expr_string).expr; exprs_strings_out[idx] = push_str8_copy(arena, expr_string); } } @@ -270,7 +270,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(registers) String8 register_name = accel->v[read_range.min + idx]; String8 register_expr = push_str8f(arena, "reg:%S", register_name); exprs_strings_out[idx] = register_name; - exprs_out[idx] = e_parse_expr_from_text(arena, register_expr).exprs.last; + exprs_out[idx] = e_parse_expr_from_text(arena, register_expr).expr; } } @@ -400,7 +400,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) if(wrap_child_w_meta_expr) { Temp scratch = scratch_begin(&arena, 1); - E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).exprs.first; + E_Expr *expr = e_parse_expr_from_text(scratch.arena, child->first->string).expr; B32 expr_is_simple = 0; if(expr->kind == E_ExprKind_LeafU64 || expr->kind == E_ExprKind_LeafF64 || @@ -428,8 +428,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) if(!md_node_is_nil(range)) { Temp scratch = scratch_begin(&arena, 1); - E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).exprs.first; - E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).exprs.first; + E_Expr *min_bound = e_parse_expr_from_text(scratch.arena, range->first->string).expr; + E_Expr *max_bound = e_parse_expr_from_text(scratch.arena, range->first->next->string).expr; E_Expr *args[] = { min_bound, @@ -689,7 +689,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).exprs.last; + E_Expr *commands = e_parse_expr_from_text(arena, str8_lit("query:commands")).expr; E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(arena, commands); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5c6220ee..90bfa3fa 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1445,7 +1445,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla E_Expr *root_expr = row->eval.expr; if(wrap_string.size != 0) { - E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).exprs.last; + E_Expr *wrap_expr = e_parse_expr_from_text(scratch.arena, wrap_string).expr; root_expr = wrap_expr; typedef struct Task Task; struct Task