further work on convergence, dead code elimination, and lens (view rule) calls

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