diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 5fc62ece..05737d53 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -72,6 +72,7 @@ E_TypeKindTable: {Bitfield "bitfield" 0 } {Variadic "variadic" 0 } {SpacePtr "space_ptr" 0 } + {Set "set" 0 } } @table(name op_kind precedence string op_pre op_sep op_pos) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 8a4ce94b..67abc754 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -70,6 +70,310 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_ctx = ctx; } +//////////////////////////////// +//~ rjf: Lookups + +internal E_LookupRule * +e_lookup_rule_from_string(String8 string) +{ + local_persist read_only E_LookupRule e_lookup_rule__default = + { + str8_lit_comp("default"), + E_LOOKUP_INFO_FUNCTION_NAME(default), + E_LOOKUP_FUNCTION_NAME(default), + }; + E_LookupRule *result = &e_lookup_rule__default; + { + U64 hash = e_hash_from_string(5381, string); + U64 slot_idx = hash%e_ir_ctx->lookup_rule_map->slots_count; + for(E_LookupRuleNode *n = e_ir_ctx->lookup_rule_map->slots[slot_idx].first; + n != 0; + n = n->next) + { + if(str8_match(n->v.name, string, 0)) + { + result = &n->v; + break; + } + } + } + return result; +} + +E_LOOKUP_INFO_FUNCTION_DEF(default) +{ + E_LookupInfo lookup_info = {0}; + Temp scratch = scratch_begin(&arena, 1); + { + E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr(scratch.arena, lhs); + E_TypeKey lhs_type_key = e_type_unwrap(lhs_irtree.type_key); + E_TypeKind lhs_type_kind = e_type_kind_from_key(lhs_type_key); + if(e_type_kind_is_pointer_or_ref(lhs_type_kind)) + { + lookup_info.idxed_expr_count = 1; + E_TypeKey direct_type_key = e_type_unwrap(e_type_direct_from_key(lhs_irtree.type_key)); + E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); + if(direct_type_kind == E_TypeKind_Array) + { + E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key); + lookup_info.idxed_expr_count = direct_type->count; + } + if(direct_type_kind == E_TypeKind_Struct || + direct_type_kind == E_TypeKind_Class || + direct_type_kind == E_TypeKind_Union || + direct_type_kind == E_TypeKind_Enum) + { + E_Type *direct_type = e_type_from_key(scratch.arena, direct_type_key); + lookup_info.named_expr_count = direct_type->count; + } + } + else if(lhs_type_kind == E_TypeKind_Struct || + lhs_type_kind == E_TypeKind_Class || + lhs_type_kind == E_TypeKind_Union || + lhs_type_kind == E_TypeKind_Enum) + { + E_Type *lhs_type = e_type_from_key(scratch.arena, lhs_type_key); + lookup_info.named_expr_count = lhs_type->count; + } + } + scratch_end(scratch); + return lookup_info; +} + +E_LOOKUP_FUNCTION_DEF(default) +{ + E_Lookup lookup = {0}; + switch(kind) + { + default:{}break; + + //- rjf: member accessing + case E_ExprKind_MemberAccess: + { + // rjf: unpack left/right expressions + E_Expr *exprl = lhs; + E_Expr *exprr = rhs; + E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKey check_type_key = l_restype; + E_TypeKind check_type_kind = l_restype_kind; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); + check_type_kind = e_type_kind_from_key(check_type_key); + } + e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs); + + // rjf: look up member + B32 r_found = 0; + E_TypeKey r_type = zero_struct; + U64 r_value = 0; + B32 r_is_constant_value = 0; + { + Temp scratch = scratch_begin(&arena, 1); + E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); + if(match.kind != E_MemberKind_Null) + { + r_found = 1; + r_type = match.type_key; + r_value = match.off; + } + if(match.kind == E_MemberKind_Null) + { + E_Type *type = e_type_from_key(scratch.arena, check_type_key); + if(type->enum_vals != 0) + { + String8 lookup_string = exprr->string; + String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); + String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); + E_EnumVal *enum_val_match = 0; + for EachIndex(idx, type->count) + { + if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || + str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) + { + enum_val_match = &type->enum_vals[idx]; + break; + } + } + if(enum_val_match != 0) + { + r_found = 1; + r_type = check_type_key; + r_value = enum_val_match->val; + r_is_constant_value = 1; + } + } + } + scratch_end(scratch); + } + + // rjf: bad conditions? -> error if applicable, exit + if(e_type_key_match(e_type_key_zero(), check_type_key)) + { + break; + } + else if(exprr->kind != E_ExprKind_LeafMember) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); + break; + } + else if(!r_found) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); + break; + } + else if(check_type_kind != E_TypeKind_Struct && + check_type_kind != E_TypeKind_Class && + check_type_kind != E_TypeKind_Union && + check_type_kind != E_TypeKind_Enum) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); + break; + } + + // rjf: generate + { + // rjf: build tree + E_IRNode *new_tree = l.root; + E_Mode mode = l.mode; + if(l_restype_kind == E_TypeKind_Ptr || + l_restype_kind == E_TypeKind_LRef || + l_restype_kind == E_TypeKind_RRef) + { + new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); + mode = E_Mode_Offset; + } + if(r_value != 0 && !r_is_constant_value) + { + E_IRNode *const_tree = e_irtree_const_u(arena, r_value); + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); + } + else if(r_is_constant_value) + { + new_tree = e_irtree_const_u(arena, r_value); + mode = E_Mode_Value; + } + + // rjf: fill + lookup.irtree_and_type.root = new_tree; + lookup.irtree_and_type.type_key = r_type; + lookup.irtree_and_type.mode = mode; + } + }break; + + //- rjf: array indexing + case E_ExprKind_ArrayIndex: + { + // rjf: unpack left/right expressions + E_Expr *exprl = lhs; + E_Expr *exprr = rhs; + E_IRTreeAndType l = e_irtree_and_type_from_expr(arena, exprl); + E_IRTreeAndType r = e_irtree_and_type_from_expr(arena, exprr); + E_TypeKey l_restype = e_type_unwrap(l.type_key); + E_TypeKey r_restype = e_type_unwrap(r.type_key); + E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); + E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); + if(e_type_kind_is_basic_or_enum(r_restype_kind)) + { + r_restype = e_type_unwrap_enum(r_restype); + r_restype_kind = e_type_kind_from_key(r_restype); + } + E_TypeKey direct_type = e_type_unwrap(l_restype); + direct_type = e_type_direct_from_key(direct_type); + direct_type = e_type_unwrap(direct_type); + U64 direct_type_size = e_type_byte_size_from_key(direct_type); + e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &l.msgs); + e_msg_list_concat_in_place(&lookup.irtree_and_type.msgs, &r.msgs); + + // rjf: bad conditions? -> error if applicable, exit + if(r.root->op == 0) + { + break; + } + else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); + break; + } + else if(!e_type_kind_is_integer(r_restype_kind)) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); + break; + } + else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); + break; + } + else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) + { + e_msgf(arena, &lookup.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); + break; + } + + // rjf: generate + E_IRNode *new_tree = &e_irnode_nil; + { + switch(l.mode) + { + // rjf: offsets -> read from base offset + default: + case E_Mode_Null: + case E_Mode_Offset: + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) + E_IRNode *base_tree = l.root; + if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) + { + base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); + } + + // rjf: ops to compute the final address + new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); + }break; + + // rjf: values -> read from stack value + case E_Mode_Value: + { + // rjf: ops to compute the offset + E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); + if(direct_type_size > 1) + { + E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); + offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); + } + + // rjf: ops to push stack value, push offset, + read from stack value + new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); + new_tree->value.u64 = direct_type_size; + e_irnode_push_child(new_tree, offset_tree); + e_irnode_push_child(new_tree, l.root); + }break; + } + } + + // rjf: fill + lookup.irtree_and_type.root = new_tree; + lookup.irtree_and_type.type_key = direct_type; + lookup.irtree_and_type.mode = l.mode; + }break; + } + return lookup; +} + //////////////////////////////// //~ rjf: IR-ization Functions @@ -400,228 +704,16 @@ e_irtree_and_type_from_expr__space(Arena *arena, E_Space *current_space, E_Expr result = e_irtree_and_type_from_expr__space(arena, current_space, expr->ref); }break; - //- rjf: array indices + //- rjf: accesses + case E_ExprKind_MemberAccess: case E_ExprKind_ArrayIndex: { - // rjf: unpack left/right expressions - E_Expr *exprl = expr->first; - E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl); - E_IRTreeAndType r = e_irtree_and_type_from_expr__space(arena, current_space, exprr); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKey r_restype = e_type_unwrap(r.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKind r_restype_kind = e_type_kind_from_key(r_restype); - if(e_type_kind_is_basic_or_enum(r_restype_kind)) - { - r_restype = e_type_unwrap_enum(r_restype); - r_restype_kind = e_type_kind_from_key(r_restype); - } - E_TypeKey direct_type = e_type_unwrap(l_restype); - direct_type = e_type_direct_from_key(direct_type); - direct_type = e_type_unwrap(direct_type); - 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) - { - break; - } - else if(l_restype_kind != E_TypeKind_Ptr && l_restype_kind != E_TypeKind_Array) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot index into this type."); - break; - } - else if(!e_type_kind_is_integer(r_restype_kind)) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index with this type."); - break; - } - else if(l_restype_kind == E_TypeKind_Ptr && direct_type_size == 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); - break; - } - else if(l_restype_kind == E_TypeKind_Array && direct_type_size == 0) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Cannot index into arrays of zero-sized types."); - break; - } - - // rjf: generate - E_IRNode *new_tree = &e_irnode_nil; - { - switch(l.mode) - { - // rjf: offsets -> read from base offset - default: - case E_Mode_Null: - case E_Mode_Offset: - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to compute the base offset (resolve to value if addr-of-pointer) - E_IRNode *base_tree = l.root; - if(l_restype_kind == E_TypeKind_Ptr && l.mode != E_Mode_Value) - { - base_tree = e_irtree_resolve_to_value(arena, l.mode, base_tree, l_restype); - } - - // rjf: ops to compute the final address - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, offset_tree, base_tree); - }break; - - // rjf: values -> read from stack value - case E_Mode_Value: - { - // rjf: ops to compute the offset - E_IRNode *offset_tree = e_irtree_resolve_to_value(arena, r.mode, r.root, r_restype); - if(direct_type_size > 1) - { - E_IRNode *const_tree = e_irtree_const_u(arena, direct_type_size); - offset_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, offset_tree, const_tree); - } - - // rjf: ops to push stack value, push offset, + read from stack value - new_tree = e_push_irnode(arena, RDI_EvalOp_ValueRead); - new_tree->value.u64 = direct_type_size; - e_irnode_push_child(new_tree, offset_tree); - e_irnode_push_child(new_tree, l.root); - }break; - } - } - - // rjf: fill - result.root = new_tree; - result.type_key = direct_type; - result.mode = l.mode; - }break; - - //- rjf: member accesses - case E_ExprKind_MemberAccess: - { - // rjf: unpack left/right expressions - E_Expr *exprl = expr->first; - E_Expr *exprr = exprl->next; - E_IRTreeAndType l = e_irtree_and_type_from_expr__space(arena, current_space, exprl); - E_TypeKey l_restype = e_type_unwrap(l.type_key); - E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); - E_TypeKey check_type_key = l_restype; - E_TypeKind check_type_kind = l_restype_kind; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - check_type_key = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(l_restype))); - check_type_kind = e_type_kind_from_key(check_type_key); - } - e_msg_list_concat_in_place(&result.msgs, &l.msgs); - - // rjf: look up member - B32 r_found = 0; - E_TypeKey r_type = zero_struct; - U64 r_value = 0; - B32 r_is_constant_value = 0; - { - Temp scratch = scratch_begin(&arena, 1); - E_Member match = e_type_member_from_key_name__cached(check_type_key, exprr->string); - if(match.kind != E_MemberKind_Null) - { - r_found = 1; - r_type = match.type_key; - r_value = match.off; - } - if(match.kind == E_MemberKind_Null) - { - E_Type *type = e_type_from_key(scratch.arena, check_type_key); - if(type->enum_vals != 0) - { - String8 lookup_string = exprr->string; - String8 lookup_string_append_1 = push_str8f(scratch.arena, "%S_%S", type->name, lookup_string); - String8 lookup_string_append_2 = push_str8f(scratch.arena, "%S%S", type->name, lookup_string); - E_EnumVal *enum_val_match = 0; - for EachIndex(idx, type->count) - { - if(str8_match(type->enum_vals[idx].name, lookup_string, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_1, 0) || - str8_match(type->enum_vals[idx].name, lookup_string_append_2, 0)) - { - enum_val_match = &type->enum_vals[idx]; - break; - } - } - if(enum_val_match != 0) - { - r_found = 1; - r_type = check_type_key; - r_value = enum_val_match->val; - r_is_constant_value = 1; - } - } - } - scratch_end(scratch); - } - - // rjf: bad conditions? -> error if applicable, exit - if(e_type_key_match(e_type_key_zero(), check_type_key)) - { - break; - } - else if(exprr->kind != E_ExprKind_LeafMember) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); - break; - } - else if(!r_found) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprr->location, "Could not find a member named `%S`.", exprr->string); - break; - } - else if(check_type_kind != E_TypeKind_Struct && - check_type_kind != E_TypeKind_Class && - check_type_kind != E_TypeKind_Union && - check_type_kind != E_TypeKind_Enum) - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); - break; - } - - // rjf: generate - { - // rjf: build tree - E_IRNode *new_tree = l.root; - E_Mode mode = l.mode; - if(l_restype_kind == E_TypeKind_Ptr || - l_restype_kind == E_TypeKind_LRef || - l_restype_kind == E_TypeKind_RRef) - { - new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype); - mode = E_Mode_Offset; - } - if(r_value != 0 && !r_is_constant_value) - { - E_IRNode *const_tree = e_irtree_const_u(arena, r_value); - new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); - } - else if(r_is_constant_value) - { - new_tree = e_irtree_const_u(arena, r_value); - mode = E_Mode_Value; - } - - // rjf: fill - result.root = new_tree; - result.type_key = r_type; - result.mode = mode; - } + E_Expr *lhs = expr->first; + E_Expr *rhs = lhs->next; + E_LookupRule *lookup_rule = e_lookup_rule_from_string(expr->string); + E_LookupInfo lookup_info = lookup_rule->lookup_info(arena, lhs); + E_Lookup lookup = lookup_rule->lookup(arena, expr->kind, lhs, rhs, lookup_info.user_data); + result = lookup.irtree_and_type; }break; //- rjf: dereference diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index ed54188b..0053ff76 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -56,6 +56,62 @@ struct E_IRTreeAndType E_MsgList msgs; }; +//////////////////////////////// +//~ rjf: Member/Index Lookup Hooks + +typedef struct E_LookupInfo E_LookupInfo; +struct E_LookupInfo +{ + void *user_data; + U64 named_expr_count; + U64 idxed_expr_count; +}; + +typedef struct E_Lookup E_Lookup; +struct E_Lookup +{ + E_IRTreeAndType irtree_and_type; +}; + +#define E_LOOKUP_INFO_FUNCTION_SIG(name) E_LookupInfo name(Arena *arena, E_Expr *lhs) +#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); + +#define E_LOOKUP_FUNCTION_SIG(name) E_Lookup name(Arena *arena, E_ExprKind kind, E_Expr *lhs, E_Expr *rhs, void *user_data) +#define E_LOOKUP_FUNCTION_NAME(name) e_lookup_##name +#define E_LOOKUP_FUNCTION_DEF(name) internal E_LOOKUP_FUNCTION_SIG(E_LOOKUP_FUNCTION_NAME(name)) +typedef E_LOOKUP_FUNCTION_SIG(E_LookupFunctionType); + +typedef struct E_LookupRule E_LookupRule; +struct E_LookupRule +{ + String8 name; + E_LookupInfoFunctionType *lookup_info; + E_LookupFunctionType *lookup; +}; + +typedef struct E_LookupRuleNode E_LookupRuleNode; +struct E_LookupRuleNode +{ + E_LookupRuleNode *next; + E_LookupRule v; +}; + +typedef struct E_LookupRuleSlot E_LookupRuleSlot; +struct E_LookupRuleSlot +{ + E_LookupRuleNode *first; + E_LookupRuleNode *last; +}; + +typedef struct E_LookupRuleMap E_LookupRuleMap; +struct E_LookupRuleMap +{ + E_LookupRuleSlot *slots; + U64 slots_count; +}; + //////////////////////////////// //~ rjf: Parse Context @@ -63,6 +119,7 @@ typedef struct E_IRCtx E_IRCtx; struct E_IRCtx { E_String2ExprMap *macro_map; + E_LookupRuleMap *lookup_rule_map; }; //////////////////////////////// @@ -83,6 +140,13 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); internal E_IRCtx *e_selected_ir_ctx(void); internal void e_select_ir_ctx(E_IRCtx *ctx); +//////////////////////////////// +//~ rjf: Lookups + +internal E_LookupRule *e_lookup_rule_from_string(String8 string); +E_LOOKUP_INFO_FUNCTION_DEF(default); +E_LOOKUP_FUNCTION_DEF(default); + //////////////////////////////// //~ rjf: IR-ization Functions diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index 1d5e9291..eec6b7bc 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -135,7 +135,7 @@ E_OpInfo e_expr_kind_op_info_table[49] = { E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, }; -U8 e_kind_basic_byte_size_table[56] = +U8 e_kind_basic_byte_size_table[57] = { 0, 0, @@ -193,9 +193,10 @@ U8 e_kind_basic_byte_size_table[56] = 0, 0, 0, +0, }; -String8 e_kind_basic_string_table[56] = +String8 e_kind_basic_string_table[57] = { str8_lit_comp(""), str8_lit_comp("void"), @@ -253,6 +254,7 @@ str8_lit_comp("enum"), str8_lit_comp("bitfield"), str8_lit_comp("variadic"), str8_lit_comp("space_ptr"), +str8_lit_comp("set"), }; C_LINKAGE_END diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 225aa598..125d8245 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -75,6 +75,7 @@ E_TypeKind_IncompleteEnum, E_TypeKind_Bitfield, E_TypeKind_Variadic, E_TypeKind_SpacePtr, +E_TypeKind_Set, E_TypeKind_COUNT, E_TypeKind_FirstBasic = E_TypeKind_Void, E_TypeKind_LastBasic = E_TypeKind_ComplexF128, @@ -164,8 +165,8 @@ extern String8 e_token_kind_strings[6]; extern String8 e_expr_kind_strings[49]; extern String8 e_interpretation_code_display_strings[11]; extern E_OpInfo e_expr_kind_op_info_table[49]; -extern U8 e_kind_basic_byte_size_table[56]; -extern String8 e_kind_basic_string_table[56]; +extern U8 e_kind_basic_byte_size_table[57]; +extern String8 e_kind_basic_string_table[57]; C_LINKAGE_END diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index d3b97378..45669943 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -13084,8 +13084,8 @@ rd_frame(void) E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); { E_IRCtx *ctx = ir_ctx; - ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); - ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); + ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); + ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); //- rjf: add macros for collections { diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 4e00fe52..fc6f4d80 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -835,17 +835,17 @@ rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index) //- rjf: watch view points <-> table coordinates internal B32 -rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b) +rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b) { return (ev_key_match(a.parent_key, b.parent_key) && ev_key_match(a.key, b.key) && a.cell_id == b.cell_id); } -internal RD_WatchViewPoint -rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) +internal RD_WatchPt +rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) { - RD_WatchViewPoint pt = zero_struct; + RD_WatchPt pt = zero_struct; pt.cell_id = (U64)tbl.x; pt.key = ev_key_from_num(block_ranges, (U64)tbl.y); pt.parent_key = ev_block_range_from_num(block_ranges, (U64)tbl.y).block->key; @@ -853,7 +853,7 @@ rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl) } internal Vec2S64 -rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt) +rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt) { Vec2S64 tbl = {0}; tbl.x = (S64)pt.cell_id; @@ -861,6 +861,40 @@ rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint return tbl; } +//- rjf: row -> info + +internal RD_WatchRowInfo +rd_watch_row_info_from_row(Arena *arena, EV_Row *row) +{ + RD_WatchRowInfo info = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + DI_Scope *di_scope = di_scope_open(); + + // rjf: unpack key & block + EV_Block *block = row->block; + EV_Key key = row->key; + E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); + E_Type *parent_type = e_type_from_key(arena, parent_irtree.type_key); + + // rjf: fill row's eval + info.eval = e_eval_from_expr(arena, row->expr); + + // rjf: determine cfg group + + + // rjf: fill row's cells + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Expr, .pct = 0.25f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Value, .pct = 0.30f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Type, .pct = 0.15f); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_ViewRule, .pct = 0.30f); + + di_scope_close(di_scope); + scratch_end(scratch); + } + return info; +} + //- rjf: row -> context info internal RD_WatchViewRowInfo @@ -1229,7 +1263,7 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn //- rjf: table coordinates -> text edit state internal RD_WatchViewTextEditState * -rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt) +rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt) { RD_WatchViewTextEditState *result = &wv->dummy_text_edit_state; if(wv->text_edit_state_slots_count != 0 && wv->text_editing != 0) @@ -1238,7 +1272,7 @@ rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint p U64 slot_idx = hash%wv->text_edit_state_slots_count; for(RD_WatchViewTextEditState *s = wv->text_edit_state_slots[slot_idx]; s != 0; s = s->pt_hash_next) { - if(rd_watch_view_point_match(pt, s->pt)) + if(rd_watch_pt_match(pt, s->pt)) { result = s; break; @@ -1416,7 +1450,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo cursor_dirty__tbl = 0; struct { - RD_WatchViewPoint *pt_state; + RD_WatchPt *pt_state; Vec2S64 pt_tbl; } points[] = @@ -1428,7 +1462,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { EV_Key last_key = points[point_idx].pt_state->key; EV_Key last_parent_key = points[point_idx].pt_state->parent_key; - points[point_idx].pt_state[0] = rd_watch_view_point_from_tbl(&block_ranges, points[point_idx].pt_tbl); + points[point_idx].pt_state[0] = rd_watch_pt_from_tbl(&block_ranges, points[point_idx].pt_tbl); if(ev_key_match(ev_key_zero(), points[point_idx].pt_state->key)) { points[point_idx].pt_state->key = last_parent_key; @@ -1460,8 +1494,8 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo Rng2S64 cursor_tbl_range = {0}; { // rjf: compute 2d table coordinates - cursor_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->cursor); - mark_tbl = rd_tbl_from_watch_view_point(&block_ranges, ewv->mark); + cursor_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->cursor); + mark_tbl = rd_tbl_from_watch_pt(&block_ranges, ewv->mark); // rjf: compute row at initial selection point (or just cursor point) mark_rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(mark_tbl.y, mark_tbl.y+1)); @@ -1544,7 +1578,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: apply cursor/mark rugpull change // B32 cursor_rugpull = 0; - if(!rd_watch_view_point_match(ewv->cursor, ewv->next_cursor)) + if(!rd_watch_pt_match(ewv->cursor, ewv->next_cursor)) { cursor_rugpull = 1; ewv->cursor = ewv->next_cursor; @@ -1598,7 +1632,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); String8 string = rd_string_from_eval_viz_row_column(scratch.arena, row, col, string_flags, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); string.size = Min(string.size, sizeof(ewv->dummy_text_edit_state.input_buffer)); - RD_WatchViewPoint pt = {row->block->key, row->key, x}; + RD_WatchPt pt = {row->block->key, row->key, x}; U64 hash = ev_hash_from_key(pt.key); U64 slot_idx = hash%ewv->text_edit_state_slots_count; RD_WatchViewTextEditState *edit_state = push_array(ewv->text_edit_arena, RD_WatchViewTextEditState, 1); @@ -1701,7 +1735,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo RD_WatchViewRowKind row_kind = rd_watch_view_row_kind_from_flags_row_info(flags, row, &row_info); for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, v2s64(x, y)); + RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, v2s64(x, y)); RD_WatchViewTextEditState *edit_state = rd_watch_view_text_edit_state_from_pt(ewv, pt); String8 string = str8(edit_state->input_buffer, edit_state->input_size); UI_TxtOp op = ui_single_line_txt_op_from_event(scratch.arena, evt, string, edit_state->cursor, edit_state->mark); @@ -1808,7 +1842,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewColumnKind_ViewRule: if(editing_complete) { - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl); + RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl); ev_key_set_view_rule(eval_view, pt.key, new_string); if(row_info.collection_entity_kind != RD_EntityKind_Nil) { @@ -1890,7 +1924,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo state_dirty = 1; snap_to_cursor = 1; RD_EntityList entities_to_remove = {0}; - RD_WatchViewPoint next_cursor_pt = {0}; + RD_WatchPt next_cursor_pt = {0}; B32 next_cursor_set = 0; EV_WindowedRowList rows = ev_rows_from_num_range(scratch.arena, eval_view, filter, &block_ranges, r1u64(selection_tbl.min.y, selection_tbl.max.y+1)); EV_WindowedRowNode *row_node = rows.first; @@ -1902,7 +1936,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(S64 x = selection_tbl.min.x; x <= selection_tbl.max.x; x += 1) { Vec2S64 tbl = v2s64(x, y); - RD_WatchViewPoint pt = rd_watch_view_point_from_tbl(&block_ranges, tbl); + RD_WatchPt pt = rd_watch_pt_from_tbl(&block_ranges, tbl); RD_WatchViewColumn *col = rd_watch_view_column_from_x(ewv, x); if(tbl.y != 0 && (col->kind == RD_WatchViewColumnKind_Expr || row_kind == RD_WatchViewRowKind_PrettyEntityControls) && row_info.collection_entity_kind != RD_EntityKind_Nil) @@ -1924,7 +1958,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo key = row->block->key; parent_key = row->block->parent->key; } - RD_WatchViewPoint new_pt = {parent_key, key, 0}; + RD_WatchPt new_pt = {parent_key, key, 0}; next_cursor_pt = new_pt; next_cursor_set = 1; } @@ -2298,7 +2332,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ui_view_rule_params_root = &md_nil_node; } RD_WatchViewRowInfo row_info = rd_watch_view_row_info_from_row(row); - RD_WatchCellList row_cells = rd_watch_cell_list_from_row_info(scratch.arena, row, &row_info); + RD_WatchRowInfo row_info_NEW = rd_watch_row_info_from_row(scratch.arena, row); ProfEnd(); //////////////////////// @@ -2425,11 +2459,11 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //////////////////// //- rjf: build all cells // - for(RD_WatchCell *cell = row_cells.first; cell != 0; cell = cell->next) + for(RD_WatchCell *cell = row_info_NEW.cells.first; cell != 0; cell = cell->next) { #if 0 // TODO(rjf): @cfg //- rjf: unpack cell info - RD_WatchViewPoint cell_pt = {x, row->block->key, row->key}; + RD_WatchPt cell_pt = {x, row->block->key, row->key}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); @@ -3046,7 +3080,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo { #if 0 // TODO(rjf): @cfg //- rjf: unpack - RD_WatchViewPoint pt = {0, row->block->key, row->key}; + RD_WatchPt pt = {0, row->block->key, row->key}; RD_View *view = rd_view_from_handle(rd_regs()->view); RD_TransientViewNode *canvas_view_node = rd_transient_view_node_from_ev_key(view, row->key); RD_View *canvas_view = canvas_view_node->view; @@ -3312,7 +3346,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo } if(ui_pressed(sig)) { - RD_WatchViewPoint cell_pt = {1, row->block->key, row->key}; + RD_WatchPt cell_pt = {1, row->block->key, row->key}; ewv->next_cursor = ewv->next_mark = cell_pt; pressed = 1; } @@ -3477,7 +3511,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo for(RD_WatchViewColumn *col = ewv->first_column; col != 0; col = col->next, x += 1) { //- rjf: unpack cell info - RD_WatchViewPoint cell_pt = {x, row->block->key, row->key}; + RD_WatchPt cell_pt = {x, row->block->key, row->key}; RD_WatchViewTextEditState *cell_edit_state = rd_watch_view_text_edit_state_from_pt(ewv, cell_pt); B32 cell_selected = (row_selected && selection_tbl.min.x <= cell_pt.x && cell_pt.x <= selection_tbl.max.x); String8 cell_pre_edit_string = rd_string_from_eval_viz_row_column(scratch.arena, eval_view, row, col, string_flags|EV_StringFlag_ReadOnlyDisplayRules, default_radix, ui_top_font(), ui_top_font_size(), row_string_max_size_px); diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 4c75d4e2..4d0aa592 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -81,6 +81,19 @@ struct RD_WatchCellList U64 count; }; +typedef struct RD_WatchRowInfo RD_WatchRowInfo; +struct RD_WatchRowInfo +{ + E_Eval eval; + String8 group_key; + RD_Cfg *group_cfg; + CTRL_Entity *group_entity; + CTRL_Entity *callstack_thread; + U64 callstack_unwind_index; + U64 callstack_inline_depth; + RD_WatchCellList cells; +}; + typedef enum RD_WatchViewColumnKind { RD_WatchViewColumnKind_Expr, @@ -141,8 +154,8 @@ typedef enum RD_WatchViewRowKind } RD_WatchViewRowKind; -typedef struct RD_WatchViewPoint RD_WatchViewPoint; -struct RD_WatchViewPoint +typedef struct RD_WatchPt RD_WatchPt; +struct RD_WatchPt { EV_Key parent_key; EV_Key key; @@ -165,7 +178,7 @@ typedef struct RD_WatchViewTextEditState RD_WatchViewTextEditState; struct RD_WatchViewTextEditState { RD_WatchViewTextEditState *pt_hash_next; - RD_WatchViewPoint pt; + RD_WatchPt pt; TxtPt cursor; TxtPt mark; U8 input_buffer[1024]; @@ -187,10 +200,10 @@ struct RD_WatchViewState U64 column_count; // rjf; table cursor state - RD_WatchViewPoint cursor; - RD_WatchViewPoint mark; - RD_WatchViewPoint next_cursor; - RD_WatchViewPoint next_mark; + RD_WatchPt cursor; + RD_WatchPt mark; + RD_WatchPt next_cursor; + RD_WatchPt next_mark; // rjf: text input state Arena *text_edit_arena; @@ -218,9 +231,12 @@ internal RD_WatchCell *rd_watch_cell_list_push_new_(Arena *arena, RD_WatchCellLi internal RD_WatchViewColumn *rd_watch_view_column_from_x(RD_WatchViewState *wv, S64 index); //- rjf: watch view points <-> table coordinates -internal B32 rd_watch_view_point_match(RD_WatchViewPoint a, RD_WatchViewPoint b); -internal RD_WatchViewPoint rd_watch_view_point_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl); -internal Vec2S64 rd_tbl_from_watch_view_point(EV_BlockRangeList *block_ranges, RD_WatchViewPoint pt); +internal B32 rd_watch_pt_match(RD_WatchPt a, RD_WatchPt b); +internal RD_WatchPt rd_watch_pt_from_tbl(EV_BlockRangeList *block_ranges, Vec2S64 tbl); +internal Vec2S64 rd_tbl_from_watch_pt(EV_BlockRangeList *block_ranges, RD_WatchPt pt); + +//- rjf: row -> info +internal RD_WatchRowInfo rd_watch_row_info_from_row(Arena *arena, EV_Row *row); //- rjf: row -> context info internal RD_WatchViewRowInfo rd_watch_view_row_info_from_row(EV_Row *row); @@ -236,7 +252,7 @@ internal E_Expr *rd_expr_from_watch_view_row_column(Arena *arena, EV_Row *row, R internal String8 rd_string_from_eval_viz_row_column(Arena *arena, EV_Row *row, RD_WatchViewColumn *col, EV_StringFlags string_flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size_px); //- rjf: table coordinates -> text edit state -internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchViewPoint pt); +internal RD_WatchViewTextEditState *rd_watch_view_text_edit_state_from_pt(RD_WatchViewState *wv, RD_WatchPt pt); //- rjf: watch view column state mutation internal RD_WatchViewColumn *rd_watch_view_column_alloc_(RD_WatchViewState *wv, RD_WatchViewColumnKind kind, F32 pct, RD_WatchViewColumnParams *params);