mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-21 13:55:43 +00:00
lens inheritance-on-expansion, composability with lens types & accesses (dot operator, array index operator), plugging in visualizers, killing dead code, etc.
This commit is contained in:
@@ -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;
|
||||
|
||||
+49
-4
@@ -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;
|
||||
|
||||
+147
-102
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user