more work on file evaluation; move eval_string <-> eval <-> file_path to formal filesystem/file spaces, rather than inferring from the expression tree; imply '.data' when generating file contents visualizer tabs

This commit is contained in:
Ryan Fleury
2025-02-16 18:36:45 -08:00
parent 5e98e40af7
commit c77f2de156
6 changed files with 132 additions and 48 deletions
+2 -1
View File
@@ -93,8 +93,9 @@ typedef U64 E_SpaceKind;
enum enum
{ {
E_SpaceKind_Null, E_SpaceKind_Null,
E_SpaceKind_HashStoreKey, E_SpaceKind_File,
E_SpaceKind_FileSystem, E_SpaceKind_FileSystem,
E_SpaceKind_HashStoreKey,
E_SpaceKind_FirstUserDefined, E_SpaceKind_FirstUserDefined,
}; };
+50 -24
View File
@@ -234,6 +234,43 @@ E_LOOKUP_INFO_FUNCTION_DEF(file)
return info; return info;
} }
E_LOOKUP_ACCESS_FUNCTION_DEF(file)
{
E_LookupAccess result = {{&e_irnode_nil}};
if(kind == E_ExprKind_MemberAccess)
{
E_FileAccel *accel = (E_FileAccel *)user_data;
String8 member_name = rhs->string;
if(str8_match(member_name, str8_lit("size"), 0))
{
result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.size);
result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64);
result.irtree_and_type.mode = E_Mode_Value;
}
else if(str8_match(member_name, str8_lit("last_modified_time"), 0))
{
result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.modified);
result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64);
result.irtree_and_type.mode = E_Mode_Value;
}
else if(str8_match(member_name, str8_lit("creation_time"), 0))
{
result.irtree_and_type.root = e_irtree_const_u(arena, accel->props.created);
result.irtree_and_type.type_key = e_type_key_basic(E_TypeKind_U64);
result.irtree_and_type.mode = E_Mode_Value;
}
else if(str8_match(member_name, str8_lit("data"), 0))
{
E_Space space = e_space_make(E_SpaceKind_File);
space.u64_0 = e_id_from_string(accel->file_path);
result.irtree_and_type.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0));
result.irtree_and_type.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size);
result.irtree_and_type.mode = E_Mode_Offset;
}
}
return result;
}
E_LOOKUP_RANGE_FUNCTION_DEF(file) E_LOOKUP_RANGE_FUNCTION_DEF(file)
{ {
E_FileAccel *accel = (E_FileAccel *)user_data; E_FileAccel *accel = (E_FileAccel *)user_data;
@@ -245,29 +282,11 @@ E_LOOKUP_RANGE_FUNCTION_DEF(file)
if(0 <= idx && idx < accel->fields.count) if(0 <= idx && idx < accel->fields.count)
{ {
String8 name = accel->fields.v[idx]; String8 name = accel->fields.v[idx];
if(str8_match(name, str8_lit("size"), 0)) expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0);
{ E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0);
expr = e_push_expr(arena, E_ExprKind_LeafU64, 0); rhs->string = push_str8_copy(arena, name);
expr->value.u64 = accel->props.size; e_expr_push_child(expr, e_expr_ref(arena, lhs));
} e_expr_push_child(expr, rhs);
else if(str8_match(name, str8_lit("last_modified_time"), 0))
{
expr = e_push_expr(arena, E_ExprKind_LeafU64, 0);
expr->value.u64 = accel->props.modified;
}
else if(str8_match(name, str8_lit("creation_time"), 0))
{
expr = e_push_expr(arena, E_ExprKind_LeafU64, 0);
expr->value.u64 = accel->props.created;
}
else if(str8_match(name, str8_lit("data"), 0))
{
expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0);
expr->space = e_space_make(E_SpaceKind_HashStoreKey);
expr->space.u128 = fs_key_from_path_range(accel->file_path, r1u64(0, max_U64));
expr->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size);
}
string = push_str8f(arena, ".%S", name);
} }
exprs[out_idx] = expr; exprs[out_idx] = expr;
exprs_strings[out_idx] = string; exprs_strings[out_idx] = string;
@@ -401,6 +420,7 @@ e_lookup_rule_map_make(Arena *arena, U64 slots_count)
.range = E_LOOKUP_RANGE_FUNCTION_NAME(folder)); .range = E_LOOKUP_RANGE_FUNCTION_NAME(folder));
e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"), e_lookup_rule_map_insert_new(arena, &map, str8_lit("file"),
.info = E_LOOKUP_INFO_FUNCTION_NAME(file), .info = E_LOOKUP_INFO_FUNCTION_NAME(file),
.access = E_LOOKUP_ACCESS_FUNCTION_NAME(file),
.range = E_LOOKUP_RANGE_FUNCTION_NAME(file)); .range = E_LOOKUP_RANGE_FUNCTION_NAME(file));
e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"), e_lookup_rule_map_insert_new(arena, &map, str8_lit("slice"),
.info = E_LOOKUP_INFO_FUNCTION_NAME(slice), .info = E_LOOKUP_INFO_FUNCTION_NAME(slice),
@@ -2203,7 +2223,7 @@ E_IRGEN_FUNCTION_DEF(default)
//- rjf: leaf file paths //- rjf: leaf file paths
case E_ExprKind_LeafFilePath: case E_ExprKind_LeafFilePath:
{ {
FileProperties props = fs_properties_from_path(expr->string); FileProperties props = os_properties_from_file_path(expr->string);
if(props.flags & FilePropertyFlag_IsFolder) if(props.flags & FilePropertyFlag_IsFolder)
{ {
E_Space space = e_space_make(E_SpaceKind_FileSystem); E_Space space = e_space_make(E_SpaceKind_FileSystem);
@@ -2213,6 +2233,11 @@ E_IRGEN_FUNCTION_DEF(default)
} }
else else
{ {
E_Space space = e_space_make(E_SpaceKind_FileSystem);
result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(expr->string)));
result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file"));
result.mode = E_Mode_Value;
#if 0
U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64)); U128 key = fs_key_from_path_range(expr->string, r1u64(0, max_U64));
E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key}; E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key};
U64 size = props.size; U64 size = props.size;
@@ -2222,6 +2247,7 @@ E_IRGEN_FUNCTION_DEF(default)
result.root->string = push_str8_copy(arena, expr->string); result.root->string = push_str8_copy(arena, expr->string);
result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size); result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size);
result.mode = E_Mode_Offset; result.mode = E_Mode_Offset;
#endif
} }
}break; }break;
@@ -584,6 +584,14 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai
expansion_row_count = expand_info.row_count; expansion_row_count = expand_info.row_count;
} }
// rjf: determine if this expansion supports child expansions
B32 allow_child_expansions = 1;
if(expand_info.single_item)
{
// NOTE(rjf): for now, just plugging in the heuristic of "is this a single row (a.k.a. visualizer)?"
allow_child_expansions = 0;
}
// rjf: generate block for expansion // rjf: generate block for expansion
EV_Block *expansion_block = &ev_nil_block; EV_Block *expansion_block = &ev_nil_block;
if(expansion_row_count != 0) if(expansion_row_count != 0)
@@ -612,7 +620,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai
U64 child_count = 0; U64 child_count = 0;
EV_Key *child_keys = 0; EV_Key *child_keys = 0;
U64 *child_nums = 0; U64 *child_nums = 0;
if(!child_count && !expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0) if(allow_child_expansions && !child_count && !expand_info.rows_default_expanded && expand_node != 0 && expansion_row_count != 0)
{ {
// rjf: count children // rjf: count children
for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){} for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){}
@@ -659,7 +667,7 @@ ev_block_tree_from_exprs(Arena *arena, EV_View *view, String8 filter, E_ExprChai
} }
// rjf: gather children expansions from inverse of expansion state // rjf: gather children expansions from inverse of expansion state
if(!child_count && (expand_info.rows_default_expanded || (expand_node == 0 && !expand_info.rows_default_expanded))) if(allow_child_expansions && !child_count && (expand_info.rows_default_expanded || (expand_node == 0 && !expand_info.rows_default_expanded)))
{ {
child_count = expand_info.row_count; child_count = expand_info.row_count;
child_keys = push_array(scratch.arena, EV_Key, child_count); child_keys = push_array(scratch.arena, EV_Key, child_count);
+68 -20
View File
@@ -3010,7 +3010,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
B32 result = 0; B32 result = 0;
switch(space.kind) switch(space.kind)
{ {
//- rjf: filesystem reads //- rjf: reads from hash store key
case E_SpaceKind_HashStoreKey: case E_SpaceKind_HashStoreKey:
{ {
U128 key = space.u128; U128 key = space.u128;
@@ -3029,6 +3029,27 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range)
hs_scope_close(scope); hs_scope_close(scope);
}break; }break;
//- rjf: file reads
case E_SpaceKind_File:
{
U64 file_path_string_id = space.u64_0;
String8 file_path = e_string_from_id(file_path_string_id);
U128 key = fs_key_from_path_range(file_path, range);
U128 hash = hs_hash_from_key(key, 0);
HS_Scope *scope = hs_scope_open();
{
String8 data = hs_data_from_hash(scope, hash);
Rng1U64 legal_range = r1u64(0, data.size);
Rng1U64 read_range = intersect_1u64(range, legal_range);
if(read_range.min < read_range.max)
{
result = 1;
MemoryCopy(out, data.str + read_range.min, dim_1u64(read_range));
}
}
hs_scope_close(scope);
}break;
//- rjf: interior control entity reads (inside process address space or thread register block) //- rjf: interior control entity reads (inside process address space or thread register block)
case RD_EvalSpaceKind_CtrlEntity: case RD_EvalSpaceKind_CtrlEntity:
{ {
@@ -3301,6 +3322,12 @@ rd_key_from_eval_space_range(E_Space space, Rng1U64 range, B32 zero_terminated)
{ {
result = space.u128; result = space.u128;
}break; }break;
case E_SpaceKind_File:
{
U64 file_path_string_id = space.u64_0;
String8 file_path = e_string_from_id(file_path_string_id);
result = fs_key_from_path_range(file_path, range);
}break;
case RD_EvalSpaceKind_CtrlEntity: case RD_EvalSpaceKind_CtrlEntity:
{ {
CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space);
@@ -3323,19 +3350,21 @@ rd_whole_range_from_eval_space(E_Space space)
{ {
case E_SpaceKind_HashStoreKey: case E_SpaceKind_HashStoreKey:
{ {
HS_Scope *scope = hs_scope_open(); U128 key = space.u128;
U128 hash = {0}; U128 hash = hs_hash_from_key(key, 0);
for(U64 idx = 0; idx < 2; idx += 1) HS_Scope *hs_scope = hs_scope_open();
{ {
hash = hs_hash_from_key(space.u128, idx); String8 data = hs_data_from_hash(hs_scope, hash);
if(!u128_match(hash, u128_zero())) result = r1u64(0, data.size);
{
break;
}
} }
String8 data = hs_data_from_hash(scope, hash); hs_scope_close(hs_scope);
result = r1u64(0, data.size); }break;
hs_scope_close(scope); case E_SpaceKind_File:
{
U64 file_path_string_id = space.u64_0;
String8 file_path = e_string_from_id(file_path_string_id);
FileProperties props = os_properties_from_file_path(file_path);
result = r1u64(0, props.size);
}break; }break;
case RD_EvalSpaceKind_CtrlEntity: case RD_EvalSpaceKind_CtrlEntity:
{ {
@@ -3463,17 +3492,33 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_un
//- rjf: eval <-> file path //- rjf: eval <-> file path
internal String8
rd_file_path_from_eval(Arena *arena, E_Eval eval)
{
String8 result = {0};
switch(eval.space.kind)
{
default:{}break;
case E_SpaceKind_File:
{
result = push_str8_copy(arena, e_string_from_id(eval.space.u64_0));
}break;
case E_SpaceKind_FileSystem:
{
result = push_str8_copy(arena, e_string_from_id(eval.value.u64));
}break;
}
return result;
}
internal String8 internal String8
rd_file_path_from_eval_string(Arena *arena, String8 string) rd_file_path_from_eval_string(Arena *arena, String8 string)
{ {
String8 result = {0}; String8 result = {0};
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
E_Expr *expr = e_parse_expr_from_text(scratch.arena, string).exprs.last; E_Eval eval = e_eval_from_string(scratch.arena, string);
if(expr->kind == E_ExprKind_LeafFilePath) result = rd_file_path_from_eval(arena, eval);
{
result = raw_from_escaped_str8(arena, expr->string);
}
scratch_end(scratch); scratch_end(scratch);
} }
return result; return result;
@@ -3484,7 +3529,7 @@ rd_eval_string_from_file_path(Arena *arena, String8 string)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
String8 string_escaped = escaped_from_raw_str8(scratch.arena, string); String8 string_escaped = escaped_from_raw_str8(scratch.arena, string);
String8 result = push_str8f(arena, "file:\"%S\"", string_escaped); String8 result = push_str8f(arena, "file:\"%S\".data", string_escaped);
scratch_end(scratch); scratch_end(scratch);
return result; return result;
} }
@@ -3933,9 +3978,11 @@ internal TXT_LangKind
rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag) rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag)
{ {
TXT_LangKind lang_kind = TXT_LangKind_Null; TXT_LangKind lang_kind = TXT_LangKind_Null;
if(eval.exprs.last->kind == E_ExprKind_LeafFilePath) Temp scratch = scratch_begin(0, 0);
String8 file_path = rd_file_path_from_eval(scratch.arena, eval);
if(file_path.size != 0)
{ {
lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(eval.exprs.last->string)); lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(file_path));
} }
else for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next) else for(E_Expr *param = tag->first->next; param != &e_expr_nil; param = param->next)
{ {
@@ -3945,6 +3992,7 @@ rd_lang_kind_from_eval_tag(E_Eval eval, E_Expr *tag)
break; break;
} }
} }
scratch_end(scratch);
return lang_kind; return lang_kind;
} }
+1
View File
@@ -1037,6 +1037,7 @@ internal Rng1U64 rd_whole_range_from_eval_space(E_Space space);
internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping); internal B32 rd_commit_eval_value_string(E_Eval dst_eval, String8 string, B32 string_needs_unescaping);
//- rjf: eval <-> file path //- rjf: eval <-> file path
internal String8 rd_file_path_from_eval(Arena *arena, E_Eval eval);
internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string); internal String8 rd_file_path_from_eval_string(Arena *arena, String8 string);
internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string); internal String8 rd_eval_string_from_file_path(Arena *arena, String8 string);
+1 -1
View File
@@ -2878,7 +2878,7 @@ RD_VIEW_UI_FUNCTION_DEF(watch)
RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression")); RD_Cfg *expr = rd_cfg_child_from_string_or_alloc(view, str8_lit("expression"));
rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last)); rd_cfg_new(expr, e_string_from_expr(scratch.arena, cell_info.eval.exprs.last));
rd_cfg_new(view, str8_lit("selected")); rd_cfg_new(view, str8_lit("selected"));
RD_RegsScope(.view = view->id) RD_RegsScope(.view = view->id, .file_path = rd_file_path_from_eval(scratch.arena, cell_info.eval))
UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX) UI_PermissionFlags(UI_PermissionFlag_Clicks|UI_PermissionFlag_ScrollX)
UI_Flags(0) UI_Flags(0)
{ {