diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index c6b1b55c..08a2d566 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -1053,11 +1053,11 @@ e_value_eval_from_eval(E_Eval eval) //- rjf: type key -> auto hooks -internal E_ExprList -e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) +internal E_AutoHookMatchList +e_push_auto_hook_matches_from_type_key(Arena *arena, E_TypeKey type_key) { ProfBeginFunction(); - E_ExprList exprs = {0}; + E_AutoHookMatchList matches = {0}; if(e_ir_ctx != 0) { Temp scratch = scratch_begin(&arena, 1); @@ -1075,8 +1075,10 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) { if(str8_match(n->type_string, type_string, 0)) { - E_Expr *expr = e_parse_from_string(n->expr_string).expr; - e_expr_list_push(arena, &exprs, expr); + E_AutoHookMatch *match = push_array(arena, E_AutoHookMatch, 1); + SLLQueuePush(matches.first, matches.last, match); + match->expr = e_parse_from_string(n->expr_string).expr; + matches.count += 1; } } } @@ -1091,8 +1093,10 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) auto_hook_node = auto_hook_node->pattern_order_next) { //////////////////////// - //- rjf: determine if this pattern fits this type's string + //- rjf: determine if this pattern fits this type's string; gather wildcard instances // + E_AutoHookWildcardInst *first_wildcard_inst = 0; + E_AutoHookWildcardInst *last_wildcard_inst = 0; B32 fits_this_type_string = 1; { U64 scan_pos = 0; @@ -1121,7 +1125,8 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) U64 paren_nest_depth = 0; U64 angle_nest_depth = 0; U64 brack_nest_depth = 0; - for(;scan_pos < type_string.size; scan_pos += 1) + U64 start_inst_off = scan_pos; + for(B32 done = 0; !done && scan_pos < type_string.size; scan_pos += 1) { if(0){} else if(type_string.str[scan_pos] == '{') { brace_nest_depth += 1; } @@ -1134,7 +1139,19 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) else if(type_string.str[scan_pos] == ']' && brack_nest_depth > 0) { brack_nest_depth -= 1; } else if(str8_match(terminator_pattern_string, str8_skip(type_string, scan_pos), StringMatchFlag_RightSideSloppy)) { - break; + done = 1; + } + if((type_string.str[scan_pos] == ',' || done) && + brace_nest_depth == 0 && + paren_nest_depth == 0 && + angle_nest_depth == 0 && + brack_nest_depth == 0) + { + String8 wildcard_inst_string = str8_skip_chop_whitespace(str8_substr(type_string, r1u64(start_inst_off, scan_pos))); + start_inst_off = scan_pos+1; + E_AutoHookWildcardInst *inst = push_array(arena, E_AutoHookWildcardInst, 1); + SLLQueuePush(first_wildcard_inst, last_wildcard_inst, inst); + inst->inst_expr = e_parse_from_string(wildcard_inst_string).expr; } } } @@ -1159,12 +1176,16 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) } //////////////////////// - //- rjf: push expression if this type fits + //- rjf: push match if this type fits // if(fits_this_type_string) { - E_Expr *expr = e_parse_from_string(auto_hook_node->expr_string).expr; - e_expr_list_push(arena, &exprs, expr); + E_AutoHookMatch *match = push_array(arena, E_AutoHookMatch, 1); + SLLQueuePush(matches.first, matches.last, match); + match->expr = e_parse_from_string(auto_hook_node->expr_string).expr; + match->first_wildcard_inst = first_wildcard_inst; + match->last_wildcard_inst = last_wildcard_inst; + matches.count += 1; } } } @@ -1172,13 +1193,13 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) scratch_end(scratch); } ProfEnd(); - return exprs; + return matches; } -internal E_ExprList -e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key) +internal E_AutoHookMatchList +e_auto_hook_matches_from_type_key(E_TypeKey type_key) { - E_ExprList exprs = {0}; + E_AutoHookMatchList matches = {0}; { U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); U64 slot_idx = hash%e_cache->type_auto_hook_cache_map->slots_count; @@ -1197,11 +1218,11 @@ e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key) node = push_array(e_cache->arena, E_TypeAutoHookCacheNode, 1); SLLQueuePush(e_cache->type_auto_hook_cache_map->slots[slot_idx].first, e_cache->type_auto_hook_cache_map->slots[slot_idx].last, node); node->key = type_key; - node->exprs = e_auto_hook_exprs_from_type_key(e_cache->arena, type_key); + node->matches = e_push_auto_hook_matches_from_type_key(e_cache->arena, type_key); } - exprs = node->exprs; + matches = node->matches; } - return exprs; + return matches; } //- rjf: string IDs diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index b88f742b..c119877d 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -663,6 +663,30 @@ struct E_String2TypeKeyMap //////////////////////////////// //~ rjf: Type Pattern -> Hook Key Data Structure (Type Views) +typedef struct E_AutoHookWildcardInst E_AutoHookWildcardInst; +struct E_AutoHookWildcardInst +{ + E_AutoHookWildcardInst *next; + E_Expr *inst_expr; +}; + +typedef struct E_AutoHookMatch E_AutoHookMatch; +struct E_AutoHookMatch +{ + E_AutoHookMatch *next; + E_Expr *expr; + E_AutoHookWildcardInst *first_wildcard_inst; + E_AutoHookWildcardInst *last_wildcard_inst; +}; + +typedef struct E_AutoHookMatchList E_AutoHookMatchList; +struct E_AutoHookMatchList +{ + E_AutoHookMatch *first; + E_AutoHookMatch *last; + U64 count; +}; + typedef struct E_AutoHookNode E_AutoHookNode; struct E_AutoHookNode { @@ -890,7 +914,7 @@ struct E_TypeAutoHookCacheNode { E_TypeAutoHookCacheNode *next; E_TypeKey key; - E_ExprList exprs; + E_AutoHookMatchList matches; }; typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot; @@ -1227,8 +1251,8 @@ internal E_Eval e_value_eval_from_eval(E_Eval eval); #define e_value_from_expr(expr) e_value_eval_from_eval(e_eval_from_expr(expr)).value //- rjf: type key -> auto hooks -internal E_ExprList e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key); -internal E_ExprList e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key); +internal E_AutoHookMatchList e_push_auto_hook_matches_from_type_key(Arena *arena, E_TypeKey type_key); +internal E_AutoHookMatchList e_auto_hook_matches_from_type_key(E_TypeKey type_key); //- rjf: string IDs internal U64 e_id_from_string(String8 string); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 643946c9..96cad565 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -2372,21 +2372,18 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I //- rjf: find any auto hooks according to this generation's type if(!disallow_autohooks && result.mode != E_Mode_Null) { - E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); - for(E_ExprNode *n = exprs.first; n != 0; n = n->next) + E_AutoHookMatchList matches = e_auto_hook_matches_from_type_key(result.type_key); + for(E_AutoHookMatch *match = matches.first; match != 0; match = match->next) { - for(E_Expr *e = n->v; e != &e_expr_nil; e = e->next) + B32 e_is_poisoned = e_expr_is_poisoned(match->expr); + if(!e_is_poisoned) { - B32 e_is_poisoned = e_expr_is_poisoned(e); - if(!e_is_poisoned) - { - Task *task = push_array(scratch.arena, Task, 1); - SLLQueuePush(first_task, last_task, task); - task->expr = e; - task->overridden = push_array(scratch.arena, E_IRTreeAndType, 1); - task->overridden[0] = result; - goto end_autohook_find; - } + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->expr = match->expr; + task->overridden = push_array(scratch.arena, E_IRTreeAndType, 1); + task->overridden[0] = result; + goto end_autohook_find; } } end_autohook_find:;