convert all eval visualization paths to incrementally building expression trees, rather than using final eval bundles; ensure all evaluation paths, in various circumstances (single line viz, row viz), go through exactly the same path; deduplicate single-row-expr evaluation paths

This commit is contained in:
Ryan Fleury
2024-08-20 12:04:23 -07:00
parent be2daf570a
commit 639239d758
21 changed files with 1436 additions and 1536 deletions
+461 -84
View File
@@ -4220,6 +4220,93 @@ df_string_from_simple_typed_eval(Arena *arena, DF_EvalVizStringFlags flags, U32
return result;
}
internal String8
df_escaped_from_raw_string(Arena *arena, String8 raw)
{
Temp scratch = scratch_begin(&arena, 1);
String8List parts = {0};
U64 start_split_idx = 0;
for(U64 idx = 0; idx <= raw.size; idx += 1)
{
U8 byte = (idx < raw.size) ? raw.str[idx] : 0;
B32 split = 1;
String8 separator_replace = {0};
switch(byte)
{
default:{split = 0;}break;
case 0: {}break;
case '\a': {separator_replace = str8_lit("\\a");}break;
case '\b': {separator_replace = str8_lit("\\b");}break;
case '\f': {separator_replace = str8_lit("\\f");}break;
case '\n': {separator_replace = str8_lit("\\n");}break;
case '\r': {separator_replace = str8_lit("\\r");}break;
case '\t': {separator_replace = str8_lit("\\t");}break;
case '\v': {separator_replace = str8_lit("\\v");}break;
case '\\': {separator_replace = str8_lit("\\\\");}break;
case '"': {separator_replace = str8_lit("\\\"");}break;
case '?': {separator_replace = str8_lit("\\?");}break;
}
if(split)
{
String8 substr = str8_substr(raw, r1u64(start_split_idx, idx));
start_split_idx = idx+1;
str8_list_push(scratch.arena, &parts, substr);
if(separator_replace.size != 0)
{
str8_list_push(scratch.arena, &parts, separator_replace);
}
}
}
StringJoin join = {0};
String8 result = str8_list_join(arena, &parts, &join);
scratch_end(scratch);
return result;
}
//- rjf: type info -> expandability/editablity
internal B32
df_type_key_is_expandable(E_TypeKey type_key)
{
B32 result = 0;
for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t))))
{
E_TypeKind kind = e_type_kind_from_key(t);
if(kind == E_TypeKind_Null || kind == E_TypeKind_Function)
{
break;
}
if(kind == E_TypeKind_Struct ||
kind == E_TypeKind_Union ||
kind == E_TypeKind_Class ||
kind == E_TypeKind_Array ||
kind == E_TypeKind_Enum)
{
result = 1;
}
}
return result;
}
internal B32
df_type_key_is_editable(E_TypeKey type_key)
{
B32 result = 0;
for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t))))
{
E_TypeKind kind = e_type_kind_from_key(t);
if(kind == E_TypeKind_Null || kind == E_TypeKind_Function)
{
break;
}
if((E_TypeKind_FirstBasic <= kind && kind <= E_TypeKind_LastBasic) || e_type_kind_is_pointer_or_ref(kind))
{
result = 1;
}
}
return result;
}
//- rjf: writing values back to child processes
internal B32
@@ -4533,6 +4620,8 @@ df_eval_viz_block_begin(Arena *arena, DF_EvalVizBlockKind kind, DF_ExpandKey par
n->v.parent_key = parent_key;
n->v.key = key;
n->v.depth = depth;
n->v.expr = &e_expr_nil;
n->v.cfg_table = &df_g_nil_cfg_table;
return &n->v;
}
@@ -4543,15 +4632,15 @@ df_eval_viz_block_split_and_continue(Arena *arena, DF_EvalVizBlockList *list, DF
split_block->visual_idx_range.max = split_block->semantic_idx_range.max = split_idx;
df_eval_viz_block_end(list, split_block);
DF_EvalVizBlock *continue_block = df_eval_viz_block_begin(arena, split_block->kind, split_block->parent_key, split_block->key, split_block->depth);
continue_block->eval = split_block->eval;
continue_block->string = split_block->string;
continue_block->member = split_block->member;
continue_block->visual_idx_range = continue_block->semantic_idx_range = r1u64(split_idx+1, total_count);
continue_block->string = split_block->string;
continue_block->expr = split_block->expr;
continue_block->visual_idx_range = continue_block->semantic_idx_range = r1u64(split_idx+1, total_count);
continue_block->cfg_table = split_block->cfg_table;
continue_block->link_bases = split_block->link_bases;
continue_block->members = split_block->members;
continue_block->enum_vals = split_block->enum_vals;
continue_block->fzy_target = split_block->fzy_target;
continue_block->fzy_backing_items = split_block->fzy_backing_items;
continue_block->fzy_target = split_block->fzy_target;
continue_block->cfg_table = split_block->cfg_table;
continue_block->link_member_type_key = split_block->link_member_type_key;
continue_block->link_member_off = split_block->link_member_off;
return continue_block;
}
@@ -4566,47 +4655,60 @@ df_eval_viz_block_end(DF_EvalVizBlockList *list, DF_EvalVizBlock *block)
}
internal void
df_append_viz_blocks_for_parent__rec(Arena *arena, DF_EvalView *eval_view, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, E_Eval eval, E_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out)
df_append_viz_blocks_for_parent__rec(Arena *arena, DF_EvalView *eval_view, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, E_Expr *expr, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
//////////////////////////////
//- rjf: determine if this key is expanded
//
DF_ExpandNode *node = df_expand_node_from_key(&eval_view->expand_tree_table, key);
B32 parent_is_expanded = (node != 0 && node->expanded && !e_type_key_match(e_type_key_zero(), eval.type_key));
B32 parent_is_expanded = (node != 0 && node->expanded);
//////////////////////////////
//- rjf: apply view rules & resolve eval
//
eval = e_dynamically_typed_eval_from_eval(eval);
eval = df_eval_from_eval_cfg_table(arena, eval, cfg_table);
//////////////////////////////
//- rjf: unpack eval
//
E_TypeKey eval_type_key = e_type_unwrap(eval.type_key);
E_TypeKind eval_type_kind = e_type_kind_from_key(eval_type_key);
String8 eval_string = push_str8_copy(arena, string);
//////////////////////////////
//- rjf: make and push block for root
//
//- rjf: push block for expression root
{
DF_EvalVizBlock *block = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Root, parent_key, key, depth);
block->eval = eval;
block->string = string;
block->expr = expr;
block->cfg_table = cfg_table;
block->string = eval_string;
block->visual_idx_range = r1u64(key.child_num-1, key.child_num+0);
block->semantic_idx_range = r1u64(key.child_num-1, key.child_num+0);
if(opt_member != 0)
{
block->member = e_type_member_copy(arena, opt_member);
}
df_eval_viz_block_end(list_out, block);
}
//- rjf: determine view rule to generate children blocks
DF_CoreViewRuleSpec *expand_view_rule_spec = df_core_view_rule_spec_from_string(str8_lit("default"));
DF_CfgVal *expand_view_rule_cfg = &df_g_nil_cfg_val;
if(parent_is_expanded)
{
for(DF_CfgVal *val = cfg_table->first_val;
val != 0 && val != &df_g_nil_cfg_val;
val = val->linear_next)
{
DF_CoreViewRuleSpec *spec = df_core_view_rule_spec_from_string(val->string);
if(spec->info.flags & DF_CoreViewRuleSpecInfoFlag_VizBlockProd)
{
expand_view_rule_spec = spec;
expand_view_rule_cfg = val;
break;
}
}
}
//- rjf: do view rule children block generation, if we have an applicable view rule
if(parent_is_expanded && expand_view_rule_spec != &df_g_nil_core_view_rule_spec)
{
expand_view_rule_spec->info.viz_block_prod(arena, eval_view, parent_key, key, node, string, expr, cfg_table, depth+1, expand_view_rule_cfg, list_out);
}
scratch_end(scratch);
ProfEnd();
//-
//-
//-
// TODO(rjf): OLD vvvvvvvvvvvvvvvvvvvv
#if 0
//////////////////////////////
//- rjf: (pointers) extract type & info to use for members and/or arrays
//
@@ -4975,6 +5077,7 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DF_EvalView *eval_view, DF_Ex
scratch_end(scratch);
ProfEnd();
#endif
}
internal DF_EvalVizBlockList
@@ -4983,9 +5086,11 @@ df_eval_viz_block_list_from_eval_view_expr_keys(Arena *arena, DF_EvalView *eval_
ProfBeginFunction();
DF_EvalVizBlockList blocks = {0};
{
E_Eval eval = e_eval_from_string(arena, expr);
U64 expr_comma_pos = str8_find_needle(expr, eval.advance, str8_lit(","), 0);
U64 passthrough_pos = str8_find_needle(expr, eval.advance, str8_lit("--"), 0);
E_TokenArray tokens = e_token_array_from_text(arena, expr);
E_Parse parse = e_parse_expr_from_text_tokens(arena, expr, &tokens);
U64 parse_opl = parse.last_token >= tokens.v + tokens.count ? expr.size : parse.last_token->range.min;
U64 expr_comma_pos = str8_find_needle(expr, parse_opl, str8_lit(","), 0);
U64 passthrough_pos = str8_find_needle(expr, parse_opl, str8_lit("--"), 0);
String8List default_view_rules = {0};
if(expr_comma_pos < expr.size && expr_comma_pos < passthrough_pos)
{
@@ -5017,13 +5122,13 @@ df_eval_viz_block_list_from_eval_view_expr_keys(Arena *arena, DF_EvalView *eval_
}
}
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, key);
DF_CfgTable view_rule_table = {0};
DF_CfgTable *view_rule_table = push_array(arena, DF_CfgTable, 1);
for(String8Node *n = default_view_rules.first; n != 0; n = n->next)
{
df_cfg_table_push_unparsed_string(arena, &view_rule_table, n->string, DF_CfgSrc_User);
df_cfg_table_push_unparsed_string(arena, view_rule_table, n->string, DF_CfgSrc_User);
}
df_cfg_table_push_unparsed_string(arena, &view_rule_table, view_rule_string, DF_CfgSrc_User);
df_append_viz_blocks_for_parent__rec(arena, eval_view, parent_key, key, expr, eval, 0, &view_rule_table, 0, &blocks);
df_cfg_table_push_unparsed_string(arena, view_rule_table, view_rule_string, DF_CfgSrc_User);
df_append_viz_blocks_for_parent__rec(arena, eval_view, parent_key, key, expr, parse.expr, view_rule_table, 0, &blocks);
}
ProfEnd();
return blocks;
@@ -5146,10 +5251,145 @@ df_parent_key_from_viz_block_list_row_num(DF_EvalVizBlockList *blocks, S64 row_n
return key;
}
//- rjf: viz block * index -> expression
internal E_Expr *
df_expr_from_eval_viz_block_index(Arena *arena, DF_EvalVizBlock *block, U64 index)
{
E_Expr *result = block->expr;
switch(block->kind)
{
default:{}break;
case DF_EvalVizBlockKind_Members:
{
E_MemberArray *members = &block->members;
if(index < members->count)
{
E_Member *member = &members->v[index];
E_Expr *dot_expr = e_expr_ref_member_access(arena, block->expr, member->name);
result = dot_expr;
}
}break;
case DF_EvalVizBlockKind_EnumMembers:
{
E_EnumValArray *enum_vals = &block->enum_vals;
if(index < enum_vals->count)
{
E_EnumVal *val = &enum_vals->v[index];
E_Expr *dot_expr = e_expr_ref_member_access(arena, block->expr, val->name);
result = dot_expr;
}
}break;
case DF_EvalVizBlockKind_Elements:
{
E_Expr *idx_expr = e_expr_ref_array_index(arena, block->expr, index);
result = idx_expr;
}break;
case DF_EvalVizBlockKind_DebugInfoTable:
{
// rjf: unpack row info
FZY_Item *item = &block->fzy_backing_items.v[index];
DF_ExpandKey parent_key = block->parent_key;
DF_ExpandKey key = block->key;
key.child_num = block->fzy_backing_items.v[index].idx;
// rjf: determine module to which this item belongs
E_Module *module = e_parse_ctx->primary_module;
U64 base_idx = 0;
{
for(U64 module_idx = 0; module_idx < e_parse_ctx->modules_count; module_idx += 1)
{
U64 all_items_count = 0;
rdi_section_raw_table_from_kind(e_parse_ctx->modules[module_idx].rdi, block->fzy_target, &all_items_count);
if(base_idx <= item->idx && item->idx < base_idx + all_items_count)
{
module = &e_parse_ctx->modules[module_idx];
break;
}
base_idx += all_items_count;
}
}
// rjf: build expr
E_Expr *item_expr = &e_expr_nil;
{
RDI_SectionKind section = block->fzy_target;
U64 element_idx = block->fzy_backing_items.v[index].idx - base_idx;
switch(section)
{
default:{}break;
case RDI_SectionKind_Procedures:
{
RDI_Procedure *procedure = rdi_element_from_name_idx(module->rdi, Procedures, element_idx);
RDI_Scope *scope = rdi_element_from_name_idx(module->rdi, Scopes, procedure->root_scope_idx);
U64 voff = *rdi_element_from_name_idx(module->rdi, ScopeVOffData, scope->voff_range_first);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ModuleOff, voff);
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
U32 type_idx = procedure->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx);
E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules));
item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0);
item_expr->mode = E_Mode_Offset;
item_expr->space = module->space;
item_expr->type_key = type_key;
item_expr->bytecode = bytecode;
item_expr->string.str = rdi_string_from_idx(module->rdi, procedure->name_string_idx, &item_expr->string.size);
}break;
case RDI_SectionKind_GlobalVariables:
{
RDI_GlobalVariable *gvar = rdi_element_from_name_idx(module->rdi, GlobalVariables, element_idx);
U64 voff = gvar->voff;
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ModuleOff, voff);
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
U32 type_idx = gvar->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx);
E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules));
item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0);
item_expr->mode = E_Mode_Offset;
item_expr->space = module->space;
item_expr->type_key = type_key;
item_expr->bytecode = bytecode;
item_expr->string.str = rdi_string_from_idx(module->rdi, gvar->name_string_idx, &item_expr->string.size);
}break;
case RDI_SectionKind_ThreadVariables:
{
RDI_ThreadVariable *tvar = rdi_element_from_name_idx(module->rdi, ThreadVariables, element_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, tvar->tls_off);
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
U32 type_idx = tvar->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, type_idx);
E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)(module - e_parse_ctx->modules));
item_expr = e_push_expr(arena, E_ExprKind_LeafBytecode, 0);
item_expr->mode = E_Mode_Offset;
item_expr->space = module->space;
item_expr->type_key = type_key;
item_expr->bytecode = bytecode;
item_expr->string.str = rdi_string_from_idx(module->rdi, tvar->name_string_idx, &item_expr->string.size);
}break;
case RDI_SectionKind_UDTs:
{
RDI_UDT *udt = rdi_element_from_name_idx(module->rdi, UDTs, element_idx);
RDI_TypeNode *type_node = rdi_element_from_name_idx(module->rdi, TypeNodes, udt->self_type_idx);
E_TypeKey type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, (U32)(module - e_parse_ctx->modules));
item_expr = e_push_expr(arena, E_ExprKind_TypeIdent, 0);
item_expr->type_key = type_key;
}break;
}
}
result = item_expr;
}break;
}
return result;
}
//- rjf: viz row list building
internal DF_EvalVizRow *
df_eval_viz_row_list_push_new(Arena *arena, DF_EvalView *eval_view, DF_EvalVizWindowedRowList *rows, DF_EvalVizBlock *block, DF_ExpandKey key, E_Eval eval)
df_eval_viz_row_list_push_new(Arena *arena, DF_EvalView *eval_view, DF_EvalVizWindowedRowList *rows, DF_EvalVizBlock *block, DF_ExpandKey key, E_Expr *expr)
{
// rjf: push
DF_EvalVizRow *row = push_array(arena, DF_EvalVizRow, 1);
@@ -5160,48 +5400,9 @@ df_eval_viz_row_list_push_new(Arena *arena, DF_EvalView *eval_view, DF_EvalVizWi
row->depth = block->depth;
row->parent_key = block->parent_key;
row->key = key;
row->eval = eval;
row->size_in_rows = 1;
// rjf: determine exandability, editability
if(e_type_kind_from_key(eval.type_key) != E_TypeKind_Null)
{
for(E_TypeKey t = eval.type_key;; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t))))
{
E_TypeKind kind = e_type_kind_from_key(t);
if(kind == E_TypeKind_Null)
{
break;
}
if(eval.mode != E_Mode_Null && ((E_TypeKind_FirstBasic <= kind && kind <= E_TypeKind_LastBasic) || kind == E_TypeKind_Ptr || kind == E_TypeKind_LRef || kind == E_TypeKind_RRef))
{
row->flags |= DF_EvalVizRowFlag_CanEditValue;
}
if(eval.mode == E_Mode_Null && kind == E_TypeKind_Enum)
{
row->flags |= DF_EvalVizRowFlag_CanExpand;
}
if(kind == E_TypeKind_Struct ||
kind == E_TypeKind_Union ||
kind == E_TypeKind_Class ||
kind == E_TypeKind_Array)
{
row->flags |= DF_EvalVizRowFlag_CanExpand;
}
if(row->flags & DF_EvalVizRowFlag_CanExpand)
{
break;
}
if(eval.mode == E_Mode_Null)
{
break;
}
if(kind == E_TypeKind_Function)
{
break;
}
}
}
row->string = block->string;
row->expr = expr;
// rjf: fill view-rule-derived info
{
@@ -5258,7 +5459,6 @@ df_eval_viz_row_list_push_new(Arena *arena, DF_EvalView *eval_view, DF_EvalVizWi
}
// rjf: fill
if(expandability_required) { row->flags |= DF_EvalVizRowFlag_CanExpand; }
row->cfg_table = cfg_table;
row->value_ui_rule_node = value_ui_rule_node;
row->value_ui_rule_spec = value_ui_rule_spec;
@@ -5269,6 +5469,183 @@ df_eval_viz_row_list_push_new(Arena *arena, DF_EvalView *eval_view, DF_EvalVizWi
return row;
}
internal DF_EvalVizWindowedRowList
df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DF_EvalView *eval_view, Rng1S64 visible_range, DF_EvalVizBlockList *blocks)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
//////////////////////////////
//- rjf: produce windowed rows, per block
//
U64 visual_idx_off = 0;
U64 semantic_idx_off = 0;
DF_EvalVizWindowedRowList list = {0};
for(DF_EvalVizBlockNode *n = blocks->first; n != 0; n = n->next)
{
DF_EvalVizBlock *block = &n->v;
//////////////////////////////
//- rjf: extract block info
//
U64 block_num_visual_rows = dim_1u64(block->visual_idx_range);
U64 block_num_semantic_rows = dim_1u64(block->semantic_idx_range);
Rng1S64 block_visual_range = r1s64(visual_idx_off, visual_idx_off + block_num_visual_rows);
Rng1S64 block_semantic_range = r1s64(semantic_idx_off, semantic_idx_off + block_num_semantic_rows);
//////////////////////////////
//- rjf: get skip/chop of block's index range
//
U64 num_skipped_visual = 0;
U64 num_chopped_visual = 0;
{
if(visible_range.min > block_visual_range.min)
{
num_skipped_visual = (visible_range.min - block_visual_range.min);
num_skipped_visual = Min(num_skipped_visual, block_num_visual_rows);
}
if(visible_range.max < block_visual_range.max)
{
num_chopped_visual = (block_visual_range.max - visible_range.max);
num_chopped_visual = Min(num_chopped_visual, block_num_visual_rows);
}
}
//////////////////////////////
//- rjf: get visible idx range & invisible counts
//
Rng1U64 visible_idx_range = block->visual_idx_range;
{
visible_idx_range.min += num_skipped_visual;
visible_idx_range.max -= num_chopped_visual;
}
//////////////////////////////
//- rjf: sum & advance
//
list.count_before_visual += num_skipped_visual;
if(block_num_visual_rows != 0)
{
list.count_before_semantic += block_num_semantic_rows * num_skipped_visual / block_num_visual_rows;
}
visual_idx_off += block_num_visual_rows;
semantic_idx_off += block_num_semantic_rows;
//////////////////////////////
//- rjf: produce rows, depending on block's kind
//
if(visible_idx_range.max > visible_idx_range.min) switch(block->kind)
{
default:{}break;
//////////////////////////////
//- rjf: single rows, piping in info from the originating block
//
case DF_EvalVizBlockKind_Null:
case DF_EvalVizBlockKind_Root:
{
df_eval_viz_row_list_push_new(arena, eval_view, &list, block, block->key, block->expr);
}break;
//////////////////////////////
//- rjf: canvas -> produce blank row, sized by the idx range specified in the block
//
case DF_EvalVizBlockKind_Canvas:
if(num_skipped_visual < block_num_visual_rows)
{
DF_ExpandKey key = df_expand_key_make(df_hash_from_expand_key(block->parent_key), 1);
DF_EvalVizRow *row = df_eval_viz_row_list_push_new(arena, eval_view, &list, block, key, block->expr);
row->size_in_rows = dim_1u64(intersect_1u64(visible_idx_range, r1u64(0, dim_1u64(block->visual_idx_range))));
row->skipped_size_in_rows= (visible_idx_range.min > block->visual_idx_range.min) ? visible_idx_range.min - block->visual_idx_range.min : 0;
row->chopped_size_in_rows= (visible_idx_range.max < block->visual_idx_range.max) ? block->visual_idx_range.max - visible_idx_range.max : 0;
}break;
//////////////////////////////
//- rjf: all elements of a debug info table -> produce rows for visible range
//
case DF_EvalVizBlockKind_DebugInfoTable:
for(U64 idx = visible_idx_range.min; idx < visible_idx_range.max; idx += 1)
{
FZY_Item *item = &block->fzy_backing_items.v[idx];
DF_ExpandKey parent_key = block->parent_key;
DF_ExpandKey key = block->key;
key.child_num = block->fzy_backing_items.v[idx].idx;
E_Expr *row_expr = df_expr_from_eval_viz_block_index(arena, block, idx);
df_eval_viz_row_list_push_new(arena, eval_view, &list, block, key, row_expr);
}break;
//////////////////////////////
//- rjf: members/elements/enum-members
//
case DF_EvalVizBlockKind_Members:
case DF_EvalVizBlockKind_EnumMembers:
case DF_EvalVizBlockKind_Elements:
{
for(U64 idx = visible_idx_range.min; idx < visible_idx_range.max; idx += 1)
{
DF_ExpandKey key = df_expand_key_make(df_hash_from_expand_key(block->parent_key), idx+1);
E_Expr *expr = df_expr_from_eval_viz_block_index(arena, block, idx);
df_eval_viz_row_list_push_new(arena, eval_view, &list, block, key, expr);
}
}break;
}
}
scratch_end(scratch);
ProfEnd();
return list;
}
//- rjf: viz row -> strings
internal String8
df_expr_string_from_viz_row(Arena *arena, DF_EvalVizRow *row)
{
String8 result = row->string;
if(result.size == 0) switch(row->expr->kind)
{
default:
{
result = e_string_from_expr(arena, row->expr);
}break;
case E_ExprKind_ArrayIndex:
{
result = push_str8f(arena, "[%S]", e_string_from_expr(arena, row->expr->last));
}break;
case E_ExprKind_LeafMember:
{
result = push_str8f(arena, ".%S", e_string_from_expr(arena, row->expr->last));
}break;
}
return result;
}
//- rjf: viz row -> expandability/editability
internal B32
df_viz_row_is_expandable(DF_EvalVizRow *row)
{
B32 result = (row->expand_ui_rule_spec != &df_g_nil_gfx_view_rule_spec && row->expand_ui_rule_spec != 0);
if(!result)
{
Temp scratch = scratch_begin(0, 0);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr);
result = df_type_key_is_expandable(irtree.type_key);
scratch_end(scratch);
}
return result;
}
internal B32
df_viz_row_is_editable(DF_EvalVizRow *row)
{
B32 result = 0;
Temp scratch = scratch_begin(0, 0);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr);
result = df_type_key_is_editable(irtree.type_key);
scratch_end(scratch);
return result;
}
////////////////////////////////
//~ rjf: Main State Accessors/Mutators
+46 -33
View File
@@ -179,7 +179,17 @@ typedef struct DF_EvalVizBlockList DF_EvalVizBlockList;
#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(name) E_Eval name(Arena *arena, E_Eval eval, DF_CfgVal *val)
#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(name) df_core_view_rule_eval_resolution__##name
#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(name) internal DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(name))
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_SIG(name) void name(Arena *arena, DF_EvalView *eval_view, E_Eval eval, String8 string, DF_CfgTable *cfg_table, DF_ExpandKey parent_key, DF_ExpandKey key, S32 depth, DF_CfgNode *cfg, struct DF_EvalVizBlockList *out)
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_SIG(name) void name(Arena *arena, \
DF_EvalView *eval_view, \
DF_ExpandKey parent_key, \
DF_ExpandKey key, \
DF_ExpandNode *expand_node, \
String8 string, \
E_Expr *expr, \
DF_CfgTable *cfg_table, \
S32 depth, \
DF_CfgVal *cfg_val, \
struct DF_EvalVizBlockList *out)
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(name) df_core_view_rule_viz_block_prod__##name
#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(name) internal DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_SIG(DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(name))
typedef DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(DF_CoreViewRuleEvalResolutionHookFunctionType);
@@ -683,7 +693,6 @@ typedef enum DF_EvalVizBlockKind
DF_EvalVizBlockKind_Members, // members of struct, class, union
DF_EvalVizBlockKind_EnumMembers, // members of enum
DF_EvalVizBlockKind_Elements, // elements of array
DF_EvalVizBlockKind_Links, // flattened nodes in a linked list
DF_EvalVizBlockKind_Canvas, // escape hatch for arbitrary UI
DF_EvalVizBlockKind_DebugInfoTable, // block of filtered debug info table elements
DF_EvalVizBlockKind_COUNT,
@@ -700,20 +709,20 @@ struct DF_EvalVizBlock
S32 depth;
// rjf: evaluation info
E_Eval eval;
String8 string;
E_Member *member;
E_Expr *expr;
// rjf: info about ranges that this block spans
Rng1U64 visual_idx_range;
Rng1U64 semantic_idx_range;
RDI_SectionKind fzy_target;
FZY_ItemArray fzy_backing_items;
// rjf: visualization config extensions
DF_CfgTable *cfg_table;
E_TypeKey link_member_type_key;
U64 link_member_off;
DF_EvalLinkBaseChunkList *link_bases;
E_MemberArray members;
E_EnumValArray enum_vals;
RDI_SectionKind fzy_target;
FZY_ItemArray fzy_backing_items;
};
typedef struct DF_EvalVizBlockNode DF_EvalVizBlockNode;
@@ -748,43 +757,30 @@ enum
DF_EvalVizStringFlag_ReadOnlyDisplayRules = (1<<0),
};
typedef U32 DF_EvalVizRowFlags;
enum
{
DF_EvalVizRowFlag_CanExpand = (1<<0),
DF_EvalVizRowFlag_CanEditValue = (1<<1),
DF_EvalVizRowFlag_Canvas = (1<<2),
DF_EvalVizRowFlag_ExprIsSpecial= (1<<3),
};
typedef struct DF_EvalVizRow DF_EvalVizRow;
struct DF_EvalVizRow
{
DF_EvalVizRow *next;
DF_EvalVizRowFlags flags;
// rjf: block info
// rjf: block hierarchy info
S32 depth;
DF_ExpandKey parent_key;
DF_ExpandKey key;
// rjf: evaluation artifacts
E_Eval eval;
E_Member *member;
// rjf: basic visualization contents
DF_CfgTable *cfg_table;
String8 display_expr;
String8 edit_expr;
// rjf: variable-size & hook info
// rjf: row size/scroll info
U64 size_in_rows;
U64 skipped_size_in_rows;
U64 chopped_size_in_rows;
// rjf: evaluation expression
String8 string;
E_Member *member;
E_Expr *expr;
// rjf: view rule attachments
DF_CfgTable *cfg_table;
struct DF_GfxViewRuleSpec *expand_ui_rule_spec;
struct DF_CfgNode *expand_ui_rule_node;
// rjf: value area override view rule spec
struct DF_GfxViewRuleSpec *value_ui_rule_spec;
struct DF_CfgNode *value_ui_rule_node;
};
@@ -1221,6 +1217,7 @@ read_only global DF_CmdSpec df_g_nil_cmd_spec = {0};
read_only global DF_CoreViewRuleSpec df_g_nil_core_view_rule_spec = {0};
read_only global DF_CfgNode df_g_nil_cfg_node = {&df_g_nil_cfg_node, &df_g_nil_cfg_node, &df_g_nil_cfg_node, &df_g_nil_cfg_node};
read_only global DF_CfgVal df_g_nil_cfg_val = {&df_g_nil_cfg_val, &df_g_nil_cfg_val, &df_g_nil_cfg_node, &df_g_nil_cfg_node};
read_only global DF_CfgTable df_g_nil_cfg_table = {0, 0, 0, &df_g_nil_cfg_val, &df_g_nil_cfg_val};
read_only global DF_Entity df_g_nil_entity =
{
// rjf: tree links
@@ -1587,6 +1584,11 @@ internal String8 df_string_from_ascii_value(Arena *arena, U8 val);
internal String8 df_string_from_hresult_facility_code(U32 code);
internal String8 df_string_from_hresult_code(U32 code);
internal String8 df_string_from_simple_typed_eval(Arena *arena, DF_EvalVizStringFlags flags, U32 radix, E_Eval eval);
internal String8 df_escaped_from_raw_string(Arena *arena, String8 raw);
//- rjf: type info -> expandability/editablity
internal B32 df_type_key_is_expandable(E_TypeKey type_key);
internal B32 df_type_key_is_editable(E_TypeKey type_key);
//- rjf: writing values back to child processes
internal B32 df_commit_eval_value(E_Eval dst_eval, E_Eval src_eval);
@@ -1601,7 +1603,7 @@ internal DF_EvalLinkBaseArray df_eval_link_base_array_from_chunk_list(Arena *are
internal DF_EvalVizBlock *df_eval_viz_block_begin(Arena *arena, DF_EvalVizBlockKind kind, DF_ExpandKey parent_key, DF_ExpandKey key, S32 depth);
internal DF_EvalVizBlock *df_eval_viz_block_split_and_continue(Arena *arena, DF_EvalVizBlockList *list, DF_EvalVizBlock *split_block, U64 split_idx);
internal void df_eval_viz_block_end(DF_EvalVizBlockList *list, DF_EvalVizBlock *block);
internal void df_append_viz_blocks_for_parent__rec(Arena *arena, DF_EvalView *view, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, E_Eval eval, E_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out);
internal void df_append_viz_blocks_for_parent__rec(Arena *arena, DF_EvalView *view, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, E_Expr *expr, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out);
internal DF_EvalVizBlockList df_eval_viz_block_list_from_eval_view_expr_keys(Arena *arena, DF_EvalView *eval_view, String8 expr, DF_ExpandKey parent_key, DF_ExpandKey key);
internal void df_eval_viz_block_list_concat__in_place(DF_EvalVizBlockList *dst, DF_EvalVizBlockList *to_push);
@@ -1610,8 +1612,19 @@ internal S64 df_row_num_from_viz_block_list_key(DF_EvalVizBlockList *blocks, DF_
internal DF_ExpandKey df_key_from_viz_block_list_row_num(DF_EvalVizBlockList *blocks, S64 row_num);
internal DF_ExpandKey df_parent_key_from_viz_block_list_row_num(DF_EvalVizBlockList *blocks, S64 row_num);
//- rjf: viz block * index -> expression
internal E_Expr *df_expr_from_eval_viz_block_index(Arena *arena, DF_EvalVizBlock *block, U64 index);
//- rjf: viz row list building
internal DF_EvalVizRow *df_eval_viz_row_list_push_new(Arena *arena, DF_EvalView *eval_view, DF_EvalVizWindowedRowList *rows, DF_EvalVizBlock *block, DF_ExpandKey key, E_Eval eval);
internal DF_EvalVizRow *df_eval_viz_row_list_push_new(Arena *arena, DF_EvalView *eval_view, DF_EvalVizWindowedRowList *rows, DF_EvalVizBlock *block, DF_ExpandKey key, E_Expr *expr);
internal DF_EvalVizWindowedRowList df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DF_EvalView *eval_view, Rng1S64 visible_range, DF_EvalVizBlockList *blocks);
//- rjf: viz row -> strings
internal String8 df_expr_string_from_viz_row(Arena *arena, DF_EvalVizRow *row);
//- rjf: viz row -> expandability/editability
internal B32 df_viz_row_is_expandable(DF_EvalVizRow *row);
internal B32 df_viz_row_is_editable(DF_EvalVizRow *row);
////////////////////////////////
//~ rjf: Main State Accessors/Mutators
+1 -1
View File
@@ -524,7 +524,7 @@ DF_CoreCmdTable:// | | | |
@table(name name_lower string ih ex er vb display_name docs schema description)
DF_CoreViewRuleTable:
{
{Null null "" - - - - "" - "" "" }
{Default default "default" - - - x "Default" - "" "" }
{Array array "array" - - x - "Array" x "x:{expr}" "Specifies that a pointer points to N elements, rather than only 1." }
{Slice slice "slice" - - x - "Slice" x "" "Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer." }
{List list "list" - - - x "List" x "x:{member}" "Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list." }
+1 -1
View File
@@ -484,7 +484,7 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[222] =
DF_CoreViewRuleSpecInfo df_g_core_view_rule_spec_info_table[18] =
{
{str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), 0, 0, },
{str8_lit_comp("default"), str8_lit_comp("Default"), str8_lit_comp(""), str8_lit_comp(""), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(default) , },
{str8_lit_comp("array"), str8_lit_comp("Array"), str8_lit_comp("x:{expr}"), str8_lit_comp("Specifies that a pointer points to N elements, rather than only 1."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(array) , 0, },
{str8_lit_comp("slice"), str8_lit_comp("Slice"), str8_lit_comp(""), str8_lit_comp("Specifies that a pointer within a struct, also containing an integer, points to the number of elements encoded by the integer."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*1)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*0), DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_NAME(slice) , 0, },
{str8_lit_comp("list"), str8_lit_comp("List"), str8_lit_comp("x:{member}"), str8_lit_comp("Specifies that some struct, union, or class forms the top of a linked list, and the member which points at the following element in the list."), (DF_CoreViewRuleSpecInfoFlag_Inherited*0)|(DF_CoreViewRuleSpecInfoFlag_Expandable*0)|(DF_CoreViewRuleSpecInfoFlag_EvalResolution*0)|(DF_CoreViewRuleSpecInfoFlag_VizBlockProd*1), 0, DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_NAME(list) , },
+2 -1
View File
@@ -351,7 +351,7 @@ DF_IconKind_COUNT,
typedef enum DF_CoreViewRuleKind
{
DF_CoreViewRuleKind_Null,
DF_CoreViewRuleKind_Default,
DF_CoreViewRuleKind_Array,
DF_CoreViewRuleKind_Slice,
DF_CoreViewRuleKind_List,
@@ -433,6 +433,7 @@ U64 inline_depth;
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(array);
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(slice);
DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(bswap);
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(default);
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(list);
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(only);
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(omit);
+301 -684
View File
File diff suppressed because it is too large Load Diff
+3 -5
View File
@@ -323,7 +323,7 @@ enum
#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(name) df_gfx_view_rule_row_ui__##name
#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(name) DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_SIG(DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_NAME(name))
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_SIG(name) void name(struct DF_Window *ws, DF_ExpandKey key, E_Eval eval, String8 string, struct DF_CfgNode *cfg, Vec2F32 dim)
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_SIG(name) void name(struct DF_Window *ws, DF_ExpandKey key, E_Eval eval, struct DF_CfgNode *cfg, Vec2F32 dim)
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(name) df_gfx_view_rule_block_ui__##name
#define DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(name) DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_SIG(DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_NAME(name))
@@ -965,10 +965,8 @@ internal void df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdLis
////////////////////////////////
//~ rjf: Eval Viz
internal String8 df_escaped_from_raw_string(Arena *arena, String8 raw);
internal String8List df_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags flags, U32 default_radix, F_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval eval, E_Member *opt_member, DF_CfgTable *cfg_table);
internal String8 df_value_string_from_eval(Arena *arena, DF_EvalVizStringFlags flags, U32 default_radix, F_Tag font, F32 font_size, F32 max_size, E_Eval eval, E_Member *opt_member, DF_CfgTable *cfg_table);
internal DF_EvalVizWindowedRowList df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks);
internal F32 df_append_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags flags, U32 default_radix, F_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval eval, DF_CfgTable *cfg_table, String8List *out);
internal String8 df_value_string_from_eval(Arena *arena, DF_EvalVizStringFlags flags, U32 default_radix, F_Tag font, F32 font_size, F32 max_size, E_Eval eval, DF_CfgTable *cfg_table);
////////////////////////////////
//~ rjf: Hover Eval
+191 -24
View File
@@ -1,6 +1,173 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: "default"
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(default)
{
Temp scratch = scratch_begin(&arena, 1);
////////////////////////////
//- rjf: unpack expression type info
//
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, expr);
E_TypeKey type_key = e_type_unwrap(irtree.type_key);
E_TypeKind type_kind = e_type_kind_from_key(type_key);
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);
////////////////////////////
//- rjf: do struct/union/class member block generation
//
if((type_kind == E_TypeKind_Struct ||
type_kind == E_TypeKind_Union ||
type_kind == E_TypeKind_Class) ||
(e_type_kind_is_pointer_or_ref(type_kind) && (direct_type_kind == E_TypeKind_Struct ||
direct_type_kind == E_TypeKind_Union ||
direct_type_kind == E_TypeKind_Class)))
{
// rjf: type -> filtered data members
E_MemberArray data_members = e_type_data_members_from_key(scratch.arena, e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key);
E_MemberArray filtered_data_members = df_filtered_data_members_from_members_cfg_table(arena, data_members, cfg_table);
// rjf: build blocks for all members, split by sub-expansions
DF_EvalVizBlock *last_vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Members, key, df_expand_key_make(df_hash_from_expand_key(key), 0), depth+1);
{
last_vb->expr = expr;
last_vb->cfg_table = cfg_table;
last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, filtered_data_members.count);
last_vb->members = filtered_data_members;
}
for(DF_ExpandNode *child = expand_node->first; child != 0; child = child->next)
{
// rjf: unpack expansion info; skip out-of-bounds splits
U64 child_num = child->key.child_num;
U64 child_idx = child_num-1;
E_Expr *child_expr = df_expr_from_eval_viz_block_index(arena, last_vb, child_idx);
if(child_idx >= last_vb->semantic_idx_range.max)
{
continue;
}
// rjf: form split: truncate & complete last block; begin next block
last_vb = df_eval_viz_block_split_and_continue(arena, out, last_vb, child_idx);
// rjf: build child config table
DF_CfgTable *child_cfg_table = cfg_table;
{
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, child->key);
if(view_rule_string.size != 0)
{
child_cfg_table = push_array(arena, DF_CfgTable, 1);
*child_cfg_table = df_cfg_table_from_inheritance(arena, cfg_table);
df_cfg_table_push_unparsed_string(arena, child_cfg_table, view_rule_string, DF_CfgSrc_User);
}
}
// rjf: recurse for child
df_append_viz_blocks_for_parent__rec(arena, eval_view, key, child->key, str8_zero(), child_expr, child_cfg_table, depth+1, out);
}
df_eval_viz_block_end(out, last_vb);
}
////////////////////////////
//- rjf: do enum member block generation
//
// (just a single block for all enum members; enum members can never be expanded)
//
else if(type_kind == E_TypeKind_Enum ||
(e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Enum))
{
E_Type *type = e_type_from_key(arena, e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key);
DF_EvalVizBlock *last_vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_EnumMembers, key, df_expand_key_make(df_hash_from_expand_key(key), 0), depth+1);
{
last_vb->expr = expr;
last_vb->cfg_table = cfg_table;
last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, type->count);
last_vb->enum_vals.v = type->enum_vals;
last_vb->enum_vals.count = type->count;
}
df_eval_viz_block_end(out, last_vb);
}
////////////////////////////
//- rjf: do array element block generation
//
else if(type_kind == E_TypeKind_Array ||
(e_type_kind_is_pointer_or_ref(type_kind) && direct_type_kind == E_TypeKind_Array))
{
// rjf: unpack array type info
E_Type *array_type = e_type_from_key(scratch.arena, e_type_kind_is_pointer_or_ref(type_kind) ? direct_type_key : type_key);
U64 array_count = array_type->count;
// rjf: build blocks for all elements, split by sub-expansions
DF_EvalVizBlock *last_vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Elements, key, df_expand_key_make(df_hash_from_expand_key(key), 0), depth+1);
{
last_vb->expr = expr;
last_vb->cfg_table = cfg_table;
last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, array_count);
}
for(DF_ExpandNode *child = expand_node->first; child != 0; child = child->next)
{
// rjf: unpack expansion info; skip out-of-bounds splits
U64 child_num = child->key.child_num;
U64 child_idx = child_num-1;
E_Expr *child_expr = df_expr_from_eval_viz_block_index(arena, last_vb, child_idx);
if(child_idx >= last_vb->semantic_idx_range.max)
{
continue;
}
// rjf: form split: truncate & complete last block; begin next block
last_vb = df_eval_viz_block_split_and_continue(arena, out, last_vb, child_idx);
// rjf: build child config table
DF_CfgTable *child_cfg_table = cfg_table;
{
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, child->key);
if(view_rule_string.size != 0)
{
child_cfg_table = push_array(arena, DF_CfgTable, 1);
*child_cfg_table = df_cfg_table_from_inheritance(arena, cfg_table);
df_cfg_table_push_unparsed_string(arena, child_cfg_table, view_rule_string, DF_CfgSrc_User);
}
}
// rjf: recurse for child
df_append_viz_blocks_for_parent__rec(arena, eval_view, key, child->key, str8_zero(), child_expr, child_cfg_table, depth+1, out);
}
df_eval_viz_block_end(out, last_vb);
}
////////////////////////////
//- rjf: do pointer-to-pointer block generation
//
else if(e_type_kind_is_pointer_or_ref(type_kind) && e_type_kind_is_pointer_or_ref(direct_type_kind))
{
// rjf: compute key
DF_ExpandKey child_key = df_expand_key_make(df_hash_from_expand_key(key), 1);
// rjf: build child config table
DF_CfgTable *child_cfg_table = cfg_table;
{
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, child_key);
if(view_rule_string.size != 0)
{
child_cfg_table = push_array(arena, DF_CfgTable, 1);
*child_cfg_table = df_cfg_table_from_inheritance(arena, cfg_table);
df_cfg_table_push_unparsed_string(arena, child_cfg_table, view_rule_string, DF_CfgSrc_User);
}
}
// rjf: recurse for child
E_Expr *child_expr = e_expr_ref_deref(arena, expr);
df_append_viz_blocks_for_parent__rec(arena, eval_view, key, child_key, str8_zero(), child_expr, child_cfg_table, depth+1, out);
}
scratch_end(scratch);
}
////////////////////////////////
//~ rjf: "array"
@@ -322,11 +489,11 @@ df_vr_eval_commit_rgba(E_Eval eval, Vec4F32 rgba)
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(rgba)
{
DF_EvalVizBlock *vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Canvas, key, df_expand_key_make(df_hash_from_expand_key(key), 1), depth);
vb->eval = eval;
vb->string = string;
vb->cfg_table = cfg_table;
vb->visual_idx_range = r1u64(0, 8);
vb->string = string;
vb->expr = expr;
vb->visual_idx_range = r1u64(0, 8);
vb->semantic_idx_range = r1u64(0, 1);
vb->cfg_table = cfg_table;
df_eval_viz_block_end(out, vb);
}
@@ -505,11 +672,11 @@ df_vr_txt_topology_info_from_cfg(DF_CfgNode *cfg)
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(text)
{
DF_EvalVizBlock *vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Canvas, key, df_expand_key_make(df_hash_from_expand_key(key), 1), depth);
vb->eval = eval;
vb->string = string;
vb->cfg_table = cfg_table;
vb->visual_idx_range = r1u64(0, 8);
vb->string = string;
vb->expr = expr;
vb->visual_idx_range = r1u64(0, 8);
vb->semantic_idx_range = r1u64(0, 1);
vb->cfg_table = cfg_table;
df_eval_viz_block_end(out, vb);
}
@@ -652,11 +819,11 @@ df_vr_disasm_topology_info_from_cfg(DF_CfgNode *cfg)
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(disasm)
{
DF_EvalVizBlock *vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Canvas, key, df_expand_key_make(df_hash_from_expand_key(key), 1), depth);
vb->eval = eval;
vb->string = string;
vb->cfg_table = cfg_table;
vb->visual_idx_range = r1u64(0, 8);
vb->string = string;
vb->expr = expr;
vb->visual_idx_range = r1u64(0, 8);
vb->semantic_idx_range = r1u64(0, 1);
vb->cfg_table = cfg_table;
df_eval_viz_block_end(out, vb);
}
@@ -774,11 +941,11 @@ DF_VIEW_UI_FUNCTION_DEF(disasm)
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(graph)
{
DF_EvalVizBlock *vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Canvas, key, df_expand_key_make(df_hash_from_expand_key(key), 1), depth);
vb->eval = eval;
vb->string = string;
vb->cfg_table = cfg_table;
vb->visual_idx_range = r1u64(0, 8);
vb->string = string;
vb->expr = expr;
vb->visual_idx_range = r1u64(0, 8);
vb->semantic_idx_range = r1u64(0, 1);
vb->cfg_table = cfg_table;
df_eval_viz_block_end(out, vb);
}
@@ -916,11 +1083,11 @@ internal UI_BOX_CUSTOM_DRAW(df_vr_bitmap_box_draw)
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(bitmap)
{
DF_EvalVizBlock *vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Canvas, key, df_expand_key_make(df_hash_from_expand_key(key), 1), depth);
vb->eval = eval;
vb->string = string;
vb->cfg_table = cfg_table;
vb->visual_idx_range = r1u64(0, 8);
vb->string = string;
vb->expr = expr;
vb->visual_idx_range = r1u64(0, 8);
vb->semantic_idx_range = r1u64(0, 1);
vb->cfg_table = cfg_table;
df_eval_viz_block_end(out, vb);
}
@@ -1326,11 +1493,11 @@ internal UI_BOX_CUSTOM_DRAW(df_vr_geo_box_draw)
DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_DEF(geo)
{
DF_EvalVizBlock *vb = df_eval_viz_block_begin(arena, DF_EvalVizBlockKind_Canvas, key, df_expand_key_make(df_hash_from_expand_key(key), 1), depth);
vb->eval = eval;
vb->string = string;
vb->cfg_table = cfg_table;
vb->visual_idx_range = r1u64(0, 16);
vb->string = string;
vb->expr = expr;
vb->visual_idx_range = r1u64(0, 16);
vb->semantic_idx_range = r1u64(0, 1);
vb->cfg_table = cfg_table;
df_eval_viz_block_end(out, vb);
}
+110 -554
View File
@@ -1232,7 +1232,7 @@ df_string_from_eval_viz_row_column(Arena *arena, DF_EvalView *ev, DF_EvalVizRow
default:{}break;
case DF_WatchViewColumnKind_Expr:
{
result = editable ? row->edit_expr : row->display_expr;
result = df_expr_string_from_viz_row(arena, row);
if(row->member != 0 && row->member->inheritance_key_chain.first != 0)
{
Temp scratch = scratch_begin(&arena, 1);
@@ -1255,11 +1255,14 @@ df_string_from_eval_viz_row_column(Arena *arena, DF_EvalView *ev, DF_EvalVizRow
}break;
case DF_WatchViewColumnKind_Value:
{
result = df_value_string_from_eval(arena, !editable * DF_EvalVizStringFlag_ReadOnlyDisplayRules, default_radix, font, font_size, max_size_px, row->eval, row->member, row->cfg_table);
E_Eval eval = e_eval_from_expr(arena, row->expr);
result = df_value_string_from_eval(arena, !editable * DF_EvalVizStringFlag_ReadOnlyDisplayRules, default_radix, font, font_size, max_size_px, eval, row->cfg_table);
}break;
case DF_WatchViewColumnKind_Type:
{
result = !e_type_key_match(row->eval.type_key, e_type_key_zero()) ? e_type_string_from_key(arena, row->eval.type_key) : str8_zero();
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, row->expr);
E_TypeKey type_key = irtree.type_key;
result = !e_type_key_match(type_key, e_type_key_zero()) ? e_type_string_from_key(arena, type_key) : str8_zero();
result = str8_skip_chop_whitespace(result);
}break;
case DF_WatchViewColumnKind_ViewRule:
@@ -1268,14 +1271,16 @@ df_string_from_eval_viz_row_column(Arena *arena, DF_EvalView *ev, DF_EvalVizRow
}break;
case DF_WatchViewColumnKind_Module:
{
E_Eval eval = e_eval_from_expr(arena, row->expr);
DF_Entity *process = df_entity_from_handle(df_interact_regs()->process);
DF_Entity *module = df_module_from_process_vaddr(process, row->eval.value.u64);
DF_Entity *module = df_module_from_process_vaddr(process, eval.value.u64);
result = df_display_string_from_entity(arena, module);
}break;
case DF_WatchViewColumnKind_Member:
{
E_Eval member_eval = e_member_eval_from_eval_member_name(row->eval, str8(col->string_buffer, col->string_size));
result = df_value_string_from_eval(arena, !editable * DF_EvalVizStringFlag_ReadOnlyDisplayRules, default_radix, font, font_size, max_size_px, member_eval, row->member, row->cfg_table);
E_Expr *expr = e_expr_ref_member_access(arena, row->expr, str8(col->string_buffer, col->string_size));
E_Eval eval = e_eval_from_expr(arena, expr);
result = df_value_string_from_eval(arena, !editable * DF_EvalVizStringFlag_ReadOnlyDisplayRules, default_radix, font, font_size, max_size_px, eval, row->cfg_table);
}break;
}
return result;
@@ -1467,7 +1472,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
switch(ewv->fill_kind)
{
////////////////////////////
//- rjf: mutable watch fill -> build blocks from top-level mutable root expressions
//- rjf: watch fill -> build blocks from top-level watch expressions
//
default:
case DF_WatchViewFillKind_Watch:
@@ -1495,7 +1500,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
}break;
////////////////////////////
//- rjf: mutable breakpoint fill -> build blocks from all breakpoints
//- rjf: breakpoint fill -> build blocks from all breakpoints
//
case DF_WatchViewFillKind_Breakpoints:
{
@@ -1523,20 +1528,18 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
}
E_MemberArray bp_members_array = e_member_array_from_list(scratch.arena, &bp_members);
E_TypeKey bp_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("Breakpoint"), .members = bp_members_array.v, .count = bp_members_array.count);
E_Eval eval =
{
.mode = E_Mode_Offset,
.space = (U64)bp,
.type_key = bp_type,
};
E_Expr *bp_expr = e_push_expr(scratch.arena, E_ExprKind_LeafID, 0);
bp_expr->type_key = bp_type;
bp_expr->mode = E_Mode_Offset;
bp_expr->space = (U64)bp;
DF_CfgTable cfg_table = {0};
df_append_viz_blocks_for_parent__rec(scratch.arena, eval_view, parent_key, key, title, eval, 0, &cfg_table, 0, &blocks);
df_append_viz_blocks_for_parent__rec(scratch.arena, eval_view, parent_key, key, title, bp_expr, &cfg_table, 0, &blocks);
}
}
}break;
////////////////////////////
//- rjf: mutable watch pin fill -> build blocks from all watch pins
//- rjf: watch pin fill -> build blocks from all watch pins
//
case DF_WatchViewFillKind_WatchPins:
{
@@ -1561,14 +1564,12 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
}
E_MemberArray wp_members_array = e_member_array_from_list(scratch.arena, &wp_members);
E_TypeKey wp_type = e_type_key_cons(.kind = E_TypeKind_Struct, .name = str8_lit("Watch Pin"), .members = wp_members_array.v, .count = wp_members_array.count);
E_Eval eval =
{
.mode = E_Mode_Offset,
.space = (U64)wp,
.type_key = wp_type,
};
E_Expr *wp_expr = e_push_expr(scratch.arena, E_ExprKind_LeafID, 0);
wp_expr->type_key = wp_type;
wp_expr->mode = E_Mode_Offset;
wp_expr->space = (U64)wp;
DF_CfgTable cfg_table = {0};
df_append_viz_blocks_for_parent__rec(scratch.arena, eval_view, parent_key, key, title, eval, 0, &cfg_table, 0, &blocks);
df_append_viz_blocks_for_parent__rec(scratch.arena, eval_view, parent_key, key, title, wp_expr, &cfg_table, 0, &blocks);
}
}
}break;
@@ -1620,26 +1621,26 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
DF_EvalVizBlock *block = df_eval_viz_block_begin(scratch.arena, DF_EvalVizBlockKind_Root, parent_key, key, 0);
{
E_TypeKey type_key = zero_struct;
String8 name = {0};
if(row->procedure != 0)
{
type_key = e_type_key_ext(E_TypeKind_Function, row->procedure->type_idx, e_parse_ctx_module_idx_from_rdi(row->rdi));
name.str = rdi_name_from_procedure(row->rdi, row->procedure, &name.size);
}
else if(row->inline_site != 0)
{
type_key = e_type_key_ext(E_TypeKind_Function, row->inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(row->rdi));
name.str = rdi_string_from_idx(row->rdi, row->inline_site->name_string_idx, &name.size);
}
E_Eval eval =
{
.value = {.u64 = regs_rip_from_arch_block(arch, row->regs)},
.mode = E_Mode_Value,
.space = (U64)process,
.type_key = type_key,
};
block->eval = eval;
block->string = name;
U64 row_vaddr = regs_rip_from_arch_block(arch, row->regs);
DF_Entity *module = df_module_from_process_vaddr(process, row_vaddr);
U64 row_voff = df_voff_from_vaddr(module, row_vaddr);
E_OpList ops = {0};
e_oplist_push_op(scratch.arena, &ops, RDI_EvalOp_ModuleOff, row_voff);
String8 bytecode = e_bytecode_from_oplist(scratch.arena, &ops);
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafBytecode, 0);
expr->bytecode = bytecode;
expr->mode = E_Mode_Value;
expr->space = (U64)process;
expr->type_key = type_key;
block->expr = expr;
block->visual_idx_range = r1u64(row_idx, row_idx+1);
block->semantic_idx_range = r1u64(row_idx, row_idx+1);
}
@@ -1806,6 +1807,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
}
//- rjf: build blocks for all table items, split by sorted sub-expansions
DF_CfgTable *cfg_table = push_array(scratch.arena, DF_CfgTable, 1);
DF_EvalVizBlock *last_vb = df_eval_viz_block_begin(scratch.arena, DF_EvalVizBlockKind_DebugInfoTable, parent_key, root_key, 0);
{
last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, items.count);
@@ -1815,43 +1817,25 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
for(U64 sub_expand_idx = 0; sub_expand_idx < sub_expand_keys_count; sub_expand_idx += 1)
{
FZY_Item *item = &items.v[sub_expand_item_idxs[sub_expand_idx]];
E_Expr *child_expr = df_expr_from_eval_viz_block_index(scratch.arena, last_vb, item->idx);
// rjf: form split: truncate & complete last block; begin next block
last_vb = df_eval_viz_block_split_and_continue(scratch.arena, &blocks, last_vb, sub_expand_item_idxs[sub_expand_idx]);
// rjf: grab rdi for this item
RDI_Parsed *rdi = &di_rdi_parsed_nil;
U64 base_idx = 0;
// rjf: build child config table
DF_CfgTable *child_cfg_table = cfg_table;
{
for(U64 rdi_idx = 0; rdi_idx < rdis_count; rdi_idx += 1)
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, sub_expand_keys[sub_expand_idx]);
if(view_rule_string.size != 0)
{
U64 elements_count = 0;
rdi_section_raw_table_from_kind(rdis[rdi_idx], fzy_target, &elements_count);
if(base_idx <= item->idx && item->idx < base_idx + elements_count)
{
rdi = rdis[rdi_idx];
break;
}
base_idx += elements_count;
child_cfg_table = push_array(scratch.arena, DF_CfgTable, 1);
*child_cfg_table = df_cfg_table_from_inheritance(scratch.arena, cfg_table);
df_cfg_table_push_unparsed_string(scratch.arena, child_cfg_table, view_rule_string, DF_CfgSrc_User);
}
}
// rjf: grab name for the expanded row
String8 name = fzy_item_string_from_rdi_target_element_idx(rdi, fzy_target, sub_expand_keys[sub_expand_idx].child_num-base_idx);
// rjf: recurse for sub-expansion
{
DF_CfgTable child_cfg = {0};
{
String8 view_rule_string = df_eval_view_rule_from_key(eval_view, df_expand_key_make(df_hash_from_expand_key(parent_key), sub_expand_keys[sub_expand_idx].child_num));
if(view_rule_string.size != 0)
{
df_cfg_table_push_unparsed_string(scratch.arena, &child_cfg, view_rule_string, DF_CfgSrc_User);
}
}
E_Eval eval = e_eval_from_string(scratch.arena, name);
df_append_viz_blocks_for_parent__rec(scratch.arena, eval_view, parent_key, sub_expand_keys[sub_expand_idx], name, eval, 0, &child_cfg, 0, &blocks);
}
// rjf: recurse for child
df_append_viz_blocks_for_parent__rec(scratch.arena, eval_view, parent_key, sub_expand_keys[sub_expand_idx], str8_zero(), child_expr, child_cfg_table, 0, &blocks);
}
df_eval_viz_block_end(&blocks, last_vb);
}break;
@@ -2030,9 +2014,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
ewv->text_edit_state_slots_count = u64_up_to_pow2(selection_dim.y+1);
ewv->text_edit_state_slots_count = Max(ewv->text_edit_state_slots_count, 64);
ewv->text_edit_state_slots = push_array(ewv->text_edit_arena, DF_WatchViewTextEditState*, ewv->text_edit_state_slots_count);
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, default_radix, code_font, ui_top_font_size(),
r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizRow *row = rows.first;
for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y; y += 1, row = row->next)
{
@@ -2063,18 +2046,17 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
if(!ewv->text_editing && evt->slot == UI_EventActionSlot_Accept && selection_tbl.min.x <= 0)
{
taken = 1;
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, default_radix, code_font, ui_top_font_size(),
r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizRow *row = rows.first;
for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next)
{
if(row->flags & DF_EvalVizRowFlag_CanExpand)
if(df_viz_row_is_expandable(row))
{
B32 is_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key);
df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, !is_expanded);
}
if(row->flags & DF_EvalVizRowFlag_Canvas)
if(row->expand_ui_rule_spec != &df_g_nil_gfx_view_rule_spec && row->expand_ui_rule_spec != 0)
{
DF_CfgNode *cfg = df_cfg_tree_copy(scratch.arena, row->expand_ui_rule_node);
DF_CfgNode *cfg_root = push_array(scratch.arena, DF_CfgNode, 1);
@@ -2085,9 +2067,9 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
cfg->parent = cfg_root;
}
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
p.string = row->edit_expr;
p.string = e_string_from_expr(scratch.arena, row->expr);
p.view_spec = df_tab_view_spec_from_gfx_view_rule_spec(row->expand_ui_rule_spec);
p.cfg_node = cfg_root;
p.cfg_node = cfg_root;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_ViewSpec);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_CfgNode);
@@ -2105,13 +2087,14 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
selection_tbl.min.x == 1)
{
taken = 1;
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, default_radix, code_font, ui_top_font_size(),
r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizRow *row = rows.first;
if(!(row->flags & DF_EvalVizRowFlag_CanEditValue))
B32 row_is_editable = df_viz_row_is_editable(row);
if(!row_is_editable)
{
U64 vaddr = row->eval.value.u64;
E_Eval eval = e_eval_from_expr(scratch.arena, row->expr);
U64 vaddr = eval.value.u64;
DF_Entity *module = df_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
U64 voff = df_voff_from_vaddr(module, vaddr);
@@ -2231,14 +2214,14 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
case DF_WatchViewColumnKind_Value:
if(editing_complete && evt->slot != UI_EventActionSlot_Cancel)
{
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, default_radix, code_font, ui_top_font_size(),
r1s64(ui_scroll_list_row_from_item(&row_blocks, y-1),
ui_scroll_list_row_from_item(&row_blocks, y-1)+1), &blocks);
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, r1s64(ui_scroll_list_row_from_item(&row_blocks, y-1),
ui_scroll_list_row_from_item(&row_blocks, y-1)+1), &blocks);
B32 success = 0;
if(rows.first != 0)
{
E_Eval write_eval = e_eval_from_string(scratch.arena, new_string);
success = df_commit_eval_value(rows.first->eval, write_eval);
E_Eval dst_eval = e_eval_from_expr(scratch.arena, rows.first->expr);
E_Eval src_eval = e_eval_from_string(scratch.arena, new_string);
success = df_commit_eval_value(dst_eval, src_eval);
}
if(!success)
{
@@ -2292,9 +2275,8 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
{
taken = 1;
String8List strs = {0};
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, default_radix, code_font, ui_top_font_size(),
r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizWindowedRowList rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, r1s64(ui_scroll_list_row_from_item(&row_blocks, selection_tbl.min.y-1),
ui_scroll_list_row_from_item(&row_blocks, selection_tbl.max.y-1)+1), &blocks);
DF_EvalVizRow *row = rows.first;
for(S64 y = selection_tbl.min.y; y <= selection_tbl.max.y && row != 0; y += 1, row = row->next)
{
@@ -2649,7 +2631,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
//
DF_EvalVizWindowedRowList rows = {0};
{
rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, default_radix, code_font, ui_top_font_size(), r1s64(visible_row_rng.min-1, visible_row_rng.max), &blocks);
rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, eval_view, r1s64(visible_row_rng.min-1, visible_row_rng.max), &blocks);
}
////////////////////////////
@@ -2666,6 +2648,9 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
U64 row_hash = df_hash_from_expand_key(row->key);
B32 row_selected = (selection_tbl.min.y <= (semantic_idx+1) && (semantic_idx+1) <= selection_tbl.max.y);
B32 row_expanded = df_expand_key_is_set(&eval_view->expand_tree_table, row->key);
E_Eval row_eval = e_eval_from_expr(scratch.arena, row->expr);
B32 row_is_expandable = df_viz_row_is_expandable(row);
B32 row_is_editable = df_viz_row_is_editable(row);
B32 next_row_expanded = row_expanded;
////////////////////////
@@ -2673,25 +2658,29 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
//
B32 row_is_fresh = 0;
B32 row_is_bad = 0;
switch(row->eval.mode)
switch(row_eval.mode)
{
default:{}break;
case E_Mode_Offset:
if(row_eval.space >= E_Space_FIXED_COUNT)
{
// TODO(rjf): @spaces pick the right process from the eval's space
U64 size = e_type_byte_size_from_key(row->eval.type_key);
size = Min(size, 64);
Rng1U64 vaddr_rng = r1u64(row->eval.value.u64, row->eval.value.u64+size);
CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, process->ctrl_machine_id, process->ctrl_handle, vaddr_rng, 0);
for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1)
DF_Entity *space_entity = (DF_Entity *)row_eval.space;
if(space_entity->kind == DF_EntityKind_Process)
{
if(slice.byte_changed_flags[idx] != 0)
U64 size = e_type_byte_size_from_key(row_eval.type_key);
size = Min(size, 64);
Rng1U64 vaddr_rng = r1u64(row_eval.value.u64, row_eval.value.u64+size);
CTRL_ProcessMemorySlice slice = ctrl_query_cached_data_from_process_vaddr_range(scratch.arena, space_entity->ctrl_machine_id, space_entity->ctrl_handle, vaddr_rng, 0);
for(U64 idx = 0; idx < (slice.data.size+63)/64; idx += 1)
{
row_is_fresh = 1;
}
if(slice.byte_bad_flags[idx] != 0)
{
row_is_bad = 1;
if(slice.byte_changed_flags[idx] != 0)
{
row_is_fresh = 1;
}
if(slice.byte_bad_flags[idx] != 0)
{
row_is_bad = 1;
}
}
}
}break;
@@ -2718,14 +2707,15 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
ui_set_next_pref_width(ui_pct(1, 0));
ui_set_next_pref_height(ui_px(scroll_list_params.row_height_px*row->size_in_rows, 1.f));
ui_set_next_focus_hot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off);
UI_Box *row_box = ui_build_box_from_stringf(row_flags|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable|(!(row->flags & DF_EvalVizRowFlag_Canvas) * UI_BoxFlag_DisableFocusOverlay), "row_%I64x", row_hash);
UI_Box *row_box = ui_build_box_from_stringf(row_flags|UI_BoxFlag_DrawSideBottom|UI_BoxFlag_Clickable|((row->expand_ui_rule_spec == &df_g_nil_gfx_view_rule_spec) * UI_BoxFlag_DisableFocusOverlay), "row_%I64x", row_hash);
ui_ts_vector_idx += 1;
ui_ts_cell_idx = 0;
////////////////////////
//- rjf: canvas row -> fill with canvas ui build
//- rjf: row with expand ui rule -> build large singular row for "escape hatch" ui
//
if(row->flags & DF_EvalVizRowFlag_Canvas) UI_Parent(row_box) UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off)
if(row->expand_ui_rule_spec != &df_g_nil_gfx_view_rule_spec)
UI_Parent(row_box) UI_FocusHot(row_selected ? UI_FocusKind_On : UI_FocusKind_Off)
{
//- rjf: build canvas row contents
ui_set_next_fixed_y(-1.f * (row->skipped_size_in_rows) * scroll_list_params.row_height_px);
@@ -2738,7 +2728,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
{
Vec2F32 canvas_dim = v2f32(scroll_list_params.dim_px.x - ui_top_font_size()*1.5f,
(row->skipped_size_in_rows+row->size_in_rows+row->chopped_size_in_rows)*scroll_list_params.row_height_px);
row->expand_ui_rule_spec->info.block_ui(ws, row->key, row->eval, row->edit_expr, row->expand_ui_rule_node, canvas_dim);
row->expand_ui_rule_spec->info.block_ui(ws, row->key, row_eval, row->expand_ui_rule_node, canvas_dim);
}
}
@@ -2766,9 +2756,9 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
cfg->parent = cfg_root;
}
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
p.string = row->edit_expr;
p.string = e_string_from_expr(scratch.arena, row->expr);
p.view_spec = df_tab_view_spec_from_gfx_view_rule_spec(row->expand_ui_rule_spec);
p.cfg_node = cfg_root;
p.cfg_node = cfg_root;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_String);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_ViewSpec);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_CfgNode);
@@ -2780,14 +2770,14 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
////////////////////////
//- rjf: build non-canvas row contents
//
if(!(row->flags & DF_EvalVizRowFlag_Canvas)) UI_Parent(row_box) UI_HeightFill
if(row->expand_ui_rule_spec == &df_g_nil_gfx_view_rule_spec) UI_Parent(row_box) UI_HeightFill
{
//////////////////////
//- rjf: draw start of cache lines in expansions
//
if((row->eval.mode == E_Mode_Offset || row->eval.mode == E_Mode_Null) &&
row->eval.msgs.count == 0 &&
row->eval.value.u64%64 == 0 && row->depth > 0 &&
if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) &&
row_eval.msgs.count == 0 &&
row_eval.value.u64%64 == 0 && row->depth > 0 &&
!row_expanded)
{
ui_set_next_fixed_x(0);
@@ -2800,14 +2790,14 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
//////////////////////
//- rjf: draw mid-row cache line boundaries in expansions
//
if((row->eval.mode == E_Mode_Offset || row->eval.mode == E_Mode_Null) &&
row->eval.msgs.max_kind == E_MsgKind_Null &&
row->eval.value.u64%64 != 0 &&
if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) &&
row_eval.msgs.max_kind == E_MsgKind_Null &&
row_eval.value.u64%64 != 0 &&
row->depth > 0 &&
!row_expanded)
{
U64 next_off = (row->eval.value.u64 + e_type_byte_size_from_key(row->eval.type_key));
if(next_off%64 != 0 && row->eval.value.u64/64 < next_off/64)
U64 next_off = (row_eval.value.u64 + e_type_byte_size_from_key(row_eval.type_key));
if(next_off%64 != 0 && row_eval.value.u64/64 < next_off/64)
{
ui_set_next_fixed_x(0);
ui_set_next_fixed_y(scroll_list_params.row_height_px - ui_top_font_size()*0.5f);
@@ -2832,7 +2822,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
String8 cell_pre_edit_string = df_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, 0, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px);
//- rjf: unpack column-kind-specific info
E_Eval cell_eval = row->eval;
E_Eval cell_eval = row_eval;
B32 cell_can_edit = 0;
FuzzyMatchRangeList cell_matches = {0};
String8 cell_error_string = {0};
@@ -2849,7 +2839,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
cell_can_edit = (row->depth == 0 && modifiable);
if(filter.size != 0)
{
cell_matches = fuzzy_match_find(scratch.arena, filter, row->display_expr);
cell_matches = fuzzy_match_find(scratch.arena, filter, df_expr_string_from_viz_row(scratch.arena, row));
}
cell_autocomp_flags = DF_AutoCompListerFlag_Locals;
}break;
@@ -2967,10 +2957,10 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
else
{
sig = df_line_editf(ws,
(DF_LineEditFlag_CodeContents*(!(row->flags & DF_EvalVizRowFlag_ExprIsSpecial) || col->kind != DF_WatchViewColumnKind_Expr)|
(DF_LineEditFlag_CodeContents|
DF_LineEditFlag_NoBackground|
DF_LineEditFlag_DisableEdit*(!cell_can_edit)|
DF_LineEditFlag_Expander*!!(x == 0 && row->flags & DF_EvalVizRowFlag_CanExpand && col->kind == DF_WatchViewColumnKind_Expr)|
DF_LineEditFlag_Expander*!!(x == 0 && row_is_expandable && col->kind == DF_WatchViewColumnKind_Expr)|
DF_LineEditFlag_ExpanderPlaceholder*(x == 0 && row->depth==0 && col->kind == DF_WatchViewColumnKind_Expr)|
DF_LineEditFlag_ExpanderSpace*(x == 0 && row->depth!=0 && col->kind == DF_WatchViewColumnKind_Expr)),
x == 0 ? row->depth : 0,
@@ -3055,7 +3045,7 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
if(DEV_eval_compiler_tooltips && x == 0 && ui_hovering(sig)) UI_Tooltip DF_Font(ws, DF_FontSlot_Code)
{
local_persist char *spaces = " ";
String8 string = row->display_expr;
String8 string = df_expr_string_from_viz_row(scratch.arena, row);
E_TokenArray tokens = e_token_array_from_text(scratch.arena, string);
E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr);
@@ -3205,440 +3195,6 @@ df_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_WatchViewS
{
df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, next_row_expanded);
}
#if 0
////////////////////
//- rjf: expression
//
ProfScope("expr")
{
DF_WatchViewPoint pt = {DF_WatchViewColumnKind_Expr, row->parent_key, row->key};
DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt);
B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x);
B32 can_edit_expr = !(row->depth > 0 || modifiable == 0);
// rjf: build
UI_Signal sig = {0};
B32 next_expanded = row_expanded;
UI_Palette(palette) UI_TableCell
UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off)
UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off)
{
B32 expr_editing_active = ui_is_focus_active();
B32 is_inherited = (row->inherited_type_key_chain.count != 0);
DF_Font(ws, DF_FontSlot_Code) UI_FlagsAdd(row->depth > 0 ? UI_BoxFlag_DrawTextWeak : 0)
{
FuzzyMatchRangeList matches = {0};
if(filter.size != 0)
{
matches = fuzzy_match_find(scratch.arena, filter, row->display_expr);
}
sig = df_line_editf(ws,
(DF_LineEditFlag_CodeContents*(!(row->flags & DF_EvalVizRowFlag_ExprIsSpecial))|
DF_LineEditFlag_NoBackground*(!is_inherited)|
DF_LineEditFlag_DisableEdit*(!can_edit_expr)|
DF_LineEditFlag_Expander*!!(row->flags & DF_EvalVizRowFlag_CanExpand)|
DF_LineEditFlag_ExpanderPlaceholder*(row->depth==0)|
DF_LineEditFlag_ExpanderSpace*(row->depth!=0)),
row->depth,
filter.size ? &matches : 0,
&edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, &next_expanded,
row->display_expr,
"###row_%I64x", row_hash);
}
if(is_inherited && ui_hovering(sig)) UI_Tooltip
{
String8List inheritance_chain_type_names = {0};
for(E_TypeKeyNode *n = row->inherited_type_key_chain.first; n != 0; n = n->next)
{
String8 inherited_type_name = e_type_string_from_key(scratch.arena, n->v);
inherited_type_name = str8_skip_chop_whitespace(inherited_type_name);
str8_list_push(scratch.arena, &inheritance_chain_type_names, inherited_type_name);
}
StringJoin join = {0};
join.sep = str8_lit("::");
String8 inheritance_type = str8_list_join(scratch.arena, &inheritance_chain_type_names, &join);
ui_set_next_pref_width(ui_children_sum(1));
UI_Row
{
ui_labelf("Inherited from ");
DF_Font(ws, DF_FontSlot_Code) df_code_label(1.f, 1.f, df_rgba_from_theme_color(DF_ThemeColor_CodeType), inheritance_type);
}
}
// rjf: autocomplete lister
if(expr_editing_active &&
selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y &&
txt_pt_match(edit_state->cursor, edit_state->mark))
{
String8 input = str8(edit_state->input_buffer, edit_state->input_size);
DF_AutoCompListerParams params = {DF_AutoCompListerFlag_Locals};
df_set_autocomp_lister_query(ws, sig.box->key, &params, input, edit_state->cursor.column-1);
}
}
// rjf: press -> commit if editing & select
if(ui_pressed(sig))
{
ewv->next_cursor = ewv->next_mark = pt;
pressed = 1;
}
// rjf: double-click -> start editing
if(ui_double_clicked(sig) && can_edit_expr)
{
ui_kill_action();
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Edit));
}
// rjf: [DEV] hovering -> tooltips
if(DEV_eval_compiler_tooltips && ui_hovering(sig)) UI_Tooltip DF_Font(ws, DF_FontSlot_Code)
{
local_persist char *spaces = " ";
String8 string = row->display_expr;
E_TokenArray tokens = e_token_array_from_text(scratch.arena, string);
E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, string, &tokens);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr);
E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root);
String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist);
UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Text:");
ui_label(string);
ui_spacer(ui_em(2.f, 1.f));
UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Tokens:");
for(U64 idx = 0; idx < tokens.count; idx += 1)
{
ui_labelf("%S: '%S'", e_token_kind_strings[tokens.v[idx].kind], str8_substr(string, tokens.v[idx].range));
}
ui_spacer(ui_em(2.f, 1.f));
UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Expression:");
{
typedef struct Task Task;
struct Task
{
Task *next;
Task *prev;
E_Expr *expr;
S64 depth;
};
Task start_task = {0, 0, parse.expr};
Task *first_task = &start_task;
Task *last_task = first_task;
for(Task *t = first_task; t != 0; t = t->next)
{
String8 ext = {0};
switch(t->expr->kind)
{
default:
{
if(t->expr->string.size != 0)
{
ext = push_str8f(scratch.arena, "'%S'", t->expr->string);
}
else if(t->expr->u32 != 0)
{
ext = push_str8f(scratch.arena, "0x%x", t->expr->u32);
}
else if(t->expr->f32 != 0)
{
ext = push_str8f(scratch.arena, "%f", t->expr->f32);
}
else if(t->expr->f64 != 0)
{
ext = push_str8f(scratch.arena, "%f", t->expr->f64);
}
else if(t->expr->u64 != 0)
{
ext = push_str8f(scratch.arena, "0x%I64x", t->expr->u64);
}
}break;
}
ui_labelf("%.*s%S%s%S", (int)t->depth*2, spaces, e_expr_kind_strings[t->expr->kind], ext.size ? " " : "", ext);
for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next)
{
Task *task = push_array(scratch.arena, Task, 1);
task->expr = child;
task->depth = t->depth+1;
DLLInsert(first_task, last_task, t, task);
}
}
}
ui_spacer(ui_em(2.f, 1.f));
UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("IR Tree:");
{
typedef struct Task Task;
struct Task
{
Task *next;
Task *prev;
E_IRNode *node;
S64 depth;
};
Task start_task = {0, 0, irtree.root};
Task *first_task = &start_task;
Task *last_task = first_task;
for(Task *t = first_task; t != 0; t = t->next)
{
String8 op_string = {0};
switch(t->node->op)
{
default:{}break;
case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break;
case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break;
#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break;
RDI_EvalOp_XList
#undef X
}
String8 ext = {0};
ui_labelf("%.*s%S", (int)t->depth*2, spaces, op_string);
for(E_IRNode *child = t->node->first; child != &e_irnode_nil; child = child->next)
{
Task *task = push_array(scratch.arena, Task, 1);
task->node = child;
task->depth = t->depth+1;
DLLInsert(first_task, last_task, t, task);
}
}
}
ui_spacer(ui_em(2.f, 1.f));
UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Op List:");
{
for(E_Op *op = oplist.first; op != 0; op = op->next)
{
String8 op_string = {0};
switch(op->opcode)
{
default:{}break;
case E_IRExtKind_Bytecode:{op_string = str8_lit("Bytecode");}break;
case E_IRExtKind_SetSpace:{op_string = str8_lit("SetSpace");}break;
#define X(name) case RDI_EvalOp_##name:{op_string = str8_lit(#name);}break;
RDI_EvalOp_XList
#undef X
}
String8 ext = {0};
switch(op->opcode)
{
case E_IRExtKind_Bytecode:{ext = str8_lit("[bytecode]");}break;
default:
{
ext = str8_from_u64(scratch.arena, op->u64, 16, 0, 0);
}break;
}
ui_labelf(" %S%s%S", op_string, ext.size ? " " : "", ext);
}
}
ui_spacer(ui_em(2.f, 1.f));
UI_Flags(UI_BoxFlag_DrawTextWeak) ui_labelf("Bytecode:");
{
for(U64 idx = 0; idx < bytecode.size; idx += 1)
{
ui_labelf(" 0x%x ('%c')", (U32)bytecode.str[idx], (char)bytecode.str[idx]);
}
}
}
// rjf: commit expansion state
if(next_expanded != row_expanded)
{
df_expand_set_expansion(eval_view->arena, &eval_view->expand_tree_table, row->parent_key, row->key, next_expanded);
}
}
////////////////////
//- rjf: value
//
ProfScope("value")
{
DF_WatchViewPoint pt = {DF_WatchViewColumnKind_Value, row->parent_key, row->key};
DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt);
B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x);
B32 value_is_error = (row->eval.msgs.max_kind != E_MsgKind_Null);
B32 value_is_hook = (!value_is_error && row->value_ui_rule_spec != &df_g_nil_gfx_view_rule_spec && row->value_ui_rule_spec != 0);
B32 value_is_complex = (!value_is_error && !value_is_hook && !(row->flags & DF_EvalVizRowFlag_CanEditValue));
B32 value_is_simple = (!value_is_error && !value_is_hook && (row->flags & DF_EvalVizRowFlag_CanEditValue));
// rjf: unpack palette
UI_BoxFlags cell_flags = 0;
UI_Palette *palette = ui_top_palette();
{
if(row_is_bad || value_is_error)
{
palette = ui_build_palette(ui_top_palette(), .text = df_rgba_from_theme_color(DF_ThemeColor_TextNegative), .text_weak = df_rgba_from_theme_color(DF_ThemeColor_TextNegative), .background = df_rgba_from_theme_color(DF_ThemeColor_HighlightOverlayError));
cell_flags |= UI_BoxFlag_DrawBackground;
}
}
// rjf: build
UI_Signal sig = {0};
ui_set_next_flags(cell_flags);
UI_Palette(palette) UI_TableCell DF_Font(ws, DF_FontSlot_Code)
UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off)
UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off)
{
// rjf: errors? -> show errors
if(value_is_error) DF_Font(ws, DF_FontSlot_Main)
{
String8List strings = {0};
for(E_Msg *msg = row->eval.msgs.first; msg != 0; msg = msg->next)
{
str8_list_push(scratch.arena, &strings, msg->text);
}
StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")};
String8 error_string = str8_list_join(scratch.arena, &strings, &join);
sig = df_error_label(error_string);
}
// rjf: hook -> call hook
if(value_is_hook) DF_Font(ws, DF_FontSlot_Main)
{
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash);
UI_Parent(box)
{
row->value_ui_rule_spec->info.row_ui(ws, row->key, row->eval, row->value_ui_rule_node);
}
sig = ui_signal_from_box(box);
}
// rjf: complex values
if(value_is_complex)
{
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###val_%I64x", row_hash);
UI_Parent(box)
{
df_code_label(1.f, 1, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), row->display_value);
}
sig = ui_signal_from_box(box);
}
// rjf: simple values (editable)
if(value_is_simple) UI_TextRasterFlags(df_raster_flags_from_slot(ws, DF_FontSlot_Code))
{
sig = df_line_editf(ws, DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, 0, row->display_value, "%S###val_%I64x", row->display_value, row_hash);
}
}
// rjf: bad & hovering -> display
if(row_is_bad && ui_hovering(sig)) UI_Tooltip
{
UI_PrefWidth(ui_children_sum(1)) df_error_label(str8_lit("Could not read memory successfully."));
}
// rjf: press -> focus & commit if editing & not selected
if(ui_pressed(sig))
{
ewv->next_cursor = ewv->next_mark = pt;
pressed = 1;
}
// rjf: double-click -> start editing
if(ui_double_clicked(sig) && value_is_simple)
{
ui_kill_action();
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Edit));
}
// rjf: double-click, not editable -> go-to-location
if(ui_double_clicked(sig) && !(row->flags & DF_EvalVizRowFlag_CanEditValue))
{
U64 vaddr = row->eval.value.u64;
DF_Entity *module = df_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
U64 voff = df_voff_from_vaddr(module, vaddr);
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff);
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
p.entity = df_handle_from_entity(process);
p.vaddr = vaddr;
if(lines.first != 0)
{
p.file_path = lines.first->v.file_path;
p.text_point = lines.first->v.pt;
}
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
}
}
////////////////////
//- rjf: type
//
ProfScope("type")
{
DF_WatchViewPoint pt = {DF_WatchViewColumnKind_Type, row->parent_key, row->key};
DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt);
B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x);
UI_TableCell DF_Font(ws, DF_FontSlot_Code)
UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off)
UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off)
{
E_TypeKey key = row->eval.type_key;
String8 string = e_type_string_from_key(scratch.arena, key);
string = str8_skip_chop_whitespace(string);
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clip|UI_BoxFlag_Clickable, "###type_%I64x", row_hash);
if(!e_type_key_match(key, e_type_key_zero())) UI_Parent(box)
{
df_code_label(1.f, 1, df_rgba_from_theme_color(DF_ThemeColor_CodeType), string);
}
UI_Signal sig = ui_signal_from_box(box);
if(ui_pressed(sig))
{
ewv->next_cursor = ewv->next_mark = pt;
pressed = 1;
}
}
}
////////////////////
//- rjf: view rule
//
ProfScope("view rule")
{
DF_WatchViewPoint pt = {DF_WatchViewColumnKind_ViewRule, row->parent_key, row->key};
DF_WatchViewTextEditState *edit_state = df_watch_view_text_edit_state_from_pt(ewv, pt);
B32 cell_selected = (row_selected && selection_tbl.min.x <= pt.column_kind && pt.column_kind <= selection_tbl.max.x);
String8 view_rule = df_eval_view_rule_from_key(eval_view, row->key);
// rjf: build
UI_Signal sig = {0};
B32 rule_editing_active = 0;
UI_TableCell DF_Font(ws, DF_FontSlot_Code)
UI_FocusHot(cell_selected ? UI_FocusKind_On : UI_FocusKind_Off)
UI_FocusActive((cell_selected && ewv->text_editing) ? UI_FocusKind_On : UI_FocusKind_Off)
UI_TextRasterFlags(df_raster_flags_from_slot(ws, DF_FontSlot_Code))
{
rule_editing_active = ui_is_focus_active();
sig = df_line_editf(ws, DF_LineEditFlag_CodeContents|DF_LineEditFlag_NoBackground, 0, 0, &edit_state->cursor, &edit_state->mark, edit_state->input_buffer, sizeof(edit_state->input_buffer), &edit_state->input_size, 0, view_rule, "###view_rule_%I64x", row_hash);
}
// rjf: press -> commit if not selected, select this cell
if(ui_pressed(sig))
{
ewv->next_cursor = ewv->next_mark = pt;
pressed = 1;
}
// rjf: autocomplete lister
if(rule_editing_active &&
selection_tbl.min.x == selection_tbl.max.x && selection_tbl.min.y == selection_tbl.max.y &&
txt_pt_match(edit_state->cursor, edit_state->mark))
{
String8 input = str8(edit_state->input_buffer, edit_state->input_size);
DF_AutoCompListerParams params = df_view_rule_autocomp_lister_params_from_input_cursor(scratch.arena, input, edit_state->cursor.column-1);
if(params.flags == 0)
{
params.flags = DF_AutoCompListerFlag_ViewRules;
}
df_set_autocomp_lister_query(ws, sig.box->key, &params, input, edit_state->cursor.column-1);
}
// rjf: double-click -> begin editing
if(ui_double_clicked(sig) && !ewv->text_editing)
{
ui_kill_action();
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Edit));
}
}
#endif
}
}
}
+46 -45
View File
@@ -73,59 +73,60 @@ E_TypeKindTable:
{Variadic "" 0 }
}
@table(name op_string)
@table(name op_kind precedence string op_pre op_sep op_pos)
E_ExprKindTable:
{
{ Nil "" }
{ Nil Null 0 "" "" "" "" }
{ Ref Null 0 "" "" "" "" }
{ ArrayIndex "[]" }
{ MemberAccess "." }
{ Deref "*" }
{ Address "&" }
{ ArrayIndex Null 0 "[]" "" "[" "]"}
{ MemberAccess Null 0 "." "" "." "" }
{ Deref UnaryPrefix 2 "*" "*" "" "" }
{ Address UnaryPrefix 2 "&" "&" "" "" }
{ Cast "cast" }
{ Sizeof "sizeof" }
{ Cast Null 0 "cast" "" "" "" }
{ Sizeof UnaryPrefix 0 "sizeof" "sizeof" "" "" }
{ Neg "-" }
{ LogNot "!" }
{ BitNot "~" }
{ Mul "*" }
{ Div "/" }
{ Mod "%" }
{ Add "+" }
{ Sub "-" }
{ LShift "<<" }
{ RShift ">>" }
{ Less "<" }
{ LsEq "<=" }
{ Grtr ">" }
{ GrEq ">=" }
{ EqEq "==" }
{ NtEq "!=" }
{ Neg UnaryPrefix 2 "-" "-" "" "" }
{ LogNot UnaryPrefix 2 "!" "!" "" "" }
{ BitNot UnaryPrefix 2 "~" "~" "" "" }
{ Mul Binary 3 "*" "" "*" "" }
{ Div Binary 3 "/" "" "/" "" }
{ Mod Binary 3 "%" "" "%" "" }
{ Add Binary 4 "+" "" "+" "" }
{ Sub Binary 4 "-" "" "-" "" }
{ LShift Binary 5 "<<" "" "<<" "" }
{ RShift Binary 5 ">>" "" ">>" "" }
{ Less Binary 6 "<" "" "<" "" }
{ LsEq Binary 6 "<=" "" "<=" "" }
{ Grtr Binary 6 ">" "" ">" "" }
{ GrEq Binary 6 ">=" "" ">=" "" }
{ EqEq Binary 7 "==" "" "==" "" }
{ NtEq Binary 7 "!=" "" "!=" "" }
{ BitAnd "&" }
{ BitXor "^" }
{ BitOr "|" }
{ LogAnd "&&" }
{ LogOr "||" }
{ BitAnd Binary 8 "&" "" "&" "" }
{ BitXor Binary 9 "^" "" "^" "" }
{ BitOr Binary 10 "|" "" "|" "" }
{ LogAnd Binary 11 "&&" "" "&&" "" }
{ LogOr Binary 12 "||" "" "||" "" }
{ Ternary "? " }
{ Ternary Null 0 "? " "" "?" ":" }
{ LeafBytecode "bytecode" }
{ LeafMember "member" }
{ LeafStringLiteral "string_literal" }
{ LeafU64 "U64" }
{ LeafF64 "F64" }
{ LeafF32 "F32" }
{ LeafIdent "leaf_ident" }
{ LeafID "leaf_id" }
{ LeafBytecode Null 0 "bytecode" "" "" "" }
{ LeafMember Null 0 "member" "" "" "" }
{ LeafStringLiteral Null 0 "string_literal" "" "" "" }
{ LeafU64 Null 0 "U64" "" "" "" }
{ LeafF64 Null 0 "F64" "" "" "" }
{ LeafF32 Null 0 "F32" "" "" "" }
{ LeafIdent Null 0 "leaf_ident" "" "" "" }
{ LeafID Null 0 "leaf_id" "" "" "" }
{ TypeIdent "type_ident" }
{ Ptr "ptr" }
{ Array "array" }
{ Func "function" }
{ TypeIdent Null 0 "type_ident" "" "" "" }
{ Ptr Null 0 "ptr" "" "" "" }
{ Array Null 0 "array" "" "" "" }
{ Func Null 0 "function" "" "" "" }
{ Define "=" }
{ Define Binary 13 "=" "" "=" "" }
}
@table(name display_string)
@@ -195,9 +196,9 @@ e_expr_kind_strings:
@expand(E_InterpretationCodeTable a) `str8_lit_comp("$(a.display_string)")`
}
@data(String8) e_expr_op_strings:
@data(E_OpInfo) e_expr_kind_op_info_table:
{
@expand(E_ExprKindTable a) `str8_lit_comp("$(a.op_string)")`
@expand(E_ExprKindTable a) `{ E_OpKind_$(a.op_kind), $(a.precedence), str8_lit_comp("$(a.op_pre)"), str8_lit_comp("$(a.op_sep)"), str8_lit_comp("$(a.op_post)") }`
}
@data(U8) e_kind_basic_byte_size_table:
+13 -6
View File
@@ -5,11 +5,9 @@
//~ rjf: Bundled Evaluation Functions
internal E_Eval
e_eval_from_string(Arena *arena, String8 string)
e_eval_from_expr(Arena *arena, E_Expr *expr)
{
E_TokenArray tokens = e_token_array_from_text(arena, string);
E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, parse.expr);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
E_OpList oplist = e_oplist_from_irtree(arena, irtree.root);
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
E_Interpretation interp = e_interpret(bytecode);
@@ -18,11 +16,10 @@ e_eval_from_string(Arena *arena, String8 string)
.value = interp.value,
.mode = irtree.mode,
.space = irtree.space,
.expr = expr,
.type_key = irtree.type_key,
.code = interp.code,
.advance = parse.last_token >= tokens.v + tokens.count ? string.size : parse.last_token->range.min,
};
e_msg_list_concat_in_place(&eval.msgs, &parse.msgs);
e_msg_list_concat_in_place(&eval.msgs, &irtree.msgs);
if(E_InterpretationCode_Good < eval.code && eval.code < E_InterpretationCode_COUNT)
{
@@ -31,6 +28,16 @@ e_eval_from_string(Arena *arena, String8 string)
return eval;
}
internal E_Eval
e_eval_from_string(Arena *arena, String8 string)
{
E_TokenArray tokens = e_token_array_from_text(arena, string);
E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens);
E_Eval eval = e_eval_from_expr(arena, parse.expr);
e_msg_list_concat_in_place(&eval.msgs, &parse.msgs);
return eval;
}
internal E_Eval
e_autoresolved_eval_from_eval(E_Eval eval)
{
+2 -1
View File
@@ -13,15 +13,16 @@ struct E_Eval
E_Value value;
E_Mode mode;
E_Space space;
E_Expr *expr;
E_TypeKey type_key;
E_InterpretationCode code;
E_MsgList msgs;
U64 advance;
};
////////////////////////////////
//~ rjf: Bundled Evaluation Functions
internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr);
internal E_Eval e_eval_from_string(Arena *arena, String8 string);
internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval);
internal E_Eval e_dynamically_typed_eval_from_eval(E_Eval eval);
+21
View File
@@ -36,6 +36,27 @@ struct E_MsgList
U64 count;
};
////////////////////////////////
//~ rjf: Operator Info
typedef enum E_OpKind
{
E_OpKind_Null,
E_OpKind_UnaryPrefix,
E_OpKind_Binary,
}
E_OpKind;
typedef struct E_OpInfo E_OpInfo;
struct E_OpInfo
{
E_OpKind kind;
S64 precedence;
String8 pre;
String8 sep;
String8 post;
};
////////////////////////////////
//~ rjf: Evaluation Spaces
+7 -1
View File
@@ -387,6 +387,12 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
{
default:{}break;
//- rjf: references -> just descend to sub-expr
case E_ExprKind_Ref:
{
result = e_irtree_and_type_from_expr(arena, expr->ref);
}break;
//- rjf: array indices
case E_ExprKind_ArrayIndex:
{
@@ -1093,7 +1099,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
//- rjf: leaf bytecode
case E_ExprKind_LeafBytecode:
{
E_IRNode *new_tree = e_irtree_bytecode_no_copy(arena, expr->string);
E_IRNode *new_tree = e_irtree_bytecode_no_copy(arena, expr->bytecode);
E_TypeKey final_type_key = expr->type_key;
result.root = new_tree;
result.type_key = final_type_key;
+143 -50
View File
@@ -17,40 +17,6 @@ global read_only String8 e_multichar_symbol_strings[] =
str8_lit_comp("||"),
};
global read_only struct {E_ExprKind kind; String8 string; S64 precedence;} e_unary_prefix_op_table[] =
{
// { E_ExprKind_???, str8_lit_comp("+"), 2 },
{ E_ExprKind_Neg, str8_lit_comp("-"), 2 },
{ E_ExprKind_LogNot, str8_lit_comp("!"), 2 },
{ E_ExprKind_Deref, str8_lit_comp("*"), 2 },
{ E_ExprKind_Address,str8_lit_comp("&"), 2 },
{ E_ExprKind_Sizeof, str8_lit_comp("sizeof"), 2 },
// { E_ExprKind_Alignof, str8_lit_comp("_Alignof"), 2 },
};
global read_only struct {E_ExprKind kind; String8 string; S64 precedence;} e_binary_op_table[] =
{
{ E_ExprKind_Mul, str8_lit_comp("*"), 3 },
{ E_ExprKind_Div, str8_lit_comp("/"), 3 },
{ E_ExprKind_Mod, str8_lit_comp("%"), 3 },
{ E_ExprKind_Add, str8_lit_comp("+"), 4 },
{ E_ExprKind_Sub, str8_lit_comp("-"), 4 },
{ E_ExprKind_LShift, str8_lit_comp("<<"), 5 },
{ E_ExprKind_RShift, str8_lit_comp(">>"), 5 },
{ E_ExprKind_Less, str8_lit_comp("<"), 6 },
{ E_ExprKind_LsEq, str8_lit_comp("<="), 6 },
{ E_ExprKind_Grtr, str8_lit_comp(">"), 6 },
{ E_ExprKind_GrEq, str8_lit_comp(">="), 6 },
{ E_ExprKind_EqEq, str8_lit_comp("=="), 7 },
{ E_ExprKind_NtEq, str8_lit_comp("!="), 7 },
{ E_ExprKind_BitAnd, str8_lit_comp("&"), 8 },
{ E_ExprKind_BitXor, str8_lit_comp("^"), 9 },
{ E_ExprKind_BitOr, str8_lit_comp("|"), 10 },
{ E_ExprKind_LogAnd, str8_lit_comp("&&"), 11 },
{ E_ExprKind_LogOr, str8_lit_comp("||"), 12 },
{ E_ExprKind_Define, str8_lit_comp("="), 13 },
};
global read_only S64 e_max_precedence = 15;
////////////////////////////////
@@ -676,7 +642,7 @@ internal E_Expr *
e_push_expr(Arena *arena, E_ExprKind kind, void *location)
{
E_Expr *e = push_array(arena, E_Expr, 1);
e->first = e->last = e->next = &e_expr_nil;
e->first = e->last = e->next = e->ref = &e_expr_nil;
e->location = location;
e->kind = kind;
return e;
@@ -688,6 +654,124 @@ e_expr_push_child(E_Expr *parent, E_Expr *child)
SLLQueuePush_NZ(&e_expr_nil, parent->first, parent->last, child, next);
}
internal E_Expr *
e_expr_ref(Arena *arena, E_Expr *ref)
{
E_Expr *expr = e_push_expr(arena, E_ExprKind_Ref, 0);
expr->ref = ref;
return expr;
}
internal E_Expr *
e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name)
{
E_Expr *root = e_push_expr(arena, E_ExprKind_MemberAccess, 0);
E_Expr *lhs_ref = e_expr_ref(arena, lhs);
E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0);
rhs->string = push_str8_copy(arena, member_name);
e_expr_push_child(root, lhs_ref);
e_expr_push_child(root, rhs);
return root;
}
internal E_Expr *
e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index)
{
E_Expr *root = e_push_expr(arena, E_ExprKind_ArrayIndex, 0);
E_Expr *lhs_ref = e_expr_ref(arena, lhs);
E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafU64, 0);
rhs->u64 = index;
e_expr_push_child(root, lhs_ref);
e_expr_push_child(root, rhs);
return root;
}
internal E_Expr *
e_expr_ref_deref(Arena *arena, E_Expr *rhs)
{
E_Expr *root = e_push_expr(arena, E_ExprKind_Deref, 0);
E_Expr *rhs_ref = e_expr_ref(arena, rhs);
e_expr_push_child(root, rhs_ref);
return rhs_ref;
}
////////////////////////////////
//~ rjf: Expression Tree -> String Conversions
internal void
e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out)
{
switch(expr->kind)
{
default:
{
E_OpInfo *op_info = &e_expr_kind_op_info_table[expr->kind];
String8 seps[] =
{
op_info->pre,
op_info->sep,
op_info->post,
};
U64 idx = 0;
for(E_Expr *child = expr->first; child != &e_expr_nil; child = child->next, idx += 1)
{
if(seps[idx].size != 0)
{
str8_list_push(arena, out, seps[idx]);
}
E_OpInfo *child_op_info = &e_expr_kind_op_info_table[child->kind];
B32 need_parens = (child_op_info->precedence > op_info->precedence);
if(need_parens)
{
str8_list_pushf(arena, out, "(");
}
e_append_strings_from_expr(arena, child, out);
if(need_parens)
{
str8_list_pushf(arena, out, ")");
}
}
}break;
case E_ExprKind_LeafBytecode:
case E_ExprKind_LeafMember:
case E_ExprKind_LeafIdent:
{
str8_list_push(arena, out, expr->string);
}break;
case E_ExprKind_LeafStringLiteral:
{
str8_list_pushf(arena, out, "\"%S\"", expr->string);
}break;
case E_ExprKind_LeafU64:
case E_ExprKind_LeafID:
{
str8_list_pushf(arena, out, "0x%I64x", expr->u64);
}break;
case E_ExprKind_LeafF64:
{
str8_list_pushf(arena, out, "%f", expr->f64);
}break;
case E_ExprKind_LeafF32:
{
str8_list_pushf(arena, out, "%f", expr->f32);
}break;
case E_ExprKind_TypeIdent:
{
String8 type_string = e_type_string_from_key(arena, expr->type_key);
str8_list_push(arena, out, type_string);
}break;
}
}
internal String8
e_string_from_expr(Arena *arena, E_Expr *expr)
{
String8List strings = {0};
e_append_strings_from_expr(arena, expr, &strings);
String8 result = str8_list_join(arena, &strings, 0);
return result;
}
////////////////////////////////
//~ rjf: Parsing Functions
@@ -966,12 +1050,13 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
void *location = 0;
// rjf: try op table
for(U64 idx = 0; idx < ArrayCount(e_unary_prefix_op_table); idx += 1)
for(EachNonZeroEnumVal(E_ExprKind, k))
{
if(str8_match(token_string, e_unary_prefix_op_table[idx].string, 0))
E_OpInfo *op_info = &e_expr_kind_op_info_table[k];
if(op_info->kind == E_OpKind_UnaryPrefix && str8_match(op_info->pre, token_string, 0))
{
prefix_unary_precedence = e_unary_prefix_op_table[idx].precedence;
prefix_unary_kind = e_unary_prefix_op_table[idx].kind;
prefix_unary_precedence = op_info->precedence;
prefix_unary_kind = k;
break;
}
}
@@ -1445,7 +1530,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
atom->mode = E_Mode_Offset;
atom->space = space;
atom->type_key = type_key;
atom->string = e_bytecode_from_oplist(arena, &oplist);
atom->string = token_string;
atom->bytecode = e_bytecode_from_oplist(arena, &oplist);
}
else if(alias_code != 0)
{
@@ -1457,7 +1543,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
atom->mode = E_Mode_Offset;
atom->space = space;
atom->type_key = type_key;
atom->string = e_bytecode_from_oplist(arena, &oplist);
atom->string = token_string;
atom->bytecode = e_bytecode_from_oplist(arena, &oplist);
}
else
{
@@ -1470,7 +1557,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
atom->mode = E_Mode_Offset;
atom->space = space;
atom->type_key = type_key;
atom->string = loc_bytecode;
atom->string = token_string;
atom->bytecode = loc_bytecode;
}break;
case RDI_LocationKind_ValBytecodeStream:
{
@@ -1478,7 +1566,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
atom->mode = E_Mode_Value;
atom->space = space;
atom->type_key = type_key;
atom->string = loc_bytecode;
atom->string = token_string;
atom->bytecode = loc_bytecode;
}break;
case RDI_LocationKind_AddrRegPlusU16:
{
@@ -1492,7 +1581,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
atom->mode = E_Mode_Offset;
atom->space = space;
atom->type_key = type_key;
atom->string = e_bytecode_from_oplist(arena, &oplist);
atom->string = token_string;
atom->bytecode = e_bytecode_from_oplist(arena, &oplist);
}break;
case RDI_LocationKind_AddrAddrRegPlusU16:
{
@@ -1507,7 +1597,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
atom->mode = E_Mode_Offset;
atom->space = space;
atom->type_key = type_key;
atom->string = e_bytecode_from_oplist(arena, &oplist);
atom->string = token_string;
atom->bytecode = e_bytecode_from_oplist(arena, &oplist);
}break;
case RDI_LocationKind_ValReg:
{
@@ -1522,7 +1613,8 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
atom->mode = E_Mode_Value;
atom->space = space;
atom->type_key = type_key;
atom->string = e_bytecode_from_oplist(arena, &oplist);
atom->string = token_string;
atom->bytecode = e_bytecode_from_oplist(arena, &oplist);
}break;
}
@@ -1763,12 +1855,13 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
// rjf: first try to find a matching binary operator
S64 binary_precedence = 0;
E_ExprKind binary_kind = 0;
for(U64 idx = 0; idx < ArrayCount(e_binary_op_table); idx += 1)
for(EachNonZeroEnumVal(E_ExprKind, k))
{
if(str8_match(token_string, e_binary_op_table[idx].string, 0))
E_OpInfo *op_info = &e_expr_kind_op_info_table[k];
if(op_info->kind == E_OpKind_Binary && str8_match(op_info->sep, token_string, 0))
{
binary_precedence = e_binary_op_table[idx].precedence;
binary_kind = e_binary_op_table[idx].kind;
binary_precedence = op_info->precedence;
binary_kind = k;
break;
}
}
+13
View File
@@ -53,6 +53,7 @@ struct E_Expr
E_Expr *first;
E_Expr *last;
E_Expr *next;
E_Expr *ref;
void *location;
E_ExprKind kind;
E_Mode mode;
@@ -63,6 +64,7 @@ struct E_Expr
U64 u64;
F64 f64;
String8 string;
String8 bytecode;
};
////////////////////////////////
@@ -219,6 +221,17 @@ internal U32 e_parse_ctx_module_idx_from_rdi(RDI_Parsed *rdi);
internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, void *location);
internal void e_expr_push_child(E_Expr *parent, E_Expr *child);
internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref);
internal E_Expr *e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name);
internal E_Expr *e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index);
internal E_Expr *e_expr_ref_deref(Arena *arena, E_Expr *rhs);
////////////////////////////////
//~ rjf: Expression Tree -> String Conversions
internal void e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out);
internal String8 e_string_from_expr(Arena *arena, E_Expr *expr);
////////////////////////////////
//~ rjf: Parsing Functions
+23
View File
@@ -156,6 +156,13 @@ e_type_kind_is_basic_or_enum(E_TypeKind kind)
return result;
}
internal B32
e_type_kind_is_pointer_or_ref(E_TypeKind kind)
{
B32 result = (kind == E_TypeKind_Ptr || kind == E_TypeKind_LRef || kind == E_TypeKind_RRef);
return result;
}
////////////////////////////////
//~ rjf: Member Functions
@@ -1409,6 +1416,22 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key)
return members;
}
internal E_Member *
e_type_member_from_array_name(E_MemberArray *members, String8 name)
{
E_Member *member = 0;
for(U64 idx = 0; idx < members->count; idx += 1)
{
if(members->v[idx].kind == E_MemberKind_DataField &&
str8_match(members->v[idx].name, name, 0))
{
member = &members->v[idx];
break;
}
}
return member;
}
internal void
e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 prec, B32 skip_return)
{
+2
View File
@@ -210,6 +210,7 @@ internal RDI_EvalTypeGroup e_type_group_from_kind(E_TypeKind kind);
internal B32 e_type_kind_is_integer(E_TypeKind kind);
internal B32 e_type_kind_is_signed(E_TypeKind kind);
internal B32 e_type_kind_is_basic_or_enum(E_TypeKind kind);
internal B32 e_type_kind_is_pointer_or_ref(E_TypeKind kind);
////////////////////////////////
//~ rjf: Member Functions
@@ -261,6 +262,7 @@ internal B32 e_type_match(E_TypeKey l, E_TypeKey r);
internal E_Member *e_type_member_copy(Arena *arena, E_Member *src);
internal int e_type_qsort_compare_members_offset(E_Member *a, E_Member *b);
internal E_MemberArray e_type_data_members_from_key(Arena *arena, E_TypeKey key);
internal E_Member *e_type_member_from_array_name(E_MemberArray *members, String8 name);
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);
+46 -44
View File
@@ -14,9 +14,10 @@ str8_lit_comp("CharLiteral"),
str8_lit_comp("Symbol"),
};
String8 e_expr_kind_strings[42] =
String8 e_expr_kind_strings[43] =
{
str8_lit_comp("Nil"),
str8_lit_comp("Ref"),
str8_lit_comp("ArrayIndex"),
str8_lit_comp("MemberAccess"),
str8_lit_comp("Deref"),
@@ -75,50 +76,51 @@ str8_lit_comp("Insufficient evaluation machine stack space."),
str8_lit_comp("Malformed bytecode."),
};
String8 e_expr_op_strings[42] =
E_OpInfo e_expr_kind_op_info_table[43] =
{
str8_lit_comp(""),
str8_lit_comp("[]"),
str8_lit_comp("."),
str8_lit_comp("*"),
str8_lit_comp("&"),
str8_lit_comp("cast"),
str8_lit_comp("sizeof"),
str8_lit_comp("-"),
str8_lit_comp("!"),
str8_lit_comp("~"),
str8_lit_comp("*"),
str8_lit_comp("/"),
str8_lit_comp("%"),
str8_lit_comp("+"),
str8_lit_comp("-"),
str8_lit_comp("<<"),
str8_lit_comp(">>"),
str8_lit_comp("<"),
str8_lit_comp("<="),
str8_lit_comp(">"),
str8_lit_comp(">="),
str8_lit_comp("=="),
str8_lit_comp("!="),
str8_lit_comp("&"),
str8_lit_comp("^"),
str8_lit_comp("|"),
str8_lit_comp("&&"),
str8_lit_comp("||"),
str8_lit_comp("? "),
str8_lit_comp("bytecode"),
str8_lit_comp("member"),
str8_lit_comp("string_literal"),
str8_lit_comp("U64"),
str8_lit_comp("F64"),
str8_lit_comp("F32"),
str8_lit_comp("leaf_ident"),
str8_lit_comp("leaf_id"),
str8_lit_comp("type_ident"),
str8_lit_comp("ptr"),
str8_lit_comp("array"),
str8_lit_comp("function"),
str8_lit_comp("="),
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Nil") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Ref") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("ArrayIndex") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp("MemberAccess") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp("Deref") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("Address") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Cast") },
{ E_OpKind_UnaryPrefix, 0, str8_lit_comp("sizeof"), str8_lit_comp(""), str8_lit_comp("Sizeof") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("Neg") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp("LogNot") },
{ E_OpKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp("BitNot") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp("Mul") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("/"), str8_lit_comp("Div") },
{ E_OpKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("%"), str8_lit_comp("Mod") },
{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("+"), str8_lit_comp("Add") },
{ E_OpKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("-"), str8_lit_comp("Sub") },
{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp("<<"), str8_lit_comp("LShift") },
{ E_OpKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(">>"), str8_lit_comp("RShift") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<"), str8_lit_comp("Less") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<="), str8_lit_comp("LsEq") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">"), str8_lit_comp("Grtr") },
{ E_OpKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">="), str8_lit_comp("GrEq") },
{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("=="), str8_lit_comp("EqEq") },
{ E_OpKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("!="), str8_lit_comp("NtEq") },
{ E_OpKind_Binary, 8, str8_lit_comp(""), str8_lit_comp("&"), str8_lit_comp("BitAnd") },
{ E_OpKind_Binary, 9, str8_lit_comp(""), str8_lit_comp("^"), str8_lit_comp("BitXor") },
{ E_OpKind_Binary, 10, str8_lit_comp(""), str8_lit_comp("|"), str8_lit_comp("BitOr") },
{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("LogAnd") },
{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("LogOr") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp("Ternary") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafBytecode") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafMember") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafStringLiteral") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafU64") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafF64") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafF32") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafIdent") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("LeafID") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("TypeIdent") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Ptr") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Array") },
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("Func") },
{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("Define") },
};
U8 e_kind_basic_byte_size_table[55] =
+3 -2
View File
@@ -91,6 +91,7 @@ typedef U32 E_ExprKind;
typedef enum E_ExprKindEnum
{
E_ExprKind_Nil,
E_ExprKind_Ref,
E_ExprKind_ArrayIndex,
E_ExprKind_MemberAccess,
E_ExprKind_Deref,
@@ -153,9 +154,9 @@ E_InterpretationCode_COUNT,
C_LINKAGE_BEGIN
extern String8 e_token_kind_strings[6];
extern String8 e_expr_kind_strings[42];
extern String8 e_expr_kind_strings[43];
extern String8 e_interpretation_code_display_strings[11];
extern String8 e_expr_op_strings[42];
extern E_OpInfo e_expr_kind_op_info_table[43];
extern U8 e_kind_basic_byte_size_table[55];
extern String8 e_kind_basic_string_table[55];
+1
View File
@@ -5,6 +5,7 @@
//~ rjf: Frontend/UI Pass Tasks
//
// [x] fix HRESULTs
// [ ] fix escape char literals
//
// [ ] fix selecting hover eval, then hover eval disappearing, causing
// busted focus, until a new hover eval is opened