begin introducing 'lookup' hook path in eval ir-tree generation, to collapse/universalize all 'access' operations, such that ., ->, and [] operations can be overridden via view rules, for cfg evaluations, and so on

This commit is contained in:
Ryan Fleury
2025-01-29 16:41:14 -08:00
parent 136a6a6d80
commit baa19f3de4
8 changed files with 471 additions and 261 deletions
+1
View File
@@ -72,6 +72,7 @@ E_TypeKindTable:
{Bitfield "bitfield" 0 }
{Variadic "variadic" 0 }
{SpacePtr "space_ptr" 0 }
{Set "set" 0 }
}
@table(name op_kind precedence string op_pre op_sep op_pos)
+312 -220
View File
@@ -70,6 +70,310 @@ e_select_ir_ctx(E_IRCtx *ctx)
e_ir_ctx = ctx;
}
////////////////////////////////
//~ rjf: Lookups
internal E_LookupRule *
e_lookup_rule_from_string(String8 string)
{
local_persist read_only E_LookupRule e_lookup_rule__default =
{
str8_lit_comp("default"),
E_LOOKUP_INFO_FUNCTION_NAME(default),
E_LOOKUP_FUNCTION_NAME(default),
};
E_LookupRule *result = &e_lookup_rule__default;
{
U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%e_ir_ctx->lookup_rule_map->slots_count;
for(E_LookupRuleNode *n = e_ir_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;
}
E_LOOKUP_INFO_FUNCTION_DEF(default)
{
E_LookupInfo lookup_info = {0};
Temp scratch = scratch_begin(&arena, 1);
{
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs);
E_TypeKey lhs_type_key = e_type_unwrap(lhs_irtree.type_key);
E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key);
if(e_type_kind_is_pointer_or_ref(lhs_type_kind))
{
lookup_info.idxed_expr_count = 1;
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_irtree.type_key));
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
if(direct_type_kind == E_TypeKind_Array)
{
E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key);
lookup_info.idxed_expr_count = direct_type->count;
}
if(direct_type_kind == E_TypeKind_Struct ||
direct_type_kind == E_TypeKind_Class ||
direct_type_kind == E_TypeKind_Union ||
direct_type_kind == E_TypeKind_Enum)
{
E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key);
lookup_info.named_expr_count = direct_type->count;
}
}
else if(lhs_type_kind == E_TypeKind_Struct ||
lhs_type_kind == E_TypeKind_Class ||
lhs_type_kind == E_TypeKind_Union ||
lhs_type_kind == E_TypeKind_Enum)
{
E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key);
lookup_info.named_expr_count = lhs_type->count;
}
}
scratch_end(scratch);
return lookup_info;
}
E_LOOKUP_FUNCTION_DEF(default)
{
E_Lookup lookup = {0};
switch(kind)
{
default:{}break;
//- rjf: member accessing
case E_ExprKind_MemberAccess:
{
// rjf: unpack left/right expressions
E_Expr *exprl = lhs;
E_Expr *exprr = rhs;
E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl);
E_TypeKey l_restype = e_type_unwrap(l.type_key);
E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype);
E_TypeKey check_type_key = l_restype;
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)
{
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);
}
e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs);
// rjf: look up member
B32 r_found = 0;
E_TypeKey r_type = zero_struct;
U64 r_value = 0;
B32 r_is_constant_value = 0;
{
Temp scratch = scratch_begin(&arena, 1);
E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string);
if(match.kind != E_MemberKind_Null)
{
r_found = 1;
r_type = match.type_key;
r_value = match.off;
}
if(match.kind == E_MemberKind_Null)
{
E_Type *type = e_type_from_key(scratch.arena, check_type_key);
if(type->enum_vals != 0)
{
String8 lookup_string = exprr->string;
String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string);
String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string);
E_EnumVal *enum_val_match = 0;
for EachIndex(idx, type->count)
{
if(str8_match(type->enum_vals[idx].name, lookup_string, 0) ||
str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) ||
str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0))
{
enum_val_match = &type->enum_vals[idx];
break;
}
}
if(enum_val_match != 0)
{
r_found = 1;
r_type = check_type_key;
r_value = enum_val_match->val;
r_is_constant_value = 1;
}
}
}
scratch_end(scratch);
}
// rjf: bad conditions? -> error if applicable, exit
if(e_type_key_match(e_type_key_zero(), check_type_key))
{
break;
}
else if(exprr->kind != E_ExprKind_LeafMember)
{
e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name.");
break;
}
else if(!r_found)
{
e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string);
break;
}
else if(check_type_kind != E_TypeKind_Struct &&
check_type_kind != E_TypeKind_Class &&
check_type_kind != E_TypeKind_Union &&
check_type_kind != E_TypeKind_Enum)
{
e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type.");
break;
}
// rjf: generate
{
// rjf: build tree
E_IRNode *new_tree = l.root;
E_Mode mode = l.mode;
if(l_restype_kind == E_TypeKind_Ptr ||
l_restype_kind == E_TypeKind_LRef ||
l_restype_kind == E_TypeKind_RRef)
{
new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype);
mode = E_Mode_Offset;
}
if(r_value != 0 && !r_is_constant_value)
{
E_IRNode *const_tree = e_irtree_const_u(arena, r_value);
new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree);
}
else if(r_is_constant_value)
{
new_tree = e_irtree_const_u(arena, r_value);
mode = E_Mode_Value;
}
// rjf: fill
lookup.irtree_and_type.root = new_tree;
lookup.irtree_and_type.type_key = r_type;
lookup.irtree_and_type.mode = mode;
}
}break;
//- rjf: array indexing
case E_ExprKind_ArrayIndex:
{
// rjf: unpack left/right expressions
E_Expr *exprl = lhs;
E_Expr *exprr = rhs;
E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl);
E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr);
E_TypeKey l_restype = e_type_unwrap(l.type_key);
E_TypeKey r_restype = e_type_unwrap(r.type_key);
E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype);
E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype);
if(e_type_kind_is_basic_or_enum(r_restype_kind))
{
r_restype = e_type_unwrap_enum(r_restype);
r_restype_kind = e_type_kind_from_key(r_restype);
}
E_TypeKey direct_type = e_type_unwrap(l_restype);
direct_type = e_type_direct_from_key(direct_type);
direct_type = e_type_unwrap(direct_type);
U64 direct_type_size = e_type_byte_size_from_key(direct_type);
e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs);
e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &r.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r.root->op == 0)
{
break;
}
else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array)
{
e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type.");
break;
}
else if(!e_type_kind_is_integer(r_restype_kind))
{
e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type.");
break;
}
else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0)
{
e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types.");
break;
}
else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0)
{
e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types.");
break;
}
// rjf: generate
E_IRNode *new_tree = &e_irnode_nil;
{
switch(l.mode)
{
// rjf: offsets -> read from base offset
default:
case E_Mode_Null:
case E_Mode_Offset:
{
// rjf: ops to compute the offset
E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype);
if(direct_type_size > 1)
{
E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size);
offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree);
}
// rjf: ops to compute the base offset (resolve to value if addr-of-pointer)
E_IRNode *base_tree = l.root;
if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value)
{
base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype);
}
// rjf: ops to compute the final address
new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree);
}break;
// rjf: values -> read from stack value
case E_Mode_Value:
{
// rjf: ops to compute the offset
E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype);
if(direct_type_size > 1)
{
E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size);
offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree);
}
// rjf: ops to push stack value, push offset, + read from stack value
new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead);
new_tree->value.u64 = direct_type_size;
e_irnode_push_child(new_tree, offset_tree);
e_irnode_push_child(new_tree, l.root);
}break;
}
}
// rjf: fill
lookup.irtree_and_type.root = new_tree;
lookup.irtree_and_type.type_key = direct_type;
lookup.irtree_and_type.mode = l.mode;
}break;
}
return lookup;
}
////////////////////////////////
//~ rjf: IR-ization Functions
@@ -400,228 +704,16 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
result = e_irtree_and_type_from_expr__space(arena, current_space, expr->ref);
}break;
//- rjf: array indices
//- rjf: accesses
case E_ExprKind_MemberAccess:
case E_ExprKind_ArrayIndex:
{
// rjf: unpack left/right expressions
E_Expr *exprl = expr->first;
E_Expr *exprr = exprl->next;
E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl);
E_IRTreeAndType r = e_irtree_and_type_from_expr__space(arena, current_space, exprr);
E_TypeKey l_restype = e_type_unwrap(l.type_key);
E_TypeKey r_restype = e_type_unwrap(r.type_key);
E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype);
E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype);
if(e_type_kind_is_basic_or_enum(r_restype_kind))
{
r_restype = e_type_unwrap_enum(r_restype);
r_restype_kind = e_type_kind_from_key(r_restype);
}
E_TypeKey direct_type = e_type_unwrap(l_restype);
direct_type = e_type_direct_from_key(direct_type);
direct_type = e_type_unwrap(direct_type);
U64 direct_type_size = e_type_byte_size_from_key(direct_type);
e_msg_list_concat_in_place(&result.msgs, &l.msgs);
e_msg_list_concat_in_place(&result.msgs, &r.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r.root->op == 0)
{
break;
}
else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type.");
break;
}
else if(!e_type_kind_is_integer(r_restype_kind))
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type.");
break;
}
else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types.");
break;
}
else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types.");
break;
}
// rjf: generate
E_IRNode *new_tree = &e_irnode_nil;
{
switch(l.mode)
{
// rjf: offsets -> read from base offset
default:
case E_Mode_Null:
case E_Mode_Offset:
{
// rjf: ops to compute the offset
E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype);
if(direct_type_size > 1)
{
E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size);
offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree);
}
// rjf: ops to compute the base offset (resolve to value if addr-of-pointer)
E_IRNode *base_tree = l.root;
if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value)
{
base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype);
}
// rjf: ops to compute the final address
new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree);
}break;
// rjf: values -> read from stack value
case E_Mode_Value:
{
// rjf: ops to compute the offset
E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype);
if(direct_type_size > 1)
{
E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size);
offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree);
}
// rjf: ops to push stack value, push offset, + read from stack value
new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead);
new_tree->value.u64 = direct_type_size;
e_irnode_push_child(new_tree, offset_tree);
e_irnode_push_child(new_tree, l.root);
}break;
}
}
// rjf: fill
result.root = new_tree;
result.type_key = direct_type;
result.mode = l.mode;
}break;
//- rjf: member accesses
case E_ExprKind_MemberAccess:
{
// rjf: unpack left/right expressions
E_Expr *exprl = expr->first;
E_Expr *exprr = exprl->next;
E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl);
E_TypeKey l_restype = e_type_unwrap(l.type_key);
E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype);
E_TypeKey check_type_key = l_restype;
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)
{
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);
}
e_msg_list_concat_in_place(&result.msgs, &l.msgs);
// rjf: look up member
B32 r_found = 0;
E_TypeKey r_type = zero_struct;
U64 r_value = 0;
B32 r_is_constant_value = 0;
{
Temp scratch = scratch_begin(&arena, 1);
E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string);
if(match.kind != E_MemberKind_Null)
{
r_found = 1;
r_type = match.type_key;
r_value = match.off;
}
if(match.kind == E_MemberKind_Null)
{
E_Type *type = e_type_from_key(scratch.arena, check_type_key);
if(type->enum_vals != 0)
{
String8 lookup_string = exprr->string;
String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string);
String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string);
E_EnumVal *enum_val_match = 0;
for EachIndex(idx, type->count)
{
if(str8_match(type->enum_vals[idx].name, lookup_string, 0) ||
str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) ||
str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0))
{
enum_val_match = &type->enum_vals[idx];
break;
}
}
if(enum_val_match != 0)
{
r_found = 1;
r_type = check_type_key;
r_value = enum_val_match->val;
r_is_constant_value = 1;
}
}
}
scratch_end(scratch);
}
// rjf: bad conditions? -> error if applicable, exit
if(e_type_key_match(e_type_key_zero(), check_type_key))
{
break;
}
else if(exprr->kind != E_ExprKind_LeafMember)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name.");
break;
}
else if(!r_found)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string);
break;
}
else if(check_type_kind != E_TypeKind_Struct &&
check_type_kind != E_TypeKind_Class &&
check_type_kind != E_TypeKind_Union &&
check_type_kind != E_TypeKind_Enum)
{
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type.");
break;
}
// rjf: generate
{
// rjf: build tree
E_IRNode *new_tree = l.root;
E_Mode mode = l.mode;
if(l_restype_kind == E_TypeKind_Ptr ||
l_restype_kind == E_TypeKind_LRef ||
l_restype_kind == E_TypeKind_RRef)
{
new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype);
mode = E_Mode_Offset;
}
if(r_value != 0 && !r_is_constant_value)
{
E_IRNode *const_tree = e_irtree_const_u(arena, r_value);
new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree);
}
else if(r_is_constant_value)
{
new_tree = e_irtree_const_u(arena, r_value);
mode = E_Mode_Value;
}
// rjf: fill
result.root = new_tree;
result.type_key = r_type;
result.mode = mode;
}
E_Expr *lhs = expr->first;
E_Expr *rhs = lhs->next;
E_LookupRule *lookup_rule = e_lookup_rule_from_string(expr->string);
E_LookupInfo lookup_info = lookup_rule->lookup_info(arena, lhs);
E_Lookup lookup = lookup_rule->lookup(arena, expr->kind, lhs, rhs, lookup_info.user_data);
result = lookup.irtree_and_type;
}break;
//- rjf: dereference
+64
View File
@@ -56,6 +56,62 @@ struct E_IRTreeAndType
E_MsgList msgs;
};
////////////////////////////////
//~ rjf: Member/Index Lookup Hooks
typedef struct E_LookupInfo E_LookupInfo;
struct E_LookupInfo
{
void *user_data;
U64 named_expr_count;
U64 idxed_expr_count;
};
typedef struct E_Lookup E_Lookup;
struct E_Lookup
{
E_IRTreeAndType irtree_and_type;
};
#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs)
#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name
#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name))
typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType);
#define E_LOOKUP_FUNCTION_SIG(name) E_Lookup name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data)
#define E_LOOKUP_FUNCTION_NAME(name) e_lookup_##name
#define E_LOOKUP_FUNCTION_DEF(name) internal E_LOOKUP_FUNCTION_SIG(E_LOOKUP_FUNCTION_NAME(name))
typedef E_LOOKUP_FUNCTION_SIG(E_LookupFunctionType);
typedef struct E_LookupRule E_LookupRule;
struct E_LookupRule
{
String8 name;
E_LookupInfoFunctionType *lookup_info;
E_LookupFunctionType *lookup;
};
typedef struct E_LookupRuleNode E_LookupRuleNode;
struct E_LookupRuleNode
{
E_LookupRuleNode *next;
E_LookupRule v;
};
typedef struct E_LookupRuleSlot E_LookupRuleSlot;
struct E_LookupRuleSlot
{
E_LookupRuleNode *first;
E_LookupRuleNode *last;
};
typedef struct E_LookupRuleMap E_LookupRuleMap;
struct E_LookupRuleMap
{
E_LookupRuleSlot *slots;
U64 slots_count;
};
////////////////////////////////
//~ rjf: Parse Context
@@ -63,6 +119,7 @@ typedef struct E_IRCtx E_IRCtx;
struct E_IRCtx
{
E_String2ExprMap *macro_map;
E_LookupRuleMap *lookup_rule_map;
};
////////////////////////////////
@@ -83,6 +140,13 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind);
internal E_IRCtx *e_selected_ir_ctx(void);
internal void e_select_ir_ctx(E_IRCtx *ctx);
////////////////////////////////
//~ rjf: Lookups
internal E_LookupRule *e_lookup_rule_from_string(String8 string);
E_LOOKUP_INFO_FUNCTION_DEF(default);
E_LOOKUP_FUNCTION_DEF(default);
////////////////////////////////
//~ rjf: IR-ization Functions
+4 -2
View File
@@ -135,7 +135,7 @@ E_OpInfo e_expr_kind_op_info_table[49] =
{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") },
};
U8 e_kind_basic_byte_size_table[56] =
U8 e_kind_basic_byte_size_table[57] =
{
0,
0,
@@ -193,9 +193,10 @@ U8 e_kind_basic_byte_size_table[56] =
0,
0,
0,
0,
};
String8 e_kind_basic_string_table[56] =
String8 e_kind_basic_string_table[57] =
{
str8_lit_comp(""),
str8_lit_comp("void"),
@@ -253,6 +254,7 @@ str8_lit_comp("enum"),
str8_lit_comp("bitfield"),
str8_lit_comp("variadic"),
str8_lit_comp("space_ptr"),
str8_lit_comp("set"),
};
C_LINKAGE_END
+3 -2
View File
@@ -75,6 +75,7 @@ E_TypeKind_IncompleteEnum,
E_TypeKind_Bitfield,
E_TypeKind_Variadic,
E_TypeKind_SpacePtr,
E_TypeKind_Set,
E_TypeKind_COUNT,
E_TypeKind_FirstBasic = E_TypeKind_Void,
E_TypeKind_LastBasic = E_TypeKind_ComplexF128,
@@ -164,8 +165,8 @@ extern String8 e_token_kind_strings[6];
extern String8 e_expr_kind_strings[49];
extern String8 e_interpretation_code_display_strings[11];
extern E_OpInfo e_expr_kind_op_info_table[49];
extern U8 e_kind_basic_byte_size_table[56];
extern String8 e_kind_basic_string_table[56];
extern U8 e_kind_basic_byte_size_table[57];
extern String8 e_kind_basic_string_table[57];
C_LINKAGE_END
+2 -2
View File
@@ -13084,8 +13084,8 @@ rd_frame(void)
E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1);
{
E_IRCtx *ctx = ir_ctx;
ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1);
ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512);
ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1);
ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512);
//- rjf: add macros for collections
{
+58 -24
View File
@@ -835,17 +835,17 @@ rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index)
//- rjf: watch view points <-> table coordinates
internal B32
rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b)
rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b)
{
return (ev_key_match(a.parent_key, b.parent_key) &&
ev_key_match(a.key, b.key) &&
a.cell_id == b.cell_id);
}
internal RD_WatchViewPoint
rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl)
internal RD_WatchPt
rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl)
{
RD_WatchViewPoint pt = zero_struct;
RD_WatchPt pt = zero_struct;
pt.cell_id = (U64)tbl.x;
pt.key = ev_key_from_num(block_ranges, (U64)tbl.y);
pt.parent_key = ev_block_range_from_num(block_ranges, (U64)tbl.y).block->key;
@@ -853,7 +853,7 @@ rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl)
}
internal Vec2S64
rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt)
rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt)
{
Vec2S64 tbl = {0};
tbl.x = (S64)pt.cell_id;
@@ -861,6 +861,40 @@ rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint
return tbl;
}
//- rjf: row -> info
internal RD_WatchRowInfo
rd_watch_row_info_from_row(Arena *arena, EV_Row *row)
{
RD_WatchRowInfo info = {0};
{
Temp scratch = scratch_begin(&arena, 1);
DI_Scope *di_scope = di_scope_open();
// rjf: unpack key & block
EV_Block *block = row->block;
EV_Key key = row->key;
E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr);
E_Type *parent_type = e_type_from_key(arena, parent_irtree.type_key);
// rjf: fill row's eval
info.eval = e_eval_from_expr(arena, row->expr);
// rjf: determine cfg group
// rjf: fill row's cells
rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f);
rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Value, .pct = 0.30f);
rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Type, .pct = 0.15f);
rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewRule, .pct = 0.30f);
di_scope_close(di_scope);
scratch_end(scratch);
}
return info;
}
//- rjf: row -> context info
internal RD_WatchViewRowInfo
@@ -1229,7 +1263,7 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn
//- rjf: table coordinates -> text edit state
internal RD_WatchViewTextEditState *
rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt)
rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt)
{
RD_WatchViewTextEditState *result = &wv->dummy_text_edit_state;
if(wv->text_edit_state_slots_count != 0 && wv->text_editing != 0)
@@ -1238,7 +1272,7 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint p
U64 slot_idx = hash%wv->text_edit_state_slots_count;
for(RD_WatchViewTextEditState *s = wv->text_edit_state_slots[slot_idx]; s != 0; s = s->pt_hash_next)
{
if(rd_watch_view_point_match(pt, s->pt))
if(rd_watch_pt_match(pt, s->pt))
{
result = s;
break;
@@ -1416,7 +1450,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
cursor_dirty__tbl = 0;
struct
{
RD_WatchViewPoint *pt_state;
RD_WatchPt *pt_state;
Vec2S64 pt_tbl;
}
points[] =
@@ -1428,7 +1462,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
{
EV_Key last_key = points[point_idx].pt_state->key;
EV_Key last_parent_key = points[point_idx].pt_state->parent_key;
points[point_idx].pt_state[0] = rd_watch_view_point_from_tbl(&block_ranges, points[point_idx].pt_tbl);
points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl);
if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key))
{
points[point_idx].pt_state->key = last_parent_key;
@@ -1460,8 +1494,8 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
Rng2S64 cursor_tbl_range = {0};
{
// rjf: compute 2d table coordinates
cursor_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->cursor);
mark_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->mark);
cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor);
mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark);
// rjf: compute row at initial selection point (or just cursor point)
mark_rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(mark_tbl.y, mark_tbl.y+1));
@@ -1544,7 +1578,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
//- rjf: apply cursor/mark rugpull change
//
B32 cursor_rugpull = 0;
if(!rd_watch_view_point_match(ewv->cursor, ewv->next_cursor))
if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor))
{
cursor_rugpull = 1;
ewv->cursor = ewv->next_cursor;
@@ -1598,7 +1632,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x);
String8 string = rd_string_from_eval_viz_row_column(scratch.arena, row, col, string_flags, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px);
string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer));
RD_WatchViewPoint pt = {row->block->key, row->key, x};
RD_WatchPt pt = {row->block->key, row->key, x};
U64 hash = ev_hash_from_key(pt.key);
U64 slot_idx = hash%ewv->text_edit_state_slots_count;
RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1);
@@ -1701,7 +1735,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info);
for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1)
{
RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, v2s64(x, y));
RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, v2s64(x, y));
RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt);
String8 string = str8(edit_state->input_buffer, edit_state->input_size);
UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark);
@@ -1808,7 +1842,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
case RD_WatchViewColumnKind_ViewRule:
if(editing_complete)
{
RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl);
RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl);
ev_key_set_view_rule(eval_view, pt.key, new_string);
if(row_info.collection_entity_kind != RD_EntityKind_Nil)
{
@@ -1890,7 +1924,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
state_dirty = 1;
snap_to_cursor = 1;
RD_EntityList entities_to_remove = {0};
RD_WatchViewPoint next_cursor_pt = {0};
RD_WatchPt next_cursor_pt = {0};
B32 next_cursor_set = 0;
EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1));
EV_WindowedRowNode *row_node = rows.first;
@@ -1902,7 +1936,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1)
{
Vec2S64 tbl = v2s64(x, y);
RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl);
RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl);
RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x);
if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Expr || row_kind == RD_WatchViewRowKind_PrettyEntityControls) &&
row_info.collection_entity_kind != RD_EntityKind_Nil)
@@ -1924,7 +1958,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
key = row->block->key;
parent_key = row->block->parent->key;
}
RD_WatchViewPoint new_pt = {parent_key, key, 0};
RD_WatchPt new_pt = {parent_key, key, 0};
next_cursor_pt = new_pt;
next_cursor_set = 1;
}
@@ -2298,7 +2332,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
ui_view_rule_params_root = &md_nil_node;
}
RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row);
RD_WatchCellList row_cells = rd_watch_cell_list_from_row_info(scratch.arena, row, &row_info);
RD_WatchRowInfo row_info_NEW = rd_watch_row_info_from_row(scratch.arena, row);
ProfEnd();
////////////////////////
@@ -2425,11 +2459,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
////////////////////
//- rjf: build all cells
//
for(RD_WatchCell *cell = row_cells.first; cell != 0; cell = cell->next)
for(RD_WatchCell *cell = row_info_NEW.cells.first; cell != 0; cell = cell->next)
{
#if 0 // TODO(rjf): @cfg
//- rjf: unpack cell info
RD_WatchViewPoint cell_pt = {x, row->block->key, row->key};
RD_WatchPt cell_pt = {x, row->block->key, row->key};
RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt);
B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x);
String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px);
@@ -3046,7 +3080,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
{
#if 0 // TODO(rjf): @cfg
//- rjf: unpack
RD_WatchViewPoint pt = {0, row->block->key, row->key};
RD_WatchPt pt = {0, row->block->key, row->key};
RD_View *view = rd_view_from_handle(rd_regs()->view);
RD_TransientViewNode *canvas_view_node = rd_transient_view_node_from_ev_key(view, row->key);
RD_View *canvas_view = canvas_view_node->view;
@@ -3312,7 +3346,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
}
if(ui_pressed(sig))
{
RD_WatchViewPoint cell_pt = {1, row->block->key, row->key};
RD_WatchPt cell_pt = {1, row->block->key, row->key};
ewv->next_cursor = ewv->next_mark = cell_pt;
pressed = 1;
}
@@ -3477,7 +3511,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo
for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next, x += 1)
{
//- rjf: unpack cell info
RD_WatchViewPoint cell_pt = {x, row->block->key, row->key};
RD_WatchPt cell_pt = {x, row->block->key, row->key};
RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt);
B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x);
String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px);
+27 -11
View File
@@ -81,6 +81,19 @@ struct RD_WatchCellList
U64 count;
};
typedef struct RD_WatchRowInfo RD_WatchRowInfo;
struct RD_WatchRowInfo
{
E_Eval eval;
String8 group_key;
RD_Cfg *group_cfg;
CTRL_Entity *group_entity;
CTRL_Entity *callstack_thread;
U64 callstack_unwind_index;
U64 callstack_inline_depth;
RD_WatchCellList cells;
};
typedef enum RD_WatchViewColumnKind
{
RD_WatchViewColumnKind_Expr,
@@ -141,8 +154,8 @@ typedef enum RD_WatchViewRowKind
}
RD_WatchViewRowKind;
typedef struct RD_WatchViewPoint RD_WatchViewPoint;
struct RD_WatchViewPoint
typedef struct RD_WatchPt RD_WatchPt;
struct RD_WatchPt
{
EV_Key parent_key;
EV_Key key;
@@ -165,7 +178,7 @@ typedef struct RD_WatchViewTextEditState RD_WatchViewTextEditState;
struct RD_WatchViewTextEditState
{
RD_WatchViewTextEditState *pt_hash_next;
RD_WatchViewPoint pt;
RD_WatchPt pt;
TxtPt cursor;
TxtPt mark;
U8 input_buffer[1024];
@@ -187,10 +200,10 @@ struct RD_WatchViewState
U64 column_count;
// rjf; table cursor state
RD_WatchViewPoint cursor;
RD_WatchViewPoint mark;
RD_WatchViewPoint next_cursor;
RD_WatchViewPoint next_mark;
RD_WatchPt cursor;
RD_WatchPt mark;
RD_WatchPt next_cursor;
RD_WatchPt next_mark;
// rjf: text input state
Arena *text_edit_arena;
@@ -218,9 +231,12 @@ internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellLi
internal RD_WatchViewColumn *rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index);
//- rjf: watch view points <-> table coordinates
internal B32 rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b);
internal RD_WatchViewPoint rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl);
internal Vec2S64 rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt);
internal B32 rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b);
internal RD_WatchPt rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl);
internal Vec2S64 rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt);
//- rjf: row -> info
internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row);
//- rjf: row -> context info
internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row);
@@ -236,7 +252,7 @@ internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, R
internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px);
//- rjf: table coordinates -> text edit state
internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt);
internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt);
//- rjf: watch view column state mutation
internal RD_WatchViewColumn *rd_watch_view_column_alloc_(RD_WatchViewState *wv, RD_WatchViewColumnKind kind, F32 pct, RD_WatchViewColumnParams *params);