pass through eval msgs appropriately in eval cache evaluations; fix rules for reverting to overridden IR trees on usage of 'raw'; more fixes/improvements

This commit is contained in:
Ryan Fleury
2025-04-24 13:04:32 -07:00
parent a6c9a1bd2a
commit a9685e6b9d
11 changed files with 195 additions and 125 deletions
+20
View File
@@ -160,6 +160,17 @@ e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push)
MemoryZeroStruct(to_push);
}
internal E_MsgList
e_msg_list_copy(Arena *arena, E_MsgList *src)
{
E_MsgList dst = {0};
for(E_Msg *msg = src->first; msg != 0; msg = msg->next)
{
e_msg(arena, &dst, msg->kind, msg->location, msg->text);
}
return dst;
}
////////////////////////////////
//~ rjf: Space Functions
@@ -796,6 +807,8 @@ e_parse_from_bundle(E_CacheBundle *bundle)
{
bundle->flags |= E_CacheBundleFlag_Parse;
bundle->parse = e_push_parse_from_string(e_cache->arena, bundle->string);
E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->parse.msgs);
e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy);
}
E_Parse parse = bundle->parse;
return parse;
@@ -810,6 +823,8 @@ e_irtree_from_bundle(E_CacheBundle *bundle)
E_IRTreeAndType overridden = e_irtree_from_key(bundle->parent_key);
E_Parse parse = e_parse_from_bundle(bundle);
bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &overridden, 0, 0, parse.expr);
E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs);
e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy);
}
E_IRTreeAndType result = bundle->irtree;
return result;
@@ -839,6 +854,10 @@ e_interpretation_from_bundle(E_CacheBundle *bundle)
bundle->flags |= E_CacheBundleFlag_Interpret;
String8 bytecode = e_bytecode_from_bundle(bundle);
E_Interpretation interpret = e_interpret(bytecode);
if(E_InterpretationCode_Good < interpret.code && interpret.code < E_InterpretationCode_COUNT)
{
e_msg(e_cache->arena, &bundle->msgs, E_MsgKind_InterpretationError, 0, e_interpretation_code_display_strings[interpret.code]);
}
bundle->interpretation = interpret;
}
E_Interpretation interpret = bundle->interpretation;
@@ -857,6 +876,7 @@ e_eval_from_bundle(E_CacheBundle *bundle)
.expr = e_parse_from_bundle(bundle).expr,
.irtree = e_irtree_from_bundle(bundle),
.bytecode = e_bytecode_from_bundle(bundle),
.msgs = bundle->msgs,
};
E_Interpretation interpretation = e_interpretation_from_bundle(bundle);
eval.code = interpretation.code;
+2
View File
@@ -887,6 +887,7 @@ struct E_CacheBundle
E_IRTreeAndType irtree;
String8 bytecode;
E_Interpretation interpretation;
E_MsgList msgs;
};
typedef struct E_CacheNode E_CacheNode;
@@ -1026,6 +1027,7 @@ internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src);
internal void e_msg(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, String8 text);
internal void e_msgf(Arena *arena, E_MsgList *msgs, E_MsgKind kind, void *location, char *fmt, ...);
internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push);
internal E_MsgList e_msg_list_copy(Arena *arena, E_MsgList *src);
////////////////////////////////
//~ rjf: Space Functions
+48 -23
View File
@@ -493,14 +493,13 @@ E_TYPE_ACCESS_FUNCTION_DEF(default)
E_Expr *exprr = exprl->next;
E_IRTreeAndType l = *lhs_irtree;
E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, exprr);
e_msg_list_concat_in_place(&result.msgs, &r.msgs);
E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype);
E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype);
E_TypeKey direct_type = e_type_key_unwrap(l_restype, E_TypeUnwrapFlag_All);
U64 direct_type_size = e_type_byte_size_from_key(direct_type);
e_msg_list_concat_in_place(&result.msgs, &l.msgs);
e_msg_list_concat_in_place(&result.msgs, &r.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r.root->op == 0)
@@ -586,7 +585,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default)
//- rjf: top-level irtree/type extraction
internal E_IRTreeAndType
e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr)
e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
@@ -603,7 +602,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
E_Expr *expr;
E_IRTreeAndType *prev;
};
Task start_task = {0, root_expr, overridden};
Task start_task = {0, root_expr, root_overridden};
Task *first_task = &start_task;
Task *last_task = first_task;
for(Task *t = first_task; t != 0; t = t->next)
@@ -614,9 +613,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
e_expr_poison(expr);
//- rjf: select the task's previous ir-tree-and-type as the overridden tree
E_IRTreeAndType *overridden = 0;
if(t->prev != 0)
{
overridden = t->prev;
overridden = push_array(arena, E_IRTreeAndType, 1);
MemoryCopyStruct(overridden, t->prev);
}
//- rjf: do expr -> irtree generation for this expression
@@ -636,6 +637,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
// rjf: unpack left-hand-side
E_Expr *lhs = expr->first;
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs);
e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs);
// rjf: try all IR trees in chain
for(E_IRTreeAndType *lhs_irtree_try = &lhs_irtree; lhs_irtree_try != 0; lhs_irtree_try = lhs_irtree_try->prev)
@@ -692,11 +694,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
E_TypeKey r_type_direct = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_All);
U64 r_type_direct_size = e_type_byte_size_from_key(r_type_direct);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r_tree.root->op == 0)
@@ -751,10 +753,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = r_tree.type_key;
E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r_tree.root->op == 0)
@@ -779,6 +781,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
E_Expr *cast_type_expr = expr->first;
E_Expr *casted_expr = cast_type_expr->next;
E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, cast_type_expr);
e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs);
E_TypeKey cast_type = cast_irtree.type_key;
E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type);
U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type);
@@ -915,12 +918,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind);
E_TypeKey r_type_promoted = e_type_key_promote(r_type);
RDI_EvalOp op = e_opcode_from_expr_kind(kind);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r_tree.root->op == 0)
@@ -948,12 +951,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
// rjf: unpack operand
E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind);
E_TypeKey r_type_promoted = e_type_key_basic(E_TypeKind_Bool);
RDI_EvalOp op = e_opcode_from_expr_kind(kind);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
// rjf: bad conditions? -> error if applicable, exit
if(r_tree.root->op == 0)
@@ -1273,6 +1276,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
{
E_Expr *lhs = expr->first;
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs);
e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs);
E_TypeKey lhs_type_key = lhs_irtree.type_key;
E_Type *lhs_type = e_type_from_key__cached(lhs_type_key);
@@ -1294,19 +1298,30 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
e_expr_push_child(call, e_expr_ref(arena, arg));
}
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call);
E_MsgList new_msgs = {0};
e_msg_list_concat_in_place(&new_msgs, &lhs_irtree.msgs);
e_msg_list_concat_in_place(&new_msgs, &result.msgs);
result.msgs = new_msgs;
// rjf: is "raw"? -> try to return overridden tree, otherwise strip all
// lens types from result; disallow auto-hooks
if(str8_match(callee->string, str8_lit("raw"), 0))
{
disallow_autohooks = 1;
if(overridden != 0)
if(overridden->root != &e_irnode_nil)
{
result = *overridden;
for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev)
E_MsgList existing_msgs = result.msgs;
for(E_IRTreeAndType *prev = overridden; prev->root != &e_irnode_nil; prev = prev->prev)
{
result = *prev;
if(e_type_kind_from_key(prev->type_key) != E_TypeKind_Lens)
{
break;
}
}
E_MsgList overridden_msgs = e_msg_list_copy(arena, &result.msgs);
result.msgs = existing_msgs;
e_msg_list_concat_in_place(&result.msgs, &overridden_msgs);
}
else
{
@@ -1322,7 +1337,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
Temp scratch = scratch_begin(&arena, 1);
// rjf: generate result via first argument to lens
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next);
// rjf: count extra arguments
U64 arg_count = 0;
@@ -1346,17 +1361,25 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
if(str8_match(lhs_type->name, str8_lit("raw"), 0))
{
disallow_autohooks = 1;
if(overridden != 0)
if(overridden->root != &e_irnode_nil)
{
E_MsgList existing_msgs = result.msgs;
result = *overridden;
for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev)
for(E_IRTreeAndType *prev = overridden; prev->root != &e_irnode_nil; prev = prev->prev)
{
result = *prev;
if(e_type_kind_from_key(prev->type_key) != E_TypeKind_Lens)
{
break;
}
}
E_MsgList overridden_msgs = e_msg_list_copy(arena, &result.msgs);
result.msgs = existing_msgs;
e_msg_list_concat_in_place(&result.msgs, &overridden_msgs);
}
else
{
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next);
result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs->next);
result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses);
}
}
@@ -1484,7 +1507,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
}
//- rjf: try to map name as overridden expression signifier ('$')
if(!string_mapped && str8_match(string, str8_lit("$"), 0) && overridden != 0)
if(!string_mapped && str8_match(string, str8_lit("$"), 0) && (overridden->root != &e_irnode_nil || overridden->msgs.first != 0))
{
E_OpList oplist = e_oplist_from_irtree(arena, overridden->root);
string_mapped = 1;
@@ -1492,11 +1515,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
mapped_bytecode_mode = overridden->mode;
mapped_type_key = overridden->type_key;
disallow_autohooks = 1;
E_MsgList msgs = e_msg_list_copy(arena, &overridden->msgs);
e_msg_list_concat_in_place(&result.msgs, &msgs);
}
//- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted)
if(!string_mapped && overridden != 0)
if(!string_mapped && overridden->root != &e_irnode_nil)
{
// TODO(rjf): @eval
E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, overridden, string);
E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, disallow_chained_fastpaths, access);
if(access_irtree.root != &e_irnode_nil)
@@ -1506,6 +1532,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
mapped_type_key = access_irtree.type_key;
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = access_irtree.mode;
e_msg_list_concat_in_place(&result.msgs, &access_irtree.msgs);
}
}
@@ -1884,7 +1911,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
}
//- rjf: error on failure-to-generate
if(!generated)
if(!generated && !str8_match(string, str8_lit("$"), 0))
{
e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string);
}
@@ -2066,8 +2093,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
//- rjf: equip previous task's irtree
if(t->prev != 0)
{
result.prev = push_array(arena, E_IRTreeAndType, 1);
result.prev[0] = *t->prev;
result.prev = overridden;
}
//- rjf: find any auto hooks according to this generation's type
@@ -2084,8 +2110,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32
Task *task = push_array(scratch.arena, Task, 1);
SLLQueuePush(first_task, last_task, task);
task->expr = e;
task->prev = push_array(scratch.arena, E_IRTreeAndType, 1);
task->prev[0] = result;
task->prev = &result;
break;
}
}
+1 -1
View File
@@ -88,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr);
//- rjf: top-level irtree/type extraction
E_TYPE_ACCESS_FUNCTION_DEF(default);
internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr);
internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr);
//- rjf: irtree -> linear ops/bytecode
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out);
+59 -77
View File
@@ -1367,7 +1367,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key)
padding_member->kind = E_MemberKind_Padding;
padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size, E_TypeFlag_IsNotText);
padding_member->off = n->off;
padding_member->name = push_str8f(arena, "[padding %I64u]", padding_idx);
padding_member->name = push_str8f(arena, "$padding_%I64u", padding_idx);
padding_idx += 1;
}
members = new_members;
@@ -2355,13 +2355,21 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(array)
U64 read_range_count = dim_1u64(idx_range);
for(U64 idx = 0; idx < read_range_count; idx += 1)
{
evals_out[idx] = e_eval_wrapf(eval, "$[I64u]", idx_range.min + idx);
evals_out[idx] = e_eval_wrapf(eval, "$[%I64u]", idx_range.min + idx);
}
}
////////////////////////////////
//~ rjf: (Built-In Type Hooks) `slice` lens
typedef struct E_SliceIRExt E_SliceIRExt;
struct E_SliceIRExt
{
E_Member *base_ptr_member;
E_Member *opl_ptr_member;
E_Member *count_member;
};
typedef struct E_SliceAccel E_SliceAccel;
struct E_SliceAccel
{
@@ -2373,7 +2381,7 @@ struct E_SliceAccel
E_TYPE_IREXT_FUNCTION_DEF(slice)
{
E_SliceAccel *accel = push_array(arena, E_SliceAccel, 1);
E_SliceIRExt *ext = push_array(arena, E_SliceIRExt, 1);
{
Temp scratch = scratch_begin(&arena, 1);
@@ -2416,77 +2424,21 @@ E_TYPE_IREXT_FUNCTION_DEF(slice)
}
}
// rjf: determine architecture
Arch arch = e_base_ctx->primary_module->arch;
if(base_ptr_member != 0)
{
E_Type *type = e_type_from_key__cached(base_ptr_member->type_key);
arch = type->arch;
}
// rjf: evaluate count member, determine count
U64 count = 0;
if(count_member != 0)
{
E_Expr *count_member_expr = e_expr_irext_member_access(arena, expr, irtree, count_member->name);
E_Value count_member_value = e_value_from_expr(count_member_expr);
count = count_member_value.u64;
}
// rjf: evaluate base ptr member, determine base address
U64 base_ptr_vaddr = 0;
if(base_ptr_member != 0)
{
E_Expr *base_ptr_member_expr = e_expr_irext_member_access(arena, expr, irtree, base_ptr_member->name);
E_Value base_ptr_member_value = e_value_from_expr(base_ptr_member_expr);
base_ptr_vaddr = base_ptr_member_value.u64;
}
// rjf: evaluate opl ptr member, determine opl address
U64 opl_ptr_vaddr = 0;
if(count_member == 0 && opl_ptr_member != 0)
{
E_Expr *opl_ptr_member_expr = e_expr_irext_member_access(arena, expr, irtree, opl_ptr_member->name);
E_Value opl_ptr_member_value = e_value_from_expr(opl_ptr_member_expr);
opl_ptr_vaddr = opl_ptr_member_value.u64;
}
// rjf: determine element type
E_TypeKey element_type_key = zero_struct;
if(base_ptr_member != 0)
{
element_type_key = e_type_key_direct(base_ptr_member->type_key);
}
// rjf: if no count, but base/opl, swap base/opl if needed, and measure count
if(count_member == 0 && opl_ptr_member != 0 && base_ptr_member != 0)
{
U64 min_vaddr = Min(base_ptr_vaddr, opl_ptr_vaddr);
U64 max_vaddr = Max(base_ptr_vaddr, opl_ptr_vaddr);
base_ptr_vaddr = min_vaddr;
opl_ptr_vaddr = max_vaddr;
count = (opl_ptr_vaddr - base_ptr_vaddr) / e_type_byte_size_from_key(element_type_key);
}
// rjf: fill
if((count_member || opl_ptr_member) && base_ptr_member)
{
accel->arch = arch;
accel->count = count;
accel->base_ptr_vaddr = base_ptr_vaddr;
accel->element_type_key = element_type_key;
}
// rjf: fill extension
ext->base_ptr_member = base_ptr_member;
ext->opl_ptr_member = opl_ptr_member;
ext->count_member = count_member;
}
scratch_end(scratch);
}
E_IRExt result = {accel};
E_IRExt result = {ext};
return result;
}
E_TYPE_ACCESS_FUNCTION_DEF(slice)
{
E_IRTreeAndType result = {&e_irnode_nil};
E_SliceAccel *accel = (E_SliceAccel *)lhs_irtree->user_data;
E_SliceIRExt *ext = (E_SliceIRExt *)lhs_irtree->user_data;
switch(expr->kind)
{
default:
@@ -2495,18 +2447,37 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice)
result = E_TYPE_ACCESS_FUNCTION_NAME(default)(arena, overridden, expr, lhs_irtree);
}break;
case E_ExprKind_ArrayIndex:
if(ext->base_ptr_member != 0)
{
E_Value rhs_value = e_value_from_expr(expr->first->next);
U64 rhs_idx = rhs_value.u64;
if(0 <= rhs_idx && rhs_idx < accel->count)
Temp scratch = scratch_begin(&arena, 1);
// rjf: compute bytecode of struct
E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree->root);
String8 lhs_bytecode = e_bytecode_from_oplist(arena, &lhs_oplist);
// rjf: build expression tree to access base pointer's member, then do an index
E_Expr *idx_expr = e_push_expr(scratch.arena, E_ExprKind_ArrayIndex, 0);
E_Expr *dot_expr = e_push_expr(scratch.arena, E_ExprKind_MemberAccess, 0);
E_Expr *lhs_expr = e_push_expr(scratch.arena, E_ExprKind_LeafBytecode, 0);
E_Expr *base_ptr_expr = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, 0);
e_expr_push_child(dot_expr, lhs_expr);
e_expr_push_child(dot_expr, base_ptr_expr);
e_expr_push_child(idx_expr, dot_expr);
e_expr_push_child(idx_expr, e_expr_ref(scratch.arena, expr->first->next));
{
E_Type *element_type = e_type_from_key__cached(accel->element_type_key);
U64 offset = element_type->byte_size*rhs_idx;
U64 vaddr = accel->base_ptr_vaddr + offset;
result.root = e_irtree_const_u(arena, vaddr);
result.type_key = accel->element_type_key;
result.mode = E_Mode_Offset;
lhs_expr->mode = lhs_irtree->mode;
lhs_expr->bytecode = lhs_bytecode;
lhs_expr->type_key = e_type_key_unwrap(lhs_irtree->type_key, E_TypeUnwrapFlag_Lenses);
}
{
base_ptr_expr->string = ext->base_ptr_member->name;
}
// rjf: compute struct.base_ptr IR tree
E_IRTreeAndType override = {&e_irnode_nil};
result = e_push_irtree_and_type_from_expr(arena, &override, 0, 0, idx_expr);
scratch_end(scratch);
}break;
}
return result;
@@ -2514,8 +2485,19 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice)
E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice)
{
E_SliceAccel *accel = (E_SliceAccel *)eval.irtree.user_data;
E_TypeExpandInfo info = {accel, accel->count};
E_SliceIRExt *accel = (E_SliceIRExt *)eval.irtree.user_data;
U64 count = 0;
{
if(accel->count_member != 0)
{
count = e_value_eval_from_eval(e_eval_wrapf(eval, "$.%S", accel->count_member->name)).value.u64;
}
else if(accel->opl_ptr_member != 0 && accel->base_ptr_member != 0)
{
count = e_value_eval_from_eval(e_eval_wrapf(eval, "$.%S - $.%S", accel->opl_ptr_member->name, accel->base_ptr_member->name)).value.u64;
}
}
E_TypeExpandInfo info = {0, count};
return info;
}
@@ -2611,7 +2593,7 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(folder)
{
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);
path_expr_string = push_str8f(arena, "file:\"%S\"", escaped_from_raw_str8(scratch.arena, folder_path));
path_expr_string = push_str8f(arena, "folder:\"%S/\"", escaped_from_raw_str8(scratch.arena, folder_path));
}
else if(accel->folders.count <= idx && idx < accel->folders.count + accel->files.count)
{