checkpoint in moving from old lookup hooks -> new type hooks; elimination of unnecessary recomputation of ir-trees/evals, just use information in already-computed evals

This commit is contained in:
Ryan Fleury
2025-04-08 14:39:28 -07:00
parent fbd78525d2
commit d3f0a9a672
19 changed files with 3369 additions and 3200 deletions
+23 -31
View File
@@ -6,17 +6,9 @@
internal E_Eval
e_eval_from_expr(Arena *arena, E_Expr *expr)
{
E_ExprChain exprs = {expr, expr};
E_Eval result = e_eval_from_exprs(arena, exprs);
return result;
}
internal E_Eval
e_eval_from_exprs(Arena *arena, E_ExprChain exprs)
{
ProfBeginFunction();
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, exprs.last);
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
E_OpList oplist = e_oplist_from_irtree(arena, irtree.root);
String8 bytecode = e_bytecode_from_oplist(arena, &oplist);
E_Interpretation interp = e_interpret(bytecode);
@@ -24,7 +16,7 @@ e_eval_from_exprs(Arena *arena, E_ExprChain exprs)
{
.value = interp.value,
.space = interp.space,
.exprs = exprs,
.expr = expr,
.irtree = irtree,
.bytecode = bytecode,
.code = interp.code,
@@ -43,7 +35,7 @@ e_eval_from_string(Arena *arena, String8 string)
{
E_TokenArray tokens = e_token_array_from_text(arena, string);
E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens);
E_Eval eval = e_eval_from_exprs(arena, parse.exprs);
E_Eval eval = e_eval_from_expr(arena, parse.exprs.first);
e_msg_list_concat_in_place(&eval.msgs, &parse.msgs);
return eval;
}
@@ -252,22 +244,22 @@ e_value_from_expr(E_Expr *expr)
E_Value result = value_eval.value;
scratch_end(scratch);
return result;
}
}
////////////////////////////////
//~ rjf: Debug Logging Functions
internal String8
e_debug_log_from_expr_string(Arena *arena, String8 string)
{
Temp scratch = scratch_begin(&arena, 1);
char *indent_spaces = " ";
String8List strings = {0};
internal String8
e_debug_log_from_expr_string(Arena *arena, String8 string)
{
Temp scratch = scratch_begin(&arena, 1);
char *indent_spaces = " ";
String8List strings = {0};
//- rjf: begin expression
String8 expr_text = string;
str8_list_pushf(scratch.arena, &strings, "`%S`\n", expr_text);
//- rjf: tokenize
E_TokenArray tokens = e_token_array_from_text(scratch.arena, expr_text);
str8_list_pushf(scratch.arena, &strings, " tokens:\n");
@@ -277,7 +269,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string)
String8 token_string = str8_substr(expr_text, token.range);
str8_list_pushf(scratch.arena, &strings, " %S: `%S`\n", e_token_kind_strings[token.kind], token_string);
}
//- rjf: parse
E_Parse parse = e_parse_expr_from_text_tokens(scratch.arena, expr_text, tokens);
{
@@ -320,7 +312,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string)
}
}
}
//- rjf: type
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.first);
{
@@ -335,7 +327,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string)
str8_list_pushf(scratch.arena, &strings, "%.*s%S\n", (int)indent*4, indent_spaces, e_type_kind_basic_string_table[type->kind]);
}
}
//- rjf: irtree
{
typedef struct Task Task;
@@ -376,10 +368,10 @@ e_debug_log_from_expr_string(Arena *arena, String8 string)
}
}
}
str8_list_pushf(scratch.arena, &strings, "\n");
String8 result = str8_list_join(arena, &strings, 0);
scratch_end(scratch);
return result;
}
str8_list_pushf(scratch.arena, &strings, "\n");
String8 result = str8_list_join(arena, &strings, 0);
scratch_end(scratch);
return result;
}
+6 -2
View File
@@ -12,18 +12,22 @@ struct E_Eval
{
E_Value value;
E_Space space;
E_ExprChain exprs;
E_Expr *expr;
E_IRTreeAndType irtree;
String8 bytecode;
E_InterpretationCode code;
E_MsgList msgs;
};
////////////////////////////////
//~ rjf: Globals
read_only global E_Eval e_eval_nil = {zero_struct, zero_struct, &e_expr_nil, {&e_irnode_nil}};
////////////////////////////////
//~ rjf: Bundled Evaluation Functions
internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr);
internal E_Eval e_eval_from_exprs(Arena *arena, E_ExprChain exprs);
internal E_Eval e_eval_from_string(Arena *arena, String8 string);
internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...);
internal E_Eval e_autoresolved_eval_from_eval(E_Eval eval);
+22 -5
View File
@@ -268,6 +268,7 @@ struct E_IRTreeAndType
{
E_IRNode *root;
E_TypeKey type_key;
void *user_data;
E_Mode mode;
E_MsgList msgs;
};
@@ -288,7 +289,6 @@ typedef enum E_MemberKind
E_MemberKind_VirtualBase,
E_MemberKind_NestedType,
E_MemberKind_Padding,
E_MemberKind_Query,
E_MemberKind_COUNT
}
E_MemberKind;
@@ -357,6 +357,11 @@ struct E_TypeExpandInfo
U64 expr_count;
};
#define E_TYPE_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_IRTreeAndType *irtree)
#define E_TYPE_IRGEN_FUNCTION_NAME(name) e_type_irgen__##name
#define E_TYPE_IRGEN_FUNCTION_DEF(name) internal E_TYPE_IRGEN_FUNCTION_SIG(E_TYPE_IRGEN_FUNCTION_NAME(name))
typedef E_TYPE_IRGEN_FUNCTION_SIG(E_TypeIRGenFunctionType);
#define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_IRTreeAndType *lhs_irtree)
#define E_TYPE_ACCESS_FUNCTION_NAME(name) e_type_access__##name
#define E_TYPE_ACCESS_FUNCTION_DEF(name) internal E_TYPE_ACCESS_FUNCTION_SIG(E_TYPE_ACCESS_FUNCTION_NAME(name))
@@ -382,6 +387,15 @@ typedef E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_SIG(E_TypeExpandIDFromNumFunctionType
#define E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_SIG(E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name))
typedef E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_SIG(E_TypeExpandNumFromIDFunctionType);
typedef struct E_TypeExpandRule E_TypeExpandRule;
struct E_TypeExpandRule
{
E_TypeExpandInfoFunctionType *info;
E_TypeExpandRangeFunctionType *range;
E_TypeExpandIDFromNumFunctionType *id_from_num;
E_TypeExpandNumFromIDFunctionType *num_from_id;
};
typedef struct E_Type E_Type;
struct E_Type
{
@@ -399,11 +413,9 @@ struct E_Type
E_Member *members;
E_EnumVal *enum_vals;
E_Expr **args;
E_TypeIRGenFunctionType *irgen;
E_TypeAccessFunctionType *access;
E_TypeExpandInfoFunctionType *expand_info;
E_TypeExpandRangeFunctionType *expand_range;
E_TypeExpandIDFromNumFunctionType *expand_id_from_num;
E_TypeExpandNumFromIDFunctionType *expand_num_from_id;
E_TypeExpandRule expand;
};
////////////////////////////////
@@ -483,6 +495,8 @@ struct E_String2ExprMap
////////////////////////////////
//~ rjf: Member/Index Lookup Hooks
#if 0 // TODO(rjf): @eval
typedef struct E_LookupInfo E_LookupInfo;
struct E_LookupInfo
{
@@ -565,10 +579,12 @@ struct E_LookupRuleExprPair
E_LookupRule *rule;
E_Expr *expr;
};
#endif
////////////////////////////////
//~ rjf: IR Generation Hooks
#if 0 // TODO(rjf): @eval
#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr)
#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name
#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name))
@@ -602,6 +618,7 @@ struct E_IRGenRuleMap
U64 slots_count;
E_IRGenRuleSlot *slots;
};
#endif
////////////////////////////////
//~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules)
+1257 -1658
View File
File diff suppressed because it is too large Load Diff
+11
View File
@@ -134,8 +134,10 @@ struct E_IRCtx
E_String2ExprMap *macro_map;
// rjf: hook maps
#if 0 // TODO(rjf): @eval
E_LookupRuleMap *lookup_rule_map;
E_IRGenRuleMap *irgen_rule_map;
#endif
E_AutoHookMap *auto_hook_map;
};
@@ -164,6 +166,7 @@ struct E_IRState
////////////////////////////////
//~ rjf: Globals
#if 0 // TODO(rjf): @eval
local_persist read_only E_LookupRule e_lookup_rule__nil =
{
str8_lit_comp("nil"),
@@ -187,6 +190,8 @@ local_persist read_only E_IRGenRule e_irgen_rule__default =
str8_lit_comp("default"),
E_IRGEN_FUNCTION_NAME(default),
};
#endif
global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil};
thread_static E_IRState *e_ir_state = 0;
@@ -204,20 +209,24 @@ internal void e_select_ir_ctx(E_IRCtx *ctx);
////////////////////////////////
//~ rjf: Lookups
#if 0 // TODO(rjf): @eval
internal E_LookupRuleMap e_lookup_rule_map_make(Arena *arena, U64 slots_count);
internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_LookupRule *rule);
#define e_lookup_rule_map_insert_new(arena, map, name_, ...) e_lookup_rule_map_insert((arena), (map), &(E_LookupRule){.name = (name_), __VA_ARGS__})
internal E_LookupRule *e_lookup_rule_from_string(String8 string);
#endif
////////////////////////////////
//~ rjf: IR Gen Rules
#if 0 // TODO(rjf): @eval
internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count);
internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule);
#define e_irgen_rule_map_insert_new(arena, map, name_, ...) e_irgen_rule_map_insert((arena), (map), &(E_IRGenRule){.name = (name_), __VA_ARGS__})
internal E_IRGenRule *e_irgen_rule_from_string(String8 string);
#endif
////////////////////////////////
//~ rjf: Auto Hooks
@@ -288,7 +297,9 @@ internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *r
////////////////////////////////
//~ rjf: Expression & IR-Tree => Rules
#if 0 // TODO(rjf): @eval
internal E_LookupRule *e_lookup_rule_from_type_key(E_TypeKey type_key);
#endif
#if 0 // TODO(rjf): @eval
internal E_LookupRuleExprPair e_lookup_rule_tag_pair_from_expr_irtree(E_Expr *expr, E_IRTreeAndType *irtree);
+451 -4
View File
@@ -396,6 +396,11 @@ e_type_key_cons_(E_ConsTypeParams *params)
node->key = key;
MemoryCopyStruct(&node->params, params);
node->params.name = push_str8_copy(e_type_state->arena, params->name);
if(node->params.expand.info != 0)
{
if(node->params.expand.id_from_num == 0) {node->params.expand.id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity);}
if(node->params.expand.num_from_id == 0) {node->params.expand.num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity);}
}
if(params->members != 0)
{
node->params.members = push_array(e_type_state->arena, E_Member, params->count);
@@ -632,11 +637,9 @@ e_type_from_key(Arena *arena, E_TypeKey key)
type->count = node->params.count;
type->depth = node->params.depth;
type->arch = node->params.arch;
type->irgen = node->params.irgen;
type->access = node->params.access;
type->expand_info = node->params.expand_info;
type->expand_range = node->params.expand_range;
type->expand_id_from_num = node->params.expand_id_from_num;
type->expand_num_from_id = node->params.expand_num_from_id;
type->expand = node->params.expand;
type->byte_size = node->byte_size;
switch(type->kind)
{
@@ -2067,3 +2070,447 @@ e_type_member_from_key_name__cached(E_TypeKey key, String8 name)
}
return result;
}
////////////////////////////////
//~ rjf: (Built-In Type Hooks) Default Hooks
E_TYPE_EXPAND_INFO_FUNCTION_DEF(default)
{
E_TypeExpandInfo result = {0};
{
E_TypeKey type_key = e_type_unwrap(irtree->type_key);
E_TypeKind type_kind = e_type_kind_from_key(type_key);
if(e_type_kind_is_pointer_or_ref(type_kind))
{
E_Type *type = e_type_from_key__cached(type_key);
result.expr_count = type->count;
if(type->count == 1)
{
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(type_key));
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
if(direct_type_kind == E_TypeKind_Struct ||
direct_type_kind == E_TypeKind_Class ||
direct_type_kind == E_TypeKind_Union)
{
E_MemberArray data_members = e_type_data_members_from_key_filter__cached(direct_type_key, filter);
result.expr_count = data_members.count;
}
else if(direct_type_kind == E_TypeKind_Enum)
{
E_Type *direct_type = e_type_from_key__cached(direct_type_key);
result.expr_count = direct_type->count;
}
}
}
else if(type_kind == E_TypeKind_Struct ||
type_kind == E_TypeKind_Class ||
type_kind == E_TypeKind_Union)
{
E_MemberArray data_members = e_type_data_members_from_key_filter__cached(type_key, filter);
result.expr_count = data_members.count;
}
else if(type_kind == E_TypeKind_Enum)
{
E_Type *direct_type = e_type_from_key__cached(type_key);
result.expr_count = direct_type->count;
}
else if(type_kind == E_TypeKind_Array)
{
E_Type *type = e_type_from_key__cached(type_key);
result.expr_count = type->count;
}
}
return result;
}
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default)
{
Temp scratch = scratch_begin(&arena, 1);
{
//- rjf: unpack type of expression
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, expr);
E_TypeKey lhs_type_key = lhs_irtree.type_key;
E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key);
E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_type_key));
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
//- rjf: pull out specific kinds of types
B32 do_struct_range = 0;
B32 do_enum_range = 0;
B32 do_index_range = 0;
E_TypeKey enum_type_key = zero_struct;
E_TypeKey struct_type_key = zero_struct;
E_TypeKind struct_type_kind = E_TypeKind_Null;
if(e_type_kind_is_pointer_or_ref(lhs_type_kind))
{
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
if(lhs_type->count == 1 &&
(direct_type_kind == E_TypeKind_Struct ||
direct_type_kind == E_TypeKind_Union ||
direct_type_kind == E_TypeKind_Class))
{
struct_type_key = direct_type_key;
struct_type_kind = direct_type_kind;
do_struct_range = 1;
}
else if(lhs_type->count == 1 && direct_type_kind == E_TypeKind_Enum)
{
do_enum_range = 1;
enum_type_key = direct_type_key;
}
else
{
do_index_range = 1;
}
}
else if(lhs_type_kind == E_TypeKind_Struct ||
lhs_type_kind == E_TypeKind_Union ||
lhs_type_kind == E_TypeKind_Class)
{
struct_type_key = lhs_type_key;
struct_type_kind = lhs_type_kind;
do_struct_range = 1;
}
else if(lhs_type_kind == E_TypeKind_Enum)
{
enum_type_key = lhs_type_key;
do_enum_range = 1;
}
else if(lhs_type_kind == E_TypeKind_Set)
{
do_index_range = 1;
}
else if(lhs_type_kind == E_TypeKind_Array)
{
do_index_range = 1;
}
//- rjf: struct case -> the lookup-range will return a range of members
if(do_struct_range)
{
E_MemberArray data_members = e_type_data_members_from_key_filter__cached(struct_type_key, filter);
Rng1U64 legal_idx_range = r1u64(0, data_members.count);
Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range);
U64 read_range_count = dim_1u64(read_range);
for(U64 idx = 0; idx < read_range_count; idx += 1)
{
U64 member_idx = idx + read_range.min;
String8 member_name = data_members.v[member_idx].name;
exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name);
}
}
//- rjf: enum case -> the lookup-range will return a range of enum constants
else if(do_enum_range)
{
E_Type *type = e_type_from_key__cached(enum_type_key);
Rng1U64 legal_idx_range = r1u64(0, type->count);
Rng1U64 read_range = intersect_1u64(legal_idx_range, idx_range);
U64 read_range_count = dim_1u64(read_range);
for(U64 idx = 0; idx < read_range_count; idx += 1)
{
U64 member_idx = idx + read_range.min;
String8 member_name = type->enum_vals[member_idx].name;
exprs_out[idx] = e_expr_irext_member_access(arena, expr, &lhs_irtree, member_name);
}
}
//- rjf: ptr case -> the lookup-range will return a range of dereferences
else if(do_index_range)
{
U64 read_range_count = dim_1u64(idx_range);
for(U64 idx = 0; idx < read_range_count; idx += 1)
{
exprs_out[idx] = e_expr_irext_array_index(arena, expr, &lhs_irtree, idx_range.min + idx);
}
}
}
scratch_end(scratch);
}
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity)
{
return num;
}
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity)
{
return id;
}
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `folder` type
typedef struct E_FolderAccel E_FolderAccel;
struct E_FolderAccel
{
String8 folder_path;
String8Array folders;
String8Array files;
};
E_TYPE_EXPAND_INFO_FUNCTION_DEF(folder)
{
E_TypeExpandInfo info = {0};
{
Temp scratch = scratch_begin(&arena, 1);
//- rjf: evaluate lhs file path ID
E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root);
String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist);
E_Interpretation lhs_interp = e_interpret(lhs_bytecode);
E_Value lhs_value = lhs_interp.value;
U64 lhs_string_id = lhs_value.u64;
String8 folder_path = e_string_from_id(lhs_string_id);
//- rjf: compute filter - omit common prefixes (common parent paths)
String8 local_filter = filter;
{
U64 folder_pos_in_filter = str8_find_needle(filter, 0, folder_path, StringMatchFlag_CaseInsensitive|StringMatchFlag_SlashInsensitive);
if(folder_pos_in_filter < filter.size)
{
local_filter = str8_skip(local_filter, folder_pos_in_filter+folder_path.size);
local_filter = str8_skip_chop_slashes(local_filter);
}
else
{
MemoryZeroStruct(&local_filter);
}
}
//- rjf: gather & filter files in this folder
String8List folder_paths = {0};
String8List file_paths = {0};
{
OS_FileIter *iter = os_file_iter_begin(scratch.arena, folder_path, 0);
for(OS_FileInfo info = {0}; os_file_iter_next(scratch.arena, iter, &info);)
{
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, local_filter, info.name);
if(matches.count == matches.needle_part_count)
{
if(info.props.flags & FilePropertyFlag_IsFolder)
{
str8_list_push(scratch.arena, &folder_paths, push_str8_copy(arena, info.name));
}
else
{
str8_list_push(scratch.arena, &file_paths, push_str8_copy(arena, info.name));
}
}
}
os_file_iter_end(iter);
}
//- rjf: build accelerator
E_FolderAccel *accel = push_array(arena, E_FolderAccel, 1);
accel->folder_path = push_str8_copy(arena, folder_path);
accel->folders = str8_array_from_list(arena, &folder_paths);
accel->files = str8_array_from_list(arena, &file_paths);
info.user_data = accel;
info.expr_count = accel->folders.count + accel->files.count;
scratch_end(scratch);
}
return info;
}
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(folder)
{
E_FolderAccel *accel = (E_FolderAccel *)user_data;
U64 out_idx = 0;
for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1)
{
Temp scratch = scratch_begin(&arena, 1);
E_Expr *expr = &e_expr_nil;
String8 expr_string = {0};
if(0 <= idx && idx < accel->folders.count)
{
String8 folder_name = accel->folders.v[idx - 0];
String8 folder_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", folder_name);
expr = e_push_expr(arena, E_ExprKind_LeafValue, 0);
expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("folder"));
expr->space = e_space_make(E_SpaceKind_FileSystem);
expr->value.u64 = e_id_from_string(folder_path);
expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, folder_name));
}
else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count)
{
String8 file_name = accel->files.v[idx - accel->folders.count];
String8 file_path = push_str8f(scratch.arena, "%S%s%S", accel->folder_path, accel->folder_path.size != 0 ? "/" : "", file_name);
expr = e_push_expr(arena, E_ExprKind_LeafValue, 0);
expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("file"));
expr->space = e_space_make(E_SpaceKind_FileSystem);
expr->value.u64 = e_id_from_string(file_path);
expr_string = push_str8f(arena, "\"%S\"", escaped_from_raw_str8(scratch.arena, file_name));
}
exprs_out[out_idx] = expr;
exprs_strings_out[out_idx] = expr_string;
scratch_end(scratch);
}
}
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(folder)
{
U64 id = 0;
E_FolderAccel *accel = (E_FolderAccel *)user_data;
String8 name = {0};
if(0 < num && num <= accel->folders.count)
{
name = accel->folders.v[num-1];
}
else if(accel->folders.count < num && num <= accel->folders.count+accel->files.count)
{
name = accel->files.v[num-accel->folders.count-1];
}
id = e_hash_from_string(5381, name);
return id;
}
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(folder)
{
U64 num = 0;
E_FolderAccel *accel = (E_FolderAccel *)user_data;
for(U64 idx = 0; idx < accel->folders.count+accel->files.count; idx += 1)
{
String8 name = {0};
if(0 <= idx && idx < accel->folders.count)
{
name = accel->folders.v[idx];
}
else if(accel->folders.count <= idx && idx < accel->folders.count+accel->files.count)
{
name = accel->files.v[idx-accel->folders.count];
}
U64 hash = e_hash_from_string(5381, name);
if(hash == id)
{
num = idx+1;
break;
}
}
return num;
}
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `file` type
typedef struct E_FileAccel E_FileAccel;
struct E_FileAccel
{
String8 file_path;
FileProperties props;
String8Array fields;
};
E_TYPE_IRGEN_FUNCTION_DEF(file)
{
E_IRTreeAndType result = *irtree;
E_FileAccel *accel = push_array(arena, E_FileAccel, 1);
{
Temp scratch = scratch_begin(&arena, 1);
//- rjf: evaluate lhs file path ID
E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, irtree->root);
String8 lhs_bytecode = e_bytecode_from_oplist(scratch.arena, &lhs_oplist);
E_Interpretation lhs_interp = e_interpret(lhs_bytecode);
E_Value lhs_value = lhs_interp.value;
U64 lhs_string_id = lhs_value.u64;
//- rjf: get file path
String8 file_path = e_string_from_id(lhs_string_id);
//- rjf: build field list
String8List fields = {0};
str8_list_pushf(arena, &fields, "size");
str8_list_pushf(arena, &fields, "last_modified_time");
str8_list_pushf(arena, &fields, "creation_time");
str8_list_pushf(arena, &fields, "data");
//- rjf: fill accel
accel->file_path = push_str8_copy(arena, file_path);
accel->props = os_properties_from_file_path(file_path);
accel->fields = str8_array_from_list(arena, &fields);
scratch_end(scratch);
}
result.user_data = accel;
return result;
}
E_TYPE_ACCESS_FUNCTION_DEF(file)
{
E_IRTreeAndType result = {&e_irnode_nil};
E_FileAccel *accel = (E_FileAccel *)lhs_irtree->user_data;
if(expr->kind == E_ExprKind_MemberAccess)
{
E_Expr *rhs = expr->first->next;
String8 member_name = rhs->string;
if(str8_match(member_name, str8_lit("size"), 0))
{
E_Space space = e_space_make(E_SpaceKind_FileSystem);
space.u64_0 = e_id_from_string(accel->file_path);
result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.size));
result.type_key = e_type_key_basic(E_TypeKind_U64);
result.mode = E_Mode_Value;
}
else if(str8_match(member_name, str8_lit("last_modified_time"), 0))
{
E_Space space = e_space_make(E_SpaceKind_FileSystem);
space.u64_0 = e_id_from_string(accel->file_path);
result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.modified));
result.type_key = e_type_key_basic(E_TypeKind_U64);
result.mode = E_Mode_Value;
}
else if(str8_match(member_name, str8_lit("creation_time"), 0))
{
E_Space space = e_space_make(E_SpaceKind_FileSystem);
space.u64_0 = e_id_from_string(accel->file_path);
result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, accel->props.created));
result.type_key = e_type_key_basic(E_TypeKind_U64);
result.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.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, 0));
result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), accel->props.size, 0);
result.mode = E_Mode_Offset;
}
}
return result;
}
E_TYPE_EXPAND_INFO_FUNCTION_DEF(file)
{
E_FileAccel *accel = push_array(arena, E_FileAccel, 1);
{
Temp scratch = scratch_begin(&arena, 1);
scratch_end(scratch);
}
E_TypeExpandInfo info = {accel, accel->fields.count};
return info;
}
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(file)
{
E_FileAccel *accel = (E_FileAccel *)user_data;
U64 out_idx = 0;
for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1)
{
E_Expr *expr = &e_expr_nil;
String8 string = {0};
if(0 <= idx && idx < accel->fields.count)
{
String8 name = accel->fields.v[idx];
expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0);
E_Expr *lhs = e_expr_ref(arena, expr);
E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0);
rhs->string = push_str8_copy(arena, name);
e_expr_push_child(expr, lhs);
e_expr_push_child(expr, rhs);
}
exprs_out[out_idx] = expr;
exprs_strings_out[out_idx] = string;
}
}
+13 -4
View File
@@ -47,11 +47,9 @@ struct E_ConsTypeParams
E_Member *members;
E_EnumVal *enum_vals;
E_Expr **args;
E_TypeIRGenFunctionType *irgen;
E_TypeAccessFunctionType *access;
E_TypeExpandInfoFunctionType *expand_info;
E_TypeExpandRangeFunctionType *expand_range;
E_TypeExpandIDFromNumFunctionType *expand_id_from_num;
E_TypeExpandNumFromIDFunctionType *expand_num_from_id;
E_TypeExpandRule expand;
};
typedef struct E_ConsTypeNode E_ConsTypeNode;
@@ -180,6 +178,17 @@ struct E_TypeState
global read_only E_Member e_member_nil = {E_MemberKind_Null};
global read_only E_Type e_type_nil = {E_TypeKind_Null};
E_TYPE_EXPAND_INFO_FUNCTION_DEF(default);
E_TYPE_EXPAND_RANGE_FUNCTION_DEF(default);
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity);
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity);
global read_only E_TypeExpandRule e_type_expand_rule__default =
{
E_TYPE_EXPAND_INFO_FUNCTION_NAME(default),
E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default),
E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity),
E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity),
};
thread_static E_TypeState *e_type_state = 0;
////////////////////////////////