Skip to content

Commit 6f4533d

Browse files
committed
rd: new ctrl entity meta evaluation path; ctrl entity meta evaluation cache; eval: auto-view-rules (via 'auto hook map'), + support for 'type patterns', e.g. for templates; ir generation / typechecking hook application + source-tag coloring (to avoid infinite recursion of repeatedly-applied auto view rules
1 parent eab5c7c commit 6f4533d

File tree

6 files changed

+372
-199
lines changed

6 files changed

+372
-199
lines changed

src/eval/eval_ir.c

Lines changed: 162 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,99 @@ e_irgen_rule_from_string(String8 string)
683683
return rule;
684684
}
685685

686+
////////////////////////////////
687+
//~ rjf: Auto Hooks
688+
689+
internal E_AutoHookMap
690+
e_auto_hook_map_make(Arena *arena, U64 slots_count)
691+
{
692+
E_AutoHookMap map = {0};
693+
map.slots_count = slots_count;
694+
map.slots = push_array(arena, E_AutoHookSlot, map.slots_count);
695+
return map;
696+
}
697+
698+
internal void
699+
e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, String8 tag_expr_string)
700+
{
701+
Temp scratch = scratch_begin(&arena, 1);
702+
E_TokenArray tokens = e_token_array_from_text(scratch.arena, pattern);
703+
E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, pattern, &tokens);
704+
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr);
705+
E_TypeKey type_key = irtree.type_key;
706+
E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1);
707+
node->type_key = type_key;
708+
U8 pattern_split = '?';
709+
node->type_pattern_parts = str8_split(arena, pattern, &pattern_split, 1, 0);
710+
node->tag_expr = e_parse_expr_from_text(arena, push_str8_copy(arena, tag_expr_string));
711+
if(!e_type_key_match(e_type_key_zero(), type_key))
712+
{
713+
U64 hash = e_hash_from_type_key(type_key);
714+
U64 slot_idx = map->slots_count;
715+
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
716+
}
717+
else
718+
{
719+
SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next);
720+
}
721+
scratch_end(scratch);
722+
}
723+
724+
internal E_ExprList
725+
e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
726+
{
727+
E_ExprList exprs = {0};
728+
{
729+
Temp scratch = scratch_begin(&arena, 1);
730+
E_AutoHookMap *map = e_ir_ctx->auto_hook_map;
731+
732+
//- rjf: gather exact-type-key-matches from the map
733+
{
734+
U64 hash = e_hash_from_type_key(type_key);
735+
U64 slot_idx = hash%map->slots_count;
736+
for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next)
737+
{
738+
if(e_type_key_match(n->type_key, type_key))
739+
{
740+
e_expr_list_push(arena, &exprs, n->tag_expr);
741+
}
742+
}
743+
}
744+
745+
//- rjf: gather fuzzy matches from all patterns in the map
746+
if(map->first_pattern != 0)
747+
{
748+
String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key));
749+
for(E_AutoHookNode *auto_hook_node = map->first_pattern; auto_hook_node != 0; auto_hook_node = auto_hook_node->pattern_order_next)
750+
{
751+
B32 fits_this_type_string = 1;
752+
U64 scan_pos = 0;
753+
for(String8Node *n = auto_hook_node->type_pattern_parts.first; n != 0; n = n->next)
754+
{
755+
U64 pattern_part_pos = str8_find_needle(type_string, scan_pos, n->string, 0);
756+
if(pattern_part_pos >= type_string.size)
757+
{
758+
fits_this_type_string = 0;
759+
break;
760+
}
761+
scan_pos = pattern_part_pos + n->string.size;
762+
}
763+
if(scan_pos < type_string.size)
764+
{
765+
fits_this_type_string = 0;
766+
}
767+
if(fits_this_type_string)
768+
{
769+
e_expr_list_push(arena, &exprs, auto_hook_node->tag_expr);
770+
}
771+
}
772+
}
773+
774+
scratch_end(scratch);
775+
}
776+
return exprs;
777+
}
778+
686779
////////////////////////////////
687780
//~ rjf: IR-ization Functions
688781

@@ -1767,9 +1860,12 @@ E_IRGEN_FUNCTION_DEF(default)
17671860
internal E_IRTreeAndType
17681861
e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
17691862
{
1863+
Temp scratch = scratch_begin(&arena, 1);
17701864
E_IRTreeAndType result = {&e_irnode_nil};
1771-
E_IRGenRule *irgen_rule = &e_irgen_rule__default;
1772-
E_Expr *irgen_rule_tag = &e_expr_nil;
1865+
1866+
//- rjf: pick the ir-generation rule from explicitly-stored expressions
1867+
E_IRGenRule *explicit_irgen_rule = &e_irgen_rule__default;
1868+
E_Expr *explicit_irgen_rule_tag = &e_expr_nil;
17731869
for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next)
17741870
{
17751871
String8 name = tag->first->string;
@@ -1789,29 +1885,80 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
17891885
}
17901886
if(!tag_is_poisoned)
17911887
{
1792-
E_UsedTagNode *n = push_array(arena, E_UsedTagNode, 1);
1793-
n->tag = tag;
1794-
DLLPushBack(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n);
1795-
irgen_rule_tag = tag;
1796-
irgen_rule = irgen_rule_candidate;
1888+
explicit_irgen_rule = irgen_rule_candidate;
1889+
explicit_irgen_rule_tag = tag;
17971890
break;
17981891
}
17991892
}
18001893
}
1801-
result = irgen_rule->irgen(arena, expr, irgen_rule_tag);
1802-
if(irgen_rule_tag != &e_expr_nil)
1894+
1895+
//- rjf: apply all ir-generation steps
1896+
typedef struct Task Task;
1897+
struct Task
1898+
{
1899+
Task *next;
1900+
E_IRGenRule *rule;
1901+
E_Expr *tag;
1902+
};
1903+
Task start_task = {0, explicit_irgen_rule, explicit_irgen_rule_tag};
1904+
Task *first_task = &start_task;
1905+
Task *last_task = first_task;
1906+
for(Task *t = first_task; t != 0; t = t->next)
18031907
{
1804-
U64 hash = e_hash_from_string(5381, str8_struct(&irgen_rule_tag));
1805-
U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count;
1806-
for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next)
1908+
// rjf: poison the tag we are about to use, so we don't recursively use it
1909+
if(t->tag != &e_expr_nil)
18071910
{
1808-
if(n->tag == irgen_rule_tag)
1911+
U64 hash = e_hash_from_string(5381, str8_struct(&t->tag));
1912+
U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count;
1913+
E_UsedTagNode *n = push_array(arena, E_UsedTagNode, 1);
1914+
n->tag = t->tag;
1915+
DLLPushBack(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n);
1916+
}
1917+
1918+
// rjf: do this rule's generation
1919+
result = t->rule->irgen(arena, expr, t->tag);
1920+
1921+
// rjf: find any auto hooks according to this generation's type
1922+
{
1923+
E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key(scratch.arena, result.type_key);
1924+
for(E_ExprNode *n = exprs.first; n != 0; n = n->next)
18091925
{
1810-
DLLRemove(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n);
1811-
break;
1926+
for(E_Expr *tag = n->v; tag != &e_expr_nil; tag = tag->next)
1927+
{
1928+
E_IRGenRule *rule = e_irgen_rule_from_string(tag->first->string);
1929+
if(rule == &e_irgen_rule__default) { rule = e_irgen_rule_from_string(tag->string); }
1930+
if(rule != &e_irgen_rule__default)
1931+
{
1932+
Task *task = push_array(scratch.arena, Task, 1);
1933+
SLLQueuePush(first_task, last_task, task);
1934+
task->rule = rule;
1935+
task->tag = tag;
1936+
break;
1937+
}
1938+
}
18121939
}
18131940
}
18141941
}
1942+
1943+
//- rjf: unpoison the tags we used
1944+
for(Task *t = first_task; t != 0; t = t->next)
1945+
{
1946+
if(t->tag != &e_expr_nil)
1947+
{
1948+
U64 hash = e_hash_from_string(5381, str8_struct(&t->tag));
1949+
U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count;
1950+
for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next)
1951+
{
1952+
if(n->tag == t->tag)
1953+
{
1954+
DLLRemove(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n);
1955+
break;
1956+
}
1957+
}
1958+
}
1959+
}
1960+
1961+
scratch_end(scratch);
18151962
return result;
18161963
}
18171964

src/eval/eval_ir.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,35 @@ struct E_IRGenRuleMap
172172
E_IRGenRuleSlot *slots;
173173
};
174174

175+
////////////////////////////////
176+
//~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules)
177+
178+
typedef struct E_AutoHookNode E_AutoHookNode;
179+
struct E_AutoHookNode
180+
{
181+
E_AutoHookNode *hash_next;
182+
E_AutoHookNode *pattern_order_next;
183+
E_TypeKey type_key;
184+
String8List type_pattern_parts;
185+
E_Expr *tag_expr;
186+
};
187+
188+
typedef struct E_AutoHookSlot E_AutoHookSlot;
189+
struct E_AutoHookSlot
190+
{
191+
E_AutoHookNode *first;
192+
E_AutoHookNode *last;
193+
};
194+
195+
typedef struct E_AutoHookMap E_AutoHookMap;
196+
struct E_AutoHookMap
197+
{
198+
U64 slots_count;
199+
E_AutoHookSlot *slots;
200+
E_AutoHookNode *first_pattern;
201+
E_AutoHookNode *last_pattern;
202+
};
203+
175204
////////////////////////////////
176205
//~ rjf: Used Tag Map Data Structure
177206

@@ -206,6 +235,7 @@ struct E_IRCtx
206235
E_String2ExprMap *macro_map;
207236
E_LookupRuleMap *lookup_rule_map;
208237
E_IRGenRuleMap *irgen_rule_map;
238+
E_AutoHookMap *auto_hook_map;
209239
E_UsedTagMap *used_tag_map;
210240
};
211241

@@ -259,6 +289,13 @@ internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGen
259289

260290
internal E_IRGenRule *e_irgen_rule_from_string(String8 string);
261291

292+
////////////////////////////////
293+
//~ rjf: Auto Hooks
294+
295+
internal E_AutoHookMap e_auto_hook_map_make(Arena *arena, U64 slots_count);
296+
internal void e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, String8 tag_expr_string);
297+
internal E_ExprList e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key);
298+
262299
////////////////////////////////
263300
//~ rjf: IR-ization Functions
264301

src/eval/eval_parse.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,15 @@ e_expr_copy(Arena *arena, E_Expr *src)
823823
return result;
824824
}
825825

826+
internal void
827+
e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr)
828+
{
829+
E_ExprNode *n = push_array(arena, E_ExprNode, 1);
830+
n->v = expr;
831+
SLLQueuePush(list->first, list->last, n);
832+
list->count +=1;
833+
}
834+
826835
////////////////////////////////
827836
//~ rjf: Expression Tree -> String Conversions
828837

src/eval/eval_parse.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,21 @@ struct E_Expr
6767
String8 bytecode;
6868
};
6969

70+
typedef struct E_ExprNode E_ExprNode;
71+
struct E_ExprNode
72+
{
73+
E_ExprNode *next;
74+
E_Expr *v;
75+
};
76+
77+
typedef struct E_ExprList E_ExprList;
78+
struct E_ExprList
79+
{
80+
E_ExprNode *first;
81+
E_ExprNode *last;
82+
U64 count;
83+
};
84+
7085
////////////////////////////////
7186
//~ rjf: Map Types
7287

@@ -229,6 +244,7 @@ internal E_Expr *e_expr_ref_deref(Arena *arena, E_Expr *rhs);
229244
internal E_Expr *e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs);
230245
internal E_Expr *e_expr_ref_bswap(Arena *arena, E_Expr *rhs);
231246
internal E_Expr *e_expr_copy(Arena *arena, E_Expr *src);
247+
internal void e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr);
232248

233249
////////////////////////////////
234250
//~ rjf: Expression Tree -> String Conversions

0 commit comments

Comments
 (0)