diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index c9d16e95..0e3ec2a7 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4699,12 +4699,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); ctx->macro_map = push_array(arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(arena, 512); -#if 0 // TODO(rjf): @eval - ctx->lookup_rule_map = push_array(arena, E_LookupRuleMap, 1); - ctx->lookup_rule_map[0] = e_lookup_rule_map_make(arena, 512); - ctx->irgen_rule_map = push_array(arena, E_IRGenRuleMap, 1); - ctx->irgen_rule_map[0] = e_irgen_rule_map_make(arena, 512); -#endif ctx->auto_hook_map = push_array(arena, E_AutoHookMap, 1); ctx->auto_hook_map[0] = e_auto_hook_map_make(arena, 512); } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 78a7021c..62bf70a7 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -581,45 +581,6 @@ struct E_LookupRuleExprPair }; #endif -//////////////////////////////// -//~ rjf: IR Generation Hooks - -#if 0 // TODO(rjf): @eval -#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr) -#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name -#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name)) -typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType); -E_IRGEN_FUNCTION_DEF(default); - -typedef struct E_IRGenRule E_IRGenRule; -struct E_IRGenRule -{ - String8 name; - E_IRGenFunctionType *irgen; -}; - -typedef struct E_IRGenRuleNode E_IRGenRuleNode; -struct E_IRGenRuleNode -{ - E_IRGenRuleNode *next; - E_IRGenRule v; -}; - -typedef struct E_IRGenRuleSlot E_IRGenRuleSlot; -struct E_IRGenRuleSlot -{ - E_IRGenRuleNode *first; - E_IRGenRuleNode *last; -}; - -typedef struct E_IRGenRuleMap E_IRGenRuleMap; -struct E_IRGenRuleMap -{ - U64 slots_count; - E_IRGenRuleSlot *slots; -}; -#endif - //////////////////////////////// //~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 03cb1a7f..56e83ce2 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -699,150 +699,6 @@ E_LOOKUP_RANGE_FUNCTION_DEF(only_and_omit) } #endif -//////////////////////////////// -//~ rjf: Lookups - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleMap -e_lookup_rule_map_make(Arena *arena, U64 slots_count) -{ - E_LookupRuleMap map = {0}; - map.slots_count = slots_count; - map.slots = push_array(arena, E_LookupRuleSlot, map.slots_count); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("default"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(default), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(default), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("folder"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(folder), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(folder), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(folder)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(file), - .access = E_LOOKUP_ACCESS_FUNCTION_NAME(file), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(slice), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(slice)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("only"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(only), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); - e_lookup_rule_map_insert_new(arena, &map, str8_lit("omit"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(omit), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(only_and_omit)); - return map; -} - -internal void -e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule) -{ - U64 hash = e_hash_from_string(5381, rule->name); - U64 slot_idx = hash%map->slots_count; - E_LookupRuleNode *n = push_array(arena, E_LookupRuleNode, 1); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); - MemoryCopyStruct(&n->v, rule); - if(n->v.info == 0) { n->v.info = E_LOOKUP_INFO_FUNCTION_NAME(default); } - if(n->v.access == 0) { n->v.access = E_LOOKUP_ACCESS_FUNCTION_NAME(default); } - if(n->v.range == 0) { n->v.range = E_LOOKUP_RANGE_FUNCTION_NAME(default); } - if(n->v.id_from_num == 0){ n->v.id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default); } - if(n->v.num_from_id == 0){ n->v.num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default); } - n->v.name = push_str8_copy(arena, n->v.name); -} - -internal E_LookupRule * -e_lookup_rule_from_string(String8 string) -{ - E_LookupRule *result = &e_lookup_rule__nil; - if(e_ir_state->ctx->lookup_rule_map != 0 && e_ir_state->ctx->lookup_rule_map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%e_ir_state->ctx->lookup_rule_map->slots_count; - for(E_LookupRuleNode *n = e_ir_state->ctx->lookup_rule_map->slots[slot_idx].first; - n != 0; - n = n->next) - { - if(str8_match(n->v.name, string, 0)) - { - result = &n->v; - break; - } - } - } - return result; -} -#endif - -//////////////////////////////// -//~ rjf: IR Gen Rules - -#if 0 // TODO(rjf): @eval -E_IRGEN_FUNCTION_DEF(bswap) -{ - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr); - E_IRNode *root = e_push_irnode(arena, RDI_EvalOp_ByteSwap); - e_irnode_push_child(root, irtree.root); - E_IRTreeAndType result = {root, irtree.type_key, irtree.mode, irtree.msgs}; - return result; -} - -E_IRGEN_FUNCTION_DEF(array) -{ - E_Expr *ptr_expr = expr->first->next; - E_Expr *count_expr = ptr_expr->next; - E_IRTreeAndType result = e_irtree_and_type_from_expr(arena, ptr_expr); - E_TypeKey element_type_key = e_type_ptee_from_key(result.type_key); - E_Value count_value = e_value_from_expr(count_expr); - result.type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, element_type_key, count_value.u64, 0); - return result; -} - -internal E_IRGenRuleMap -e_irgen_rule_map_make(Arena *arena, U64 slots_count) -{ - E_IRGenRuleMap map = {0}; - map.slots_count = slots_count; - map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("default"), .irgen = E_IRGEN_FUNCTION_NAME(default)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("bswap"), .irgen = E_IRGEN_FUNCTION_NAME(bswap)); - e_irgen_rule_map_insert_new(arena, &map, str8_lit("array"), .irgen = E_IRGEN_FUNCTION_NAME(array)); - return map; -} - -internal void -e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule) -{ - U64 hash = e_hash_from_string(5381, rule->name); - U64 slot_idx = hash%map->slots_count; - E_IRGenRuleNode *n = push_array(arena, E_IRGenRuleNode, 1); - MemoryCopyStruct(&n->v, rule); - n->v.name = push_str8_copy(arena, n->v.name); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n); -} - -internal E_IRGenRule * -e_irgen_rule_from_string(String8 string) -{ - E_IRGenRule *rule = &e_irgen_rule__default; - if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->ctx->irgen_rule_map != 0 && e_ir_state->ctx->irgen_rule_map->slots_count != 0) - { - E_IRGenRuleMap *map = e_ir_state->ctx->irgen_rule_map; - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%map->slots_count; - for(E_IRGenRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next) - { - if(str8_match(string, n->v.name, 0)) - { - rule = &n->v; - break; - } - } - } - return rule; -} -#endif - //////////////////////////////// //~ rjf: Auto Hooks @@ -1658,8 +1514,47 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { default:{}break; - //- rjf: accesses + //- rjf: member accesses case E_ExprKind_MemberAccess: + { + // rjf: unpack left-hand-size + E_Expr *lhs = expr->first; + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + + // rjf: if the right-hand-side is a call, then this is short-hand for + // the right-hand-side call, with the left-hand-side as the first argument. + E_Expr *rhs = lhs->next; + if(rhs->kind == E_ExprKind_Call) + { + E_Expr *rhs_copy = e_expr_copy(arena, rhs); + e_expr_insert_child(rhs_copy, rhs_copy->first, e_expr_ref(arena, lhs)); + result = e_irtree_and_type_from_expr(arena, rhs_copy); + } + + // rjf: if the right-hand-side is a leaf identifier, then this is an + // "access" to the left-hand-side. + else if(rhs->kind == E_ExprKind_LeafIdentifier) + { + // rjf: pick access hook based on type + E_Type *lhs_type = e_type_from_key__cached(lhs_irtree.type_key); + E_TypeAccessFunctionType *lhs_access = lhs_type->access; + if(lhs_access == 0) + { + lhs_access = E_TYPE_ACCESS_FUNCTION_NAME(default); + } + + // rjf: call into hook to do access + result = lhs_access(arena, expr, &lhs_irtree); + } + + // rjf: if the right-hand-side is anything else, this is an invalid formation. + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Expected identifier or call after `.`."); + } + }break; + + //- rjf: array indices case E_ExprKind_ArrayIndex: { // rjf: unpack left-hand-size @@ -1686,7 +1581,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr); E_TypeKey r_type = e_type_unwrap(r_tree.type_key); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); - E_TypeKey r_type_direct = e_type_direct_from_key(r_type); + E_TypeKey r_type_direct = e_type_unwrap(e_type_direct_from_key(r_type)); U64 r_type_direct_size = e_type_byte_size_from_key(r_type_direct); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -3181,94 +3076,3 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type e_expr_push_child(root, rhs_bytecode); return root; } - -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Rules - -#if 0 // TODO(rjf): @eval -internal E_LookupRule * -e_lookup_rule_from_type_key(E_TypeKey type_key) -{ - E_LookupRule *rule = &e_lookup_rule__default; - - // rjf: unpack type - E_Type *type = e_type_from_key__cached(type_key); - - // rjf: sets / lenses -> try to implicitly map to a rule based on name - if(type->kind == E_TypeKind_Set || type->kind == E_TypeKind_Lens) - { - E_LookupRule *candidate = e_lookup_rule_from_string(type->name); - if(candidate != &e_lookup_rule__nil) - { - rule = candidate; - } - } - - return rule; -} -#endif - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleExprPair -e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) -{ - E_LookupRuleExprPair result = {&e_lookup_rule__default, &e_expr_nil}; - { - // rjf: first try explicitly-stored tags - B32 default_is_forced = 0; - if(result.rule == &e_lookup_rule__default) - { - for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) - { - if(e_expr_is_poisoned(tag)) { continue; } - if(str8_match(tag->string, e_lookup_rule__default.name, 0)) - { - result.rule = &e_lookup_rule__default; - result.tag = &e_expr_nil; - default_is_forced = 1; - break; - } - E_LookupRule *candidate = e_lookup_rule_from_string(tag->string); - if(candidate != &e_lookup_rule__nil) - { - result.rule = candidate; - result.tag = tag; - } - } - } - - // rjf: next try implicit set name -> rule mapping - if(!default_is_forced && result.rule == &e_lookup_rule__default) - { - E_TypeKind type_kind = e_type_kind_from_key(irtree->type_key); - if(type_kind == E_TypeKind_Stub) - { - E_Type *type = e_type_from_key__cached(irtree->type_key); - String8 name = type->name; - E_LookupRule *candidate = e_lookup_rule_from_string(name); - if(candidate != &e_lookup_rule__nil) - { - result.rule = candidate; - } - } - } - - // rjf: next try auto hook map - if(!default_is_forced && result.rule == &e_lookup_rule__default) - { - E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); - for(E_ExprNode *n = tags.first; n != 0; n = n->next) - { - if(e_expr_is_poisoned(n->v)) { continue; } - E_LookupRule *candidate = e_lookup_rule_from_string(n->v->string); - if(candidate != &e_lookup_rule__nil) - { - result.rule = candidate; - result.tag = n->v; - } - } - } - } - return result; -} -#endif diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index 871527e2..dc266067 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -134,10 +134,6 @@ struct E_IRCtx E_String2ExprMap *macro_map; // rjf: hook maps -#if 0 // TODO(rjf): @eval - E_LookupRuleMap *lookup_rule_map; - E_IRGenRuleMap *irgen_rule_map; -#endif E_AutoHookMap *auto_hook_map; }; @@ -166,32 +162,6 @@ struct E_IRState //////////////////////////////// //~ rjf: Globals -#if 0 // TODO(rjf): @eval -local_persist read_only E_LookupRule e_lookup_rule__nil = -{ - str8_lit_comp("nil"), - E_LOOKUP_INFO_FUNCTION_NAME(default), - E_LOOKUP_ACCESS_FUNCTION_NAME(default), - E_LOOKUP_RANGE_FUNCTION_NAME(default), - E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), - E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), -}; -local_persist read_only E_LookupRule e_lookup_rule__default = -{ - str8_lit_comp("default"), - E_LOOKUP_INFO_FUNCTION_NAME(default), - E_LOOKUP_ACCESS_FUNCTION_NAME(default), - E_LOOKUP_RANGE_FUNCTION_NAME(default), - E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default), - E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default), -}; -local_persist read_only E_IRGenRule e_irgen_rule__default = -{ - str8_lit_comp("default"), - E_IRGEN_FUNCTION_NAME(default), -}; -#endif - global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; thread_static E_IRState *e_ir_state = 0; @@ -206,28 +176,6 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); internal void e_select_ir_ctx(E_IRCtx *ctx); -//////////////////////////////// -//~ rjf: Lookups - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count); -internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule); -#define e_lookup_rule_map_insert_new(arena, map, name_, ...) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), __VA_ARGS__}) - -internal E_LookupRule *e_lookup_rule_from_string(String8 string); -#endif - -//////////////////////////////// -//~ rjf: IR Gen Rules - -#if 0 // TODO(rjf): @eval -internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count); -internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule); -#define e_irgen_rule_map_insert_new(arena, map, name_, ...) e_irgen_rule_map_insert((arena), (map), &(E_IRGenRule){.name = (name_), __VA_ARGS__}) - -internal E_IRGenRule *e_irgen_rule_from_string(String8 string); -#endif - //////////////////////////////// //~ rjf: Auto Hooks @@ -294,15 +242,4 @@ internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAnd internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Rules - -#if 0 // TODO(rjf): @eval -internal E_LookupRule *e_lookup_rule_from_type_key(E_TypeKey type_key); -#endif - -#if 0 // TODO(rjf): @eval -internal E_LookupRuleExprPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); -#endif - #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index f93e91dd..9c46201f 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1208,7 +1208,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok B32 is_postfix_unary = 0; // rjf: dot/arrow operator - if(token.kind == E_TokenKind_Symbol && + if(max_precedence >= 1 && + token.kind == E_TokenKind_Symbol && (str8_match(token_string, str8_lit("."), 0) || str8_match(token_string, str8_lit("->"), 0))) { @@ -1217,43 +1218,29 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok // rjf: advance past operator it += 1; - // rjf: expect member name - String8 member_name = {0}; - B32 good_member_name = 0; - { - E_Token member_name_maybe = e_token_at_it(it, &tokens); - String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); - if(member_name_maybe.kind != E_TokenKind_Identifier) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Expected member name after `%S`.", token_string); - } - else - { - member_name = member_name_maybe_string; - good_member_name = 1; - } - } + // rjf: parse right-hand-side + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), 0, 1); + e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); + E_Expr *rhs = rhs_expr_parse.exprs.last; + it = rhs_expr_parse.last_token; - // rjf: produce lookup member expr - if(good_member_name) + // rjf: produce member access expr + if(rhs == &e_expr_nil) { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name.str); - member_expr->string = member_name; + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Missing right-hand-side of `.`."); + } + else + { + E_Expr *lhs = atom; atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); - } - - // rjf: increment past good member names - if(good_member_name) - { - it += 1; + e_expr_push_child(atom, lhs); + e_expr_push_child(atom, rhs); } } // rjf: array index - if(token.kind == E_TokenKind_Symbol && + if(max_precedence >= 1 && + token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) { is_postfix_unary = 1; @@ -1292,9 +1279,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tok } // rjf: calls - if(token.kind == E_TokenKind_Symbol && + if(max_precedence >= 0 && + token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { + is_postfix_unary = 1; + // rjf: skip ( it += 1; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 96773dc3..936c7d9e 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -348,7 +348,8 @@ e_hash_from_cons_type_params(E_ConsTypeParams *params) internal B32 e_cons_type_params_match(E_ConsTypeParams *l, E_ConsTypeParams *r) { - B32 result = (l->kind == r->kind && + B32 result = (l->kind != E_TypeKind_Lens && + l->kind == r->kind && l->flags == r->flags && str8_match(l->name, r->name, 0) && e_type_key_match(l->direct_key, r->direct_key) && @@ -1665,7 +1666,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr default: { E_Type *type = e_type_from_key__cached(key); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); + str8_list_pushf(arena, out, "%S ", type->name); }break; case E_TypeKind_Bitfield: @@ -1702,7 +1703,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr case E_TypeKind_Alias: { E_Type *type = e_type_from_key__cached(key); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); + str8_list_pushf(arena, out, "%S ", type->name); }break; case E_TypeKind_IncompleteStruct: keyword = str8_lit("struct"); goto fwd_udt; @@ -1714,7 +1715,7 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_Type *type = e_type_from_key__cached(key); str8_list_push(arena, out, keyword); str8_list_push(arena, out, str8_lit(" ")); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); + str8_list_pushf(arena, out, "%S ", type->name); }break; case E_TypeKind_Array: @@ -1753,20 +1754,15 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_pushf(arena, out, ", "); } } - str8_list_pushf(arena, out, ") <- ("); + str8_list_pushf(arena, out, ") <- "); E_TypeKey direct = e_type_direct_from_key(key); - e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - str8_list_pushf(arena, out, ")"); + e_type_lhs_string_from_key(arena, direct, out, 2, skip_return); }break; case E_TypeKind_Ptr: { E_TypeKey direct = e_type_direct_from_key(key); e_type_lhs_string_from_key(arena, direct, out, 1, skip_return); - if(!e_type_kind_is_pointer_or_ref(e_type_kind_from_key(direct))) - { - str8_list_push(arena, out, str8_lit(" ")); - } str8_list_push(arena, out, str8_lit("*")); E_Type *type = e_type_from_key__cached(key); if(type->count != 1) @@ -1879,6 +1875,12 @@ e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr E_TypeKey direct = e_type_direct_from_key(key); e_type_rhs_string_from_key(arena, direct, out, 2); }break; + + case E_TypeKind_Lens: + if(prec == 1) + { + str8_list_push(arena, out, str8_lit(")")); + }break; } } diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index f4dc6cc8..ca2886b6 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1572,17 +1572,20 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) B32 need_pop = 1; B32 need_new_task = 0; EV_StringIterTask new_task = {0}; + S32 top_task_depth = 0; if(it->top_task != 0) { result = 1; //- rjf: unpack task U64 task_idx = it->top_task->idx; - S32 depth = it->top_task->depth; + S32 depth = top_task_depth = it->top_task->depth; EV_StringParams *params = &it->top_task->params; E_Eval eval = it->top_task->eval; E_TypeKey type_key = eval.irtree.type_key; E_TypeKind type_kind = e_type_kind_from_key(type_key); + String8 expansion_opener_symbol = str8_lit("{"); + String8 expansion_closer_symbol = str8_lit("}"); //- rjf: type evaluations -> display type string if(eval.irtree.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) @@ -1606,42 +1609,81 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) //- rjf: lenses // case E_TypeKind_Lens: - switch(task_idx) { - default:{}break; - - // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type - case 0: + E_Type *type = e_type_from_key__cached(type_key); + B32 lens_applied = 1; + EV_StringParams lens_params = *params; + if(0){} + else if(str8_match(type->name, str8_lit("bin"), 0)) { lens_params.radix = 2; } + else if(str8_match(type->name, str8_lit("oct"), 0)) { lens_params.radix = 8; } + else if(str8_match(type->name, str8_lit("dec"), 0)) { lens_params.radix = 10; } + else if(str8_match(type->name, str8_lit("hex"), 0)) { lens_params.radix = 16; } + else if(str8_match(type->name, str8_lit("digits"), 0) && type->count >= 1) + { + E_Value value = e_value_from_expr(type->args[0]); + lens_params.min_digits = value.u64; + } + else + { + lens_applied = 0; + } + if(lens_applied) { - Temp scratch = scratch_begin(&arena, 1); - String8List strings = {0}; - { - E_Type *type = e_type_from_key__cached(type_key); - str8_list_pushf(scratch.arena, &strings, "%S(", type->name); - for EachIndex(idx, type->count) - { - String8 string = e_string_from_expr(scratch.arena, type->args[idx]); - str8_list_push(scratch.arena, &strings, string); - if(idx+1 < type->count) - { - str8_list_pushf(scratch.arena, &strings, ", "); - } - } - str8_list_pushf(scratch.arena, &strings, ") <- ("); - } - *out_string = str8_list_join(arena, &strings, 0); need_new_task = 1; - new_task.params = *params; + need_pop = 1; + new_task.params = lens_params; new_task.eval = eval; new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); - scratch_end(scratch); - }break; - - // rjf: step 1 -> close - case 1: + } + else switch(task_idx) { - *out_string = str8_lit(")"); - }break; + default:{}break; + + // rjf: step 0 -> generate lens description, then descend to same evaluation w/ direct type + case 0: + { + Temp scratch = scratch_begin(&arena, 1); + String8List strings = {0}; + { + str8_list_pushf(scratch.arena, &strings, "%S(", type->name); + for EachIndex(idx, type->count) + { + String8 string = e_string_from_expr(scratch.arena, type->args[idx]); + str8_list_push(scratch.arena, &strings, string); + if(idx+1 < type->count) + { + str8_list_pushf(scratch.arena, &strings, ", "); + } + } + str8_list_pushf(scratch.arena, &strings, ") <- ("); + } + *out_string = str8_list_join(arena, &strings, 0); + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); + scratch_end(scratch); + }break; + + // rjf: step 1 -> close + case 1: + { + *out_string = str8_lit(")"); + }break; + } + }break; + + ////////////////////////// + //- rjf: modifiers + // + case E_TypeKind_Modifier: + { + need_pop = 1; + need_new_task = 1; + new_task.params = *params; + new_task.eval = eval; + new_task.eval.irtree.type_key = e_type_direct_from_key(eval.irtree.type_key); }break; ////////////////////////// @@ -1651,7 +1693,14 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case E_TypeKind_Ptr: case E_TypeKind_LRef: case E_TypeKind_RRef: + case E_TypeKind_Array: { + if(type_kind == E_TypeKind_Array && it->top_task->redirect_array_to_sets_and_structs) + { + expansion_opener_symbol = str8_lit("["); + expansion_closer_symbol = str8_lit("]"); + goto arrays_and_sets_and_structs; + } typedef struct EV_StringPtrData EV_StringPtrData; struct EV_StringPtrData { @@ -1661,6 +1710,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) B32 ptee_has_content; B32 ptee_has_string; B32 did_prefix_content; + B32 did_redirect; }; EV_StringPtrData *ptr_data = it->top_task->user_data; if(ptr_data == 0) @@ -1668,13 +1718,17 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) ptr_data = it->top_task->user_data = push_array(arena, EV_StringPtrData, 1); ptr_data->value_eval = e_value_eval_from_eval(eval); ptr_data->type = e_type_from_key__cached(type_key); - ptr_data->direct_type = e_type_from_key__cached(e_type_direct_from_key(type_key)); + ptr_data->direct_type = e_type_from_key__cached(e_type_unwrap(e_type_direct_from_key(e_type_unwrap(type_key)))); ptr_data->ptee_has_content = (ptr_data->direct_type->kind != E_TypeKind_Null && ptr_data->direct_type->kind != E_TypeKind_Void); ptr_data->ptee_has_string = ((E_TypeKind_Char8 <= ptr_data->direct_type->kind && ptr_data->direct_type->kind <= E_TypeKind_UChar32) || ptr_data->direct_type->kind == E_TypeKind_S8 || ptr_data->direct_type->kind == E_TypeKind_U8); } - switch(task_idx) + if(ptr_data->did_redirect) + { + need_pop = 1; + } + else switch(task_idx) { default:{}break; @@ -1744,31 +1798,147 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } if(module != &e_module_nil) { + RDI_Parsed *rdi = module->rdi; U64 voff = vaddr - module->vaddr_range.min; - RDI_Procedure *procedure = rdi_procedure_from_voff(module->rdi, voff); - String8 procedure_name = {0}; - procedure_name.str = rdi_name_from_procedure(module->rdi, procedure, &procedure_name.size); - if(procedure_name.size != 0) + B32 good_symbol_match = 0; + + // NOTE(rjf): read-only -> generate non-parseable things, like type-info / inlines + if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) { - // NOTE(rjf): read-only -> generate non-parseable things, like type-info - if(params->flags & EV_StringFlag_ReadOnlyDisplayRules) + // rjf: voff -> scope + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); + + // rjf: scope -> # of max possible inline depth + U64 inline_site_count = 0; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) { - // TODO(rjf) - *out_string = procedure_name; + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s->inline_site_idx != 0) + { + inline_site_count += 1; + } + else + { + break; + } } - // NOTE(rjf): non-read-only -> only generate thing which can be parsed, so just procedure name + // rjf: depth in [1, max]? -> form name from inline site + if(0 < ptr_data->type->depth && ptr_data->type->depth <= inline_site_count) + { + RDI_InlineSite *inline_site = 0; + U64 s_inline_depth = inline_site_count; + for(U64 s_idx = scope_idx, s_idx_next = 0; s_idx != 0; s_idx = s_idx_next) + { + RDI_Scope *s = rdi_element_from_name_idx(rdi, Scopes, s_idx); + s_idx_next = s->parent_scope_idx; + if(s_inline_depth == ptr_data->type->depth) + { + inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx); + break; + } + s_inline_depth -= 1; + if(s_inline_depth == 0) + { + break; + } + } + if(inline_site != 0) + { + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, module_idx); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); + if(inline_site->type_idx != 0) + { + Temp scratch = scratch_begin(&arena, 1); + String8List list = {0}; + str8_list_pushf(scratch.arena, &list, "[inlined] "); + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + *out_string = str8_list_join(arena, &list, 0); + scratch_end(scratch); + } + else + { + *out_string = push_str8_copy(arena, name); + } + good_symbol_match = (name.size != 0); + } + } + + // rjf: depth == 0 or depth >= max? -> form name from scope procedure else { - *out_string = procedure_name; + Temp scratch = scratch_begin(&arena, 1); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, module_idx); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + if(procedure->type_idx != 0) + { + String8List list = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &list, 0, 0); + str8_list_push(scratch.arena, &list, name); + e_type_rhs_string_from_key(scratch.arena, type, &list, 0); + *out_string = str8_list_join(arena, &list, 0); + } + else + { + *out_string = push_str8_copy(arena, name); + } + good_symbol_match = (out_string->size != 0); + scratch_end(scratch); } - - ptr_data->did_prefix_content = 1; } + + // NOTE(rjf): non-read-only -> only generate thing which can be parsed, so just procedure name + else + { + // rjf: voff -> scope + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); + RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); + + // rjf: scope -> procedure / string + RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope); + String8 procedure_name = {0}; + procedure_name.str = rdi_name_from_procedure(rdi, procedure, &procedure_name.size); + + *out_string = procedure_name; + good_symbol_match = (procedure_name.size != 0); + } + + ptr_data->did_prefix_content = good_symbol_match; } } - need_pop = 0; + // rjf: if this is an array, and we do not have a prefix, then we need to + // generate a new task which redirects array types -> sets and structs. + if(type_kind == E_TypeKind_Array && !ptr_data->did_prefix_content) + { + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = eval; + new_task.redirect_array_to_sets_and_structs = 1; + ptr_data->did_redirect = 1; + } + + // rjf: if this is an array, and we *did* prefix content, then we are + // just done. + else if(type_kind == E_TypeKind_Array && ptr_data->did_prefix_content) + { + // NOTE(rjf): no-op, task is done. + } + + // rjf: otherwise, keep going on this task + else + { + need_pop = 0; + } }break; //- rjf: step 1 -> do pointer value + descend if needed @@ -1799,6 +1969,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) E_Expr *deref_expr = e_expr_irext_deref(arena, eval.expr, &eval.irtree); E_Eval deref_eval = e_eval_from_expr(arena, deref_expr); need_new_task = 1; + need_pop = 0; new_task.params = *params; new_task.eval = deref_eval; } @@ -1822,15 +1993,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) }break; ////////////////////////// - //- rjf: arrays - // - case E_TypeKind_Array: - { - // TODO(rjf) - }break; - - ////////////////////////// - //- rjf: non-string-arrays/structs/sets + //- rjf: non-string-arrays/structs, sets // case E_TypeKind_Struct: case E_TypeKind_Union: @@ -1841,7 +2004,64 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case E_TypeKind_Set: arrays_and_sets_and_structs: { - + typedef struct EV_ExpandedTypeData EV_ExpandedTypeData; + struct EV_ExpandedTypeData + { + E_Type *type; + E_TypeExpandRule *expand_rule; + E_TypeExpandInfo expand_info; + }; + EV_ExpandedTypeData *expand_data = (EV_ExpandedTypeData *)it->top_task->user_data; + if(expand_data == 0) + { + expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); + expand_data->type = e_type_from_key__cached(type_key); + expand_data->expand_rule = &e_type_expand_rule__default; + if(expand_data->type->expand.info != 0) + { + expand_data->expand_rule = &expand_data->type->expand; + } + expand_data->expand_info = expand_data->expand_rule->info(arena, eval.expr, &eval.irtree, params->filter); + } + switch(task_idx) + { + //- rjf: step 0 -> generate opener symbol + case 0: + { + need_pop = 0; + *out_string = expansion_opener_symbol; + }break; + + default: + //- rjf: last step -> generate closer symbol + if(task_idx == expand_data->expand_info.expr_count+1) + { + *out_string = expansion_closer_symbol; + } + + //- rjf: middle step -> generate new task for next thing in expansion + else + { + E_Expr *next_expr = &e_expr_nil; + String8 next_string = {0}; + expand_data->expand_rule->range(arena, expand_data->expand_info.user_data, eval.expr, &eval.irtree, params->filter, r1u64(task_idx-1, task_idx), &next_expr, &next_string); + if(next_expr != &e_expr_nil) + { + need_new_task = 1; + need_pop = 0; + new_task.params = *params; + new_task.eval = e_eval_from_expr(arena, next_expr); + if(task_idx > 1) + { + *out_string = str8_lit(", "); + } + } + else + { + need_pop = 0; + } + }break; + } }break; } } @@ -1852,6 +2072,14 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) it->top_task->idx += 1; } + //- rjf: if result is good, and we want to pop? -> pop + if(result && need_pop) + { + EV_StringIterTask *task = it->top_task; + SLLStackPop(it->top_task); + SLLStackPush(it->free_task, task); + } + //- rjf: if result is good, and we have a new task? -> push if(result && need_new_task) { @@ -1865,62 +2093,10 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) new_t = push_array(arena, EV_StringIterTask, 1); } MemoryCopyStruct(new_t, &new_task); - new_t->depth = it->top_task->depth+1; + new_t->depth = top_task_depth+1; SLLStackPush(it->top_task, new_t); new_t->idx = 0; } - //- rjf: if result is good, but we don't have a new task? -> pop - else if(result && need_pop) - { - EV_StringIterTask *task = it->top_task; - SLLStackPop(it->top_task); - SLLStackPush(it->free_task, task); - } - return result; } - -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Expand Rule - -#if 0 // TODO(rjf): @eval -internal EV_ExpandRuleTagPair -ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree) -{ - EV_ExpandRuleTagPair result = {&ev_nil_expand_rule, &e_expr_nil}; - { - // rjf: first try explicitly-stored tags - if(result.rule == &ev_nil_expand_rule) - { - for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) - { - EV_ExpandRule *candidate = ev_expand_rule_from_string(tag->string); - if(candidate != &ev_nil_expand_rule) - { - result.rule = candidate; - result.tag = tag; - break; - } - } - } - - // rjf: next try auto hook map - if(result.rule == &ev_nil_expand_rule) - { - E_ExprList tags = e_auto_hook_exprs_from_type_key__cached(irtree->type_key); - for(E_ExprNode *n = tags.first; n != 0; n = n->next) - { - EV_ExpandRule *candidate = ev_expand_rule_from_string(n->v->string); - if(candidate != &ev_nil_expand_rule) - { - result.rule = candidate; - result.tag = n->v; - break; - } - } - } - } - return result; -} -#endif diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 7f5115d0..86325d44 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -147,12 +147,12 @@ struct EV_Block U64 split_relative_idx; // rjf: evaluation info - String8 string; - E_Eval eval; - E_TypeExpandInfo type_expand_info; - E_TypeExpandRule *type_expand_rule; - EV_ExpandInfo viz_expand_info; - EV_ExpandRule *viz_expand_rule; + String8 string; + E_Eval eval; + E_TypeExpandInfo type_expand_info; + E_TypeExpandRule *type_expand_rule; + EV_ExpandInfo viz_expand_info; + EV_ExpandRule *viz_expand_rule; // rjf: expansion info U64 row_count; @@ -199,8 +199,8 @@ struct EV_Row EV_Block *block; EV_Key key; U64 visual_size; - String8 string; - E_Eval eval; + String8 string; + E_Eval eval; }; typedef struct EV_WindowedRowNode EV_WindowedRowNode; @@ -246,6 +246,7 @@ struct EV_StringParams U32 radix; U32 min_digits; U8 digit_group_separator; + String8 filter; }; typedef struct EV_StringIterTask EV_StringIterTask; @@ -256,6 +257,7 @@ struct EV_StringIterTask E_Eval eval; U64 idx; S32 depth; + B32 redirect_array_to_sets_and_structs; void *user_data; }; @@ -343,8 +345,8 @@ internal U64 ev_depth_from_block(EV_Block *block); //////////////////////////////// //~ rjf: Block Coordinate Spaces - -internal U64 ev_block_id_from_num(EV_Block *block, U64 num); + +internal U64 ev_block_id_from_num(EV_Block *block, U64 num); internal U64 ev_block_num_from_id(EV_Block *block, U64 id); internal EV_BlockRangeList ev_block_range_list_from_tree(Arena *arena, EV_BlockTree *block_tree); internal EV_BlockRange ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num); @@ -376,11 +378,4 @@ internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw); internal EV_StringIter *ev_string_iter_begin(Arena *arena, E_Eval eval, EV_StringParams *params); internal B32 ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string); -//////////////////////////////// -//~ rjf: Expression & IR-Tree => Expand Rule - -#if 0 // TODO(rjf): @eval -internal EV_ExpandRuleTagPair ev_expand_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree); -#endif - #endif // EVAL_VISUALIZATION_CORE_H diff --git a/src/mule/mule_main.cpp b/src/mule/mule_main.cpp index f1799a40..7b8b03dc 100644 --- a/src/mule/mule_main.cpp +++ b/src/mule/mule_main.cpp @@ -299,6 +299,10 @@ type_coverage_eval_tests(void) L"This is a string, but instead of being encoded in a stream of bytes,\n" L"it is encoded in a stream of 2-byte packages!\n"; + const char *const_string = "Hello, World!"; + const char const_string_array[] = "Hello, World!"; + const char *const const_ptr_const_string = "Hello, World!"; + void *pointer = &basics; Basics *pointer_to_basics = &basics; Basics **pointer_to_pointer_to_basics = &pointer_to_basics; diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 2f63d32b..ad581ca8 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -9619,10 +9619,18 @@ rd_value_string_from_eval_NEW(Arena *arena, String8 filter, EV_StringParams *par { EV_StringIter *iter = ev_string_iter_begin(scratch.arena, eval, params); F32 space_taken_px = 0; - for(String8 string = {0}; ev_string_iter_next(scratch.arena, iter, &string) && space_taken_px < max_size;) + for(String8 string = {0}; ev_string_iter_next(scratch.arena, iter, &string);) { - str8_list_push(scratch.arena, &strs, string); - space_taken_px += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + if(space_taken_px > max_size) + { + str8_list_push(scratch.arena, &strs, str8_lit("...")); + break; + } + else + { + str8_list_push(scratch.arena, &strs, string); + space_taken_px += fnt_dim_from_tag_size_string(font, font_size, 0, 0, string).x; + } } } String8 result = str8_list_join(arena, &strs, 0); @@ -12272,12 +12280,6 @@ rd_frame(void) ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); -#if 0 // TODO(rjf): @eval - ctx->lookup_rule_map = push_array(scratch.arena, E_LookupRuleMap, 1); - ctx->lookup_rule_map[0] = e_lookup_rule_map_make(scratch.arena, 512); - ctx->irgen_rule_map = push_array(scratch.arena, E_IRGenRuleMap, 1); - ctx->irgen_rule_map[0] = e_irgen_rule_map_make(scratch.arena, 512); -#endif ctx->auto_hook_map = push_array(scratch.arena, E_AutoHookMap, 1); ctx->auto_hook_map[0] = e_auto_hook_map_make(scratch.arena, 512); @@ -12433,19 +12435,19 @@ rd_frame(void) //- rjf: add types for queries { -#if 0 // TODO(rjf): @eval e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("environment"), e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment"), .flags = E_TypeFlag_EditableChildren, + .irgen = E_TYPE_IRGEN_FUNCTION_NAME(environment), + .access = E_TYPE_ACCESS_FUNCTION_NAME(environment), .expand = { - .info = E_LOOKUP_INFO_FUNCTION_NAME(environment), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(environment), - .id_from_num = E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(environment), - .num_from_id = E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(environment), + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(environment), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(environment), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(environment), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(environment), })); -#endif e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("call_stack"), @@ -12555,20 +12557,21 @@ rd_frame(void) e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); } -#if 0 // TODO(rjf): @eval //- rjf: add macro / lookup rules for unattached processes { String8 collection_name = str8_lit("unattached_processes"); - E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(unattached_processes), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(unattached_processes) + }); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; expr->space = e_space_make(RD_EvalSpaceKind_MetaCtrlEntity); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); - e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, str8_lit("unattached_processes"), - .info = E_LOOKUP_INFO_FUNCTION_NAME(unattached_processes), - .range = E_LOOKUP_RANGE_FUNCTION_NAME(unattached_processes)); + e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, collection_name, collection_type_key); } -#endif //- rjf: add macro for commands { @@ -12665,10 +12668,10 @@ rd_frame(void) e_select_ir_ctx(ir_ctx); //////////////////////////// - //- rjf: generate macros for all view ui rules + //- rjf: generate macros for all view rules // { - //- rjf: choose set of view ui rules + //- rjf: choose set of view rules // TODO(rjf): generate via metaprogram struct { @@ -12678,6 +12681,11 @@ rd_frame(void) } view_ui_rule_table[] = { + {str8_lit("bin")}, + {str8_lit("oct")}, + {str8_lit("dec")}, + {str8_lit("hex")}, + {str8_lit("digits")}, {str8_lit("text"), RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, {str8_lit("disasm"), RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, {str8_lit("memory"), RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 98eb4a48..defd8482 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -765,44 +765,26 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack) return result; } -#if 0 // TODO(rjf): @eval - //////////////////////////////// //~ rjf: `environment` Type Hooks -E_TYPE_ACCESS_FUNCTION_DEF(environment) +typedef struct RD_EnvironmentAccel RD_EnvironmentAccel; +struct RD_EnvironmentAccel { - E_LookupAccess result = {{&e_irnode_nil}}; - if(kind == E_ExprKind_ArrayIndex) + RD_CfgArray cfgs; +}; + +E_TYPE_IRGEN_FUNCTION_DEF(environment) +{ + E_IRTreeAndType result = *irtree; + RD_EnvironmentAccel *accel = push_array(arena, RD_EnvironmentAccel, 1); { Temp scratch = scratch_begin(&arena, 1); - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType rhs_irtree = e_irtree_and_type_from_expr(scratch.arena, rhs); - E_OpList rhs_oplist = e_oplist_from_irtree(scratch.arena, rhs_irtree.root); - String8 rhs_bytecode = e_bytecode_from_oplist(scratch.arena, &rhs_oplist); - E_Interpretation rhs_interp = e_interpret(rhs_bytecode); - E_Value rhs_value = rhs_interp.value; - if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) - { - RD_Cfg *cfg = cfgs->v[rhs_value.u64]; - result.irtree_and_type.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); - result.irtree_and_type.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); - result.irtree_and_type.mode = E_Mode_Offset; - } - scratch_end(scratch); - } - return result; -} - -E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) -{ - E_TypeExpandInfo result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - E_OpList oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root); String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); E_Interpretation interpret = e_interpret(bytecode); - RD_Cfg *target = rd_cfg_from_eval_space(interpret.space); + E_Space space = interpret.space; + RD_Cfg *target = rd_cfg_from_eval_space(space); RD_CfgList env_strings = {0}; for(RD_Cfg *child = target->first; child != &rd_nil_cfg; child = child->next) { @@ -811,57 +793,80 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) rd_cfg_list_push(scratch.arena, &env_strings, child); } } - RD_CfgArray *accel = push_array(arena, RD_CfgArray, 1); - *accel = rd_cfg_array_from_list(arena, &env_strings); - result.user_data = accel; - result.idxed_expr_count = accel->count + 1; + accel->cfgs = rd_cfg_array_from_list(arena, &env_strings); + scratch_end(scratch); } - scratch_end(scratch); + result.user_data = accel; + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(environment) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_ArrayIndex) + { + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)lhs_irtree->user_data; + RD_CfgArray *cfgs = &accel->cfgs; + E_Value rhs_value = e_value_from_expr(expr->first->next); + if(0 <= rhs_value.u64 && rhs_value.u64 < cfgs->count) + { + RD_Cfg *cfg = cfgs->v[rhs_value.u64]; + result.root = e_irtree_set_space(arena, rd_eval_space_from_cfg(cfg), e_irtree_const_u(arena, 0)); + result.type_key = e_type_key_cons_ptr(arch_from_context(), e_type_key_basic(E_TypeKind_U8), 1, E_TypeFlag_IsCodeText); + result.mode = E_Mode_Offset; + } + } + return result; +} + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment) +{ + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)irtree->user_data; + E_TypeExpandInfo result = {accel, accel->cfgs.count + 1}; return result; } E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment) { - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); - Rng1U64 legal_idx_range = r1u64(0, cfgs->count); + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->cfgs.count); Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); U64 read_range_count = dim_1u64(read_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { U64 cfg_idx = read_range.min + idx; - if(cfg_idx < cfgs->count) + if(cfg_idx < accel->cfgs.count) { - exprs[idx] = e_expr_irext_array_index(arena, lhs, &lhs_irtree, cfg_idx); + exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, cfg_idx); } } } -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment) +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(environment) { U64 id = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; - if(1 <= num && num <= cfgs->count) + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)user_data; + if(1 <= num && num <= accel->cfgs.count) { U64 idx = (num-1); - id = cfgs->v[idx]->id; + id = accel->cfgs.v[idx]->id; } - else if(num == cfgs->count+1) + else if(num == accel->cfgs.count+1) { id = max_U64; } return id; } -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(environment) { U64 num = 0; - RD_CfgArray *cfgs = (RD_CfgArray *)user_data; + RD_EnvironmentAccel *accel = (RD_EnvironmentAccel *)user_data; if(id != 0 && id != max_U64) { - for EachIndex(idx, cfgs->count) + for EachIndex(idx, accel->cfgs.count) { - if(cfgs->v[idx]->id == id) + if(accel->cfgs.v[idx]->id == id) { num = idx+1; break; @@ -870,7 +875,7 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment) } else if(id == max_U64) { - num = cfgs->count + 1; + num = accel->cfgs.count + 1; } return num; } @@ -893,20 +898,21 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) Temp scratch = scratch_begin(&arena, 1); //- rjf: evaluate lhs machine, if we have one - E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs->root); + E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root); String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist); E_Interpretation lhs_interp = e_interpret(lhs_bytecode); CTRL_Entity *lhs_entity = rd_ctrl_entity_from_eval_space(lhs_interp.space); //- rjf: gather all machines we're searching through - CTRL_EntityList machines = {0}; + CTRL_EntityArray machines = {0}; if(lhs_entity->kind == CTRL_EntityKind_Machine) { - ctrl_entity_list_push(scratch.arena, &machines, lhs_entity); + machines.v = &lhs_entity; + machines.count = 1; } else { - machines = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); + machines = ctrl_entity_array_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Machine); } //- rjf: gather system processes from this machine @@ -920,9 +926,9 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) Node *first = 0; Node *last = 0; U64 count = 0; - for(CTRL_EntityNode *n = machines.first; n != 0; n = n->next) + for EachIndex(idx, machines.count) { - CTRL_Entity *machine = n->v; + CTRL_Entity *machine = machines.v[idx]; DMN_ProcessIter iter = {0}; dmn_process_iter_begin(&iter); for(DMN_ProcessInfo info = {0}; dmn_process_iter_next(scratch.arena, &iter, &info);) @@ -970,7 +976,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes) accel->infos_count = infos_count; accel->machines = infos_machines; info.user_data = accel; - info.idxed_expr_count = infos_count; + info.expr_count = infos_count; scratch_end(scratch); } return info; @@ -991,7 +997,6 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes) exprs_out[out_idx] = expr; } } -#endif //////////////////////////////// //~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index 03e6c830..5c1627cb 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -56,22 +56,21 @@ E_TYPE_IRGEN_FUNCTION_DEF(call_stack); E_TYPE_ACCESS_FUNCTION_DEF(call_stack); E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack); -#if 0 // TODO(rjf): @eval //////////////////////////////// //~ rjf: `environment` Type Hooks +E_TYPE_IRGEN_FUNCTION_DEF(environment); E_TYPE_ACCESS_FUNCTION_DEF(environment); E_TYPE_EXPAND_INFO_FUNCTION_DEF(environment); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(environment); -E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(environment); -E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(environment); +E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(environment); +E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(environment); //////////////////////////////// //~ rjf: `unattached_processes` Type Hooks E_TYPE_EXPAND_INFO_FUNCTION_DEF(unattached_processes); E_TYPE_EXPAND_RANGE_FUNCTION_DEF(unattached_processes); -#endif //////////////////////////////// //~ rjf: Control Entity List Type Hooks (`processes`, `threads`, etc.) diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8a8ba428..270b02dd 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1289,7 +1289,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .default_pct = 0.65f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.15f, .pct = take_pct()); #undef take_pct } @@ -1313,7 +1313,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, .default_pct = 0.05f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = module_eval, .default_pct = 0.20f, .pct = take_pct()); #undef take_pct }