From 6296d2bd96d1ff344164d23d9cc2e6150539322a Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 6 Feb 2024 11:47:52 -0800 Subject: [PATCH] first pass of watch window macros; fix active-but-disabled line edit rendering; other minor fixes --- src/ctrl/ctrl_core.c | 7 +- src/df/core/df_core.c | 30 ++--- src/df/core/df_core.h | 12 +- src/df/gfx/df_gfx.c | 69 ++++++---- src/df/gfx/df_gfx.h | 6 +- src/df/gfx/df_view_rule_hooks.c | 28 ++--- src/df/gfx/df_view_rule_hooks.h | 6 +- src/df/gfx/df_views.c | 77 +++++++++--- src/df/gfx/df_views.h | 2 +- src/eval/eval.mdesk | 7 +- src/eval/eval_compiler.c | 123 ++++++++++-------- src/eval/eval_compiler.h | 127 +------------------ src/eval/eval_core.c | 179 ++++++++++++++++++++++++++ src/eval/eval_core.h | 217 ++++++++++++++++++++++++++++++++ src/eval/eval_inc.c | 7 ++ src/eval/eval_inc.h | 12 ++ src/eval/eval_parser.c | 82 +----------- src/eval/eval_parser.h | 47 +------ src/eval/generated/eval.meta.h | 8 ++ src/raddbg/raddbg_main.cpp | 13 +- src/ui/ui_basic_widgets.c | 6 +- src/ui/ui_core.c | 27 ++-- src/ui/ui_core.h | 1 + 23 files changed, 688 insertions(+), 405 deletions(-) create mode 100644 src/eval/eval_core.c create mode 100644 src/eval/eval_core.h create mode 100644 src/eval/eval_inc.c create mode 100644 src/eval/eval_inc.h diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 9128cfdd..e97f1142 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -2117,7 +2117,10 @@ ctrl_thread__launch_and_init(CTRL_Msg *msg) break; } } - run_ctrls.run_entity_count -= 1; + if(run_ctrls.run_entity_count > 0) + { + run_ctrls.run_entity_count -= 1; + } if(run_ctrls.run_entity_count == 0) { done = 1; @@ -2886,7 +2889,7 @@ ctrl_thread__run(CTRL_Msg *msg) EVAL_IRTreeAndType ir_tree_and_type = {&eval_irtree_nil}; if(parse_has_expr && errors.count == 0) { - ir_tree_and_type = eval_irtree_and_type_from_expr(temp.arena, parse_ctx.type_graph, rdbg, parse.expr, &errors); + ir_tree_and_type = eval_irtree_and_type_from_expr(temp.arena, parse_ctx.type_graph, rdbg, &eval_string2expr_map_nil, parse.expr, &errors); } EVAL_OpList op_list = {0}; if(parse_has_expr && ir_tree_and_type.tree != &eval_irtree_nil) diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 494a140d..6c7df93c 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -1082,7 +1082,7 @@ df_cmd_params_apply_spec_query(Arena *arena, DF_CtrlCtx *ctrl_ctx, DF_CmdParams U64 vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx->unwind_count); DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, vaddr); - DF_Eval eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, &parse_ctx, query); + DF_Eval eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, query); if(eval.errors.count == 0) { TG_Kind eval_type_kind = tg_kind_from_key(tg_unwrapped_from_graph_raddbg_key(parse_ctx.type_graph, parse_ctx.rdbg, eval.type_key)); @@ -4123,7 +4123,7 @@ df_eval_parse_ctx_from_src_loc(DBGI_Scope *scope, DF_Entity *file, TxtPt pt) } internal DF_Eval -df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, String8 string) +df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, String8 string) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -4175,7 +4175,7 @@ df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ EVAL_IRTreeAndType ir_tree_and_type = {&eval_irtree_nil}; if(parse_has_expr && errors.count == 0) { - ir_tree_and_type = eval_irtree_and_type_from_expr(arena, parse_ctx->type_graph, parse_ctx->rdbg, parse.expr, &errors); + ir_tree_and_type = eval_irtree_and_type_from_expr(arena, parse_ctx->type_graph, parse_ctx->rdbg, macro_map, parse.expr, &errors); } //- rjf: get list of ops @@ -4376,7 +4376,7 @@ df_dynamically_typed_eval_from_eval(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_Ctr } internal DF_Eval -df_eval_from_eval_cfg_table(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_Eval eval, DF_CfgTable *cfg) +df_eval_from_eval_cfg_table(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_Eval eval, DF_CfgTable *cfg) { ProfBeginFunction(); @@ -4386,7 +4386,7 @@ df_eval_from_eval_cfg_table(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ct DF_CoreViewRuleSpec *spec = df_core_view_rule_spec_from_string(val->string); if(spec->info.flags & DF_CoreViewRuleSpecInfoFlag_EvalResolution) { - eval = spec->info.eval_resolution(arena, scope, ctrl_ctx, parse_ctx, eval, val); + eval = spec->info.eval_resolution(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval, val); goto end_resolve; } } @@ -5025,7 +5025,7 @@ df_eval_viz_block_end(DF_EvalVizBlockList *list, DF_EvalVizBlock *block) } internal void -df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalView *eval_view, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out) +df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalView *eval_view, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -5040,7 +5040,7 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalVie //- rjf: apply view rules & resolve eval // eval = df_dynamically_typed_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval); - eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, eval, cfg_table); + eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval, cfg_table); ////////////////////////////// //- rjf: unpack eval @@ -5178,7 +5178,7 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalVie expand_view_rule_cfg != &df_g_nil_cfg_val) ProfScope("build viz blocks for lens") { - expand_view_rule_spec->info.viz_block_prod(arena, scope, ctrl_ctx, parse_ctx, eval_view, eval, cfg_table, parent_key, key, depth+1, expand_view_rule_cfg->last, list_out); + expand_view_rule_spec->info.viz_block_prod(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, eval, cfg_table, parent_key, key, depth+1, expand_view_rule_cfg->last, list_out); } ////////////////////////////// @@ -5232,7 +5232,7 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalVie child_eval.mode = udt_eval.mode; child_eval.offset = udt_eval.offset + member->off; } - df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, key, child->key, member->name, child_eval, member, &child_cfg, depth+1, list_out); + df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, macro_map, key, child->key, member->name, child_eval, member, &child_cfg, depth+1, list_out); } } df_eval_viz_block_end(list_out, last_vb); @@ -5348,7 +5348,7 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalVie child_eval.mode = link_base.mode; child_eval.offset = link_base.offset; } - df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, key, child->key, push_str8f(arena, "[%I64u]", child_idx), child_eval, 0, &child_cfg, depth+1, list_out); + df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, macro_map, key, child->key, push_str8f(arena, "[%I64u]", child_idx), child_eval, 0, &child_cfg, depth+1, list_out); } } df_eval_viz_block_end(list_out, last_vb); @@ -5405,7 +5405,7 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalVie child_eval.mode = arr_eval.mode; child_eval.offset = arr_eval.offset + child_idx*element_type_byte_size; } - df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, key, child->key, push_str8f(arena, "[%I64u]", child_idx), child_eval, 0, &child_cfg, depth+1, list_out); + df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, macro_map, key, child->key, push_str8f(arena, "[%I64u]", child_idx), child_eval, 0, &child_cfg, depth+1, list_out); } } df_eval_viz_block_end(list_out, last_vb); @@ -5418,7 +5418,7 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalVie ProfScope("build viz blocks for ptr-to-ptrs") { String8 subexpr = push_str8f(arena, "*(%S)", string); - df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, key, df_expand_key_make(df_hash_from_expand_key(key), 1), subexpr, ptr_eval, 0, cfg_table, depth+1, list_out); + df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, macro_map, key, df_expand_key_make(df_hash_from_expand_key(key), 1), subexpr, ptr_eval, 0, cfg_table, depth+1, list_out); } scratch_end(scratch); @@ -5426,14 +5426,14 @@ df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalVie } internal DF_EvalVizBlockList -df_eval_viz_block_list_from_eval_view_expr_num(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_EvalView *eval_view, String8 expr, U64 num) +df_eval_viz_block_list_from_eval_view_expr_num(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, String8 expr, U64 num) { ProfBeginFunction(); DF_EvalVizBlockList blocks = {0}; { DF_ExpandKey start_parent_key = df_expand_key_make(5381, 0); DF_ExpandKey start_key = df_expand_key_make(df_hash_from_expand_key(start_parent_key), num); - DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, expr); + DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, macro_map, expr); U64 expr_comma_pos = str8_find_needle(expr, 0, str8_lit(","), 0); String8List default_view_rules = {0}; if(expr_comma_pos < expr.size) @@ -5464,7 +5464,7 @@ df_eval_viz_block_list_from_eval_view_expr_num(Arena *arena, DBGI_Scope *scope, 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, scope, eval_view, ctrl_ctx, parse_ctx, start_parent_key, start_key, expr, eval, 0, &view_rule_table, 0, &blocks); + df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, macro_map, start_parent_key, start_key, expr, eval, 0, &view_rule_table, 0, &blocks); } ProfEnd(); return blocks; diff --git a/src/df/core/df_core.h b/src/df/core/df_core.h index 9627b556..848f50a7 100644 --- a/src/df/core/df_core.h +++ b/src/df/core/df_core.h @@ -265,10 +265,10 @@ struct DF_Eval //////////////////////////////// //~ rjf: View Rule Hook Types -#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(name) DF_Eval name(Arena *arena, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_Eval eval, struct DF_CfgVal *val) +#define DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_SIG(name) DF_Eval name(Arena *arena, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_Eval eval, struct 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, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, struct DF_EvalView *eval_view, DF_Eval eval, struct DF_CfgTable *cfg_table, DF_ExpandKey parent_key, DF_ExpandKey key, S32 depth, struct DF_CfgNode *cfg, struct DF_EvalVizBlockList *out) +#define DF_CORE_VIEW_RULE_VIZ_BLOCK_PROD_FUNCTION_SIG(name) void name(Arena *arena, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_EvalView *eval_view, DF_Eval eval, struct DF_CfgTable *cfg_table, DF_ExpandKey parent_key, DF_ExpandKey key, S32 depth, struct DF_CfgNode *cfg, 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); @@ -1576,10 +1576,10 @@ internal CTRL_Event df_ctrl_last_stop_event(void); internal B32 df_eval_memory_read(void *u, void *out, U64 addr, U64 size); internal EVAL_ParseCtx df_eval_parse_ctx_from_process_vaddr(DBGI_Scope *scope, DF_Entity *process, U64 vaddr); internal EVAL_ParseCtx df_eval_parse_ctx_from_src_loc(DBGI_Scope *scope, DF_Entity *file, TxtPt pt); -internal DF_Eval df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, String8 string); +internal DF_Eval df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, String8 string); internal DF_Eval df_value_mode_eval_from_eval(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx, DF_Eval eval); internal DF_Eval df_dynamically_typed_eval_from_eval(TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx, DF_Eval eval); -internal DF_Eval df_eval_from_eval_cfg_table(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_Eval eval, DF_CfgTable *cfg); +internal DF_Eval df_eval_from_eval_cfg_table(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_Eval eval, DF_CfgTable *cfg); //////////////////////////////// //~ rjf: Evaluation Views @@ -1617,8 +1617,8 @@ 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, DBGI_Scope *scope, DF_EvalView *view, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out); -internal DF_EvalVizBlockList df_eval_viz_block_list_from_eval_view_expr_num(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_EvalView *eval_view, String8 expr, U64 num); +internal void df_append_viz_blocks_for_parent__rec(Arena *arena, DBGI_Scope *scope, DF_EvalView *view, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_ExpandKey parent_key, DF_ExpandKey key, String8 string, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table, S32 depth, DF_EvalVizBlockList *list_out); +internal DF_EvalVizBlockList df_eval_viz_block_list_from_eval_view_expr_num(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, String8 expr, U64 num); internal void df_eval_viz_block_list_concat__in_place(DF_EvalVizBlockList *dst, DF_EvalVizBlockList *to_push); //- rjf: viz block list <-> table coordinates diff --git a/src/df/gfx/df_gfx.c b/src/df/gfx/df_gfx.c index 1c4757ab..eab71082 100644 --- a/src/df/gfx/df_gfx.c +++ b/src/df/gfx/df_gfx.c @@ -1515,7 +1515,9 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D } if(df_panel_is_nil(panel->first)) { - ws->focused_panel = panel; + DF_CmdParams p = df_cmd_params_from_window(ws); + p.panel = df_handle_from_panel(panel); + df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel)); break; } } @@ -1569,7 +1571,9 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D break; } } - ws->focused_panel = dst_panel; + DF_CmdParams p = df_cmd_params_from_window(ws); + p.panel = df_handle_from_panel(dst_panel); + df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FocusPanel)); } }break; @@ -4941,6 +4945,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D //- rjf: build query text input UI_Parent(query_container_box) UI_WidthFill UI_PrefHeight(ui_px(query_line_edit_height, 1.f)) + UI_Focus(UI_FocusKind_On) { ui_set_next_flags(UI_BoxFlag_DrawDropShadow|UI_BoxFlag_DrawBorder); UI_Row @@ -5086,8 +5091,9 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); U64 thread_unwind_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, ctrl_ctx.unwind_count); EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_unwind_rip_vaddr); + EVAL_String2ExprMap *macro_map = &eval_string2expr_map_nil; String8 expr = ws->hover_eval_string; - DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, expr); + DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); //- rjf: build if good if(!tg_key_match(eval.type_key, tg_key_zero()) && !ui_any_ctx_menu_is_open()) @@ -5099,8 +5105,8 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D U64 expr_hash = df_hash_from_string(expr); DF_EvalViewKey eval_view_key = df_eval_view_key_from_stringf("eval_hover_%I64x", expr_hash); DF_EvalView *eval_view = df_eval_view_from_key(eval_view_key); - DF_EvalVizBlockList viz_blocks = df_eval_viz_block_list_from_eval_view_expr_num(scratch.arena, scope, &ctrl_ctx, &parse_ctx, eval_view, expr, 1); - DF_EvalVizWindowedRowList viz_rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, eval_view, 10, ui_top_font(), ui_top_font_size(), r1s64(0, 50), &viz_blocks); + DF_EvalVizBlockList viz_blocks = df_eval_viz_block_list_from_eval_view_expr_num(scratch.arena, scope, &ctrl_ctx, &parse_ctx, macro_map, eval_view, expr, 1); + DF_EvalVizWindowedRowList viz_rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, macro_map, eval_view, 10, ui_top_font(), ui_top_font_size(), r1s64(0, 50), &viz_blocks); //- rjf: animate { @@ -5245,7 +5251,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D if(sig.commit) { String8 commit_string = str8(ws->hover_eval_txt_buffer, ws->hover_eval_txt_size); - DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, commit_string); + DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, commit_string); B32 success = df_commit_eval_value(parse_ctx.type_graph, parse_ctx.rdbg, &ctrl_ctx, row->eval, write_eval); if(success == 0) { @@ -5553,6 +5559,7 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D panel_box = ui_build_box_from_key(UI_BoxFlag_MouseClickable| UI_BoxFlag_Clip| UI_BoxFlag_DrawBorder| + ((ws->focused_panel != panel)*UI_BoxFlag_DisableFocusViz)| ((ws->focused_panel != panel)*UI_BoxFlag_DrawOverlay), panel_key); } @@ -6647,6 +6654,16 @@ df_window_update_and_render(Arena *arena, OS_EventList *events, DF_Window *ws, D MemoryCopyArray(inst->corner_radii, b->corner_radii); } + // rjf: draw focus active disabled vis + if(b->flags & UI_BoxFlag_Clickable && !(b->flags & UI_BoxFlag_DisableFocusViz) && b->focus_active_disabled_t > 0.01f) + { + Vec4F32 color = df_rgba_from_theme_color(DF_ThemeColor_FailureBackground); + color.w *= b->focus_active_disabled_t; + R_Rect2DInst *inst = d_rect(pad_2f32(b->rect, 1.f), color, 0, 2.f, 1.f); + inst->colors[Corner_10] = inst->colors[Corner_01] = inst->colors[Corner_11] = v4f32(color.x, color.y, color.z, color.w/3.f); + MemoryCopyArray(inst->corner_radii, b->corner_radii); + } + // rjf: draw overlay if(b->flags & UI_BoxFlag_DrawOverlay && b->overlay_color.w > 0.05f) { @@ -7093,7 +7110,7 @@ df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags } internal DF_EvalVizWindowedRowList -df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks) +df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -7276,7 +7293,7 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop // rjf: apply view rules to eval { member_eval = df_dynamically_typed_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, member_eval); - member_eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, member_eval, &view_rule_table); + member_eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, macro_map, member_eval, &view_rule_table); } // rjf: build & push row @@ -7330,7 +7347,7 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop // rjf: apply view rules to eval { eval = df_dynamically_typed_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval); - eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, eval, &view_rule_table); + eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval, &view_rule_table); } // rjf: build & push row @@ -7377,7 +7394,7 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop // rjf: apply view rules to eval { elem_eval = df_dynamically_typed_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, elem_eval); - elem_eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, elem_eval, &view_rule_table); + elem_eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, macro_map, elem_eval, &view_rule_table); } // rjf: build row @@ -7428,7 +7445,7 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop // rjf: apply view rules to eval link_eval = df_dynamically_typed_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, link_eval); - link_eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, link_eval, &view_rule_table); + link_eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, macro_map, link_eval, &view_rule_table); TG_Kind link_type_kind = tg_kind_from_key(link_eval.type_key); // rjf: build row @@ -7480,7 +7497,7 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop key.child_num = block->backing_search_items.v[idx].idx; // rjf: get eval for this row - DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, name); + DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, macro_map, name); // rjf: get view rules String8 view_rule_string = df_eval_view_rule_from_key(eval_view, key); @@ -7490,7 +7507,7 @@ df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scop // rjf: apply view rules to eval { eval = df_dynamically_typed_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval); - eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, eval, &view_rule_table); + eval = df_eval_from_eval_cfg_table(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval, &view_rule_table); } // rjf: build row @@ -9665,7 +9682,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_ { DF_Entity *pin = n->entity; String8 pin_expr = pin->name; - DF_Eval eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, pin_expr); + DF_Eval eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, &eval_string2expr_map_nil, pin_expr); String8 eval_string = {0}; if(!tg_key_match(tg_key_zero(), eval.type_key)) { @@ -10790,9 +10807,11 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx if(is_auto_focus_active) { ui_push_focus_active(UI_FocusKind_On); } B32 is_focus_hot = ui_is_focus_hot(); B32 is_focus_active = ui_is_focus_active(); + B32 is_focus_hot_disabled = (!is_focus_hot && ui_top_focus_hot() == UI_FocusKind_On); + B32 is_focus_active_disabled = (!is_focus_active && ui_top_focus_active() == UI_FocusKind_On); //- rjf: build top-level box - if(is_focus_active) + if(is_focus_active || is_focus_active_disabled) { ui_set_next_hover_cursor(OS_Cursor_IBar); } @@ -10802,7 +10821,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx (!(flags & DF_LineEditFlag_NoBackground)*UI_BoxFlag_DrawBackground)| (!!(flags & DF_LineEditFlag_Border)*UI_BoxFlag_DrawBorder)| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| - is_focus_active*(UI_BoxFlag_Clip), + (is_focus_active || is_focus_active_disabled)*(UI_BoxFlag_Clip), key); //- rjf: build indent @@ -10968,7 +10987,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx F32 cursor_off = 0; UI_Parent(scrollable_box) { - if(!is_focus_active && flags & DF_LineEditFlag_CodeContents) + if(!is_focus_active && !is_focus_active_disabled && flags & DF_LineEditFlag_CodeContents) { String8 display_string = ui_display_part_from_key_string(string); if(!(flags & DF_LineEditFlag_PreferDisplayString) && pre_edit_value.size != 0) @@ -10998,7 +11017,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } } } - else if(!is_focus_active && !(flags & DF_LineEditFlag_CodeContents)) + else if(!is_focus_active && !is_focus_active_disabled && !(flags & DF_LineEditFlag_CodeContents)) { String8 display_string = ui_display_part_from_key_string(string); if(!(flags & DF_LineEditFlag_PreferDisplayString) && pre_edit_value.size != 0) @@ -11015,7 +11034,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx ui_box_equip_fuzzy_match_ranges(box, matches); } } - else if(is_focus_active && flags & DF_LineEditFlag_CodeContents) + else if((is_focus_active || is_focus_active_disabled) && flags & DF_LineEditFlag_CodeContents) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); Temp scratch = scratch_begin(0, 0); @@ -11029,14 +11048,14 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); draw_data->cursor = *cursor; draw_data->mark = *mark; - draw_data->cursor_color = ui_top_text_cursor_color(); + draw_data->cursor_color = is_focus_active ? ui_top_text_cursor_color() : df_rgba_from_theme_color(DF_ThemeColor_FailureBackground); draw_data->select_color = ui_top_text_select_color(); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); mouse_pt = txt_pt(1, 1+ui_box_char_pos_from_xy(editstr_box, ui_mouse())); cursor_off = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), str8_prefix(edit_string, cursor->column-1)).x; scratch_end(scratch); } - else if(is_focus_active && !(flags & DF_LineEditFlag_CodeContents)) + else if((is_focus_active || is_focus_active_disabled) && !(flags & DF_LineEditFlag_CodeContents)) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); F32 total_text_width = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), edit_string).x; @@ -11047,7 +11066,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx draw_data->edited_string = push_str8_copy(ui_build_arena(), edit_string); draw_data->cursor = *cursor; draw_data->mark = *mark; - draw_data->cursor_color = ui_top_text_cursor_color(); + draw_data->cursor_color = is_focus_active ? ui_top_text_cursor_color() : df_rgba_from_theme_color(DF_ThemeColor_FailureBackground); draw_data->select_color = ui_top_text_select_color(); ui_box_equip_display_string(editstr_box, edit_string); ui_box_equip_custom_draw(editstr_box, ui_line_edit_draw, draw_data); @@ -11065,6 +11084,10 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx } *cursor = mouse_pt; } + if(!is_focus_active && is_focus_active_disabled && sig.pressed) + { + *cursor = *mark = mouse_pt; + } //- rjf: focus cursor { @@ -11082,7 +11105,7 @@ df_line_edit(DF_LineEditFlags flags, S32 depth, FuzzyMatchRangeList *matches, Tx scrollable_box->view_off_target.x += min_delta; scrollable_box->view_off_target.x += max_delta; } - if(!is_focus_active) + if(!is_focus_active && !is_focus_active_disabled) { scrollable_box->view_off_target.x = scrollable_box->view_off.x = 0; } diff --git a/src/df/gfx/df_gfx.h b/src/df/gfx/df_gfx.h index e8f701c3..c55cf7d2 100644 --- a/src/df/gfx/df_gfx.h +++ b/src/df/gfx/df_gfx.h @@ -356,11 +356,11 @@ enum #define DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(name) df_gfx_view_rule_line_stringize__##name #define DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_DEF(name) internal DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_SIG(DF_GFX_VIEW_RULE_LINE_STRINGIZE_FUNCTION_NAME(name)) -#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_SIG(name) void name(DF_ExpandKey key, DF_Eval eval, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, struct DF_CfgNode *cfg) +#define DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_SIG(name) void name(DF_ExpandKey key, DF_Eval eval, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, struct DF_CfgNode *cfg) #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, DF_Eval eval, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, 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, DF_Eval eval, DBGI_Scope *dbgi_scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, 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)) @@ -962,7 +962,7 @@ internal void df_window_update_and_render(Arena *arena, OS_EventList *events, DF internal String8 df_eval_escaped_from_raw_string(Arena *arena, String8 raw); internal String8List df_single_line_eval_value_strings_from_eval(Arena *arena, DF_EvalVizStringFlags flags, TG_Graph *graph, RADDBG_Parsed *rdbg, DF_CtrlCtx *ctrl_ctx, U32 default_radix, F_Tag font, F32 font_size, F32 max_size, S32 depth, DF_Eval eval, TG_Member *opt_member, DF_CfgTable *cfg_table); -internal DF_EvalVizWindowedRowList df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks); +internal DF_EvalVizWindowedRowList df_eval_viz_windowed_row_list_from_viz_block_list(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_EvalView *eval_view, U32 default_radix, F_Tag font, F32 font_size, Rng1S64 visible_range, DF_EvalVizBlockList *blocks); //////////////////////////////// //~ rjf: Hover Eval diff --git a/src/df/gfx/df_view_rule_hooks.c b/src/df/gfx/df_view_rule_hooks.c index d998464a..3e2568b4 100644 --- a/src/df/gfx/df_view_rule_hooks.c +++ b/src/df/gfx/df_view_rule_hooks.c @@ -198,7 +198,7 @@ df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RADDBG_Parse } internal DF_BitmapTopologyInfo -df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CfgNode *cfg) +df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg) { Temp scratch = scratch_begin(0, 0); DF_BitmapTopologyInfo info = {0}; @@ -222,10 +222,10 @@ df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx String8 width_expr = str8_list_join(scratch.arena, &width_expr_strs, 0); String8 height_expr = str8_list_join(scratch.arena, &height_expr_strs, 0); String8 fmt_string = fmt_cfg->first->string; - DF_Eval width_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, width_expr); + DF_Eval width_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, width_expr); DF_Eval width_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, width_eval); info.width = width_eval_value.imm_u64; - DF_Eval height_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, height_expr); + DF_Eval height_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, height_expr); DF_Eval height_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, height_eval); info.height = height_eval_value.imm_u64; if(fmt_string.size != 0) @@ -245,7 +245,7 @@ df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx } internal DF_GeoTopologyInfo -df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CfgNode *cfg) +df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg) { Temp scratch = scratch_begin(0, 0); DF_GeoTopologyInfo result = {0}; @@ -273,9 +273,9 @@ df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ct String8 count_expr = str8_list_join(scratch.arena, &count_expr_strs, &join); String8 vertices_base_expr = str8_list_join(scratch.arena, &vertices_base_expr_strs, &join); String8 vertices_size_expr = str8_list_join(scratch.arena, &vertices_size_expr_strs, &join); - DF_Eval count_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, count_expr); - DF_Eval vertices_base_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, vertices_base_expr); - DF_Eval vertices_size_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, vertices_size_expr); + DF_Eval count_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, count_expr); + DF_Eval vertices_base_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, vertices_base_expr); + DF_Eval vertices_size_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, vertices_size_expr); DF_Eval count_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, count_eval); DF_Eval vertices_base_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, vertices_base_eval); DF_Eval vertices_size_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, vertices_size_eval); @@ -288,7 +288,7 @@ df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ct } internal DF_TxtTopologyInfo -df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CfgNode *cfg) +df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg) { Temp scratch = scratch_begin(0, 0); DF_TxtTopologyInfo result = zero_struct; @@ -305,7 +305,7 @@ df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ct } lang_string = lang_cfg->first->string; String8 size_expr = str8_list_join(scratch.arena, &size_expr_strs, &join); - DF_Eval size_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, size_expr); + DF_Eval size_eval = df_eval_from_string(scratch.arena, scope, ctrl_ctx, parse_ctx, macro_map, size_expr); DF_Eval size_val_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, size_eval); result.lang = txt_lang_kind_from_extension(lang_string); result.size_cap = size_val_eval.imm_u64; @@ -336,7 +336,7 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(array) str8_list_push(scratch.arena, &array_size_expr_strs, child->string); } String8 array_size_expr = str8_list_join(scratch.arena, &array_size_expr_strs, 0); - DF_Eval array_size_eval = df_eval_from_string(arena, dbgi_scope, ctrl_ctx, parse_ctx, array_size_expr); + DF_Eval array_size_eval = df_eval_from_string(arena, dbgi_scope, ctrl_ctx, parse_ctx, macro_map, array_size_expr); DF_Eval array_size_eval_value = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, array_size_eval); eval_error_list_concat_in_place(&eval.errors, &array_size_eval.errors); array_size = array_size_eval_value.imm_u64; @@ -675,7 +675,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text) state->last_open_frame_idx = df_frame_index(); { //- rjf: unpack params - DF_TxtTopologyInfo top = df_view_rule_hooks__txt_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, cfg); + DF_TxtTopologyInfo top = df_view_rule_hooks__txt_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, macro_map, cfg); //- rjf: resolve to address value & range DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval); @@ -846,7 +846,7 @@ DF_GFX_VIEW_RULE_ROW_UI_FUNCTION_DEF(bitmap) { DF_Eval value_eval = df_value_mode_eval_from_eval(parse_ctx->type_graph, parse_ctx->rdbg, ctrl_ctx, eval); U64 base_vaddr = value_eval.imm_u64 ? value_eval.imm_u64 : value_eval.offset; - DF_BitmapTopologyInfo topology = df_view_rule_hooks__bitmap_topology_info_from_cfg(scope, ctrl_ctx, parse_ctx, cfg); + DF_BitmapTopologyInfo topology = df_view_rule_hooks__bitmap_topology_info_from_cfg(scope, ctrl_ctx, parse_ctx, macro_map, cfg); U64 expected_size = topology.width*topology.height*r_tex2d_format_bytes_per_pixel_table[topology.fmt]; UI_Font(df_font_from_slot(DF_FontSlot_Code)) UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) ui_labelf("0x%I64x -> Bitmap (%I64u x %I64u)", base_vaddr, topology.width, topology.height); @@ -873,7 +873,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap) DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); //- rjf: unpack image dimensions & form vaddr range - DF_BitmapTopologyInfo topology_info = df_view_rule_hooks__bitmap_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, cfg); + DF_BitmapTopologyInfo topology_info = df_view_rule_hooks__bitmap_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, macro_map, cfg); U64 expected_size = topology_info.width*topology_info.height*r_tex2d_format_bytes_per_pixel_table[topology_info.fmt]; Rng1U64 vaddr_range = r1u64(base_vaddr, base_vaddr+expected_size); @@ -1116,7 +1116,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(geo) U64 base_vaddr = value_eval.imm_u64 ? value_eval.imm_u64 : value_eval.offset; //- rjf: extract extra geo topology info from view rule - DF_GeoTopologyInfo top = df_view_rule_hooks__geo_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, cfg); + DF_GeoTopologyInfo top = df_view_rule_hooks__geo_topology_info_from_cfg(dbgi_scope, ctrl_ctx, parse_ctx, macro_map, cfg); Rng1U64 index_buffer_vaddr_range = r1u64(base_vaddr, base_vaddr+top.index_count*sizeof(U32)); Rng1U64 vertex_buffer_vaddr_range = top.vertices_vaddr_range; diff --git a/src/df/gfx/df_view_rule_hooks.h b/src/df/gfx/df_view_rule_hooks.h index 2c7de70c..2d7ea22d 100644 --- a/src/df/gfx/df_view_rule_hooks.h +++ b/src/df/gfx/df_view_rule_hooks.h @@ -34,8 +34,8 @@ struct DF_TxtTopologyInfo internal Vec4F32 df_view_rule_hooks__rgba_from_eval(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed *raddbg, DF_Entity *process); internal void df_view_rule_hooks__eval_commit_rgba(DF_Eval eval, TG_Graph *graph, RADDBG_Parsed *raddbg, DF_CtrlCtx *ctrl_ctx, Vec4F32 rgba); -internal DF_BitmapTopologyInfo df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CfgNode *cfg); -internal DF_GeoTopologyInfo df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CfgNode *cfg); -internal DF_TxtTopologyInfo df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CfgNode *cfg); +internal DF_BitmapTopologyInfo df_view_rule_hooks__bitmap_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg); +internal DF_GeoTopologyInfo df_view_rule_hooks__geo_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg); +internal DF_TxtTopologyInfo df_view_rule_hooks__txt_topology_info_from_cfg(DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_CfgNode *cfg); #endif //DF_VIEW_RULE_HOOKS_H diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 7e357274..361baa6a 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -633,7 +633,7 @@ df_string_from_eval_root(DF_EvalRoot *root) //- rjf: windowed watch tree visualization (both single-line and multi-line) internal DF_EvalVizBlockList -df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_View *view, DF_EvalWatchViewState *ews) +df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_EvalWatchViewState *ews) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -657,7 +657,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF FuzzyMatchRangeList matches = fuzzy_match_find(arena, filter, root_expr_string); if(matches.count == matches.needle_part_count) { - DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, eval_view, root_expr_string, num); + DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, num); df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks); } } @@ -681,7 +681,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF FuzzyMatchRangeList matches = fuzzy_match_find(arena, filter, root_expr_string); if(matches.count == matches.needle_part_count) { - DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, eval_view, root_expr_string, num); + DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, num); df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks); } } @@ -691,7 +691,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF FuzzyMatchRangeList matches = fuzzy_match_find(arena, filter, root_expr_string); if(matches.count == matches.needle_part_count) { - DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, eval_view, root_expr_string, num); + DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, num); df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks); } } @@ -709,7 +709,7 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF FuzzyMatchRangeList matches = fuzzy_match_find(arena, filter, root_expr_string); if(matches.count == matches.needle_part_count) { - DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, eval_view, root_expr_string, num); + DF_EvalVizBlockList root_blocks = df_eval_viz_block_list_from_eval_view_expr_num(arena, scope, ctrl_ctx, parse_ctx, macro_map, eval_view, root_expr_string, num); df_eval_viz_block_list_concat__in_place(&blocks, &root_blocks); } } @@ -835,8 +835,8 @@ df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF df_cfg_table_push_unparsed_string(arena, &child_cfg, view_rule_string, DF_CfgSrc_User); } } - DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, name); - df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, parent_key, sub_expand_keys[sub_expand_idx], name, eval, 0, &child_cfg, 0, &blocks); + DF_Eval eval = df_eval_from_string(arena, scope, ctrl_ctx, parse_ctx, macro_map, name); + df_append_viz_blocks_for_parent__rec(arena, scope, eval_view, ctrl_ctx, parse_ctx, macro_map, parent_key, sub_expand_keys[sub_expand_idx], name, eval, 0, &child_cfg, 0, &blocks); } } df_eval_viz_block_end(&blocks, last_vb); @@ -920,10 +920,49 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW // EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, thread_ip_vaddr); + ////////////////////////////// + //- rjf: state -> macro map + // + EVAL_String2ExprMap macro_map = eval_string2expr_map_make(scratch.arena, 256); + for(DF_EvalRoot *root = ewv->first_root; root != 0; root = root->next) + { + String8 root_expr = str8(root->expr_buffer, root->expr_buffer_string_size); + + //- rjf: unpack arguments + DF_Entity *process = thread->parent; + U64 unwind_count = ctrl_ctx.unwind_count; + CTRL_Unwind unwind = df_query_cached_unwind_from_thread(thread); + Architecture arch = df_architecture_from_entity(thread); + U64 reg_size = regs_block_size_from_architecture(arch); + U64 thread_unwind_ip_vaddr = 0; + void *thread_unwind_regs_block = push_array(scratch.arena, U8, reg_size); + { + U64 idx = 0; + for(CTRL_UnwindFrame *f = unwind.first; f != 0; f = f->next, idx += 1) + { + if(idx == unwind_count) + { + thread_unwind_ip_vaddr = f->rip; + thread_unwind_regs_block = f->regs; + break; + } + } + } + + //- rjf: lex & parse + EVAL_TokenArray tokens = eval_token_array_from_text(scratch.arena, root_expr); + EVAL_ParseResult parse = eval_parse_expr_from_text_tokens(scratch.arena, &parse_ctx, root_expr, &tokens); + EVAL_ErrorList errors = parse.errors; + if(errors.count == 0) + { + eval_push_leaf_ident_exprs_from_expr__in_place(scratch.arena, ¯o_map, parse.expr, &errors); + } + } + ////////////////////////////// //- rjf: state -> viz blocks // - DF_EvalVizBlockList blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, view, ewv); + DF_EvalVizBlockList blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, view, ewv); ////////////////////////////// //- rjf: does this eval watch view allow mutation? -> add extra block for editable empty row @@ -1098,7 +1137,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW //- rjf: viz blocks -> rows DF_EvalVizWindowedRowList rows = {0}; { - rows = df_eval_viz_windowed_row_list_from_viz_block_list(scratch.arena, scope, &ctrl_ctx, &parse_ctx, eval_view, default_radix, code_font, code_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, scope, &ctrl_ctx, &parse_ctx, ¯o_map, eval_view, default_radix, code_font, code_font_size, r1s64(visible_row_rng.min-1, visible_row_rng.max), &blocks); } //- rjf: build table @@ -1165,7 +1204,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW { 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 - scroll_list_params.row_height_px); - row->expand_ui_rule_spec->info.block_ui(ws, row->key, row->eval, scope, &ctrl_ctx, &parse_ctx, row->expand_ui_rule_node, canvas_dim); + row->expand_ui_rule_spec->info.block_ui(ws, row->key, row->eval, scope, &ctrl_ctx, &parse_ctx, ¯o_map, row->expand_ui_rule_node, canvas_dim); } } } @@ -1341,7 +1380,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW if(parse.expr != &eval_expr_nil && errors.count == 0) { ui_labelf("Type:"); - ir_tree_and_type = eval_irtree_and_type_from_expr(scratch.arena, parse_ctx.type_graph, parse_ctx.rdbg, parse.expr, &errors); + ir_tree_and_type = eval_irtree_and_type_from_expr(scratch.arena, parse_ctx.type_graph, parse_ctx.rdbg, &eval_string2expr_map_nil, parse.expr, &errors); TG_Key type_key = ir_tree_and_type.type_key; String8 type_string = tg_string_from_key(scratch.arena, parse_ctx.type_graph, parse_ctx.rdbg, type_key); UI_TextColor(df_rgba_from_theme_color(DF_ThemeColor_WeakText)) @@ -1428,7 +1467,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW } StringJoin join = {str8_lit(""), str8_lit(" "), str8_lit("")}; String8 error_string = str8_list_join(scratch.arena, &strings, &join); - df_error_label(error_string); + sig = df_error_label(error_string); } // rjf: hook -> call hook @@ -1437,7 +1476,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW 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(row->key, row->eval, scope, &ctrl_ctx, &parse_ctx, row->value_ui_rule_node); + row->value_ui_rule_spec->info.row_ui(row->key, row->eval, scope, &ctrl_ctx, &parse_ctx, ¯o_map, row->value_ui_rule_node); } sig = ui_signal_from_box(box); } @@ -1628,7 +1667,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW case DF_EvalWatchViewColumnKind_Value: { Temp scratch = scratch_begin(0, 0); - DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, commit_string); + DF_Eval write_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, commit_string); B32 success = df_commit_eval_value(parse_ctx.type_graph, parse_ctx.rdbg, &ctrl_ctx, commit_row->eval, write_eval); if(success == 0) { @@ -1671,7 +1710,7 @@ df_eval_watch_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_EvalW // if(edit_commit) { - blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, view, ewv); + blocks = df_eval_viz_block_list_from_watch_view_state(scratch.arena, scope, &ctrl_ctx, &parse_ctx, ¯o_map, view, ewv); if(modifiable) { DF_EvalVizBlock *b = df_eval_viz_block_begin(scratch.arena, DF_EvalVizBlockKind_Null, empty_row_parent_key, empty_row_key, 0); @@ -5403,7 +5442,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) String8 expr = txti_string_from_handle_txt_rng(scratch.arena, txti_handle, expr_rng); if(expr.size != 0) { - DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, expr); + DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); if(eval.mode != EVAL_EvalMode_NULL) { df_set_hover_eval(ws, sig.mouse_expr_baseline_pos, ctrl_ctx, entity, sig.mouse_pt, 0, expr); @@ -6311,7 +6350,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly) String8 expr = str8_substr(code_slice_params.line_text[line_idx], r1u64(sig.mouse_expr_rng.min.column-1, sig.mouse_expr_rng.max.column-1)); if(expr.size != 0) { - DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, expr); + DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); if(eval.mode != EVAL_EvalMode_NULL) { U64 off = dasm_inst_array_off_from_idx(&insts, sig.mouse_expr_rng.min.line-1); @@ -7207,7 +7246,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output) String8 expr = txti_string_from_handle_txt_rng(scratch.arena, txti_handle, expr_rng); if(expr.size != 0) { - DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, expr); + DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); if(eval.mode != EVAL_EvalMode_NULL) { df_set_hover_eval(ws, sig.mouse_expr_baseline_pos, ctrl_ctx, entity, sig.mouse_pt, 0, expr); @@ -7843,7 +7882,7 @@ DF_VIEW_UI_FUNCTION_DEF(Memory) for(EVAL_String2NumMapNode *n = parse_ctx.locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; - DF_Eval local_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, local_name); + DF_Eval local_eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, local_name); if(local_eval.mode == EVAL_EvalMode_Addr) { TG_Kind local_eval_type_kind = tg_kind_from_key(local_eval.type_key); diff --git a/src/df/gfx/df_views.h b/src/df/gfx/df_views.h index baf36ffb..0a5933dc 100644 --- a/src/df/gfx/df_views.h +++ b/src/df/gfx/df_views.h @@ -455,7 +455,7 @@ internal DF_EvalRoot * df_eval_root_from_expand_key(DF_EvalWatchViewState *ews, internal String8 df_string_from_eval_root(DF_EvalRoot *root); //- rjf: windowed watch tree visualization -internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_View *view, DF_EvalWatchViewState *ews); +internal DF_EvalVizBlockList df_eval_viz_block_list_from_watch_view_state(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, EVAL_String2ExprMap *macro_map, DF_View *view, DF_EvalWatchViewState *ews); //- rjf: eval/watch views main hooks internal void df_eval_watch_view_init(DF_EvalWatchViewState *ewv, DF_View *view, DF_EvalWatchViewFillKind fill_kind); diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 9bd5dda9..8e26553a 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -39,16 +39,19 @@ EVAL_ExprKindTable: { Ternary 3 "? " } - { LeafBytecode 0 "bytecode" } + { LeafBytecode 0 "bytecode" } { LeafMember 0 "member" } { LeafU64 0 "U64" } { LeafF64 0 "F64" } { LeafF32 0 "F32" } - { TypeIdent 0 "type_ident" } + { TypeIdent 0 "type_ident" } { Ptr 1 "ptr" } { Array 2 "array" } { Func 1 "function" } + + { Define 2 "=" } + { LeafIdent 0 "leaf_ident" } } @table_gen diff --git a/src/eval/eval_compiler.c b/src/eval/eval_compiler.c index 321b3fa4..e3ffdd35 100644 --- a/src/eval/eval_compiler.c +++ b/src/eval/eval_compiler.c @@ -1,44 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ allen: Eval Errors - -internal void -eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text){ - EVAL_Error *error = push_array_no_zero(arena, EVAL_Error, 1); - SLLQueuePush(list->first, list->last, error); - list->count += 1; - list->max_kind = Max(kind, list->max_kind); - error->kind = kind; - error->location = location; - error->text = text; -} - -internal void -eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...){ - va_list args; - va_start(args, fmt); - String8 text = push_str8fv(arena, fmt, args); - va_end(args); - eval_error(arena, list, kind, location, text); -} - -internal void -eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push){ - if (dst->last != 0){ - if (to_push->last != 0){ - dst->last->next = to_push->first; - dst->last = to_push->last; - dst->count += to_push->count; - } - } - else{ - *dst = *to_push; - } - MemoryZeroStruct(to_push); -} - //////////////////////////////// //~ allen: EVAL Bytecode Helpers @@ -284,6 +246,16 @@ eval_expr_leaf_member(Arena *arena, void *location, String8 name){ return(result); } +internal EVAL_Expr* +eval_expr_leaf_ident(Arena *arena, void *location, String8 name) +{ + EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); + result->location = location; + result->kind = EVAL_ExprKind_LeafIdent; + result->name = name; + return(result); +} + internal EVAL_Expr* eval_expr_leaf_bytecode(Arena *arena, void *location, TG_Key type_key, String8 bytecode, EVAL_EvalMode mode){ EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); @@ -717,6 +689,35 @@ eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, //////////////////////////////// //~ allen: EVAL Compiler Phases +internal void +eval_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, EVAL_String2ExprMap *map, EVAL_Expr *expr, EVAL_ErrorList *eout) +{ + switch(expr->kind) + { + default: + { + U64 children_count = eval_expr_kind_child_counts[expr->kind]; + for(U64 idx = 0; idx < children_count; idx += 1) + { + eval_push_leaf_ident_exprs_from_expr__in_place(arena, map, expr->children[idx], eout); + } + }break; + case EVAL_ExprKind_Define: + { + EVAL_Expr *exprl = expr->children[0]; + EVAL_Expr *exprr = expr->children[1]; + if(exprl->kind != EVAL_ExprKind_LeafIdent) + { + eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Left side of assignment must be an identifier."); + } + else + { + eval_string2expr_map_insert(arena, map, exprl->name, exprr); + } + }break; + } +} + internal TG_Key eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_Expr *expr, EVAL_ErrorList *eout){ TG_Key result = zero_struct; @@ -761,7 +762,7 @@ eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVA } internal EVAL_IRTreeAndType -eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_Expr *expr, EVAL_ErrorList *eout) +eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout) { ProfBeginFunction(); EVAL_IRTreeAndType result = {0}; @@ -780,8 +781,8 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb EVAL_Expr *exprl = expr->children[0]; EVAL_Expr *exprr = expr->children[1]; - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprl, eout); - EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprr, eout); + EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout); + EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout); if (l.tree->op != 0 && r.tree->op != 0){ TG_Key l_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l.type_key); @@ -860,7 +861,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb EVAL_Expr *exprl = expr->children[0]; EVAL_Expr *exprr = expr->children[1]; - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprl, eout); + EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout); if (l.tree->op != 0 && !tg_key_match(tg_key_zero(), l.type_key)){ TG_Key l_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l.type_key); @@ -978,7 +979,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb { EVAL_Expr *exprc = expr->children[0]; - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprc, eout); + EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout); if (c.tree->op != 0){ TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key); @@ -1035,7 +1036,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb case EVAL_ExprKind_Address: { EVAL_Expr *exprc = expr->children[0]; - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprc, eout); + EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout); if(c.tree->op != 0 && !tg_key_match(c.type_key, tg_key_zero())) { TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key); @@ -1069,7 +1070,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb TG_Key cast_type_key = eval_type_from_type_expr(arena, graph, rdbg, exprl, eout); TG_Kind cast_type_kind = tg_kind_from_key(cast_type_key); - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprr, eout); + EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout); if(cast_type_kind != TG_Kind_Null && c.tree->op != 0) { @@ -1135,7 +1136,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb // size of value expression default: { - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprc, eout); + EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout); type_key = c.type_key; }break; } @@ -1163,7 +1164,7 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb { EVAL_Expr *exprc = expr->children[0]; - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprc, eout); + EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout); if (c.tree->op != 0){ TG_Key c_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, c.type_key); TG_Key p_type = eval_type_promote(graph, rdbg, c_restype); @@ -1217,8 +1218,8 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb EVAL_Expr *exprl = expr->children[0]; EVAL_Expr *exprr = expr->children[1]; - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprl, eout); - EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprr, eout); + EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout); + EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout); if (l.tree->op != 0 && r.tree->op != 0){ TG_Key l_restype = tg_unwrapped_from_graph_raddbg_key(graph, rdbg, l.type_key); @@ -1407,9 +1408,9 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb EVAL_Expr *exprl = expr->children[1]; EVAL_Expr *exprr = expr->children[2]; - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprc, eout); - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprl, eout); - EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, exprr, eout); + EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprc, eout); + EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprl, eout); + EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, exprr, eout); if (l.tree->op != 0 && r.tree->op != 0 && c.tree->op != 0){ @@ -1536,6 +1537,24 @@ eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdb { eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Type expression not expected."); }break; + + case EVAL_ExprKind_Define: + { + result = eval_irtree_and_type_from_expr(arena, graph, rdbg, leaf_ident_expr_map, expr->children[1], eout); + }break; + case EVAL_ExprKind_LeafIdent: + { + String8 name = expr->name; + EVAL_Expr *leaf_ident_expr = eval_expr_from_string(leaf_ident_expr_map, name); + if(leaf_ident_expr == &eval_expr_nil) + { + eval_errorf(arena, eout, EVAL_ErrorKind_ResolutionFailure, expr->location, "\"%S\" could not be found.", name); + } + else + { + result = eval_irtree_and_type_from_expr(arena, graph, rdbg, &eval_string2expr_map_nil, leaf_ident_expr, eout); + } + }break; } ProfEnd(); diff --git a/src/eval/eval_compiler.h b/src/eval/eval_compiler.h index f9b6aecc..ab2ec297 100644 --- a/src/eval/eval_compiler.h +++ b/src/eval/eval_compiler.h @@ -4,129 +4,6 @@ #ifndef EVAL_COMPILER_H #define EVAL_COMPILER_H -//////////////////////////////// -//~ allen: EVAL Error Types - -typedef enum EVAL_ErrorKind -{ - EVAL_ErrorKind_Null, - EVAL_ErrorKind_MalformedInput, - EVAL_ErrorKind_MissingInfo, - EVAL_ErrorKind_ResolutionFailure, - EVAL_ErrorKind_COUNT -} -EVAL_ErrorKind; - -typedef struct EVAL_Error EVAL_Error; -struct EVAL_Error{ - EVAL_Error *next; - EVAL_ErrorKind kind; - void *location; - String8 text; -}; - -typedef struct EVAL_ErrorList EVAL_ErrorList; -struct EVAL_ErrorList{ - EVAL_Error *first; - EVAL_Error *last; - EVAL_ErrorKind max_kind; - U64 count; -}; - -//////////////////////////////// -//~ allen: EVAL Op List Types - -enum{ - EVAL_IRExtKind_Bytecode = RADDBG_EvalOp_COUNT, - EVAL_IRExtKind_COUNT -}; - -typedef struct EVAL_Op EVAL_Op; -struct EVAL_Op{ - EVAL_Op *next; - RADDBG_EvalOp opcode; - union{ - U64 p; - String8 bytecode; - }; -}; - -typedef struct EVAL_OpList EVAL_OpList; -struct EVAL_OpList{ - EVAL_Op *first_op; - EVAL_Op *last_op; - U32 op_count; - U32 encoded_size; -}; - -//////////////////////////////// -//- allen: EVAL Expression Types - -#include "eval/generated/eval.meta.h" - -typedef enum EVAL_EvalMode{ - EVAL_EvalMode_NULL, - EVAL_EvalMode_Value, - EVAL_EvalMode_Addr, - EVAL_EvalMode_Reg -} -EVAL_EvalMode; - -typedef struct EVAL_Expr EVAL_Expr; -struct EVAL_Expr{ - EVAL_ExprKind kind; - void *location; - union{ - EVAL_Expr *children[3]; - U32 u32; - U64 u64; - F32 f32; - F64 f64; - struct{ - EVAL_Expr *child; - U64 u64; - } child_and_constant; - String8 name; - struct{ - TG_Key type_key; - String8 bytecode; - EVAL_EvalMode mode; - }; - }; -}; - -global read_only EVAL_Expr eval_expr_nil = {0}; - -//////////////////////////////// -//~ allen: EVAL Compiler Types - -typedef struct EVAL_IRTree EVAL_IRTree; -struct EVAL_IRTree{ - RADDBG_EvalOp op; - EVAL_IRTree *children[3]; - union{ - U64 p; - String8 bytecode; - }; -}; - -global read_only EVAL_IRTree eval_irtree_nil = {0}; - -typedef struct EVAL_IRTreeAndType EVAL_IRTreeAndType; -struct EVAL_IRTreeAndType{ - EVAL_IRTree *tree; - TG_Key type_key; - EVAL_EvalMode mode; -}; - - -//////////////////////////////// -//~ allen: Eval Error Helpers - -internal void eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text); -internal void eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...); -internal void eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push); - //////////////////////////////// //~ allen: EVAL Bytecode Helpers @@ -155,6 +32,7 @@ internal EVAL_Expr* eval_expr_f64(Arena *arena, void *location, F64 f64); internal EVAL_Expr* eval_expr_f32(Arena *arena, void *location, F32 f32); internal EVAL_Expr* eval_expr_child_and_u64(Arena *arena, EVAL_ExprKind kind, void *location, EVAL_Expr *child, U64 u64); internal EVAL_Expr* eval_expr_leaf_member(Arena *arena, void *location, String8 name); +internal EVAL_Expr* eval_expr_leaf_ident(Arena *arena, void *location, String8 name); internal EVAL_Expr* eval_expr_leaf_bytecode(Arena *arena, void *location, TG_Key type_key, String8 bytecode, EVAL_EvalMode mode); internal EVAL_Expr* eval_expr_leaf_op_list(Arena *arena, void *location, TG_Key type_key, EVAL_OpList *ops, EVAL_EvalMode mode); internal EVAL_Expr* eval_expr_leaf_type(Arena *arena, void *location, TG_Key type_key); @@ -196,8 +74,9 @@ internal EVAL_IRTree* eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph //////////////////////////////// //~ allen: EVAL Compiler Phases +internal void eval_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, EVAL_String2ExprMap *map, EVAL_Expr *expr, EVAL_ErrorList *eout); internal TG_Key eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_Expr *expr, EVAL_ErrorList *eout); -internal EVAL_IRTreeAndType eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_Expr *expr, EVAL_ErrorList *eout); +internal EVAL_IRTreeAndType eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RADDBG_Parsed *rdbg, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout); internal void eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out); #endif //EVAL_COMPILER_H diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c new file mode 100644 index 00000000..33ef9357 --- /dev/null +++ b/src/eval/eval_core.c @@ -0,0 +1,179 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +//////////////////////////////// +//~ rjf: Basic Functions + +internal U64 +eval_hash_from_string(String8 string) +{ + U64 result = 5381; + for(U64 i = 0; i < string.size; i += 1) + { + result = ((result << 5) + result) + string.str[i]; + } + return result; +} + +//////////////////////////////// +//~ rjf: Error List Building Functions + +internal void +eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text){ + EVAL_Error *error = push_array_no_zero(arena, EVAL_Error, 1); + SLLQueuePush(list->first, list->last, error); + list->count += 1; + list->max_kind = Max(kind, list->max_kind); + error->kind = kind; + error->location = location; + error->text = text; +} + +internal void +eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...){ + va_list args; + va_start(args, fmt); + String8 text = push_str8fv(arena, fmt, args); + va_end(args); + eval_error(arena, list, kind, location, text); +} + +internal void +eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push){ + if (dst->last != 0){ + if (to_push->last != 0){ + dst->last->next = to_push->first; + dst->last = to_push->last; + dst->count += to_push->count; + } + } + else{ + *dst = *to_push; + } + MemoryZeroStruct(to_push); +} + +//////////////////////////////// +//~ rjf: Map Functions + +//- rjf: string -> num + +internal EVAL_String2NumMap +eval_string2num_map_make(Arena *arena, U64 slot_count) +{ + EVAL_String2NumMap map = {0}; + map.slots_count = slot_count; + map.slots = push_array(arena, EVAL_String2NumMapSlot, map.slots_count); + return map; +} + +internal void +eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num) +{ + U64 hash = eval_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + EVAL_String2NumMapNode *existing_node = 0; + for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) + { + if(str8_match(node->string, string, 0) && node->num == num) + { + existing_node = node; + break; + } + } + if(existing_node == 0) + { + EVAL_String2NumMapNode *node = push_array(arena, EVAL_String2NumMapNode, 1); + SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); + SLLQueuePush_N(map->first, map->last, node, order_next); + node->string = push_str8_copy(arena, string); + node->num = num; + } +} + +internal U64 +eval_num_from_string(EVAL_String2NumMap *map, String8 string) +{ + U64 num = 0; + if(map->slots_count != 0) + { + U64 hash = eval_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + EVAL_String2NumMapNode *existing_node = 0; + for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) + { + if(str8_match(node->string, string, 0)) + { + existing_node = node; + break; + } + } + if(existing_node != 0) + { + num = existing_node->num; + } + } + return num; +} + +//- rjf: string -> expr + +internal EVAL_String2ExprMap +eval_string2expr_map_make(Arena *arena, U64 slot_count) +{ + EVAL_String2ExprMap map = {0}; + map.slots_count = slot_count; + map.slots = push_array(arena, EVAL_String2ExprMapSlot, map.slots_count); + return map; +} + +internal void +eval_string2expr_map_insert(Arena *arena, EVAL_String2ExprMap *map, String8 string, EVAL_Expr *expr) +{ + U64 hash = eval_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + EVAL_String2ExprMapNode *existing_node = 0; + for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first; + node != 0; + node = node->hash_next) + { + if(str8_match(node->string, string, 0)) + { + existing_node = node; + break; + } + } + if(existing_node == 0) + { + EVAL_String2ExprMapNode *node = push_array(arena, EVAL_String2ExprMapNode, 1); + SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); + node->string = push_str8_copy(arena, string); + existing_node = node; + } + existing_node->expr = expr; +} + +internal EVAL_Expr * +eval_expr_from_string(EVAL_String2ExprMap *map, String8 string) +{ + EVAL_Expr *expr = &eval_expr_nil; + if(map->slots_count != 0) + { + U64 hash = eval_hash_from_string(string); + U64 slot_idx = hash%map->slots_count; + EVAL_String2ExprMapNode *existing_node = 0; + for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) + { + if(str8_match(node->string, string, 0)) + { + existing_node = node; + break; + } + } + if(existing_node != 0) + { + expr = existing_node->expr; + } + } + return expr; +} diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h new file mode 100644 index 00000000..6213ead1 --- /dev/null +++ b/src/eval/eval_core.h @@ -0,0 +1,217 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef EVAL_CORE_H +#define EVAL_CORE_H + +//////////////////////////////// +//~ rjf: Errors + +typedef enum EVAL_ErrorKind +{ + EVAL_ErrorKind_Null, + EVAL_ErrorKind_MalformedInput, + EVAL_ErrorKind_MissingInfo, + EVAL_ErrorKind_ResolutionFailure, + EVAL_ErrorKind_COUNT +} +EVAL_ErrorKind; + +typedef struct EVAL_Error EVAL_Error; +struct EVAL_Error +{ + EVAL_Error *next; + EVAL_ErrorKind kind; + void *location; + String8 text; +}; + +typedef struct EVAL_ErrorList EVAL_ErrorList; +struct EVAL_ErrorList +{ + EVAL_Error *first; + EVAL_Error *last; + EVAL_ErrorKind max_kind; + U64 count; +}; + +//////////////////////////////// +//~ rjf: Operation Types + +enum +{ + EVAL_IRExtKind_Bytecode = RADDBG_EvalOp_COUNT, + EVAL_IRExtKind_COUNT +}; + +typedef struct EVAL_Op EVAL_Op; +struct EVAL_Op +{ + EVAL_Op *next; + RADDBG_EvalOp opcode; + union + { + U64 p; + String8 bytecode; + }; +}; + +typedef struct EVAL_OpList EVAL_OpList; +struct EVAL_OpList +{ + EVAL_Op *first_op; + EVAL_Op *last_op; + U32 op_count; + U32 encoded_size; +}; + +//////////////////////////////// +//~ rjf: Generated Code + +#include "eval/generated/eval.meta.h" + +//////////////////////////////// +//~ rjf: Expression Tree Types + +typedef enum EVAL_EvalMode +{ + EVAL_EvalMode_NULL, + EVAL_EvalMode_Value, + EVAL_EvalMode_Addr, + EVAL_EvalMode_Reg +} +EVAL_EvalMode; + +typedef struct EVAL_Expr EVAL_Expr; +struct EVAL_Expr +{ + EVAL_ExprKind kind; + void *location; + union + { + EVAL_Expr *children[3]; + U32 u32; + U64 u64; + F32 f32; + F64 f64; + struct + { + EVAL_Expr *child; + U64 u64; + } child_and_constant; + String8 name; + struct + { + TG_Key type_key; + String8 bytecode; + EVAL_EvalMode mode; + }; + }; +}; + +//////////////////////////////// +//~ rjf: IR Tree Types + +typedef struct EVAL_IRTree EVAL_IRTree; +struct EVAL_IRTree{ + RADDBG_EvalOp op; + EVAL_IRTree *children[3]; + union{ + U64 p; + String8 bytecode; + }; +}; + +typedef struct EVAL_IRTreeAndType EVAL_IRTreeAndType; +struct EVAL_IRTreeAndType{ + EVAL_IRTree *tree; + TG_Key type_key; + EVAL_EvalMode mode; +}; + +//////////////////////////////// +//~ rjf: Map Types + +//- rjf: string -> num + +typedef struct EVAL_String2NumMapNode EVAL_String2NumMapNode; +struct EVAL_String2NumMapNode +{ + EVAL_String2NumMapNode *order_next; + EVAL_String2NumMapNode *hash_next; + String8 string; + U64 num; +}; + +typedef struct EVAL_String2NumMapSlot EVAL_String2NumMapSlot; +struct EVAL_String2NumMapSlot +{ + EVAL_String2NumMapNode *first; + EVAL_String2NumMapNode *last; +}; + +typedef struct EVAL_String2NumMap EVAL_String2NumMap; +struct EVAL_String2NumMap +{ + U64 slots_count; + EVAL_String2NumMapSlot *slots; + EVAL_String2NumMapNode *first; + EVAL_String2NumMapNode *last; +}; + +//- rjf: string -> expr + +typedef struct EVAL_String2ExprMapNode EVAL_String2ExprMapNode; +struct EVAL_String2ExprMapNode +{ + EVAL_String2ExprMapNode *hash_next; + String8 string; + EVAL_Expr *expr; +}; + +typedef struct EVAL_String2ExprMapSlot EVAL_String2ExprMapSlot; +struct EVAL_String2ExprMapSlot +{ + EVAL_String2ExprMapNode *first; + EVAL_String2ExprMapNode *last; +}; + +typedef struct EVAL_String2ExprMap EVAL_String2ExprMap; +struct EVAL_String2ExprMap +{ + U64 slots_count; + EVAL_String2ExprMapSlot *slots; +}; + +//////////////////////////////// +//~ rjf: Globals + +global read_only EVAL_Expr eval_expr_nil = {0}; +global read_only EVAL_IRTree eval_irtree_nil = {0}; + +//////////////////////////////// +//~ rjf: Basic Functions + +internal U64 eval_hash_from_string(String8 string); + +//////////////////////////////// +//~ rjf: Error List Building Functions + +internal void eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text); +internal void eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...); +internal void eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push); + +//////////////////////////////// +//~ rjf: Map Functions + +//- rjf: string -> num +internal EVAL_String2NumMap eval_string2num_map_make(Arena *arena, U64 slot_count); +internal void eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num); +internal U64 eval_num_from_string(EVAL_String2NumMap *map, String8 string); + +//- rjf: string -> expr +internal EVAL_String2ExprMap eval_string2expr_map_make(Arena *arena, U64 slot_count); +internal void eval_string2expr_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, EVAL_Expr *expr); +internal EVAL_Expr *eval_expr_from_string(EVAL_String2ExprMap *map, String8 string); + +#endif // EVAL_CORE_H diff --git a/src/eval/eval_inc.c b/src/eval/eval_inc.c new file mode 100644 index 00000000..791890a7 --- /dev/null +++ b/src/eval/eval_inc.c @@ -0,0 +1,7 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#include "eval/eval_core.c" +#include "eval/eval_compiler.c" +#include "eval/eval_machine.c" +#include "eval/eval_parser.c" diff --git a/src/eval/eval_inc.h b/src/eval/eval_inc.h new file mode 100644 index 00000000..56c2c648 --- /dev/null +++ b/src/eval/eval_inc.h @@ -0,0 +1,12 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +#ifndef EVAL_INC_H +#define EVAL_INC_H + +#include "eval/eval_core.h" +#include "eval/eval_compiler.h" +#include "eval/eval_machine.h" +#include "eval/eval_parser.h" + +#endif // EVAL_INC_H diff --git a/src/eval/eval_parser.c b/src/eval/eval_parser.c index f7b536f3..1d134bb7 100644 --- a/src/eval/eval_parser.c +++ b/src/eval/eval_parser.c @@ -48,85 +48,11 @@ global read_only struct {EVAL_ExprKind kind; String8 string; S64 precedence;} ev { EVAL_ExprKind_BitOr, str8_lit_comp("|"), 10 }, { EVAL_ExprKind_LogAnd, str8_lit_comp("&&"), 11 }, { EVAL_ExprKind_LogOr, str8_lit_comp("||"), 12 }, + { EVAL_ExprKind_Define, str8_lit_comp("="), 13 }, }; global read_only S64 eval_g_max_precedence = 15; -//////////////////////////////// -//~ rjf: Basic Functions - -internal U64 -eval_hash_from_string(String8 string) -{ - U64 result = 5381; - for(U64 i = 0; i < string.size; i += 1) - { - result = ((result << 5) + result) + string.str[i]; - } - return result; -} - -//////////////////////////////// -//~ rjf: Map Functions - -internal EVAL_String2NumMap -eval_string2num_map_make(Arena *arena, U64 slot_count) -{ - EVAL_String2NumMap map = {0}; - map.slots_count = slot_count; - map.slots = push_array(arena, EVAL_String2NumMapSlot, map.slots_count); - return map; -} - -internal void -eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num) -{ - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - EVAL_String2NumMapNode *existing_node = 0; - for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0) && node->num == num) - { - existing_node = node; - break; - } - } - if(existing_node == 0) - { - EVAL_String2NumMapNode *node = push_array(arena, EVAL_String2NumMapNode, 1); - SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); - SLLQueuePush_N(map->first, map->last, node, order_next); - node->string = push_str8_copy(arena, string); - node->num = num; - } -} - -internal U64 -eval_num_from_string(EVAL_String2NumMap *map, String8 string) -{ - U64 num = 0; - if(map->slots_count != 0) - { - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - EVAL_String2NumMapNode *existing_node = 0; - for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0)) - { - existing_node = node; - break; - } - } - if(existing_node != 0) - { - num = existing_node->num; - } - } - return num; -} - //////////////////////////////// //~ rjf: Map Building Fast Paths @@ -1210,10 +1136,10 @@ eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8 } } - // rjf: error on map failure - if(mapped_identifier == 0) + //- rjf: map failure -> attach as leaf identifier, to be resolved later + if(!mapped_identifier) { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_ResolutionFailure, token_string.str, "Unknown identifier \"%S\".", token_string); + atom = eval_expr_leaf_ident(arena, token_string.str, token_string); it += 1; } }break; diff --git a/src/eval/eval_parser.h b/src/eval/eval_parser.h index 3bf24c08..b711da0b 100644 --- a/src/eval/eval_parser.h +++ b/src/eval/eval_parser.h @@ -1,36 +1,8 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -#ifndef EVAL2_PARSER_H -#define EVAL2_PARSER_H - -//////////////////////////////// -//~ rjf: Maps - -typedef struct EVAL_String2NumMapNode EVAL_String2NumMapNode; -struct EVAL_String2NumMapNode -{ - EVAL_String2NumMapNode *order_next; - EVAL_String2NumMapNode *hash_next; - String8 string; - U64 num; -}; - -typedef struct EVAL_String2NumMapSlot EVAL_String2NumMapSlot; -struct EVAL_String2NumMapSlot -{ - EVAL_String2NumMapNode *first; - EVAL_String2NumMapNode *last; -}; - -typedef struct EVAL_String2NumMap EVAL_String2NumMap; -struct EVAL_String2NumMap -{ - U64 slots_count; - EVAL_String2NumMapSlot *slots; - EVAL_String2NumMapNode *first; - EVAL_String2NumMapNode *last; -}; +#ifndef EVAL_PARSER_H +#define EVAL_PARSER_H //////////////////////////////// //~ rjf: Token Types @@ -107,20 +79,9 @@ struct EVAL_ParseCtx //~ rjf: Globals read_only global EVAL_String2NumMap eval_string2num_map_nil = {0}; +read_only global EVAL_String2ExprMap eval_string2expr_map_nil = {0}; global read_only EVAL_ParseResult eval_parse_result_nil = {0, &eval_expr_nil}; -//////////////////////////////// -//~ rjf: Basic Functions - -internal U64 eval_hash_from_string(String8 string); - -//////////////////////////////// -//~ rjf: Map Functions - -internal EVAL_String2NumMap eval_string2num_map_make(Arena *arena, U64 slot_count); -internal void eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num); -internal U64 eval_num_from_string(EVAL_String2NumMap *map, String8 string); - //////////////////////////////// //~ rjf: Debug-Info-Driven Map Building Fast Paths @@ -145,4 +106,4 @@ internal EVAL_ParseResult eval_parse_type_from_text_tokens(Arena *arena, EVAL_Pa internal EVAL_ParseResult eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens, S64 max_precedence); internal EVAL_ParseResult eval_parse_expr_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens); -#endif // EVAL2_PARSER_H +#endif // EVAL_PARSER_H diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 5e7d648d..418412c8 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -46,6 +46,8 @@ EVAL_ExprKind_TypeIdent, EVAL_ExprKind_Ptr, EVAL_ExprKind_Array, EVAL_ExprKind_Func, +EVAL_ExprKind_Define, +EVAL_ExprKind_LeafIdent, EVAL_ExprKind_COUNT }; @@ -88,6 +90,8 @@ U8 eval_expr_kind_child_counts[] = 1, 2, 1, +2, +0, }; String8 eval_expr_kind_strings[] = @@ -129,6 +133,8 @@ str8_lit_comp("TypeIdent"), str8_lit_comp("Ptr"), str8_lit_comp("Array"), str8_lit_comp("Func"), +str8_lit_comp("Define"), +str8_lit_comp("LeafIdent"), }; String8 eval_expr_op_strings[] = @@ -170,6 +176,8 @@ str8_lit_comp("type_ident"), str8_lit_comp("ptr"), str8_lit_comp("array"), str8_lit_comp("function"), +str8_lit_comp("="), +str8_lit_comp("leaf_ident"), }; diff --git a/src/raddbg/raddbg_main.cpp b/src/raddbg/raddbg_main.cpp index 471e4e9d..922c3c2f 100644 --- a/src/raddbg/raddbg_main.cpp +++ b/src/raddbg/raddbg_main.cpp @@ -1,3 +1,6 @@ +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + //////////////////////////////// //~ rjf: Includes @@ -29,9 +32,7 @@ #include "type_graph/type_graph.h" #include "dbgi/dbgi.h" #include "demon/demon_inc.h" -#include "eval/eval_compiler.h" -#include "eval/eval_machine.h" -#include "eval/eval_parser.h" +#include "eval/eval_inc.h" #include "unwind/unwind.h" #include "ctrl/ctrl_inc.h" #include "dasm/dasm.h" @@ -72,9 +73,7 @@ #include "type_graph/type_graph.c" #include "dbgi/dbgi.c" #include "demon/demon_inc.c" -#include "eval/eval_compiler.c" -#include "eval/eval_machine.c" -#include "eval/eval_parser.c" +#include "eval/eval_inc.c" #include "unwind/unwind.c" #include "ctrl/ctrl_inc.c" #include "dasm/dasm.c" @@ -276,7 +275,7 @@ win32_exception_filter(EXCEPTION_POINTERS* exception_ptrs) } } } - + buflen += wnsprintfW(buffer + buflen, ArrayCount(buffer) - buflen, L"\nVersion: %S%S", RADDBG_VERSION_STRING_LITERAL, RADDBG_GIT_STR); TASKDIALOGCONFIG dialog = {0}; diff --git a/src/ui/ui_basic_widgets.c b/src/ui/ui_basic_widgets.c index df726de4..417abf17 100644 --- a/src/ui/ui_basic_widgets.c +++ b/src/ui/ui_basic_widgets.c @@ -174,6 +174,8 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, ui_push_focus_active(is_auto_focus_active ? UI_FocusKind_On : UI_FocusKind_Null); B32 is_focus_hot = ui_is_focus_hot(); B32 is_focus_active = ui_is_focus_active(); + B32 is_focus_hot_disabled = (!is_focus_hot && ui_top_focus_hot() == UI_FocusKind_On); + B32 is_focus_active_disabled = (!is_focus_active && ui_top_focus_active() == UI_FocusKind_On); //- rjf: build top-level box ui_set_next_hover_cursor(is_focus_active ? OS_Cursor_IBar : OS_Cursor_HandPoint); @@ -183,7 +185,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, UI_BoxFlag_ClickToFocus| ((is_auto_focus_hot || is_auto_focus_active)*UI_BoxFlag_KeyboardClickable)| UI_BoxFlag_DrawHotEffects| - is_focus_active*(UI_BoxFlag_Clip|UI_BoxFlag_AllowOverflowX|UI_BoxFlag_ViewClamp), + (is_focus_active || is_focus_active_disabled)*(UI_BoxFlag_Clip|UI_BoxFlag_AllowOverflowX|UI_BoxFlag_ViewClamp), key); //- rjf: take navigation actions for editing @@ -240,7 +242,7 @@ ui_line_edit(TxtPt *cursor, TxtPt *mark, U8 *edit_buffer, U64 edit_buffer_size, UI_Parent(box) { String8 edit_string = str8(edit_buffer, edit_string_size_out[0]); - if(!is_focus_active) + if(!is_focus_active && !is_focus_active_disabled) { String8 display_string = ui_display_part_from_key_string(string); if(pre_edit_value.size != 0) diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index bfc32221..0ee5cf2b 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1159,6 +1159,7 @@ ui_end_build(void) box->first_touched_build_index == box->first_disabled_build_index); B32 is_focus_hot = !!(box->flags & UI_BoxFlag_FocusHot) && !(box->flags & UI_BoxFlag_FocusHotDisabled); B32 is_focus_active = !!(box->flags & UI_BoxFlag_FocusActive) && !(box->flags & UI_BoxFlag_FocusActiveDisabled); + B32 is_focus_active_disabled = !!(box->flags & UI_BoxFlag_FocusActiveDisabled); // rjf: determine rates F32 hot_rate = fast_rate; @@ -1173,15 +1174,16 @@ ui_end_build(void) box_is_animating = (box_is_animating || abs_f32((F32)is_disabled - box->disabled_t) > 0.01f); box_is_animating = (box_is_animating || abs_f32((F32)is_focus_hot - box->focus_hot_t) > 0.01f); box_is_animating = (box_is_animating || abs_f32((F32)is_focus_active - box->focus_active_t) > 0.01f); + box_is_animating = (box_is_animating || abs_f32((F32)is_focus_active_disabled - box->focus_active_disabled_t) > 0.01f); box_is_animating = (box_is_animating || abs_f32(box->view_off_target.x - box->view_off.x) > 0.5f); box_is_animating = (box_is_animating || abs_f32(box->view_off_target.y - box->view_off.y) > 0.5f); if(box->flags & UI_BoxFlag_AnimatePosX) { - box_is_animating = (box_is_animating || fabsf(box->fixed_position_animated.x - box->fixed_position.x) > 0.5f); + box_is_animating = (box_is_animating || abs_f32(box->fixed_position_animated.x - box->fixed_position.x) > 0.5f); } if(box->flags & UI_BoxFlag_AnimatePosY) { - box_is_animating = (box_is_animating || fabsf(box->fixed_position_animated.y - box->fixed_position.y) > 0.5f); + box_is_animating = (box_is_animating || abs_f32(box->fixed_position_animated.y - box->fixed_position.y) > 0.5f); } ui_state->is_animating = (ui_state->is_animating || box_is_animating); #if 0 // NOTE(rjf): enable to debug animation-causing-frames (or not) @@ -1193,21 +1195,22 @@ ui_end_build(void) #endif // rjf: animate interaction transition states - box->hot_t += hot_rate * ((F32)is_hot - box->hot_t); - box->active_t += active_rate * ((F32)is_active - box->active_t); - box->disabled_t += disabled_rate * ((F32)is_disabled - box->disabled_t); - box->focus_hot_t += focus_rate * ((F32)is_focus_hot - box->focus_hot_t); - box->focus_active_t += focus_rate * ((F32)is_focus_active - box->focus_active_t); + box->hot_t += hot_rate * ((F32)is_hot - box->hot_t); + box->active_t += active_rate * ((F32)is_active - box->active_t); + box->disabled_t += disabled_rate * ((F32)is_disabled - box->disabled_t); + box->focus_hot_t += focus_rate * ((F32)is_focus_hot - box->focus_hot_t); + box->focus_active_t += focus_rate * ((F32)is_focus_active - box->focus_active_t); + box->focus_active_disabled_t += focus_rate * ((F32)is_focus_active_disabled - box->focus_active_disabled_t); // rjf: animate positions { box->fixed_position_animated.x += fast_rate * (box->fixed_position.x - box->fixed_position_animated.x); box->fixed_position_animated.y += fast_rate * (box->fixed_position.y - box->fixed_position_animated.y); - if(fabsf(box->fixed_position.x - box->fixed_position_animated.x) < 1) + if(abs_f32(box->fixed_position.x - box->fixed_position_animated.x) < 1) { box->fixed_position_animated.x = box->fixed_position.x; } - if(fabsf(box->fixed_position.y - box->fixed_position_animated.y) < 1) + if(abs_f32(box->fixed_position.y - box->fixed_position_animated.y) < 1) { box->fixed_position_animated.y = box->fixed_position.y; } @@ -1229,11 +1232,11 @@ ui_end_build(void) { box->view_off.x += fast_rate * (box->view_off_target.x - box->view_off.x); box->view_off.y += fast_rate * (box->view_off_target.y - box->view_off.y); - if(fabsf(box->view_off.x - box->view_off_target.x) < 2) + if(abs_f32(box->view_off.x - box->view_off_target.x) < 2) { box->view_off.x = box->view_off_target.x; } - if(fabsf(box->view_off.y - box->view_off_target.y) < 2) + if(abs_f32(box->view_off.y - box->view_off_target.y) < 2) { box->view_off.y = box->view_off_target.y; } @@ -1310,6 +1313,8 @@ ui_end_build(void) } //- rjf: hovering possibly-truncated drawn text -> store text + if(ui_key_match(ui_key_zero(), ui_state->active_box_key[Side_Min]) && + ui_key_match(ui_key_zero(), ui_state->active_box_key[Side_Max])) { B32 found = 0; for(UI_Box *box = ui_state->root, *next = 0; !ui_box_is_nil(box); box = next) diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 1eff61f2..1d4663a1 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -306,6 +306,7 @@ struct UI_Box F32 disabled_t; F32 focus_hot_t; F32 focus_active_t; + F32 focus_active_disabled_t; Vec2F32 view_off; Vec2F32 view_off_target; Vec2F32 view_bounds;