diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 62bf70a7..3a4a1f6a 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -296,12 +296,13 @@ E_MemberKind; typedef U32 E_TypeFlags; enum { - E_TypeFlag_Const = (1<<0), - E_TypeFlag_Volatile = (1<<1), - E_TypeFlag_IsPlainText = (1<<2), - E_TypeFlag_IsCodeText = (1<<3), - E_TypeFlag_IsPathText = (1<<4), - E_TypeFlag_EditableChildren = (1<<5), + E_TypeFlag_Const = (1<<0), + E_TypeFlag_Volatile = (1<<1), + E_TypeFlag_IsPlainText = (1<<2), + E_TypeFlag_IsCodeText = (1<<3), + E_TypeFlag_IsPathText = (1<<4), + E_TypeFlag_EditableChildren = (1<<5), + E_TypeFlag_InheritedOnAccess = (1<<6), }; typedef struct E_Member E_Member; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 60f1969a..182a469c 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1242,6 +1242,7 @@ e_expr_unpoison(E_Expr *expr) E_TYPE_ACCESS_FUNCTION_DEF(default) { + Temp scratch = scratch_begin(&arena, 1); E_IRTreeAndType result = {&e_irnode_nil}; switch(expr->kind) { @@ -1260,8 +1261,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_TypeKind check_type_kind = l_restype_kind; if(l_restype_kind == E_TypeKind_Ptr || l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef || - l_restype_kind == E_TypeKind_Lens) + l_restype_kind == E_TypeKind_RRef) { check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); check_type_kind = e_type_kind_from_key(check_type_key); @@ -1472,6 +1472,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) result.mode = mode; }break; } + scratch_end(scratch); return result; } @@ -1482,6 +1483,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); + E_TypeKeyList inherited_lenses = {0}; E_IRTreeAndType result = {&e_irnode_nil}; ////////////////////////////// @@ -1519,10 +1521,26 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { - // rjf: unpack left-hand-size + // rjf: unpack left-hand-side E_Expr *lhs = expr->first; E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs); + // rjf: gather inherited lenses from the left-hand-side + { + E_TypeKey k = lhs_irtree.type_key; + E_TypeKind kind = e_type_kind_from_key(k); + for(;kind == E_TypeKind_Lens;) + { + E_Type *lens_type = e_type_from_key__cached(k); + if(lens_type->flags & E_TypeFlag_InheritedOnAccess) + { + e_type_key_list_push_front(scratch.arena, &inherited_lenses, k); + } + k = e_type_direct_from_key(k); + kind = e_type_kind_from_key(k); + } + } + // 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; @@ -2180,7 +2198,12 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } // rjf: patch resultant type with a lens w/ args, pointing to the original type - result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, .count = arg_count, .args = args, .direct_key = result.type_key, .name = lhs_type->name); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, + .flags = lhs_type->flags, + .count = arg_count, + .args = args, + .direct_key = result.type_key, + .name = lhs_type->name); scratch_end(scratch); } @@ -2790,6 +2813,28 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) e_expr_unpoison(t->expr); } + ////////////////////////////// + //- rjf: apply inherited lenses to the resultant type + // + if(inherited_lenses.count != 0) + { + E_Type *result_type = e_type_from_key__cached(result.type_key); + for(E_TypeKeyNode *n = inherited_lenses.first; n != 0; n = n->next) + { + E_Type *src_type = e_type_from_key__cached(n->v); + E_TypeKey dst_type_key = e_type_key_cons(.kind = src_type->kind, + .flags = src_type->flags, + .name = src_type->name, + .count = src_type->count, + .args = src_type->args, + .irgen = src_type->irgen, + .access = src_type->access, + .expand = src_type->expand, + .direct_key = result.type_key); + result.type_key = dst_type_key; + } + } + scratch_end(scratch); ProfEnd(); return result; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index acf3c6c1..e4c8b899 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1337,7 +1337,8 @@ e_type_unwrap(E_TypeKey key) E_TypeKind kind = e_type_kind_from_key(result); if((E_TypeKind_FirstIncomplete <= kind && kind <= E_TypeKind_LastIncomplete) || kind == E_TypeKind_Modifier || - kind == E_TypeKind_Alias) + kind == E_TypeKind_Alias || + kind == E_TypeKind_Lens) { result = e_type_direct_from_key(result); } @@ -1889,6 +1890,91 @@ e_type_string_from_key(Arena *arena, E_TypeKey key) return result; } +internal E_TypeKey +e_default_expansion_type_from_key(E_TypeKey root_key) +{ + E_TypeKey type_key = zero_struct; + for(E_TypeKey key = root_key; + !e_type_key_match(e_type_key_zero(), key); + key = e_type_direct_from_key(key)) + { + B32 done = 1; + E_TypeKind kind = e_type_kind_from_key(key); + + //- rjf: if we have pointers which point to a single thing (count = 1), + // or we have a lens, or we have a modifier node, then we will defer to + // the next type in the chain. + // + // if this pointer points to N things (count > 1), then we can use it for + // array-like expansion. + // + if(e_type_kind_is_pointer_or_ref(kind)) + { + E_Type *type = e_type_from_key__cached(key); + if(!e_type_key_match(e_type_key_basic(E_TypeKind_Void), type->direct_type_key)) + { + if(type->count == 1) + { + done = 0; + } + else if(type->count > 1) + { + type_key = key; + } + } + } + + //- rjf: if we have lenses or modifiers in the type chain, then we will + // defer to the next type in the chain. + // + // NOTE(rjf): while it may seem like a lens type needs to do something + // different, because lenses sometimes want to define their own expansion + // rules, they would've redirected to an entirely different expansion + // hook. if we are in the default expansion hook, then the lenses do not + // impact the expansion at all (e.g. they are for other cosmetic things, + // like visualizers or integer radix changes), and so in that case we + // want to ignore them. + // + else if(kind == E_TypeKind_Lens || + kind == E_TypeKind_Modifier) + { + done = 0; + } + + //- rjf: if we've reached a struct-like, then we can use that for + // struct-like expansion. + else if(kind == E_TypeKind_Struct || + kind == E_TypeKind_Union || + kind == E_TypeKind_Class || + kind == E_TypeKind_Set) + { + type_key = key; + } + + //- rjf: if we've reached an enum-like, then we can use that for + // enum-like expansion. + else if(kind == E_TypeKind_Enum) + { + type_key = key; + } + + //- rjf: if we've reached an array, then we can use that for array-like + // expansion. + else if(kind == E_TypeKind_Array) + { + type_key = key; + } + + //- rjf: if we're done, then just break. + if(done) + { + break; + } + } + + return type_key; +} + //- rjf: type key data structures internal void @@ -1900,6 +1986,15 @@ e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key) list->count += 1; } +internal void +e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key) +{ + E_TypeKeyNode *n = push_array(arena, E_TypeKeyNode, 1); + n->v = key; + SLLQueuePushFront(list->first, list->last, n); + list->count += 1; +} + internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src) { @@ -2105,47 +2200,48 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(default) { E_TypeExpandInfo result = {0}; { - E_TypeKey type_key = e_type_unwrap(irtree->type_key); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(e_type_kind_is_pointer_or_ref(type_kind) || - type_kind == E_TypeKind_Lens) + //- rjf: try to extract a struct-like type key, enum-like, or array-like + // type key, for expansion + E_TypeKey expand_type_key = e_default_expansion_type_from_key(irtree->type_key); + + //- rjf: struct type? -> use the struct type for expansion + B32 did_expansion = 0; + if(!did_expansion) { - E_Type *type = e_type_from_key__cached(type_key); - result.expr_count = type->count; - if(type->count == 1 || type_kind == E_TypeKind_Lens) + E_TypeKind struct_type_kind = e_type_kind_from_key(expand_type_key); + if(struct_type_kind == E_TypeKind_Struct || + struct_type_kind == E_TypeKind_Class || + struct_type_kind == E_TypeKind_Union) { - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - if(direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Class || - direct_type_kind == E_TypeKind_Union) - { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(direct_type_key, filter); - result.expr_count = data_members.count; - } - else if(direct_type_kind == E_TypeKind_Enum) - { - E_Type *direct_type = e_type_from_key__cached(direct_type_key); - result.expr_count = direct_type->count; - } + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(expand_type_key, filter); + result.expr_count = data_members.count; + did_expansion = 1; } } - else if(type_kind == E_TypeKind_Struct || - type_kind == E_TypeKind_Class || - type_kind == E_TypeKind_Union) + + //- rjf: array-like type? -> use the array-like for expansion + if(!did_expansion) { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(type_key, filter); - result.expr_count = data_members.count; + E_TypeKind array_type_kind = e_type_kind_from_key(expand_type_key); + if(array_type_kind == E_TypeKind_Array || + array_type_kind == E_TypeKind_Ptr) + { + E_Type *array_type = e_type_from_key__cached(expand_type_key); + result.expr_count = array_type->count; + did_expansion = 1; + } } - else if(type_kind == E_TypeKind_Enum) + + //- rjf: enum-like type? -> use the enum-like for expansion + if(!did_expansion) { - E_Type *direct_type = e_type_from_key__cached(type_key); - result.expr_count = direct_type->count; - } - else if(type_kind == E_TypeKind_Array) - { - E_Type *type = e_type_from_key__cached(type_key); - result.expr_count = type->count; + E_TypeKind enum_type_kind = e_type_kind_from_key(expand_type_key); + if(enum_type_kind == E_TypeKind_Enum) + { + E_Type *enum_type = e_type_from_key__cached(expand_type_key); + result.expr_count = enum_type->count; + did_expansion = 1; + } } } return result; @@ -2155,70 +2251,17 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { Temp scratch = scratch_begin(&arena, 1); { - //- rjf: unpack type of expression - E_IRTreeAndType lhs_irtree = *irtree; - E_TypeKey lhs_type_key = lhs_irtree.type_key; - E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); - E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key)); - E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); - - //- rjf: pull out specific kinds of types - B32 do_struct_range = 0; - B32 do_enum_range = 0; - B32 do_index_range = 0; - E_TypeKey enum_type_key = zero_struct; - E_TypeKey struct_type_key = zero_struct; - E_TypeKind struct_type_kind = E_TypeKind_Null; - if(e_type_kind_is_pointer_or_ref(lhs_type_kind) || - lhs_type_kind == E_TypeKind_Lens) - { - E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); - if((lhs_type->count == 1 || - lhs_type_kind == E_TypeKind_Lens) && - (direct_type_kind == E_TypeKind_Struct || - direct_type_kind == E_TypeKind_Union || - direct_type_kind == E_TypeKind_Class)) - { - struct_type_key = direct_type_key; - struct_type_kind = direct_type_kind; - do_struct_range = 1; - } - else if(lhs_type->count == 1 && direct_type_kind == E_TypeKind_Enum) - { - do_enum_range = 1; - enum_type_key = direct_type_key; - } - else - { - do_index_range = 1; - } - } - else if(lhs_type_kind == E_TypeKind_Struct || - lhs_type_kind == E_TypeKind_Union || - lhs_type_kind == E_TypeKind_Class) - { - struct_type_key = lhs_type_key; - struct_type_kind = lhs_type_kind; - do_struct_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Enum) - { - enum_type_key = lhs_type_key; - do_enum_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Set) - { - do_index_range = 1; - } - else if(lhs_type_kind == E_TypeKind_Array) - { - do_index_range = 1; - } + //- rjf: try to extract a struct-like type key, enum-like, or array-like + // type key, for expansion + E_TypeKey expand_type_key = e_default_expansion_type_from_key(irtree->type_key); + E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); //- rjf: struct case -> the lookup-range will return a range of members - if(do_struct_range) + if(expand_type_kind == E_TypeKind_Struct || + expand_type_kind == E_TypeKind_Class || + expand_type_kind == E_TypeKind_Union) { - E_MemberArray data_members = e_type_data_members_from_key_filter__cached(struct_type_key, filter); + E_MemberArray data_members = e_type_data_members_from_key_filter__cached(expand_type_key, filter); Rng1U64 legal_idx_range = r1u64(0, data_members.count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); @@ -2226,14 +2269,14 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { U64 member_idx = idx + read_range.min; String8 member_name = data_members.v[member_idx].name; - exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name); + exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); } } //- rjf: enum case -> the lookup-range will return a range of enum constants - else if(do_enum_range) + else if(expand_type_kind == E_TypeKind_Enum) { - E_Type *type = e_type_from_key__cached(enum_type_key); + E_Type *type = e_type_from_key__cached(expand_type_key); Rng1U64 legal_idx_range = r1u64(0, type->count); Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range); U64 read_range_count = dim_1u64(read_range); @@ -2241,17 +2284,19 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default) { U64 member_idx = idx + read_range.min; String8 member_name = type->enum_vals[member_idx].name; - exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name); + exprs_out[idx] = e_expr_irext_member_access(arena, expr, irtree, member_name); } } //- rjf: ptr case -> the lookup-range will return a range of dereferences - else if(do_index_range) + else if(expand_type_kind == E_TypeKind_Ptr || + expand_type_kind == E_TypeKind_Array || + expand_type_kind == E_TypeKind_Set) { U64 read_range_count = dim_1u64(idx_range); for(U64 idx = 0; idx < read_range_count; idx += 1) { - exprs_out[idx] = e_expr_irext_array_index(arena, expr, &lhs_irtree, idx_range.min + idx); + exprs_out[idx] = e_expr_irext_array_index(arena, expr, irtree, idx_range.min + idx); } } } diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 8217065c..cb5e06f7 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -264,9 +264,11 @@ internal E_Member *e_type_member_from_array_name(E_MemberArray *members, String8 internal void e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec, B32 skip_return); internal void e_type_rhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec); internal String8 e_type_string_from_key(Arena *arena, E_TypeKey key); +internal E_TypeKey e_default_expansion_type_from_key(E_TypeKey key); //- rjf: type key data structures internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); +internal void e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index b7eea0cb..4c7ae9dd 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -83,30 +83,19 @@ internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { B32 result = 0; - for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))) { - E_TypeKind kind = e_type_kind_from_key(t); - if(kind == E_TypeKind_Null || kind == E_TypeKind_Function) - { - break; - } - if(kind == E_TypeKind_Struct || - kind == E_TypeKind_Union || - kind == E_TypeKind_Class || - kind == E_TypeKind_Array || - kind == E_TypeKind_Set || - (kind == E_TypeKind_Enum && mode == E_Mode_Null)) + E_TypeKey expand_type_key = e_default_expansion_type_from_key(type_key); + E_TypeKind expand_type_kind = e_type_kind_from_key(expand_type_key); + if(expand_type_kind == E_TypeKind_Struct || + expand_type_kind == E_TypeKind_Union || + expand_type_kind == E_TypeKind_Class || + expand_type_kind == E_TypeKind_Array || + expand_type_kind == E_TypeKind_Set || + e_type_kind_is_pointer_or_ref(expand_type_kind) || + (expand_type_kind == E_TypeKind_Enum && mode == E_Mode_Null)) { result = 1; } - if(kind == E_TypeKind_Ptr) - { - E_Type *type = e_type_from_key__cached(t); - if(type->count > 1) - { - result = 1; - } - } } return result; } @@ -396,6 +385,27 @@ ev_expand_rule_from_string(String8 string) return info; } +internal EV_ExpandRule * +ev_expand_rule_from_type_key(E_TypeKey type_key) +{ + EV_ExpandRule *rule = &ev_nil_expand_rule; + { + E_TypeKey k = type_key; + E_TypeKind kind = e_type_kind_from_key(k); + for(;kind == E_TypeKind_Lens; k = e_type_direct_from_key(k), kind = e_type_kind_from_key(k)) + { + E_Type *type = e_type_from_key__cached(k); + EV_ExpandRule *candidate = ev_expand_rule_from_string(type->name); + if(candidate != &ev_nil_expand_rule) + { + rule = candidate; + break; + } + } + } + return rule; +} + //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) @@ -471,66 +481,6 @@ ev_resolved_from_expr(Arena *arena, E_Expr *expr) } #endif -//////////////////////////////// -//~ rjf: Upgrading Expressions w/ Tags From All Sources - -#if 0 // TODO(rjf): @eval -internal void -ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr) -{ - Temp scratch = scratch_begin(&arena, 1); - if(expr != &e_expr_nil) - { - // rjf: push inherited tags first (we want these to be found first, since tags are applied - // in order, and explicit ones should always be strongest) - { - for(E_Expr *src_tag = block->expr->first_tag; src_tag != &e_expr_nil; src_tag = src_tag->next) - { - B32 is_inherited = 0; - // TODO(rjf): table-drive this - if(str8_match(src_tag->string, str8_lit("hex"), 0) || - str8_match(src_tag->string, str8_lit("oct"), 0) || - str8_match(src_tag->string, str8_lit("bin"), 0) || - str8_match(src_tag->string, str8_lit("dec"), 0) || - str8_match(src_tag->string, str8_lit("no_addr"), 0) || - str8_match(src_tag->string, str8_lit("digits"), 0) || - str8_match(src_tag->string, str8_lit("no_string"), 0) || - str8_match(src_tag->string, str8_lit("only"), 0) || - str8_match(src_tag->string, str8_lit("omit"), 0)) - { - is_inherited = 1; - } - if(is_inherited) - { - e_expr_push_tag(expr, e_expr_copy(arena, src_tag)); - } - } - } - - // rjf: push tags inferred from the type - { - E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr); - 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) - { - e_expr_push_tag(expr, e_expr_copy(arena, n->v)); - } - } - - // rjf: push explicitly-attached tags (via key) next - String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); - E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); - E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, tag_expr_tokens); - for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) - { - next = tag->next; - e_expr_push_tag(expr, tag); - } - } - scratch_end(scratch); -} -#endif - //////////////////////////////// //~ rjf: Block Building @@ -546,9 +496,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp EV_Key root_key = ev_key_root(); EV_Key root_row_key = ev_key_make(ev_hash_from_key(root_key), 1); E_Expr *root_expr = e_expr_copy(arena, expr); -#if 0 // TODO(rjf): @eval - ev_keyed_expr_push_tags(arena, view, &ev_nil_block, root_row_key, root_expr); -#endif //- rjf: generate root block tree.root = push_array(arena, EV_Block, 1); @@ -606,9 +553,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp } // rjf: get eval's visualization expansion rule - // TODO(rjf): @eval EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(t->expr, &expr_irtree); - EV_ExpandRule *viz_expand_rule = &ev_nil_expand_rule; - E_Expr *viz_expand_rule_tag = &e_expr_nil; + EV_ExpandRule *viz_expand_rule = ev_expand_rule_from_type_key(type_key); // rjf: skip if no expansion rule, & type info disallows expansion if(viz_expand_rule == &ev_nil_expand_rule && !ev_type_key_and_mode_is_expandable(type_key, mode)) @@ -618,7 +563,7 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp // rjf: get top-level lookup/expansion info E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval.expr, &t->eval.irtree, filter); - EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr, viz_expand_rule_tag); + EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr); // rjf: determine expansion info U64 expansion_row_count = type_expand_info.expr_count; @@ -738,9 +683,6 @@ ev_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, E_Expr *exp { E_Eval child_eval = e_eval_from_expr(arena, child_expr); EV_Key child_key = child_keys[idx]; -#if 0 // TODO(rjf): @eval - ev_keyed_expr_push_tags(arena, view, expansion_block, child_key, child_expr); -#endif Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; @@ -857,7 +799,7 @@ ev_block_range_from_num(EV_BlockRangeList *block_ranges, U64 num) U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { - U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + U64 range_size = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); Rng1U64 global_range = r1u64(base_num, base_num + range_size); if(contains_1u64(global_range, num)) { @@ -880,7 +822,7 @@ ev_key_from_num(EV_BlockRangeList *block_ranges, U64 num) U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { - U64 range_size = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + U64 range_size = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); Rng1U64 global_range = r1u64(base_num, base_num + range_size); if(contains_1u64(global_range, num)) { @@ -906,14 +848,14 @@ ev_num_from_key(EV_BlockRangeList *block_ranges, EV_Key key) if(hash == key.parent_hash) { U64 relative_num = ev_block_num_from_id(n->v.block, key.child_id); - Rng1U64 num_range = r1u64(n->v.range.min, n->v.block->single_item ? (n->v.range.min+1) : n->v.range.max); + Rng1U64 num_range = r1u64(n->v.range.min, n->v.block->viz_expand_info.single_item ? (n->v.range.min+1) : n->v.range.max); if(contains_1u64(num_range, relative_num-1)) { result = base_num + (relative_num - 1 - n->v.range.min); break; } } - base_num += n->v.block->single_item ? 1 : dim_1u64(n->v.range); + base_num += n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); } return result; } @@ -927,10 +869,10 @@ ev_vnum_from_num(EV_BlockRangeList *block_ranges, U64 num) U64 base_num = 1; for(EV_BlockRangeNode *n = block_ranges->first; n != 0; n = n->next) { - U64 next_base_num = base_num + (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + U64 next_base_num = base_num + (n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range)); if(base_num <= num && num < next_base_num) { - U64 relative_vnum = (n->v.block->single_item ? 0 : (num - base_num)); + U64 relative_vnum = (n->v.block->viz_expand_info.single_item ? 0 : (num - base_num)); vnum = base_vnum + relative_vnum; break; } @@ -957,12 +899,12 @@ ev_num_from_vnum(EV_BlockRangeList *block_ranges, U64 vnum) U64 next_base_vnum = base_vnum + dim_1u64(n->v.range); if(base_vnum <= vnum && vnum < next_base_vnum) { - U64 relative_num = (n->v.block->single_item ? 0 : (vnum - base_vnum)); + U64 relative_num = (n->v.block->viz_expand_info.single_item ? 0 : (vnum - base_vnum)); num = base_num + relative_num; break; } base_vnum = next_base_vnum; - base_num += (n->v.block->single_item ? 1 : dim_1u64(n->v.range)); + base_num += (n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range)); } } return num; @@ -1009,7 +951,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 rows.count_before_visual += num_skipped; if(block_num_visual_rows != 0 && num_skipped != 0) { - if(n->v.block->single_item) + if(n->v.block->viz_expand_info.single_item) { if(num_skipped >= block_num_visual_rows) { @@ -1034,7 +976,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 { range_exprs[idx] = &e_expr_nil; } - if(n->v.block->single_item || n->v.block->parent == &ev_nil_block) + if(n->v.block->viz_expand_info.single_item || n->v.block->parent == &ev_nil_block) { is_standalone_row = 1; } @@ -1054,7 +996,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 EV_Row *row = &row_node->row; row->block = n->v.block; row->key = ev_key_make(ev_hash_from_key(row->block->key), 1); - row->visual_size = n->v.block->single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; + row->visual_size = n->v.block->viz_expand_info.single_item ? (n->v.block->row_count - (num_skipped + num_chopped)) : 1; row->string = n->v.block->string; row->eval = n->v.block->eval; } @@ -1067,9 +1009,6 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); E_Expr *row_expr = range_exprs[idx]; E_Eval row_eval = e_eval_from_expr(arena, row_expr); -#if 0 // TODO(rjf): @eval - ev_keyed_expr_push_tags(arena, view, n->v.block, row_key, row_expr); -#endif EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -1121,16 +1060,14 @@ ev_row_is_expandable(EV_Row *row) { E_IRTreeAndType irtree = row->eval.irtree; - // rjf: determine if view rules force expandability + // rjf: determine if lenses force expandability if(!result) { -#if 0 // TODO(rjf): @eval - EV_ExpandRuleTagPair expand_rule_and_tag = ev_expand_rule_tag_pair_from_expr_irtree(row->expr, &irtree); - if(expand_rule_and_tag.rule != &ev_nil_expand_rule) + EV_ExpandRule *expand_rule = ev_expand_rule_from_type_key(irtree.type_key); + if(expand_rule != &ev_nil_expand_rule) { result = 1; } -#endif } // rjf: determine if type info force expandability @@ -1736,13 +1673,16 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case 0: { // rjf: try strings - if(!ptr_data->did_prefix_content && ptr_data->ptee_has_string && !(params->flags & EV_StringFlag_DisableStrings)) + if(!ptr_data->did_prefix_content && ptr_data->ptee_has_string && + !(params->flags & EV_StringFlag_DisableStrings) && + (type_kind == E_TypeKind_Array || + params->flags & EV_StringFlag_ReadOnlyDisplayRules)) { Temp scratch = scratch_begin(&arena, 1); // rjf: read string data U64 string_memory_addr = ptr_data->value_eval.value.u64; - U64 string_buffer_size = 256; + U64 string_buffer_size = 4096; U8 *string_buffer = push_array(scratch.arena, U8, string_buffer_size); for(U64 try_size = string_buffer_size; try_size >= 16; try_size /= 2) { @@ -1765,7 +1705,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) } // rjf: escape and quote - B32 string__is_escaped_and_quoted = (!(params->flags & EV_StringFlag_DisableAddresses) || depth > 0); + B32 string__is_escaped_and_quoted = (!(params->flags & EV_StringFlag_DisableStringQuotes) || depth > 0); String8 string__escaped_and_quoted = string; if(string__is_escaped_and_quoted) { diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 86325d44..35a20c57 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -87,7 +87,7 @@ struct EV_ExpandInfo B32 rows_default_expanded; }; -#define EV_EXPAND_RULE_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, E_Expr *tag) +#define EV_EXPAND_RULE_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr) #define EV_EXPAND_RULE_INFO_FUNCTION_NAME(name) ev_expand_rule_info__##name #define EV_EXPAND_RULE_INFO_FUNCTION_DEF(name) internal EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_EXPAND_RULE_INFO_FUNCTION_NAME(name)) typedef EV_EXPAND_RULE_INFO_FUNCTION_SIG(EV_ExpandRuleInfoHookFunctionType); @@ -156,8 +156,6 @@ struct EV_Block // rjf: expansion info U64 row_count; - B32 single_item; - B32 rows_default_expanded; }; typedef struct EV_BlockTree EV_BlockTree; @@ -237,6 +235,7 @@ enum EV_StringFlag_PrettyNames = (1<<1), EV_StringFlag_DisableAddresses = (1<<2), EV_StringFlag_DisableStrings = (1<<3), + EV_StringFlag_DisableStringQuotes = (1<<4), }; typedef struct EV_StringParams EV_StringParams; @@ -282,7 +281,22 @@ global read_only EV_ExpandRule ev_nil_expand_rule = EV_EXPAND_RULE_INFO_FUNCTION_NAME(nil), }; thread_static EV_ExpandRuleTable *ev_view_rule_info_table = 0; -global read_only EV_Block ev_nil_block = {&ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, &ev_nil_block, {0}, 0, {0}, {zero_struct, zero_struct, &e_expr_nil, &e_irnode_nil}}; +global read_only EV_Block ev_nil_block = +{ + &ev_nil_block, + &ev_nil_block, + &ev_nil_block, + &ev_nil_block, + &ev_nil_block, + {0}, + 0, + {0}, + {zero_struct, zero_struct, &e_expr_nil, &e_irnode_nil}, + {0}, + &e_type_expand_rule__default, + {0}, + &ev_nil_expand_rule, +}; //////////////////////////////// //~ rjf: Key Functions @@ -322,6 +336,7 @@ internal void ev_expand_rule_table_push(Arena *arena, EV_ExpandRuleTable *table, #define ev_expand_rule_table_push_new(arena, table, ...) ev_expand_rule_table_push((arena), (table), &(EV_ExpandRule){__VA_ARGS__}) internal void ev_select_expand_rule_table(EV_ExpandRuleTable *table); internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); +internal EV_ExpandRule *ev_expand_rule_from_type_key(E_TypeKey type_key); //////////////////////////////// //~ rjf: Expression Resolution (Dynamic Overrides, View Rule Application) @@ -330,13 +345,6 @@ internal EV_ExpandRule *ev_expand_rule_from_string(String8 string); internal E_Expr *ev_resolved_from_expr(Arena *arena, E_Expr *expr); #endif -//////////////////////////////// -//~ rjf: Upgrading Expressions w/ Tags From All Sources - -#if 0 // TODO(rjf): @eval -internal void ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key, E_Expr *expr); -#endif - //////////////////////////////// //~ rjf: Block Building diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e36800f6..cc4ce525 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1404,16 +1404,6 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) return result; } -internal E_Expr * -rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg) -{ - E_Expr *expr = &e_expr_nil; - { - // TODO(rjf): @cfg - } - return expr; -} - //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -1949,7 +1939,7 @@ rd_whole_range_from_eval_space(E_Space space) //- rjf: writing values back to child processes internal B32 -rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping) +rd_commit_eval_value_string(E_Eval dst_eval, String8 string) { B32 result = 0; if(dst_eval.irtree.mode == E_Mode_Offset) @@ -1984,17 +1974,14 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un e_type_kind_is_integer(direct_type_kind)) { B32 is_quoted = 0; - if(string_needs_unescaping) + if(string.size >= 1 && string.str[0] == '"') { - if(string.size >= 1 && string.str[0] == '"') - { - string = str8_skip(string, 1); - is_quoted = 1; - } - if(string.size >= 1 && string.str[string.size-1] == '"') - { - string = str8_chop(string, 1); - } + string = str8_skip(string, 1); + is_quoted = 1; + } + if(string.size >= 1 && string.str[string.size-1] == '"') + { + string = str8_chop(string, 1); } if(is_quoted) { @@ -2652,7 +2639,7 @@ rd_view_ui(Rng2F32 rect) { UI_ScrollListRowBlock block = {0}; block.row_count = dim_1u64(n->v.range); - block.item_count = n->v.block->single_item ? 1 : dim_1u64(n->v.range); + block.item_count = n->v.block->viz_expand_info.single_item ? 1 : dim_1u64(n->v.range); ui_scroll_list_row_block_chunk_list_push(scratch.arena, &row_block_chunks, 256, &block); } row_blocks = ui_scroll_list_row_block_array_from_chunk_list(scratch.arena, &row_block_chunks); @@ -3134,7 +3121,7 @@ rd_view_ui(Rng2F32 rect) if(should_commit_asap) { B32 success = 0; - success = rd_commit_eval_value_string(cell_info.eval, new_string, 0); + success = rd_commit_eval_value_string(cell_info.eval, new_string); if(!success) { log_user_error(str8_lit("Could not commit value successfully.")); @@ -3268,7 +3255,7 @@ rd_view_ui(Rng2F32 rect) case RD_WatchCellKind_Eval: { RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), row_string_max_size_px); - rd_commit_eval_value_string(cell_info.eval, str8_zero(), 0); + rd_commit_eval_value_string(cell_info.eval, str8_zero()); }break; } } @@ -4069,7 +4056,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: view ui contents - cell_info.view_ui_rule->ui(cell_info.eval, cell_info.view_ui_tag, cell_rect); + cell_info.view_ui_rule->ui(cell_info.eval, cell_rect); // rjf: loading fill UI_Parent(loading_overlay_container) @@ -4442,7 +4429,7 @@ rd_view_ui(Rng2F32 rect) // if(next_cell_toggled != cell_toggled) { - rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0"), 0); + rd_commit_eval_value_string(cell_info.eval, next_cell_toggled ? str8_lit("1") : str8_lit("0")); } //////////// @@ -4488,8 +4475,7 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); - E_Expr *tag = rd_tag_from_cfg(scratch.arena, view); - view_ui_rule->ui(expr_eval, tag, rect); + view_ui_rule->ui(expr_eval, rect); scratch_end(scratch); } } @@ -4595,7 +4581,7 @@ rd_view_cfg_value_from_string(String8 string) internal U64 rd_base_offset_from_eval(E_Eval eval) { - if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(eval.irtree.type_key))) + if(e_type_kind_is_pointer_or_ref(e_type_kind_from_key(e_type_unwrap(eval.irtree.type_key)))) { eval = e_value_eval_from_eval(eval); } @@ -4603,15 +4589,20 @@ rd_base_offset_from_eval(E_Eval eval) } internal Rng1U64 -rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_range_from_eval(E_Eval eval) { U64 size = 0; - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("size"), 0)) + for EachIndex(idx, type->count) { - size = e_value_from_expr(param->first->next).u64; - break; + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("size"), 0)) + { + size = e_value_from_expr(arg->first->next).u64; + break; + } } } E_TypeKey type_key = e_type_unwrap(eval.irtree.type_key); @@ -4643,7 +4634,7 @@ rd_range_from_eval_tag(E_Eval eval, E_Expr *tag) } internal TXT_LangKind -rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_lang_kind_from_eval(E_Eval eval) { TXT_LangKind lang_kind = TXT_LangKind_Null; Temp scratch = scratch_begin(0, 0); @@ -4654,12 +4645,17 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) } if(lang_kind == TXT_LangKind_Null) { - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("lang"), 0)) + for EachIndex(idx, type->count) { - lang_kind = txt_lang_kind_from_extension(param->first->next->string); - break; + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("lang"), 0)) + { + lang_kind = txt_lang_kind_from_extension(arg->first->next->string); + break; + } } } } @@ -4668,7 +4664,7 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) } internal Arch -rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_arch_from_eval(E_Eval eval) { // rjf: try implicitly from either `eval` itself, or from context CTRL_Entity *ctrl_entity = rd_ctrl_entity_from_eval_space(eval.space); @@ -4683,18 +4679,25 @@ rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) arch = arch_from_context(); } - // rjf: try arch parameters - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + // rjf: try arch arguments + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - String8 param_arch_string = param->string; - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("arch"), 0)) + for EachIndex(idx, type->count) { - param_arch_string = param->first->next->string; - } - if(str8_match(param->first->next->string, str8_lit("x64"), 0)) - { - arch = Arch_x64; - break; + E_Expr *arg = type->args[idx]; + { + String8 arg_arch_string = arg->string; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("arch"), 0)) + { + arg_arch_string = arg->first->next->string; + } + if(str8_match(arg->first->next->string, str8_lit("x64"), 0)) + { + arch = Arch_x64; + break; + } + } } } @@ -4702,45 +4705,54 @@ rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag) } internal Vec2S32 -rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_dim2s32_from_eval(E_Eval eval) { Vec2S32 dim = v2s32(1, 1); B32 got_x = 0; B32 got_y = 0; // rjf: try explicitly passed dimensions - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define) + for EachIndex(idx, type->count) { - if(str8_match(param->first->string, str8_lit("w"), 0)) + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define) { - got_x = 1; - dim.x = e_value_from_expr(param->first->next).s64; - } - if(str8_match(param->first->string, str8_lit("h"), 0)) - { - got_y = 1; - dim.y = e_value_from_expr(param->first->next).s64; + if(str8_match(arg->first->string, str8_lit("w"), 0)) + { + got_x = 1; + dim.x = e_value_from_expr(arg->first->next).s64; + } + if(str8_match(arg->first->string, str8_lit("h"), 0)) + { + got_y = 1; + dim.y = e_value_from_expr(arg->first->next).s64; + } } } } // rjf: try ordered non-define arguments - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + if(type->kind == E_TypeKind_Lens) { - if(param->kind != E_ExprKind_Define) + for EachIndex(idx, type->count) { - if(!got_x) + E_Expr *arg = type->args[idx]; + if(arg->kind != E_ExprKind_Define) { - got_x = 1; - dim.x = e_value_from_expr(param).s64; - } - else if(!got_y) - { - got_y = 1; - dim.y = e_value_from_expr(param).s64; - break; + if(!got_x) + { + got_x = 1; + dim.x = e_value_from_expr(arg).s64; + } + else if(!got_y) + { + got_y = 1; + dim.y = e_value_from_expr(arg).s64; + break; + } } } } @@ -4749,39 +4761,48 @@ rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag) } internal R_Tex2DFormat -rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) +rd_tex2dformat_from_eval(E_Eval eval) { R_Tex2DFormat fmt = R_Tex2DFormat_RGBA8; B32 got_fmt = 0; // rjf: try explicitly passed formats - for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_Define && str8_match(param->first->string, str8_lit("fmt"), 0)) + for EachIndex(idx, type->count) { - got_fmt = 1; - for EachEnumVal(R_Tex2DFormat, f) + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, str8_lit("fmt"), 0)) { - if(str8_match(param->first->next->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + got_fmt = 1; + for EachEnumVal(R_Tex2DFormat, f) { - fmt = f; - break; + if(str8_match(arg->first->next->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } } } } } // rjf: try implicit non-define arguments - for(E_Expr *param = tag->first->next; param != &e_expr_nil && !got_fmt; param = param->next) + if(type->kind == E_TypeKind_Lens) { - if(param->kind == E_ExprKind_LeafIdentifier) + for EachIndex(idx, type->count) { - for EachEnumVal(R_Tex2DFormat, f) + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_LeafIdentifier) { - if(str8_match(param->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + for EachEnumVal(R_Tex2DFormat, f) { - fmt = f; - break; + if(str8_match(arg->string, r_tex2d_format_display_string_table[f], StringMatchFlag_CaseInsensitive)) + { + fmt = f; + break; + } } } } @@ -4791,15 +4812,20 @@ rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag) } internal E_Value -rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key) +rd_value_from_eval_key(E_Eval eval, String8 key) { E_Value value = zero_struct; - for(E_Expr *arg = tag->first->next; arg != &e_expr_nil; arg = arg->next) + E_Type *type = e_type_from_key__cached(eval.irtree.type_key); + if(type->kind == E_TypeKind_Lens) { - if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, key, 0)) + for EachIndex(idx, type->count) { - value = e_value_from_expr(arg->first->next); - break; + E_Expr *arg = type->args[idx]; + if(arg->kind == E_ExprKind_Define && str8_match(arg->first->string, key, 0)) + { + value = e_value_from_expr(arg->first->next); + break; + } } } return value; @@ -6253,10 +6279,8 @@ rd_window_frame(void) if(build_hover_eval) { // rjf: determine if we have a top-level visualizer -#if 0 // TODO(rjf): @eval - EV_ExpandRuleTagPair expand_rule_tag = ev_expand_rule_tag_pair_from_expr_irtree(hover_eval.exprs.last, &hover_eval.irtree); -#endif - RD_ViewUIRule *view_ui_rule = &rd_nil_view_ui_rule; // TODO(rjf): @eval rd_view_ui_rule_from_string(expand_rule_tag.rule->string); + EV_ExpandRule *expand_rule = ev_expand_rule_from_type_key(hover_eval.irtree.type_key); + RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(expand_rule->string); // rjf: determine view name String8 view_name = str8_lit("watch"); @@ -12677,23 +12701,24 @@ rd_frame(void) struct { String8 name; + B32 inherited; RD_ViewUIFunctionType *ui; EV_ExpandRuleInfoHookFunctionType *expand; } 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)}, - {str8_lit("bitmap"), RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, - {str8_lit("checkbox"), RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, - {str8_lit("color_rgba"), RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, - {str8_lit("geo3d"), RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, + {str8_lit("bin"), 1}, + {str8_lit("oct"), 1}, + {str8_lit("dec"), 1}, + {str8_lit("hex"), 1}, + {str8_lit("digits"), 1}, + {str8_lit("text"), 0, RD_VIEW_UI_FUNCTION_NAME(text), EV_EXPAND_RULE_INFO_FUNCTION_NAME(text)}, + {str8_lit("disasm"), 0, RD_VIEW_UI_FUNCTION_NAME(disasm), EV_EXPAND_RULE_INFO_FUNCTION_NAME(disasm)}, + {str8_lit("memory"), 0, RD_VIEW_UI_FUNCTION_NAME(memory), EV_EXPAND_RULE_INFO_FUNCTION_NAME(memory)}, + {str8_lit("bitmap"), 0, RD_VIEW_UI_FUNCTION_NAME(bitmap), EV_EXPAND_RULE_INFO_FUNCTION_NAME(bitmap)}, + {str8_lit("checkbox"), 0, RD_VIEW_UI_FUNCTION_NAME(checkbox), 0}, + {str8_lit("color_rgba"), 0, RD_VIEW_UI_FUNCTION_NAME(color_rgba), EV_EXPAND_RULE_INFO_FUNCTION_NAME(color_rgba)}, + {str8_lit("geo3d"), 0, RD_VIEW_UI_FUNCTION_NAME(geo3d), EV_EXPAND_RULE_INFO_FUNCTION_NAME(geo3d)}, }; //- rjf: fill view ui rules in expand rule map, view ui rule map @@ -12712,8 +12737,13 @@ rd_frame(void) } for EachElement(idx, view_ui_rule_table) { + E_TypeFlags type_flags = 0; + if(view_ui_rule_table[idx].inherited) + { + type_flags |= E_TypeFlag_InheritedOnAccess; + } E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .name = view_ui_rule_table[idx].name); + expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .flags = type_flags, .name = view_ui_rule_table[idx].name); e_string2expr_map_insert(scratch.arena, e_ir_state->ctx->macro_map, view_ui_rule_table[idx].name, expr); } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 32780f50..83a604ee 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -92,7 +92,7 @@ enum //////////////////////////////// //~ rjf: View UI Hook Types -#define RD_VIEW_UI_FUNCTION_SIG(name) void name(E_Eval eval, E_Expr *tag, Rng2F32 rect) +#define RD_VIEW_UI_FUNCTION_SIG(name) void name(E_Eval eval, Rng2F32 rect) #define RD_VIEW_UI_FUNCTION_NAME(name) rd_view_ui__##name #define RD_VIEW_UI_FUNCTION_DEF(name) internal RD_VIEW_UI_FUNCTION_SIG(RD_VIEW_UI_FUNCTION_NAME(name)) typedef RD_VIEW_UI_FUNCTION_SIG(RD_ViewUIFunctionType); @@ -908,8 +908,6 @@ internal RD_Cfg *rd_immediate_cfg_from_keyf(char *fmt, ...); internal String8 rd_mapped_from_file_path(Arena *arena, String8 file_path); internal String8List rd_possible_overrides_from_file_path(Arena *arena, String8 file_path); -internal E_Expr *rd_tag_from_cfg(Arena *arena, RD_Cfg *cfg); - //////////////////////////////// //~ rjf: Control Entity Info Extraction @@ -941,7 +939,7 @@ internal Rng1U64 rd_whole_range_from_eval_space(E_Space space); //~ rjf: Evaluation Visualization //- rjf: writing values back to child processes -internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping); +internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string); //- rjf: eval <-> file path internal String8 rd_file_path_from_eval(Arena *arena, E_Eval eval); @@ -971,12 +969,12 @@ internal E_Value rd_view_cfg_value_from_string(String8 string); //- rjf: evaluation & tag (a view's 'call') parameter extraction internal U64 rd_base_offset_from_eval(E_Eval eval); -internal Rng1U64 rd_range_from_eval_tag(E_Eval eval, E_Expr *tag); -internal TXT_LangKind rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag); -internal Arch rd_arch_from_eval_tag(E_Eval eval, E_Expr *tag); -internal Vec2S32 rd_dim2s32_from_eval_tag(E_Eval eval, E_Expr *tag); -internal R_Tex2DFormat rd_tex2dformat_from_eval_tag(E_Eval eval, E_Expr *tag); -internal E_Value rd_value_from_eval_tag_key(E_Eval eval, E_Expr *tag, String8 key); +internal Rng1U64 rd_range_from_eval(E_Eval eval); +internal TXT_LangKind rd_lang_kind_from_eval(E_Eval eval); +internal Arch rd_arch_from_eval(E_Eval eval); +internal Vec2S32 rd_dim2s32_from_eval(E_Eval eval); +internal R_Tex2DFormat rd_tex2dformat_from_eval(E_Eval eval); +internal E_Value rd_value_from_eval_key(E_Eval eval, String8 key); //- rjf: pushing/attaching view resources internal void *rd_view_state_by_size(U64 size); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 21d64a88..09afb46b 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1051,14 +1051,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: determine view ui rule - // TODO(rjf): @eval - info.view_ui_rule = &rd_nil_view_ui_rule; // rd_view_ui_rule_from_string(row->block->expand_rule->string); -#if 0 // TODO(rjf): @eval - if(info.view_ui_rule != &rd_nil_view_ui_rule) - { - info.view_ui_tag = row->block->expand_tag; - } -#endif + info.view_ui_rule = rd_view_ui_rule_from_string(row->block->viz_expand_rule->string); // rjf: fill row's cells { @@ -1311,9 +1304,9 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; 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_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("lens:hex((U64)($expr))"), .default_pct = 0.20f, .pct = take_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("lens:hex((uint64)($expr))"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .eval = (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), .string = str8_lit(" "), @@ -1332,7 +1325,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_Expr, .default_pct = 0.25f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr => default)"), .default_pct = 0.15f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("typeof($expr)"), .default_pct = 0.15f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Tag, .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1353,7 +1346,6 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: fill basics/defaults result.view_ui_rule = &rd_nil_view_ui_rule; - result.view_ui_tag = &e_expr_nil; result.fstrs = cell->fstrs; result.flags = cell->flags; result.cfg = &rd_nil_cfg; @@ -1495,16 +1487,22 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla //- rjf: evaluate wrapped expression result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : e_eval_from_expr(arena, root_expr)); - //- rjf: determine default radix - U32 default_radix = 10; - if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && - rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) + //- rjf: determine string generation parameters based on evaluation + EV_StringParams string_params = {string_flags, 10}; { - default_radix = 16; + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCfg || + result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) + { + string_params.flags |= EV_StringFlag_DisableStringQuotes; + } + if(result.eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && + rd_ctrl_entity_from_eval_space(result.eval.space)->kind == CTRL_EntityKind_Module) + { + string_params.radix = 16; + } } //- rjf: generate strings/flags based on that expression & fill - EV_StringParams string_params = {.flags = string_flags, .radix = default_radix}; result.string = rd_value_string_from_eval_NEW(arena, rd_view_query_input(), &string_params, font, font_size, max_size_px, result.eval); result.flags |= !!(ev_type_key_is_editable(result.eval.irtree.type_key) && result.eval.irtree.mode == E_Mode_Offset) * RD_WatchCellFlag_CanEdit; E_Type *type = e_type_from_key__cached(result.eval.irtree.type_key); @@ -1529,7 +1527,6 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla { result.eval = (cell->eval.irtree.mode != E_Mode_Null ? cell->eval : row->eval); result.view_ui_rule = row_info->view_ui_rule; - result.view_ui_tag = row_info->view_ui_tag; }break; } @@ -1743,9 +1740,9 @@ RD_VIEW_UI_FUNCTION_DEF(text) if(rd_regs()->cursor.column == 0) { rd_regs()->cursor.column = 1; } if(rd_regs()->mark.line == 0) { rd_regs()->mark.line = 1; } if(rd_regs()->mark.column == 0) { rd_regs()->mark.column = 1; } - Rng1U64 range = rd_range_from_eval_tag(eval, tag); + Rng1U64 range = rd_range_from_eval(eval); rd_regs()->text_key = rd_key_from_eval_space_range(eval.space, range, 1); - rd_regs()->lang_kind = rd_lang_kind_from_eval_tag(eval, tag); + rd_regs()->lang_kind = rd_lang_kind_from_eval(eval); U128 hash = {0}; TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, rd_regs()->text_key, rd_regs()->lang_kind, &hash); String8 data = hs_data_from_hash(hs_scope, hash); @@ -2002,8 +1999,8 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { space = auto_space; } - Rng1U64 range = rd_range_from_eval_tag(eval, tag); - Arch arch = rd_arch_from_eval_tag(eval, tag); + Rng1U64 range = rd_range_from_eval(eval); + Arch arch = rd_arch_from_eval(eval); CTRL_Entity *space_entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *dasm_module = &ctrl_entity_nil; DI_Key dbgi_key = {0}; @@ -2170,7 +2167,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ////////////////////////////// //- rjf: unpack parameterization info // - Rng1U64 space_range = rd_range_from_eval_tag(eval, tag); + Rng1U64 space_range = rd_range_from_eval(eval); if(eval.space.kind == 0) { eval.space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); @@ -3085,8 +3082,8 @@ RD_VIEW_UI_FUNCTION_DEF(bitmap) ////////////////////////////// //- rjf: evaluate expression // - Vec2S32 dim = rd_dim2s32_from_eval_tag(eval, tag); - R_Tex2DFormat fmt = rd_tex2dformat_from_eval_tag(eval, tag); + Vec2S32 dim = rd_dim2s32_from_eval(eval); + R_Tex2DFormat fmt = rd_tex2dformat_from_eval(eval); U64 base_offset = rd_base_offset_from_eval(eval); U64 expected_size = dim.x*dim.y*r_tex2d_format_bytes_per_pixel_table[fmt]; Rng1U64 offset_range = r1u64(base_offset, base_offset + expected_size); @@ -3283,7 +3280,7 @@ RD_VIEW_UI_FUNCTION_DEF(checkbox) E_Eval value_eval = e_value_eval_from_eval(eval); if(ui_clicked(rd_icon_buttonf(value_eval.value.u64 == 0 ? RD_IconKind_CheckHollow : RD_IconKind_CheckFilled, 0, "###check"))) { - rd_commit_eval_value_string(eval, value_eval.value.u64 == 0 ? str8_lit("1") : str8_lit("0"), 0); + rd_commit_eval_value_string(eval, value_eval.value.u64 == 0 ? str8_lit("1") : str8_lit("0")); } } @@ -3484,9 +3481,9 @@ RD_VIEW_UI_FUNCTION_DEF(geo3d) ////////////////////////////// //- rjf: unpack parameters // - U64 count = rd_value_from_eval_tag_key(eval, tag, str8_lit("count")).u64; - U64 vtx_base_off = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx")).u64; - U64 vtx_size = rd_value_from_eval_tag_key(eval, tag, str8_lit("vtx_size")).u64; + U64 count = rd_value_from_eval_key(eval, str8_lit("count")).u64; + U64 vtx_base_off = rd_value_from_eval_key(eval, str8_lit("vtx")).u64; + U64 vtx_size = rd_value_from_eval_key(eval, str8_lit("vtx_size")).u64; F32 yaw_target = rd_view_cfg_value_from_string(str8_lit("yaw")).f32; F32 pitch_target = rd_view_cfg_value_from_string(str8_lit("pitch")).f32; F32 zoom_target = rd_view_cfg_value_from_string(str8_lit("zoom")).f32; diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index a4961eda..099929d0 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -118,7 +118,6 @@ struct RD_WatchRowCellInfo String8 error_tooltip; String8 inheritance_tooltip; RD_ViewUIRule *view_ui_rule; - E_Expr *view_ui_tag; }; typedef enum RD_WatchViewColumnKind