mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-25 05:04:58 -07:00
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
This commit is contained in:
@@ -117,6 +117,8 @@ E_ExprKindTable:
|
||||
|
||||
{ Ternary Null 0 "? " "" "?" ":"}
|
||||
|
||||
{ Call Null 0 "()" "(" "," ")"}
|
||||
|
||||
{ LeafBytecode Null 0 "bytecode" "" "" "" }
|
||||
{ LeafMember Null 0 "member" "" "" "" }
|
||||
{ LeafStringLiteral Null 0 "string_literal" "" "" "" }
|
||||
@@ -136,6 +138,8 @@ E_ExprKindTable:
|
||||
{ Line Binary 1 ":" "" ":" "" }
|
||||
|
||||
{ Define Binary 13 "=" "" "=" "" }
|
||||
|
||||
{ Tag Null 0 "=>" "=>" "," "" }
|
||||
}
|
||||
|
||||
@table(name display_string)
|
||||
|
||||
+276
-42
@@ -455,6 +455,196 @@ E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default)
|
||||
return id;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IR Gen Rules
|
||||
|
||||
E_IRGEN_FUNCTION_DEF(cast)
|
||||
{
|
||||
E_Expr *type_expr = tag->first->next;
|
||||
E_TypeKey type_key = e_type_from_expr(type_expr);
|
||||
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
|
||||
E_IRTreeAndType result = {irtree.root, type_key, irtree.mode, irtree.msgs};
|
||||
return result;
|
||||
}
|
||||
|
||||
E_IRGEN_FUNCTION_DEF(bswap)
|
||||
{
|
||||
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
|
||||
E_IRNode *root = e_push_irnode(arena, RDI_EvalOp_ByteSwap);
|
||||
e_irnode_push_child(root, irtree.root);
|
||||
E_IRTreeAndType result = {root, irtree.type_key, irtree.mode, irtree.msgs};
|
||||
return result;
|
||||
}
|
||||
|
||||
E_IRGEN_FUNCTION_DEF(array)
|
||||
{
|
||||
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
|
||||
E_TypeKey type_key = irtree.type_key;
|
||||
E_TypeKind type_kind = e_type_kind_from_key(type_key);
|
||||
if(e_type_kind_is_pointer_or_ref(type_kind))
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Eval count_eval = e_eval_from_expr(scratch.arena, tag->first->next);
|
||||
E_TypeKey element_type_key = e_type_ptee_from_key(type_key);
|
||||
E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count_eval.value.u64);
|
||||
E_TypeKey ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0);
|
||||
irtree.type_key = ptr_type_key;
|
||||
scratch_end(scratch);
|
||||
}
|
||||
return irtree;
|
||||
}
|
||||
|
||||
E_IRGEN_FUNCTION_DEF(slice)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr);
|
||||
E_TypeKind type_kind = e_type_kind_from_key(irtree.type_key);
|
||||
if(type_kind == E_TypeKind_Struct || type_kind == E_TypeKind_Class)
|
||||
{
|
||||
// rjf: unpack members
|
||||
E_MemberArray members = e_type_data_members_from_key__cached(irtree.type_key);
|
||||
|
||||
// rjf: choose base pointer & count members
|
||||
E_Member *base_ptr_member = 0;
|
||||
E_Member *count_member = 0;
|
||||
for(U64 idx = 0; idx < members.count; idx += 1)
|
||||
{
|
||||
E_Member *member = &members.v[idx];
|
||||
E_TypeKey member_type = e_type_unwrap(member->type_key);
|
||||
E_TypeKind member_type_kind = e_type_kind_from_key(member_type);
|
||||
if(count_member == 0 && e_type_kind_is_integer(member_type_kind))
|
||||
{
|
||||
count_member = member;
|
||||
}
|
||||
if(base_ptr_member == 0 && e_type_kind_is_pointer_or_ref(member_type_kind))
|
||||
{
|
||||
base_ptr_member = &members.v[idx];
|
||||
}
|
||||
if(count_member != 0 && base_ptr_member != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: evaluate count member, determine count
|
||||
U64 count = 0;
|
||||
if(count_member != 0)
|
||||
{
|
||||
E_Expr *count_member_expr = e_expr_ref_member_access(scratch.arena, expr, count_member->name);
|
||||
E_Eval count_member_eval = e_eval_from_expr(scratch.arena, count_member_expr);
|
||||
E_Eval count_member_value_eval = e_value_eval_from_eval(count_member_eval);
|
||||
count = count_member_value_eval.value.u64;
|
||||
}
|
||||
|
||||
// rjf: generate new struct slice type
|
||||
E_TypeKey slice_type_key = zero_struct;
|
||||
if(base_ptr_member != 0 && count_member != 0)
|
||||
{
|
||||
String8 struct_name = e_type_string_from_key(scratch.arena, irtree.type_key);
|
||||
E_TypeKey element_type_key = e_type_ptee_from_key(base_ptr_member->type_key);
|
||||
E_TypeKey array_type_key = e_type_key_cons_array(element_type_key, count);
|
||||
E_TypeKey sized_base_ptr_type_key = e_type_key_cons_ptr(e_type_state->ctx->primary_module->arch, array_type_key, 0);
|
||||
E_MemberList slice_type_members = {0};
|
||||
e_member_list_push(scratch.arena, &slice_type_members, count_member);
|
||||
e_member_list_push(scratch.arena, &slice_type_members, &(E_Member){.kind = E_MemberKind_DataField, .type_key = sized_base_ptr_type_key, .name = base_ptr_member->name, .pretty_name = base_ptr_member->pretty_name, .off = base_ptr_member->off});
|
||||
E_MemberArray slice_type_members_array = e_member_array_from_list(scratch.arena, &slice_type_members);
|
||||
slice_type_key = e_type_key_cons(.arch = e_type_state->ctx->primary_module->arch,
|
||||
.kind = E_TypeKind_Struct,
|
||||
.name = struct_name,
|
||||
.members = slice_type_members_array.v,
|
||||
.count = slice_type_members_array.count);
|
||||
}
|
||||
|
||||
// rjf: overwrite type
|
||||
irtree.type_key = slice_type_key;
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return irtree;
|
||||
}
|
||||
|
||||
E_IRGEN_FUNCTION_DEF(wrap)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_Expr *expr_to_irify = expr;
|
||||
E_Expr *wrap_expr_src = tag->first->next;
|
||||
if(wrap_expr_src != &e_expr_nil)
|
||||
{
|
||||
expr_to_irify = e_expr_copy(scratch.arena, wrap_expr_src);
|
||||
typedef struct Task Task;
|
||||
struct Task
|
||||
{
|
||||
Task *next;
|
||||
E_Expr *parent;
|
||||
E_Expr *expr;
|
||||
};
|
||||
Task start_task = {0, &e_expr_nil, expr_to_irify};
|
||||
Task *first_task = &start_task;
|
||||
Task *last_task = first_task;
|
||||
for(Task *t = first_task; t != 0; t = t->next)
|
||||
{
|
||||
if(t->expr->kind == E_ExprKind_LeafIdent && str8_match(t->expr->string, str8_lit("$expr"), 0))
|
||||
{
|
||||
E_Expr *original_expr_ref = e_expr_ref(arena, expr);
|
||||
if(t->parent != &e_expr_nil)
|
||||
{
|
||||
e_expr_insert_child(t->parent, t->expr, original_expr_ref);
|
||||
e_expr_remove_child(t->parent, t->expr);
|
||||
}
|
||||
}
|
||||
else for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
task->parent = t->expr;
|
||||
task->expr = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
E_IRTreeAndType irtree = e_irtree_and_type_from_expr(arena, expr_to_irify);
|
||||
scratch_end(scratch);
|
||||
return irtree;
|
||||
}
|
||||
|
||||
internal E_IRGenRuleMap
|
||||
e_irgen_rule_map_make(Arena *arena, U64 slots_count)
|
||||
{
|
||||
E_IRGenRuleMap map = {0};
|
||||
map.slots_count = slots_count;
|
||||
map.slots = push_array(arena, E_IRGenRuleSlot, map.slots_count);
|
||||
return map;
|
||||
}
|
||||
|
||||
internal void
|
||||
e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGenRule *rule)
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, rule->name);
|
||||
U64 slot_idx = hash%map->slots_count;
|
||||
E_IRGenRuleNode *n = push_array(arena, E_IRGenRuleNode, 1);
|
||||
MemoryCopyStruct(&n->v, rule);
|
||||
n->v.name = push_str8_copy(arena, n->v.name);
|
||||
SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, n);
|
||||
}
|
||||
|
||||
internal E_IRGenRule *
|
||||
e_irgen_rule_from_string(String8 string)
|
||||
{
|
||||
E_IRGenRule *rule = &e_irgen_rule__default;
|
||||
{
|
||||
E_IRGenRuleMap *map = e_ir_ctx->irgen_rule_map;
|
||||
U64 hash = e_hash_from_string(5381, string);
|
||||
U64 slot_idx = hash%map->slots_count;
|
||||
for(E_IRGenRuleNode *n = map->slots[slot_idx].first; n != 0; n = n->next)
|
||||
{
|
||||
if(str8_match(string, n->v.name, 0))
|
||||
{
|
||||
rule = &n->v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rule;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IR-ization Functions
|
||||
|
||||
@@ -752,8 +942,7 @@ e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_Type
|
||||
|
||||
//- rjf: top-level irtree/type extraction
|
||||
|
||||
internal E_IRTreeAndType
|
||||
e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr *expr)
|
||||
E_IRGEN_FUNCTION_DEF(default)
|
||||
{
|
||||
E_IRTreeAndType result = {&e_irnode_nil};
|
||||
E_ExprKind kind = expr->kind;
|
||||
@@ -764,7 +953,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
//- rjf: references -> just descend to sub-expr
|
||||
case E_ExprKind_Ref:
|
||||
{
|
||||
result = e_irtree_and_type_from_expr__space(arena, current_space, expr->ref);
|
||||
result = e_irtree_and_type_from_expr(arena, expr->ref);
|
||||
}break;
|
||||
|
||||
//- rjf: accesses
|
||||
@@ -793,7 +982,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
// rjf: unpack operand
|
||||
E_Expr *r_expr = expr->first;
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
E_TypeKey r_type = e_type_unwrap(r_tree.type_key);
|
||||
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
|
||||
E_TypeKey r_type_direct = e_type_direct_from_key(r_type);
|
||||
@@ -848,7 +1037,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
// rjf: unpack operand
|
||||
E_Expr *r_expr = expr->first;
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
E_TypeKey r_type = r_tree.type_key;
|
||||
E_TypeKey r_type_unwrapped = e_type_unwrap(r_type);
|
||||
E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped);
|
||||
@@ -879,7 +1068,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
E_TypeKey cast_type = e_type_from_expr(cast_type_expr);
|
||||
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);
|
||||
E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr__space(arena, current_space, casted_expr);
|
||||
E_IRTreeAndType casted_tree = e_irtree_and_type_from_expr(arena, casted_expr);
|
||||
e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs);
|
||||
E_TypeKey casted_type = e_type_unwrap(casted_tree.type_key);
|
||||
E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type);
|
||||
@@ -945,7 +1134,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
}break;
|
||||
default:
|
||||
{
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
|
||||
r_type = r_tree.type_key;
|
||||
}break;
|
||||
@@ -975,7 +1164,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
// rjf: evaluate operand tree
|
||||
E_Expr *r_expr = expr->first;
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
|
||||
|
||||
// rjf: fill output
|
||||
@@ -989,7 +1178,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
// rjf: unpack operand
|
||||
E_Expr *r_expr = expr->first;
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
|
||||
E_TypeKey r_type = e_type_unwrap(r_tree.type_key);
|
||||
E_TypeKind r_type_kind = e_type_kind_from_key(r_type);
|
||||
@@ -1017,7 +1206,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
//- rjf: unary operations
|
||||
case E_ExprKind_Pos:
|
||||
{
|
||||
result = e_irtree_and_type_from_expr__space(arena, current_space, expr->first);
|
||||
result = e_irtree_and_type_from_expr(arena, expr->first);
|
||||
}break;
|
||||
case E_ExprKind_Neg:
|
||||
case E_ExprKind_LogNot:
|
||||
@@ -1025,7 +1214,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
// rjf: unpack operand
|
||||
E_Expr *r_expr = expr->first;
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
E_TypeKey r_type = e_type_unwrap(r_tree.type_key);
|
||||
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);
|
||||
@@ -1080,8 +1269,8 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
B32 is_comparison = e_expr_kind_is_comparison(kind);
|
||||
E_Expr *l_expr = expr->first;
|
||||
E_Expr *r_expr = l_expr->next;
|
||||
E_IRTreeAndType l_tree = e_irtree_and_type_from_expr__space(arena, current_space, l_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs);
|
||||
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
|
||||
E_TypeKey l_type = e_type_unwrap_enum(e_type_unwrap(l_tree.type_key));
|
||||
@@ -1304,9 +1493,9 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
E_Expr *c_expr = expr->first;
|
||||
E_Expr *l_expr = c_expr->next;
|
||||
E_Expr *r_expr = l_expr->next;
|
||||
E_IRTreeAndType c_tree = e_irtree_and_type_from_expr__space(arena, current_space, c_expr);
|
||||
E_IRTreeAndType l_tree = e_irtree_and_type_from_expr__space(arena, current_space, l_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr__space(arena, current_space, r_expr);
|
||||
E_IRTreeAndType c_tree = e_irtree_and_type_from_expr(arena, c_expr);
|
||||
E_IRTreeAndType l_tree = e_irtree_and_type_from_expr(arena, l_expr);
|
||||
E_IRTreeAndType r_tree = e_irtree_and_type_from_expr(arena, r_expr);
|
||||
e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs);
|
||||
e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs);
|
||||
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
|
||||
@@ -1350,6 +1539,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
case E_ExprKind_LeafBytecode:
|
||||
{
|
||||
E_IRNode *new_tree = e_irtree_bytecode_no_copy(arena, expr->bytecode);
|
||||
new_tree->space = expr->space;
|
||||
E_TypeKey final_type_key = expr->type_key;
|
||||
result.root = new_tree;
|
||||
result.type_key = final_type_key;
|
||||
@@ -1427,7 +1617,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
else
|
||||
{
|
||||
e_string2expr_map_inc_poison(e_ir_ctx->macro_map, expr->string);
|
||||
result = e_irtree_and_type_from_expr__space(arena, current_space, macro_expr);
|
||||
result = e_irtree_and_type_from_expr(arena, macro_expr);
|
||||
e_string2expr_map_dec_poison(e_ir_ctx->macro_map, expr->string);
|
||||
}
|
||||
}break;
|
||||
@@ -1437,6 +1627,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
E_IRNode *new_tree = e_push_irnode(arena, RDI_EvalOp_ConstU64);
|
||||
new_tree->value.u64 = expr->value.u64;
|
||||
new_tree->space = expr->space;
|
||||
result.root = new_tree;
|
||||
result.type_key = expr->type_key;
|
||||
result.mode = E_Mode_Offset;
|
||||
@@ -1449,8 +1640,8 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
E_Space space = {E_SpaceKind_HashStoreKey, .u128 = key};
|
||||
U64 size = fs_size_from_path(expr->string);
|
||||
E_IRNode *base_offset = e_irtree_const_u(arena, 0);
|
||||
E_IRNode *set_space = e_irtree_set_space(arena, space, base_offset);
|
||||
result.root = set_space;
|
||||
base_offset->space = space;
|
||||
result.root = base_offset;
|
||||
result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), size);
|
||||
result.mode = E_Mode_Offset;
|
||||
}break;
|
||||
@@ -1459,6 +1650,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
case E_ExprKind_TypeIdent:
|
||||
{
|
||||
result.root = e_irtree_const_u(arena, 0);
|
||||
result.root->space = expr->space;
|
||||
result.type_key = expr->type_key;
|
||||
result.mode = E_Mode_Null;
|
||||
}break;
|
||||
@@ -1476,7 +1668,7 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
E_Expr *lhs = expr->first;
|
||||
E_Expr *rhs = expr->last;
|
||||
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr__space(arena, current_space, lhs);
|
||||
E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(arena, lhs);
|
||||
U64 line_num = rhs->value.u64;
|
||||
B32 space_is_good = 1;
|
||||
E_Space space = {0};
|
||||
@@ -1506,10 +1698,10 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
Rng1U64 line_range = text_info.lines_ranges[line_num-1];
|
||||
U64 line_size = dim_1u64(line_range);
|
||||
E_IRNode *line_offset = e_irtree_const_u(arena, line_range.min);
|
||||
E_IRNode *set_space = e_irtree_set_space(arena, space, line_offset);
|
||||
result.root = set_space;
|
||||
result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), line_size);
|
||||
result.mode = E_Mode_Offset;
|
||||
result.root = line_offset;
|
||||
result.root->space = space;
|
||||
result.type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), line_size);
|
||||
result.mode = E_Mode_Offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1524,41 +1716,82 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr
|
||||
{
|
||||
E_Expr *lhs = expr->first;
|
||||
E_Expr *rhs = lhs->next;
|
||||
result = e_irtree_and_type_from_expr__space(arena, current_space, rhs);
|
||||
result = e_irtree_and_type_from_expr(arena, rhs);
|
||||
if(lhs->kind != E_ExprKind_LeafIdent)
|
||||
{
|
||||
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier.");
|
||||
}
|
||||
}break;
|
||||
}
|
||||
|
||||
//- rjf: if the expression's space does not match the current, then push a set-space node
|
||||
// before returning
|
||||
E_Space zero_space = zero_struct;
|
||||
if(!MemoryMatchStruct(current_space, &expr->space) &&
|
||||
!MemoryMatchStruct(&zero_space, &expr->space))
|
||||
{
|
||||
result.root = e_irtree_set_space(arena, expr->space, result.root);
|
||||
*current_space = expr->space;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
internal E_IRTreeAndType
|
||||
e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
|
||||
{
|
||||
E_Space space = e_interpret_ctx->primary_space;
|
||||
E_IRTreeAndType result = e_irtree_and_type_from_expr__space(arena, &space, expr);
|
||||
E_IRTreeAndType result = {&e_irnode_nil};
|
||||
E_IRGenRule *irgen_rule = &e_irgen_rule__default;
|
||||
E_Expr *irgen_rule_tag = &e_expr_nil;
|
||||
for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next)
|
||||
{
|
||||
String8 name = tag->first->string;
|
||||
E_IRGenRule *irgen_rule_candidate = e_irgen_rule_from_string(name);
|
||||
if(irgen_rule_candidate != &e_irgen_rule__default)
|
||||
{
|
||||
B32 tag_is_poisoned = 0;
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&tag));
|
||||
U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count;
|
||||
for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->tag == tag)
|
||||
{
|
||||
tag_is_poisoned = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!tag_is_poisoned)
|
||||
{
|
||||
E_UsedTagNode *n = push_array(arena, E_UsedTagNode, 1);
|
||||
n->tag = tag;
|
||||
DLLPushBack(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n);
|
||||
irgen_rule_tag = tag;
|
||||
irgen_rule = irgen_rule_candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = irgen_rule->irgen(arena, expr, irgen_rule_tag);
|
||||
if(irgen_rule_tag != &e_expr_nil)
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&irgen_rule_tag));
|
||||
U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count;
|
||||
for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->tag == irgen_rule_tag)
|
||||
{
|
||||
DLLRemove(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: irtree -> linear ops/bytecode
|
||||
|
||||
internal void
|
||||
e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out)
|
||||
e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out)
|
||||
{
|
||||
U32 op = root->op;
|
||||
{
|
||||
E_Space zero_space = zero_struct;
|
||||
if(!MemoryMatchStruct(&root->space, &zero_space) &&
|
||||
!MemoryMatchStruct(&root->space, current_space))
|
||||
{
|
||||
*current_space = root->space;
|
||||
e_oplist_push_set_space(arena, out, root->space);
|
||||
}
|
||||
}
|
||||
switch(op)
|
||||
{
|
||||
case RDI_EvalOp_Stop:
|
||||
@@ -1581,7 +1814,7 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out)
|
||||
child != &e_irnode_nil;
|
||||
child = child->next)
|
||||
{
|
||||
e_append_oplist_from_irtree(arena, child, out);
|
||||
e_append_oplist_from_irtree(arena, child, current_space, out);
|
||||
}
|
||||
}break;
|
||||
|
||||
@@ -1632,7 +1865,7 @@ e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out)
|
||||
child != &e_irnode_nil && idx < child_count;
|
||||
child = child->next, idx += 1)
|
||||
{
|
||||
e_append_oplist_from_irtree(arena, child, out);
|
||||
e_append_oplist_from_irtree(arena, child, current_space, out);
|
||||
}
|
||||
|
||||
// rjf: emit op to compute this node
|
||||
@@ -1646,7 +1879,8 @@ internal E_OpList
|
||||
e_oplist_from_irtree(Arena *arena, E_IRNode *root)
|
||||
{
|
||||
E_OpList ops = {0};
|
||||
e_append_oplist_from_irtree(arena, root, &ops);
|
||||
E_Space space = e_interpret_ctx->primary_space;
|
||||
e_append_oplist_from_irtree(arena, root, &space, &ops);
|
||||
return ops;
|
||||
}
|
||||
|
||||
|
||||
+84
-7
@@ -42,6 +42,7 @@ struct E_IRNode
|
||||
E_IRNode *last;
|
||||
E_IRNode *next;
|
||||
RDI_EvalOp op;
|
||||
E_Space space;
|
||||
String8 string;
|
||||
E_Value value;
|
||||
};
|
||||
@@ -84,31 +85,30 @@ struct E_LookupRange
|
||||
#define E_LOOKUP_INFO_FUNCTION_NAME(name) e_lookup_info_##name
|
||||
#define E_LOOKUP_INFO_FUNCTION_DEF(name) internal E_LOOKUP_INFO_FUNCTION_SIG(E_LOOKUP_INFO_FUNCTION_NAME(name))
|
||||
typedef E_LOOKUP_INFO_FUNCTION_SIG(E_LookupInfoFunctionType);
|
||||
E_LOOKUP_INFO_FUNCTION_DEF(default);
|
||||
|
||||
#define E_LOOKUP_ACCESS_FUNCTION_SIG(name) E_LookupAccess name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data)
|
||||
#define E_LOOKUP_ACCESS_FUNCTION_NAME(name) e_lookup_access_##name
|
||||
#define E_LOOKUP_ACCESS_FUNCTION_DEF(name) internal E_LOOKUP_ACCESS_FUNCTION_SIG(E_LOOKUP_ACCESS_FUNCTION_NAME(name))
|
||||
typedef E_LOOKUP_ACCESS_FUNCTION_SIG(E_LookupAccessFunctionType);
|
||||
E_LOOKUP_ACCESS_FUNCTION_DEF(default);
|
||||
|
||||
#define E_LOOKUP_RANGE_FUNCTION_SIG(name) E_LookupRange name(Arena *arena, E_Expr *lhs, Rng1U64 idx_range, void *user_data)
|
||||
#define E_LOOKUP_RANGE_FUNCTION_NAME(name) e_lookup_range_##name
|
||||
#define E_LOOKUP_RANGE_FUNCTION_DEF(name) internal E_LOOKUP_RANGE_FUNCTION_SIG(E_LOOKUP_RANGE_FUNCTION_NAME(name))
|
||||
typedef E_LOOKUP_RANGE_FUNCTION_SIG(E_LookupRangeFunctionType);
|
||||
E_LOOKUP_RANGE_FUNCTION_DEF(default);
|
||||
|
||||
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data)
|
||||
#define E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(name) e_lookup_id_from_num_##name
|
||||
#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))
|
||||
typedef E_LOOKUP_ID_FROM_NUM_FUNCTION_SIG(E_LookupIDFromNumFunctionType);
|
||||
E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default);
|
||||
|
||||
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data)
|
||||
#define E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(name) e_lookup_num_from_id_##name
|
||||
#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))
|
||||
typedef E_LOOKUP_NUM_FROM_ID_FUNCTION_SIG(E_LookupNumFromIDFunctionType);
|
||||
|
||||
E_LOOKUP_INFO_FUNCTION_DEF(default);
|
||||
E_LOOKUP_ACCESS_FUNCTION_DEF(default);
|
||||
E_LOOKUP_RANGE_FUNCTION_DEF(default);
|
||||
E_LOOKUP_ID_FROM_NUM_FUNCTION_DEF(default);
|
||||
E_LOOKUP_NUM_FROM_ID_FUNCTION_DEF(default);
|
||||
|
||||
typedef struct E_LookupRule E_LookupRule;
|
||||
@@ -143,6 +143,68 @@ struct E_LookupRuleMap
|
||||
U64 slots_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IR Generation Hooks
|
||||
|
||||
#define E_IRGEN_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_Expr *tag)
|
||||
#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))
|
||||
typedef E_IRGEN_FUNCTION_SIG(E_IRGenFunctionType);
|
||||
E_IRGEN_FUNCTION_DEF(default);
|
||||
|
||||
typedef struct E_IRGenRule E_IRGenRule;
|
||||
struct E_IRGenRule
|
||||
{
|
||||
String8 name;
|
||||
E_IRGenFunctionType *irgen;
|
||||
};
|
||||
|
||||
typedef struct E_IRGenRuleNode E_IRGenRuleNode;
|
||||
struct E_IRGenRuleNode
|
||||
{
|
||||
E_IRGenRuleNode *next;
|
||||
E_IRGenRule v;
|
||||
};
|
||||
|
||||
typedef struct E_IRGenRuleSlot E_IRGenRuleSlot;
|
||||
struct E_IRGenRuleSlot
|
||||
{
|
||||
E_IRGenRuleNode *first;
|
||||
E_IRGenRuleNode *last;
|
||||
};
|
||||
|
||||
typedef struct E_IRGenRuleMap E_IRGenRuleMap;
|
||||
struct E_IRGenRuleMap
|
||||
{
|
||||
U64 slots_count;
|
||||
E_IRGenRuleSlot *slots;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Used Tag Map Data Structure
|
||||
|
||||
typedef struct E_UsedTagNode E_UsedTagNode;
|
||||
struct E_UsedTagNode
|
||||
{
|
||||
E_UsedTagNode *next;
|
||||
E_UsedTagNode *prev;
|
||||
E_Expr *tag;
|
||||
};
|
||||
|
||||
typedef struct E_UsedTagSlot E_UsedTagSlot;
|
||||
struct E_UsedTagSlot
|
||||
{
|
||||
E_UsedTagNode *first;
|
||||
E_UsedTagNode *last;
|
||||
};
|
||||
|
||||
typedef struct E_UsedTagMap E_UsedTagMap;
|
||||
struct E_UsedTagMap
|
||||
{
|
||||
U64 slots_count;
|
||||
E_UsedTagSlot *slots;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Parse Context
|
||||
|
||||
@@ -151,6 +213,8 @@ struct E_IRCtx
|
||||
{
|
||||
E_String2ExprMap *macro_map;
|
||||
E_LookupRuleMap *lookup_rule_map;
|
||||
E_IRGenRuleMap *irgen_rule_map;
|
||||
E_UsedTagMap *used_tag_map;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -165,6 +229,11 @@ local_persist read_only E_LookupRule e_lookup_rule__default =
|
||||
E_LOOKUP_ID_FROM_NUM_FUNCTION_NAME(default),
|
||||
E_LOOKUP_NUM_FROM_ID_FUNCTION_NAME(default),
|
||||
};
|
||||
local_persist read_only E_IRGenRule e_irgen_rule__default =
|
||||
{
|
||||
str8_lit_comp("default"),
|
||||
E_IRGEN_FUNCTION_NAME(default),
|
||||
};
|
||||
global read_only E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil};
|
||||
thread_static E_IRCtx *e_ir_ctx = 0;
|
||||
|
||||
@@ -189,6 +258,15 @@ internal void e_lookup_rule_map_insert(Arena *arena, E_LookupRuleMap *map, E_Loo
|
||||
|
||||
internal E_LookupRule *e_lookup_rule_from_string(String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IR Gen Rules
|
||||
|
||||
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);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: IR-ization Functions
|
||||
|
||||
@@ -221,11 +299,10 @@ internal E_IRNode *e_irtree_convert_hi(Arena *arena, E_IRNode *c, E_TypeKey out,
|
||||
internal E_IRNode *e_irtree_resolve_to_value(Arena *arena, E_Mode from_mode, E_IRNode *tree, E_TypeKey type_key);
|
||||
|
||||
//- rjf: top-level irtree/type extraction
|
||||
internal E_IRTreeAndType e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr *expr);
|
||||
internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr);
|
||||
|
||||
//- rjf: irtree -> linear ops/bytecode
|
||||
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_OpList *out);
|
||||
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out);
|
||||
internal E_OpList e_oplist_from_irtree(Arena *arena, E_IRNode *root);
|
||||
internal String8 e_bytecode_from_oplist(Arena *arena, E_OpList *oplist);
|
||||
|
||||
|
||||
+158
-1
@@ -15,6 +15,7 @@ global read_only String8 e_multichar_symbol_strings[] =
|
||||
str8_lit_comp("!="),
|
||||
str8_lit_comp("&&"),
|
||||
str8_lit_comp("||"),
|
||||
str8_lit_comp("=>"),
|
||||
};
|
||||
|
||||
global read_only S64 e_max_precedence = 15;
|
||||
@@ -649,7 +650,7 @@ internal E_Expr *
|
||||
e_push_expr(Arena *arena, E_ExprKind kind, void *location)
|
||||
{
|
||||
E_Expr *e = push_array(arena, E_Expr, 1);
|
||||
e->first = e->last = e->next = e->ref = &e_expr_nil;
|
||||
e->first = e->last = e->next = e->ref = e->first_tag = e->last_tag = &e_expr_nil;
|
||||
e->location = location;
|
||||
e->kind = kind;
|
||||
return e;
|
||||
@@ -673,6 +674,12 @@ e_expr_remove_child(E_Expr *parent, E_Expr *child)
|
||||
DLLRemove_NPZ(&e_expr_nil, parent->first, parent->last, child, next, prev);
|
||||
}
|
||||
|
||||
internal void
|
||||
e_expr_push_tag(E_Expr *parent, E_Expr *child)
|
||||
{
|
||||
DLLPushBack_NPZ(&e_expr_nil, parent->first_tag, parent->last_tag, child, next, prev);
|
||||
}
|
||||
|
||||
internal E_Expr *
|
||||
e_expr_ref(Arena *arena, E_Expr *ref)
|
||||
{
|
||||
@@ -744,6 +751,78 @@ e_expr_ref_bswap(Arena *arena, E_Expr *rhs)
|
||||
return root;
|
||||
}
|
||||
|
||||
internal E_Expr *
|
||||
e_expr_copy(Arena *arena, E_Expr *src)
|
||||
{
|
||||
E_Expr *result = &e_expr_nil;
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
{
|
||||
typedef struct Task Task;
|
||||
struct Task
|
||||
{
|
||||
Task *next;
|
||||
E_Expr *dst_parent;
|
||||
E_Expr *src;
|
||||
B32 is_ref;
|
||||
B32 is_tag;
|
||||
};
|
||||
Task start_task = {0, &e_expr_nil, src};
|
||||
Task *first_task = &start_task;
|
||||
Task *last_task = first_task;
|
||||
for(Task *t = first_task; t != 0; t = t->next)
|
||||
{
|
||||
E_Expr *dst = e_push_expr(arena, t->src->kind, t->src->location);
|
||||
dst->mode = t->src->mode;
|
||||
dst->space = t->src->space;
|
||||
dst->type_key = t->src->type_key;
|
||||
dst->value = t->src->value;
|
||||
dst->string = push_str8_copy(arena, t->src->string);
|
||||
dst->bytecode = push_str8_copy(arena, t->src->bytecode);
|
||||
if(t->dst_parent == &e_expr_nil)
|
||||
{
|
||||
result = dst;
|
||||
}
|
||||
else if(t->is_ref)
|
||||
{
|
||||
t->dst_parent->ref = dst;
|
||||
}
|
||||
else if(t->is_tag)
|
||||
{
|
||||
e_expr_push_tag(t->dst_parent, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
e_expr_push_child(t->dst_parent, dst);
|
||||
}
|
||||
if(t->src->ref != &e_expr_nil)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->dst_parent = dst;
|
||||
task->src = t->src->ref;
|
||||
task->is_ref = 1;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
for(E_Expr *src_child = t->src->first; src_child != &e_expr_nil; src_child = src_child->next)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->dst_parent = dst;
|
||||
task->src = src_child;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
for(E_Expr *src_child = t->src->first_tag; src_child != &e_expr_nil; src_child = src_child->next)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->dst_parent = dst;
|
||||
task->src = src_child;
|
||||
task->is_tag = 1;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Expression Tree -> String Conversions
|
||||
|
||||
@@ -1943,6 +2022,44 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: calls
|
||||
if(token.kind == E_TokenKind_Symbol &&
|
||||
str8_match(token_string, str8_lit("("), 0))
|
||||
{
|
||||
it += 1;
|
||||
E_Expr *callee_expr = atom;
|
||||
E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str);
|
||||
e_expr_push_child(call_expr, callee_expr);
|
||||
for(B32 done = 0; !done && it < it_opl;)
|
||||
{
|
||||
E_Token token = e_token_at_it(it, tokens);
|
||||
String8 token_string = str8_substr(text, token.range);
|
||||
if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit(")"), 0))
|
||||
{
|
||||
done = 1;
|
||||
it += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl);
|
||||
E_Parse arg_parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence);
|
||||
e_msg_list_concat_in_place(&result.msgs, &arg_parse.msgs);
|
||||
if(arg_parse.expr != &e_expr_nil)
|
||||
{
|
||||
e_expr_push_child(call_expr, arg_parse.expr);
|
||||
}
|
||||
it = arg_parse.last_token;
|
||||
E_Token maybe_comma = e_token_at_it(it, tokens);
|
||||
String8 maybe_comma_string = str8_substr(text, token.range);
|
||||
if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0))
|
||||
{
|
||||
it += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
atom = call_expr;
|
||||
}
|
||||
|
||||
// rjf: quit if this doesn't look like any patterns of postfix unary we know
|
||||
if(!is_postfix_unary)
|
||||
{
|
||||
@@ -2100,6 +2217,46 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: parse tags
|
||||
{
|
||||
if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0))
|
||||
{
|
||||
for(B32 done = 0; !done && it < it_opl;)
|
||||
{
|
||||
E_Token maybe_identifier = e_token_at_it(it, tokens);
|
||||
E_Token maybe_open_paren = e_token_at_it(it+1, tokens);
|
||||
String8 maybe_open_paren_string = str8_substr(text, maybe_open_paren.range);
|
||||
if(maybe_identifier.kind == E_TokenKind_Identifier &&
|
||||
maybe_open_paren.kind == E_TokenKind_Symbol &&
|
||||
str8_match(maybe_open_paren_string, str8_lit("("), 0))
|
||||
{
|
||||
E_TokenArray tag_tokens = e_token_array_make_first_opl(it, it_opl);
|
||||
E_Parse tag_parse = e_parse_expr_from_text_tokens(arena, text, &tag_tokens);
|
||||
e_msg_list_concat_in_place(&result.msgs, &tag_parse.msgs);
|
||||
it = tag_parse.last_token;
|
||||
if(tag_parse.expr != &e_expr_nil)
|
||||
{
|
||||
e_expr_push_tag(atom, tag_parse.expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
done = 1;
|
||||
}
|
||||
E_Token maybe_comma = e_token_at_it(it, tokens);
|
||||
String8 maybe_comma_string = str8_substr(text, token.range);
|
||||
if(maybe_comma.kind == E_TokenKind_Symbol && str8_match(maybe_comma_string, str8_lit(","), 0))
|
||||
{
|
||||
it += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: if we parsed nothing successfully, we're done
|
||||
if(it == start_it)
|
||||
{
|
||||
|
||||
@@ -52,6 +52,8 @@ struct E_Expr
|
||||
{
|
||||
E_Expr *first;
|
||||
E_Expr *last;
|
||||
E_Expr *first_tag;
|
||||
E_Expr *last_tag;
|
||||
E_Expr *next;
|
||||
E_Expr *prev;
|
||||
E_Expr *ref;
|
||||
@@ -218,6 +220,7 @@ internal E_Expr *e_push_expr(Arena *arena, E_ExprKind kind, void *location);
|
||||
internal void e_expr_insert_child(E_Expr *parent, E_Expr *prev, E_Expr *child);
|
||||
internal void e_expr_push_child(E_Expr *parent, E_Expr *child);
|
||||
internal void e_expr_remove_child(E_Expr *parent, E_Expr *child);
|
||||
internal void e_expr_push_tag(E_Expr *parent, E_Expr *child);
|
||||
internal E_Expr *e_expr_ref(Arena *arena, E_Expr *ref);
|
||||
internal E_Expr *e_expr_ref_addr(Arena *arena, E_Expr *rhs);
|
||||
internal E_Expr *e_expr_ref_member_access(Arena *arena, E_Expr *lhs, String8 member_name);
|
||||
@@ -225,6 +228,7 @@ internal E_Expr *e_expr_ref_array_index(Arena *arena, E_Expr *lhs, U64 index);
|
||||
internal E_Expr *e_expr_ref_deref(Arena *arena, E_Expr *rhs);
|
||||
internal E_Expr *e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs);
|
||||
internal E_Expr *e_expr_ref_bswap(Arena *arena, E_Expr *rhs);
|
||||
internal E_Expr *e_expr_copy(Arena *arena, E_Expr *src);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Expression Tree -> String Conversions
|
||||
|
||||
@@ -14,7 +14,7 @@ str8_lit_comp("CharLiteral"),
|
||||
str8_lit_comp("Symbol"),
|
||||
};
|
||||
|
||||
String8 e_expr_kind_strings[49] =
|
||||
String8 e_expr_kind_strings[51] =
|
||||
{
|
||||
str8_lit_comp("Nil"),
|
||||
str8_lit_comp("Ref"),
|
||||
@@ -49,6 +49,7 @@ str8_lit_comp("BitOr"),
|
||||
str8_lit_comp("LogAnd"),
|
||||
str8_lit_comp("LogOr"),
|
||||
str8_lit_comp("Ternary"),
|
||||
str8_lit_comp("Call"),
|
||||
str8_lit_comp("LeafBytecode"),
|
||||
str8_lit_comp("LeafMember"),
|
||||
str8_lit_comp("LeafStringLiteral"),
|
||||
@@ -65,6 +66,7 @@ str8_lit_comp("Array"),
|
||||
str8_lit_comp("Func"),
|
||||
str8_lit_comp("Line"),
|
||||
str8_lit_comp("Define"),
|
||||
str8_lit_comp("Tag"),
|
||||
};
|
||||
|
||||
String8 e_interpretation_code_display_strings[11] =
|
||||
@@ -82,7 +84,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."),
|
||||
str8_lit_comp("Malformed bytecode."),
|
||||
};
|
||||
|
||||
E_OpInfo e_expr_kind_op_info_table[49] =
|
||||
E_OpInfo e_expr_kind_op_info_table[51] =
|
||||
{
|
||||
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
|
||||
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
|
||||
@@ -117,6 +119,7 @@ E_OpInfo e_expr_kind_op_info_table[49] =
|
||||
{ E_OpKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp("") },
|
||||
{ E_OpKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp("") },
|
||||
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(":") },
|
||||
{ E_OpKind_Null, 0, str8_lit_comp("("), str8_lit_comp(","), str8_lit_comp(")") },
|
||||
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
|
||||
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
|
||||
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
|
||||
@@ -133,6 +136,7 @@ E_OpInfo e_expr_kind_op_info_table[49] =
|
||||
{ E_OpKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("") },
|
||||
{ E_OpKind_Binary, 1, str8_lit_comp(""), str8_lit_comp(":"), str8_lit_comp("") },
|
||||
{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") },
|
||||
{ E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") },
|
||||
};
|
||||
|
||||
U8 e_kind_basic_byte_size_table[57] =
|
||||
|
||||
@@ -125,6 +125,7 @@ E_ExprKind_BitOr,
|
||||
E_ExprKind_LogAnd,
|
||||
E_ExprKind_LogOr,
|
||||
E_ExprKind_Ternary,
|
||||
E_ExprKind_Call,
|
||||
E_ExprKind_LeafBytecode,
|
||||
E_ExprKind_LeafMember,
|
||||
E_ExprKind_LeafStringLiteral,
|
||||
@@ -141,6 +142,7 @@ E_ExprKind_Array,
|
||||
E_ExprKind_Func,
|
||||
E_ExprKind_Line,
|
||||
E_ExprKind_Define,
|
||||
E_ExprKind_Tag,
|
||||
E_ExprKind_COUNT,
|
||||
} E_ExprKindEnum;
|
||||
|
||||
@@ -162,9 +164,9 @@ E_InterpretationCode_COUNT,
|
||||
|
||||
C_LINKAGE_BEGIN
|
||||
extern String8 e_token_kind_strings[6];
|
||||
extern String8 e_expr_kind_strings[49];
|
||||
extern String8 e_expr_kind_strings[51];
|
||||
extern String8 e_interpretation_code_display_strings[11];
|
||||
extern E_OpInfo e_expr_kind_op_info_table[49];
|
||||
extern E_OpInfo e_expr_kind_op_info_table[51];
|
||||
extern U8 e_kind_basic_byte_size_table[57];
|
||||
extern String8 e_kind_basic_string_table[57];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user