Skip to content

Commit 07c9268

Browse files
committed
eval: specify formal way in which tags (view rules) can fit into expression language, both in parsing & in structure; introduce ir-generation hook step in eval pipeline, transfer most of the default non-vbisualization view rule features to that layer
1 parent aac93b5 commit 07c9268

File tree

7 files changed

+536
-54
lines changed

7 files changed

+536
-54
lines changed

src/eval/eval.mdesk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ E_ExprKindTable:
117117

118118
{ Ternary Null 0 "? " "" "?" ":"}
119119

120+
{ Call Null 0 "()" "(" "," ")"}
121+
120122
{ LeafBytecode Null 0 "bytecode" "" "" "" }
121123
{ LeafMember Null 0 "member" "" "" "" }
122124
{ LeafStringLiteral Null 0 "string_literal" "" "" "" }
@@ -136,6 +138,8 @@ E_ExprKindTable:
136138
{ Line Binary 1 ":" "" ":" "" }
137139

138140
{ Define Binary 13 "=" "" "=" "" }
141+
142+
{ Tag Null 0 "=>" "=>" "," "" }
139143
}
140144

141145
@table(name display_string)

src/eval/eval_ir.c

Lines changed: 276 additions & 42 deletions
Large diffs are not rendered by default.

src/eval/eval_ir.h

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct E_IRNode
4242
E_IRNode *last;
4343
E_IRNode *next;
4444
RDI_EvalOp op;
45+
E_Space space;
4546
String8 string;
4647
E_Value value;
4748
};
@@ -84,31 +85,30 @@ struct E_LookupRange
8485
#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name
8586
#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name))
8687
typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType);
88+
E_LOOKUP_INFO_FUNCTION_DEF(default);
8789

8890
#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data)
8991
#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name
9092
#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name))
9193
typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType);
94+
E_LOOKUP_ACCESS_FUNCTION_DEF(default);
9295

9396
#define E_LOOKUP_RANGE_FUNCTION_SIG(name) E_LookupRange name(Arena *arena, E_Expr *lhs, Rng1U64 idx_range, void *user_data)
9497
#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name
9598
#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name))
9699
typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType);
100+
E_LOOKUP_RANGE_FUNCTION_DEF(default);
97101

98102
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data)
99103
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name
100104
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(name) internal E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name))
101105
typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType);
106+
E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default);
102107

103108
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data)
104109
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name
105110
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(name) internal E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name))
106111
typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType);
107-
108-
E_LOOKUP_INFO_FUNCTION_DEF(default);
109-
E_LOOKUP_ACCESS_FUNCTION_DEF(default);
110-
E_LOOKUP_RANGE_FUNCTION_DEF(default);
111-
E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default);
112112
E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default);
113113

114114
typedef struct E_LookupRule E_LookupRule;
@@ -143,6 +143,68 @@ struct E_LookupRuleMap
143143
U64 slots_count;
144144
};
145145

146+
////////////////////////////////
147+
//~ rjf: IR Generation Hooks
148+
149+
#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag)
150+
#define E_IRGEN_FUNCTION_NAME(name) e_irgen_##name
151+
#define E_IRGEN_FUNCTION_DEF(name) internal E_IRGEN_FUNCTION_SIG(E_IRGEN_FUNCTION_NAME(name))
152+
typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType);
153+
E_IRGEN_FUNCTION_DEF(default);
154+
155+
typedef struct E_IRGenRule E_IRGenRule;
156+
struct E_IRGenRule
157+
{
158+
String8 name;
159+
E_IRGenFunctionType *irgen;
160+
};
161+
162+
typedef struct E_IRGenRuleNode E_IRGenRuleNode;
163+
struct E_IRGenRuleNode
164+
{
165+
E_IRGenRuleNode *next;
166+
E_IRGenRule v;
167+
};
168+
169+
typedef struct E_IRGenRuleSlot E_IRGenRuleSlot;
170+
struct E_IRGenRuleSlot
171+
{
172+
E_IRGenRuleNode *first;
173+
E_IRGenRuleNode *last;
174+
};
175+
176+
typedef struct E_IRGenRuleMap E_IRGenRuleMap;
177+
struct E_IRGenRuleMap
178+
{
179+
U64 slots_count;
180+
E_IRGenRuleSlot *slots;
181+
};
182+
183+
////////////////////////////////
184+
//~ rjf: Used Tag Map Data Structure
185+
186+
typedef struct E_UsedTagNode E_UsedTagNode;
187+
struct E_UsedTagNode
188+
{
189+
E_UsedTagNode *next;
190+
E_UsedTagNode *prev;
191+
E_Expr *tag;
192+
};
193+
194+
typedef struct E_UsedTagSlot E_UsedTagSlot;
195+
struct E_UsedTagSlot
196+
{
197+
E_UsedTagNode *first;
198+
E_UsedTagNode *last;
199+
};
200+
201+
typedef struct E_UsedTagMap E_UsedTagMap;
202+
struct E_UsedTagMap
203+
{
204+
U64 slots_count;
205+
E_UsedTagSlot *slots;
206+
};
207+
146208
////////////////////////////////
147209
//~ rjf: Parse Context
148210

@@ -151,6 +213,8 @@ struct E_IRCtx
151213
{
152214
E_String2ExprMap *macro_map;
153215
E_LookupRuleMap *lookup_rule_map;
216+
E_IRGenRuleMap *irgen_rule_map;
217+
E_UsedTagMap *used_tag_map;
154218
};
155219

156220
////////////////////////////////
@@ -165,6 +229,11 @@ local_persist read_only E_LookupRule e_lookup_rule__default =
165229
E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default),
166230
E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default),
167231
};
232+
local_persist read_only E_IRGenRule e_irgen_rule__default =
233+
{
234+
str8_lit_comp("default"),
235+
E_IRGEN_FUNCTION_NAME(default),
236+
};
168237
global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil};
169238
thread_static E_IRCtx *e_ir_ctx = 0;
170239

@@ -189,6 +258,15 @@ internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_Loo
189258

190259
internal E_LookupRule *e_lookup_rule_from_string(String8 string);
191260

261+
////////////////////////////////
262+
//~ rjf: IR Gen Rules
263+
264+
internal E_IRGenRuleMap e_irgen_rule_map_make(Arena *arena, U64 slots_count);
265+
internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule);
266+
#define e_irgen_rule_map_insert_new(arena, map, name_, ...) e_irgen_rule_map_insert((arena), (map), &(E_IRGenRule){.name = (name_), __VA_ARGS__})
267+
268+
internal E_IRGenRule *e_irgen_rule_from_string(String8 string);
269+
192270
////////////////////////////////
193271
//~ rjf: IR-ization Functions
194272

@@ -221,11 +299,10 @@ internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out,
221299
internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key);
222300

223301
//- rjf: top-level irtree/type extraction
224-
internal E_IRTreeAndType e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr *expr);
225302
internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr);
226303

227304
//- rjf: irtree -> linear ops/bytecode
228-
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out);
305+
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out);
229306
internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root);
230307
internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist);
231308

src/eval/eval_parse.c

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ global read_only String8 e_multichar_symbol_strings[] =
1515
str8_lit_comp("!="),
1616
str8_lit_comp("&&"),
1717
str8_lit_comp("||"),
18+
str8_lit_comp("=>"),
1819
};
1920

2021
global read_only S64 e_max_precedence = 15;
@@ -649,7 +650,7 @@ internal E_Expr *
649650
e_push_expr(Arena *arena, E_ExprKind kind, void *location)
650651
{
651652
E_Expr *e = push_array(arena, E_Expr, 1);
652-
e->first = e->last = e->next = e->ref = &e_expr_nil;
653+
e->first = e->last = e->next = e->ref = e->first_tag = e->last_tag = &e_expr_nil;
653654
e->location = location;
654655
e->kind = kind;
655656
return e;
@@ -673,6 +674,12 @@ e_expr_remove_child(E_Expr *parent, E_Expr *child)
673674
DLLRemove_NPZ(&e_expr_nil, parent->first, parent->last, child, next, prev);
674675
}
675676

677+
internal void
678+
e_expr_push_tag(E_Expr *parent, E_Expr *child)
679+
{
680+
DLLPushBack_NPZ(&e_expr_nil, parent->first_tag, parent->last_tag, child, next, prev);
681+
}
682+
676683
internal E_Expr *
677684
e_expr_ref(Arena *arena, E_Expr *ref)
678685
{
@@ -744,6 +751,78 @@ e_expr_ref_bswap(Arena *arena, E_Expr *rhs)
744751
return root;
745752
}
746753

754+
internal E_Expr *
755+
e_expr_copy(Arena *arena, E_Expr *src)
756+
{
757+
E_Expr *result = &e_expr_nil;
758+
Temp scratch = scratch_begin(&arena, 1);
759+
{
760+
typedef struct Task Task;
761+
struct Task
762+
{
763+
Task *next;
764+
E_Expr *dst_parent;
765+
E_Expr *src;
766+
B32 is_ref;
767+
B32 is_tag;
768+
};
769+
Task start_task = {0, &e_expr_nil, src};
770+
Task *first_task = &start_task;
771+
Task *last_task = first_task;
772+
for(Task *t = first_task; t != 0; t = t->next)
773+
{
774+
E_Expr *dst = e_push_expr(arena, t->src->kind, t->src->location);
775+
dst->mode = t->src->mode;
776+
dst->space = t->src->space;
777+
dst->type_key = t->src->type_key;
778+
dst->value = t->src->value;
779+
dst->string = push_str8_copy(arena, t->src->string);
780+
dst->bytecode = push_str8_copy(arena, t->src->bytecode);
781+
if(t->dst_parent == &e_expr_nil)
782+
{
783+
result = dst;
784+
}
785+
else if(t->is_ref)
786+
{
787+
t->dst_parent->ref = dst;
788+
}
789+
else if(t->is_tag)
790+
{
791+
e_expr_push_tag(t->dst_parent, dst);
792+
}
793+
else
794+
{
795+
e_expr_push_child(t->dst_parent, dst);
796+
}
797+
if(t->src->ref != &e_expr_nil)
798+
{
799+
Task *task = push_array(scratch.arena, Task, 1);
800+
task->dst_parent = dst;
801+
task->src = t->src->ref;
802+
task->is_ref = 1;
803+
SLLQueuePush(first_task, last_task, task);
804+
}
805+
for(E_Expr *src_child = t->src->first; src_child != &e_expr_nil; src_child = src_child->next)
806+
{
807+
Task *task = push_array(scratch.arena, Task, 1);
808+
task->dst_parent = dst;
809+
task->src = src_child;
810+
SLLQueuePush(first_task, last_task, task);
811+
}
812+
for(E_Expr *src_child = t->src->first_tag; src_child != &e_expr_nil; src_child = src_child->next)
813+
{
814+
Task *task = push_array(scratch.arena, Task, 1);
815+
task->dst_parent = dst;
816+
task->src = src_child;
817+
task->is_tag = 1;
818+
SLLQueuePush(first_task, last_task, task);
819+
}
820+
}
821+
}
822+
scratch_end(scratch);
823+
return result;
824+
}
825+
747826
////////////////////////////////
748827
//~ rjf: Expression Tree -> String Conversions
749828

@@ -1943,6 +2022,44 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
19432022
}
19442023
}
19452024

2025+
// rjf: calls
2026+
if(token.kind == E_TokenKind_Symbol &&
2027+
str8_match(token_string, str8_lit("("), 0))
2028+
{
2029+
it += 1;
2030+
E_Expr *callee_expr = atom;
2031+
E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str);
2032+
e_expr_push_child(call_expr, callee_expr);
2033+
for(B32 done = 0; !done && it < it_opl;)
2034+
{
2035+
E_Token token = e_token_at_it(it, tokens);
2036+
String8 token_string = str8_substr(text, token.range);
2037+
if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit(")"), 0))
2038+
{
2039+
done = 1;
2040+
it += 1;
2041+
}
2042+
else
2043+
{
2044+
E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl);
2045+
E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence);
2046+
e_msg_list_concat_in_place(&result.msgs, &arg_parse.msgs);
2047+
if(arg_parse.expr != &e_expr_nil)
2048+
{
2049+
e_expr_push_child(call_expr, arg_parse.expr);
2050+
}
2051+
it = arg_parse.last_token;
2052+
E_Token maybe_comma = e_token_at_it(it, tokens);
2053+
String8 maybe_comma_string = str8_substr(text, token.range);
2054+
if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0))
2055+
{
2056+
it += 1;
2057+
}
2058+
}
2059+
}
2060+
atom = call_expr;
2061+
}
2062+
19462063
// rjf: quit if this doesn't look like any patterns of postfix unary we know
19472064
if(!is_postfix_unary)
19482065
{
@@ -2100,6 +2217,46 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
21002217
}
21012218
}
21022219

2220+
//- rjf: parse tags
2221+
{
2222+
if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0))
2223+
{
2224+
for(B32 done = 0; !done && it < it_opl;)
2225+
{
2226+
E_Token maybe_identifier = e_token_at_it(it, tokens);
2227+
E_Token maybe_open_paren = e_token_at_it(it+1, tokens);
2228+
String8 maybe_open_paren_string = str8_substr(text, maybe_open_paren.range);
2229+
if(maybe_identifier.kind == E_TokenKind_Identifier &&
2230+
maybe_open_paren.kind == E_TokenKind_Symbol &&
2231+
str8_match(maybe_open_paren_string, str8_lit("("), 0))
2232+
{
2233+
E_TokenArray tag_tokens = e_token_array_make_first_opl(it, it_opl);
2234+
E_Parse tag_parse = e_parse_expr_from_text_tokens(arena, text, &tag_tokens);
2235+
e_msg_list_concat_in_place(&result.msgs, &tag_parse.msgs);
2236+
it = tag_parse.last_token;
2237+
if(tag_parse.expr != &e_expr_nil)
2238+
{
2239+
e_expr_push_tag(atom, tag_parse.expr);
2240+
}
2241+
else
2242+
{
2243+
done = 1;
2244+
}
2245+
E_Token maybe_comma = e_token_at_it(it, tokens);
2246+
String8 maybe_comma_string = str8_substr(text, token.range);
2247+
if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0))
2248+
{
2249+
it += 1;
2250+
}
2251+
}
2252+
else
2253+
{
2254+
done = 1;
2255+
}
2256+
}
2257+
}
2258+
}
2259+
21032260
// rjf: if we parsed nothing successfully, we're done
21042261
if(it == start_it)
21052262
{

0 commit comments

Comments
 (0)