diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 0c2316bf..e66e8af6 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -4663,8 +4663,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) // rjf: build eval type context { E_TypeCtx *ctx = &scope->type_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; @@ -4675,10 +4673,15 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ProfScope("build eval parse context") { E_ParseCtx *ctx = &scope->parse_ctx; - ctx->ip_vaddr = thread_rip_vaddr; - ctx->ip_voff = thread_rip_voff; - ctx->ip_thread_space = e_space_make(CTRL_EvalSpaceKind_Entity); - ctx->ip_thread_space.u64_0 = (U64)thread; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + } + e_select_parse_ctx(&scope->parse_ctx); + + // rjf: build eval IR context + { + E_IRCtx *ctx = &scope->ir_ctx; ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; @@ -4686,12 +4689,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) ctx->reg_alias_map = ctrl_string2alias_from_arch(arch); ctx->locals_map = e_push_locals_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); ctx->member_map = e_push_member_map_from_rdi_voff(arena, eval_modules_primary->rdi, thread_rip_voff); - } - e_select_parse_ctx(&scope->parse_ctx); - - // rjf: build eval IR context - { - E_IRCtx *ctx = &scope->ir_ctx; ctx->macro_map = push_array(arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(arena, 512); ctx->lookup_rule_map = push_array(arena, E_LookupRuleMap, 1); diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index b9a1d33c..976f691b 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -119,9 +119,7 @@ E_ExprKindTable: { Call Null 0 "(" "," ")"} { LeafBytecode Null 0 "" "" "" } - { LeafMember Null 0 "" "" "" } { LeafStringLiteral Null 0 "" "" "" } - { LeafBool Null 0 "" "" "" } { LeafU64 Null 0 "" "" "" } { LeafF64 Null 0 "" "" "" } { LeafF32 Null 0 "" "" "" } diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 11c8e68a..e14531e9 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -43,7 +43,7 @@ internal E_Eval e_eval_from_string(Arena *arena, String8 string) { E_TokenArray tokens = e_token_array_from_text(arena, string); - E_Parse parse = e_parse_expr_from_text_tokens(arena, string, &tokens); + E_Parse parse = e_parse_expr_from_text_tokens(arena, string, tokens); E_Eval eval = e_eval_from_exprs(arena, parse.exprs); e_msg_list_concat_in_place(&eval.msgs, &parse.msgs); return eval; diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 24d2a320..3bdd069e 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -58,12 +58,6 @@ e_expr_kind_is_comparison(E_ExprKind kind) //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_IRCtx * -e_selected_ir_ctx(void) -{ - return e_ir_state->ctx; -} - internal void e_select_ir_ctx(E_IRCtx *ctx) { @@ -75,9 +69,14 @@ e_select_ir_ctx(E_IRCtx *ctx) e_ir_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); - if(ctx->macro_map == 0) {ctx->macro_map = &e_string2expr_map_nil;} + if(ctx->regs_map == 0) { ctx->regs_map = &e_string2num_map_nil; } + if(ctx->reg_alias_map == 0) { ctx->reg_alias_map = &e_string2num_map_nil; } + if(ctx->locals_map == 0) { ctx->locals_map = &e_string2num_map_nil; } + if(ctx->member_map == 0) { ctx->member_map = &e_string2num_map_nil; } + if(ctx->macro_map == 0) {ctx->macro_map = &e_string2expr_map_nil;} e_ir_state->ctx = ctx; - e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); + e_ir_state->ip_procedure = rdi_procedure_from_voff(ctx->primary_module->rdi, ctx->ip_voff); + e_ir_state->used_tag_map = push_array(e_ir_state->arena, E_UsedTagMap, 1); e_ir_state->used_tag_map->slots_count = 64; e_ir_state->used_tag_map->slots = push_array(e_ir_state->arena, E_UsedTagSlot, e_ir_state->used_tag_map->slots_count); e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); @@ -340,7 +339,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(file) { String8 name = accel->fields.v[idx]; expr = e_push_expr(arena, E_ExprKind_MemberAccess, 0); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); rhs->string = push_str8_copy(arena, name); e_expr_push_child(expr, e_expr_ref(arena, lhs)); e_expr_push_child(expr, rhs); @@ -659,7 +658,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default) { break; } - else if(exprr->kind != E_ExprKind_LeafMember) + else if(exprr->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.irtree_and_type.msgs, E_MsgKind_MalformedInput, exprl->location, "Expected member name."); break; @@ -1320,7 +1319,7 @@ e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams * if(params->type_pattern.size != 0) { E_TokenArray tokens = e_token_array_from_text(scratch.arena, params->type_pattern); - E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, &tokens); + E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, params->type_pattern, tokens); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.exprs.last); type_key = irtree.type_key; } @@ -2470,12 +2469,6 @@ E_IRGEN_FUNCTION_DEF(default) result.mode = expr->mode; }break; - //- rjf: (unexpected) leaf member - case E_ExprKind_LeafMember: - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "(internal) Leaf member not expected here."); - }break; - //- rjf: leaf string literal case E_ExprKind_LeafStringLiteral: { @@ -2487,14 +2480,6 @@ E_IRGEN_FUNCTION_DEF(default) result.mode = E_Mode_Value; }break; - //- rjf: leaf bools - case E_ExprKind_LeafBool: - { - result.root = e_irtree_const_u(arena, expr->value.u64); - result.type_key = expr->type_key; - result.mode = E_Mode_Value; - }break; - //- rjf: leaf U64s case E_ExprKind_LeafU64: { @@ -2533,6 +2518,683 @@ E_IRGEN_FUNCTION_DEF(default) //- rjf: leaf identifiers case E_ExprKind_LeafIdentifier: { + Temp scratch = scratch_begin(&arena, 1); + String8 qualifier = expr->qualifier; + String8 string = expr->string; + String8 string__redirected = string; + B32 string_mapped = 0; + E_TypeKey mapped_type_key = zero_struct; + E_Module *mapped_location_block_module = &e_module_nil; + RDI_LocationBlock *mapped_location_block = 0; + + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_strings = {0}; + { + E_Module *module = e_ir_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_ir_state->ip_procedure; + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) + { + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) + { + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string); + str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + + //- rjf: try to map name as member - if found, string__redirected := "this", and turn + // on later implicit-member-lookup generation + B32 string_is_implicit_member_name = 0; + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) + { + E_Module *module = e_ir_state->ctx->primary_module; + U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + RDI_Parsed *rdi = module->rdi; + RDI_Procedure *procedure = e_ir_state->ip_procedure; + RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); + E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); + E_Member member = e_type_member_from_key_name__cached(container_type_key, string); + if(member.kind != E_MemberKind_Null) + { + string_is_implicit_member_name = 1; + string__redirected = str8_lit("this"); + } + } + + //- rjf: try locals + if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) + { + U64 ip_voff = e_ir_state->ctx->ip_voff; + E_Module *module = e_ir_state->ctx->primary_module; + U32 module_idx = (U32)(module - e_ir_state->ctx->modules); + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string__redirected); + if(local_num != 0) + { + RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); + + // rjf: extract local's type key + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local->type_idx); + mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local->type_idx, module_idx); + + // rjf: extract local's location block + for(U32 loc_block_idx = local->location_first; + loc_block_idx < local->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= ip_voff && ip_voff < block->scope_off_opl) + { + mapped_location_block_module = module; + mapped_location_block = block; + } + } + } + } + + //- rjf: mapped to location block -> extract or produce bytecode for this mapping + E_Mode mapped_bytecode_mode = E_Mode_Offset; + E_Space mapped_bytecode_space = zero_struct; + String8 mapped_bytecode = {0}; + if(mapped_location_block != 0) + { + E_Module *module = mapped_location_block_module; + E_Space space = module->space; + Arch arch = module->arch; + RDI_Parsed *rdi = module->rdi; + RDI_LocationBlock *block = mapped_location_block; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) + { + RDI_LocationKind loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) + { + default:{}break; + case RDI_LocationKind_ValBytecodeStream: {mapped_bytecode_mode = E_Mode_Value;}goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream:{mapped_bytecode_mode = E_Mode_Offset;}goto bytecode_stream; + bytecode_stream:; + { + string_mapped = 1; + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) + { + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); + } + mapped_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + if(block->location_data_off + sizeof(RDI_LocationRegPlusU16) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: + { + string_mapped = 1; + RDI_LocationRegPlusU16 loc = *(RDI_LocationRegPlusU16 *)(all_location_data + block->location_data_off); + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Offset; + mapped_bytecode_space = space; + }break; + case RDI_LocationKind_ValReg: + if(block->location_data_off + sizeof(RDI_LocationReg) <= all_location_data_size) + { + string_mapped = 1; + RDI_LocationReg loc = *(RDI_LocationReg *)(all_location_data + block->location_data_off); + + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); + mapped_bytecode_mode = E_Mode_Value; + mapped_bytecode_space = space; + }break; + } + } + } + + //- rjf: generate IR trees for bytecode + B32 generated = 0; + if(!generated && mapped_bytecode.size != 0) + { + generated = 1; + E_IRNode *root = e_irtree_bytecode_no_copy(arena, mapped_bytecode); + root->space = mapped_bytecode_space; + result.root = root; + result.type_key = mapped_type_key; + result.mode = mapped_bytecode_mode; + } + + //- rjf: generate IR trees for macros + if(!generated) + { + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, string); + if(macro_expr != &e_expr_nil) + { + generated = 1; + e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, string); + result = e_irtree_and_type_from_expr(arena, macro_expr); + e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, string); + } + } + + //- rjf: error on failure-to-generate + if(!generated) + { + e_msgf(arena, &result.msgs, E_MsgKind_ResolutionFailure, expr->location, "`%S` could not be found.", string); + } + + //- TODO(rjf): +#if 0 + B32 mapped_identifier = 0; + B32 identifier_is_constant_value = 0; + B32 identifier_looks_like_type_expr = 0; + RDI_LocationKind loc_kind = RDI_LocationKind_NULL; + RDI_LocationReg loc_reg = {0}; + RDI_LocationRegPlusU16 loc_reg_u16 = {0}; + String8 loc_bytecode = {0}; + U64 constant_value = 0; + REGS_RegCode reg_code = 0; + REGS_AliasCode alias_code = 0; + E_TypeKey type_key = zero_struct; + String8 local_lookup_string = token_string; + E_Space space = {0}; + Arch arch = Arch_Null; + + + //- rjf: identifiers surrounded by ``s should have those `s stripped + if(local_lookup_string.size >= 2 && + local_lookup_string.str[0] == '`' && + local_lookup_string.str[local_lookup_string.size-1] == '`') + { + token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); + } + + //- rjf: form namespaceified fallback versions of this lookup string + String8List namespaceified_token_strings = {0}; + { + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); + U64 proc_idx = scope->proc_idx; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); + U64 name_size = 0; + U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); + String8 containing_procedure_name = str8(name_ptr, name_size); + U64 last_past_scope_resolution_pos = 0; + for(;;) + { + U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; + U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; + U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); + if(past_next_scope_resolution_pos >= containing_procedure_name.size) + { + break; + } + String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); + String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); + str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); + last_past_scope_resolution_pos = past_next_scope_resolution_pos; + } + } + + //- rjf: try members + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") + { + U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); + if(data_member_num != 0) + { + atom_implicit_member_name = token_string; + local_lookup_string = str8_lit("this"); + } + } + + //- rjf: try locals + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") + { + E_Module *module = e_parse_state->ctx->primary_module; + RDI_Parsed *rdi = module->rdi; + U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); + if(local_num != 0) + { + RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); + + // rjf: grab location info + for(U32 loc_block_idx = local_var->location_first; + loc_block_idx < local_var->location_opl; + loc_block_idx += 1) + { + RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); + if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) + { + mapped_identifier = 1; + space = module->space; + arch = module->arch; + U64 all_location_data_size = 0; + U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); + if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) + { + loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); + switch(loc_kind) + { + default:{mapped_identifier = 0;}break; + case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; + case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; + bytecode_stream:; + { + U64 bytecode_size = 0; + U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); + U64 off_opl = all_location_data_size; + for(U64 off = off_first, next_off = off_opl; + off < all_location_data_size; + off = next_off) + { + next_off = off_opl; + U8 op = all_location_data[off]; + if(op == 0) + { + break; + } + U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; + U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); + bytecode_size += (1 + p_size); + next_off = (off + 1 + p_size); + } + loc_bytecode = str8(all_location_data + off_first, bytecode_size); + }break; + case RDI_LocationKind_AddrRegPlusU16: + case RDI_LocationKind_AddrAddrRegPlusU16: + { + MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); + }break; + case RDI_LocationKind_ValReg: + { + MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); + }break; + } + } + } + } + } + } + + //- rjf: try registers + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") + { + U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); + if(reg_num != 0) + { + reg_code = reg_num; + type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try register aliases + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") + { + U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); + if(alias_num != 0) + { + alias_code = (REGS_AliasCode)alias_num; + type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); + mapped_identifier = 1; + space = e_parse_state->ctx->ip_thread_space; + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try global variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + // NOTE(rjf): apparently, PDBs can be produced such that they + // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I + // don't know of a magic hash table fixup path in PDBs, so + // in this case, I'm going to prefer the latest-added global. + U32 match_idx = matches[matches_count-1]; + RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = global_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try thread variables + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); + loc_kind = RDI_LocationKind_AddrBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = thread_var->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try procedures + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") + { + for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) + { + E_Module *module = &e_parse_state->ctx->modules[module_idx]; + RDI_Parsed *rdi = module->rdi; + RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); + RDI_ParsedNameMap parsed_name_map = {0}; + rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); + RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); + U32 matches_count = 0; + U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); + for(String8Node *n = namespaceified_token_strings.first; + n != 0 && matches_count == 0; + n = n->next) + { + node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); + matches_count = 0; + matches = rdi_matches_from_map_node(rdi, node, &matches_count); + } + if(matches_count != 0) + { + U32 match_idx = matches[0]; + RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); + RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); + U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); + E_OpList oplist = {0}; + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); + loc_kind = RDI_LocationKind_ValBytecodeStream; + loc_bytecode = e_bytecode_from_oplist(arena, &oplist); + U32 type_idx = procedure->type_idx; + RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); + type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); + mapped_identifier = 1; + space = module->space; + arch = module->arch; + break; + } + } + } + + //- rjf: try types + if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") + { + type_key = e_leaf_type_from_name(token_string); + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + mapped_identifier = 1; + identifier_looks_like_type_expr = 1; + MemoryZeroStruct(&space); + arch = e_parse_state->ctx->primary_module->arch; + } + } + + //- rjf: try basic constants + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 1; + } + if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) + { + mapped_identifier = 1; + identifier_is_constant_value = 1; + type_key = e_type_key_basic(E_TypeKind_Bool); + constant_value = 0; + } + + //- rjf: attach on map + if(mapped_identifier != 0) ProfScope("attach on map") + { + it += 1; + + // rjf: build atom + switch(loc_kind) + { + default: + { + if(identifier_is_constant_value) + { + atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); + atom->value.u64 = constant_value; + atom->type_key = type_key; + } + else if(identifier_looks_like_type_expr) + { + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it-1, it_opl)); + E_Expr *type = type_parse.exprs.last; + e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); + it = type_parse.last_token; + atom = type; + } + else if(reg_code != 0) + { + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else if(alias_code != 0) + { + REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; + REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; + E_OpList oplist = {0}; + e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); + } + }break; + case RDI_LocationKind_AddrBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_ValBytecodeStream: + { + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = loc_bytecode; + }break; + case RDI_LocationKind_AddrRegPlusU16: + { + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + case RDI_LocationKind_AddrAddrRegPlusU16: + { + E_OpList oplist = {0}; + U64 byte_size = bit_size_from_arch(arch)/8; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Offset; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + case RDI_LocationKind_ValReg: + { + REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); + REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; + E_OpList oplist = {0}; + U64 byte_size = (U64)reg_rng.byte_size; + U64 byte_pos = 0; + U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); + e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); + atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); + atom->mode = E_Mode_Value; + atom->space = space; + atom->type_key = type_key; + atom->string = token_string; + atom->bytecode = e_bytecode_from_oplist(arena, &oplist); + }break; + } + + // rjf: implicit local lookup -> attach member access node + if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) + { + E_Expr *member_container = atom; + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); + member_expr->string = atom_implicit_member_name; + atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); + atom->space = space; + e_expr_push_child(atom, member_container); + e_expr_push_child(atom, member_expr); + } + } + + //- rjf: map failure -> attach as leaf identifier, to be resolved later + if(!mapped_identifier) + { + atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); + atom->string = token_string; + it += 1; + } + + + + E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, expr->string); if(macro_expr == &e_expr_nil) { @@ -2544,6 +3206,9 @@ E_IRGEN_FUNCTION_DEF(default) result = e_irtree_and_type_from_expr(arena, macro_expr); e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, expr->string); } +#endif + + scratch_end(scratch); }break; //- rjf: leaf offsets @@ -2933,7 +3598,7 @@ e_expr_irext_member_access(Arena *arena, E_Expr *lhs, E_IRTreeAndType *lhs_irtre lhs_bytecode->mode = lhs_irtree->mode; lhs_bytecode->type_key = lhs_irtree->type_key; lhs_bytecode->bytecode = e_bytecode_from_oplist(arena, &lhs_oplist); - E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafMember, 0); + E_Expr *rhs = e_push_expr(arena, E_ExprKind_LeafIdentifier, 0); rhs->string = push_str8_copy(arena, member_name); e_expr_push_child(root, lhs_bytecode); e_expr_push_child(root, rhs); diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index b23023bc..adb12aa8 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -116,7 +116,24 @@ struct E_StringIDMap typedef struct E_IRCtx E_IRCtx; struct E_IRCtx { + // rjf: instruction pointer info + U64 ip_vaddr; + U64 ip_voff; + E_Space ip_thread_space; + + // rjf: modules + E_Module *modules; + U64 modules_count; + E_Module *primary_module; + + // rjf: identifier-resolution maps + E_String2NumMap *regs_map; + E_String2NumMap *reg_alias_map; + E_String2NumMap *locals_map; // (within `primary_module`) + E_String2NumMap *member_map; // (within `primary_module`) E_String2ExprMap *macro_map; + + // rjf: hook maps E_LookupRuleMap *lookup_rule_map; E_IRGenRuleMap *irgen_rule_map; E_AutoHookMap *auto_hook_map; @@ -134,6 +151,9 @@ struct E_IRState // rjf: ir context E_IRCtx *ctx; + // rjf: unpacked ctx + RDI_Procedure *ip_procedure; + // rjf: caches E_UsedTagMap *used_tag_map; E_TypeAutoHookCacheMap *type_auto_hook_cache_map; @@ -179,7 +199,6 @@ internal B32 e_expr_kind_is_comparison(E_ExprKind kind); //////////////////////////////// //~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) -internal E_IRCtx *e_selected_ir_ctx(void); internal void e_select_ir_ctx(E_IRCtx *ctx); //////////////////////////////// diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index 352067e2..38386ed2 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -315,10 +315,6 @@ e_select_parse_ctx(E_ParseCtx *ctx) e_parse_state->arena_eval_start_pos = arena_pos(arena); } arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); - if(ctx->regs_map == 0) { ctx->regs_map = &e_string2num_map_nil; } - if(ctx->reg_alias_map == 0) { ctx->reg_alias_map = &e_string2num_map_nil; } - if(ctx->locals_map == 0) { ctx->locals_map = &e_string2num_map_nil; } - if(ctx->member_map == 0) { ctx->member_map = &e_string2num_map_nil; } if(ctx->primary_module == 0){ ctx->primary_module = &e_module_nil; } e_parse_state->ctx = ctx; } @@ -537,7 +533,6 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) } }break; case E_ExprKind_LeafBytecode: - case E_ExprKind_LeafMember: case E_ExprKind_LeafIdentifier: { str8_list_push(arena, out, expr->string); @@ -547,7 +542,6 @@ e_append_strings_from_expr(Arena *arena, E_Expr *expr, String8List *out) str8_list_pushf(arena, out, "\"%S\"", expr->string); }break; case E_ExprKind_LeafU64: - case E_ExprKind_LeafBool: { str8_list_pushf(arena, out, "%I64u", expr->value.u64); }break; @@ -771,15 +765,15 @@ e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, } internal E_Parse -e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) +e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) { E_Parse parse = {0, &e_expr_nil, &e_expr_nil}; - E_Token *token_it = tokens->v; + E_Token *token_it = tokens.v; //- rjf: parse unsigned marker B32 unsigned_marker = 0; { - E_Token token = e_token_at_it(token_it, tokens); + E_Token token = e_token_at_it(token_it, &tokens); if(token.kind == E_TokenKind_Identifier) { String8 token_string = str8_substr(text, token.range); @@ -793,7 +787,7 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) //- rjf: parse base type { - E_Token token = e_token_at_it(token_it, tokens); + E_Token token = e_token_at_it(token_it, &tokens); if(token.kind == E_TokenKind_Identifier) { String8 token_string = str8_substr(text, token.range); @@ -836,7 +830,7 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) { for(;;) { - E_Token token = e_token_at_it(token_it, tokens); + E_Token token = e_token_at_it(token_it, &tokens); if(token.kind != E_TokenKind_Symbol) { break; @@ -862,20 +856,24 @@ e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) } internal E_Parse -e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count) +e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); - E_Token *it = tokens->v; - E_Token *it_opl = tokens->v + tokens->count; + E_Token *it = tokens.v; + E_Token *it_opl = tokens.v + tokens.count; E_Parse result = {0, &e_expr_nil, &e_expr_nil}; + ////////////////////////////// //- rjf: parse chain of expressions + // for(U64 chain_count = 0; it < it_opl && chain_count < max_chain_count;) { + //////////////////////////// //- rjf: exit on symbols callers may be waiting on + // { - E_Token token = e_token_at_it(it, tokens); + 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) || @@ -887,10 +885,12 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + //////////////////////////// //- rjf: skip commas, semicolons, etc. + // for(;it < it_opl;) { - E_Token token = e_token_at_it(it, tokens); + 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) || @@ -904,22 +904,24 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + //////////////////////////// //- rjf: parse prefix unaries - typedef struct PrefixUnaryNode PrefixUnaryNode; - struct PrefixUnaryNode + // + typedef struct PrefixUnaryTask PrefixUnaryTask; + struct PrefixUnaryTask { - PrefixUnaryNode *next; + PrefixUnaryTask *next; E_ExprKind kind; E_Expr *cast_expr; void *location; }; - PrefixUnaryNode *first_prefix_unary = 0; - PrefixUnaryNode *last_prefix_unary = 0; + PrefixUnaryTask *first_prefix_unary = 0; + PrefixUnaryTask *last_prefix_unary = 0; { for(;it < it_opl;) { E_Token *start_it = it; - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); S64 prefix_unary_precedence = 0; E_ExprKind prefix_unary_kind = 0; @@ -948,7 +950,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: try casting expression if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) { - E_Token some_type_identifier_maybe = e_token_at_it(it+1, tokens); + E_Token some_type_identifier_maybe = e_token_at_it(it+1, &tokens); String8 some_type_identifier_maybe_string = str8_substr(text, some_type_identifier_maybe.range); if(some_type_identifier_maybe.kind == E_TokenKind_Identifier) { @@ -959,15 +961,14 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; // rjf: parse type expr - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); + E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, e_token_array_make_first_opl(it, it_opl)); E_Expr *type = type_parse.exprs.last; e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); it = type_parse.last_token; location = token_string.str; // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { @@ -1002,7 +1003,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: push prefix unary if we got one { - PrefixUnaryNode *op_n = push_array(scratch.arena, PrefixUnaryNode, 1); + PrefixUnaryTask *op_n = push_array(scratch.arena, PrefixUnaryTask, 1); op_n->kind = prefix_unary_kind; op_n->cast_expr = cast_expr; op_n->location = location; @@ -1011,44 +1012,49 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } + //////////////////////////// //- rjf: parse atom + // E_Expr *atom = &e_expr_nil; String8 atom_implicit_member_name = {0}; if(it < it_opl) { - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); - //- rjf: gather resolution qualifier + ////////////////////////// + //- rjf: consume resolution qualifiers + // String8 resolution_qualifier = {0}; if(token.kind == E_TokenKind_Identifier) { - E_Token next_token = e_token_at_it(it+1, tokens); + E_Token next_token = e_token_at_it(it+1, &tokens); String8 next_token_string = str8_substr(text, next_token.range); if(next_token.kind == E_TokenKind_Symbol && str8_match(next_token_string, str8_lit(":"), 0)) { it += 2; resolution_qualifier = token_string; - token = e_token_at_it(it, tokens); + token = e_token_at_it(it, &tokens); token_string = str8_substr(text, token.range); } } - //- rjf: descent to nested expression + ////////////////////////// + //- rjf: descent to nested expression (...) + // if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) { // rjf: skip ( it += 1; // rjf: parse () contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); atom = nested_parse.exprs.last; it = nested_parse.last_token; // rjf: expect ) - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { @@ -1062,15 +1068,16 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } - //- rjf: descent to assembly-style dereference sub-expression + ////////////////////////// + //- rjf: descent to assembly-style dereference sub-expression [...] + // else if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) { // rjf: skip [ it += 1; // rjf: parse [] contents - E_TokenArray nested_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, &nested_parse_tokens, e_max_precedence, 1); + E_Parse nested_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &nested_parse.msgs); atom = nested_parse.exprs.last; it = nested_parse.last_token; @@ -1093,7 +1100,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } // rjf: expect ] - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) { @@ -1107,569 +1114,115 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } - //- rjf: leaf (identifier, literal) - else if(token.kind != E_TokenKind_Symbol) + ////////////////////////// + //- rjf: leaf identifier + // + else if(token.kind == E_TokenKind_Identifier) { - switch(token.kind) + atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); + atom->string = token_string; + it += 1; + } + + ////////////////////////// + //- rjf: leaf numeric + // + else if(token.kind == E_TokenKind_Numeric) + { + U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); + it += 1; + + // rjf: no . => integral + if(dot_pos == token_string.size) { - //- rjf: identifier => name resolution - default: - case E_TokenKind_Identifier: - { - B32 mapped_identifier = 0; - B32 identifier_is_constant_value = 0; - B32 identifier_type_is_possibly_dynamically_overridden = 0; - B32 identifier_looks_like_type_expr = 0; - RDI_LocationKind loc_kind = RDI_LocationKind_NULL; - RDI_LocationReg loc_reg = {0}; - RDI_LocationRegPlusU16 loc_reg_u16 = {0}; - String8 loc_bytecode = {0}; - U64 constant_value = 0; - REGS_RegCode reg_code = 0; - REGS_AliasCode alias_code = 0; - E_TypeKey type_key = zero_struct; - String8 local_lookup_string = token_string; - E_Space space = {0}; - Arch arch = Arch_Null; - - //- rjf: identifiers surrounded by ``s should have those `s stripped - if(local_lookup_string.size >= 2 && - local_lookup_string.str[0] == '`' && - local_lookup_string.str[local_lookup_string.size-1] == '`') - { - token_string = local_lookup_string = str8_substr(local_lookup_string, r1u64(1, local_lookup_string.size-1)); - } - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_token_strings = {0}; - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, e_parse_state->ctx->ip_voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); - String8 containing_procedure_name = str8(name_ptr, name_size); - U64 last_past_scope_resolution_pos = 0; - for(;;) - { - U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2; - U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1; - U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos); - if(past_next_scope_resolution_pos >= containing_procedure_name.size) - { - break; - } - String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos); - String8 namespaceified_token_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, token_string); - str8_list_push_front(scratch.arena, &namespaceified_token_strings, namespaceified_token_string); - last_past_scope_resolution_pos = past_next_scope_resolution_pos; - } - } - - //- rjf: try members - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("member"), 0))) ProfScope("try to map name as member") - { - U64 data_member_num = e_num_from_string(e_parse_state->ctx->member_map, token_string); - if(data_member_num != 0) - { - atom_implicit_member_name = token_string; - local_lookup_string = str8_lit("this"); - } - } - - //- rjf: try locals - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("local"), 0))) ProfScope("try to map name as local") - { - E_Module *module = e_parse_state->ctx->primary_module; - RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, local_lookup_string); - if(local_num != 0) - { - identifier_type_is_possibly_dynamically_overridden = 1; - RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_num-1); - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, local_var->type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), local_var->type_idx, (U32)(module - e_parse_state->ctx->modules)); - - // rjf: grab location info - for(U32 loc_block_idx = local_var->location_first; - loc_block_idx < local_var->location_opl; - loc_block_idx += 1) - { - RDI_LocationBlock *block = rdi_element_from_name_idx(rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= e_parse_state->ctx->ip_voff && e_parse_state->ctx->ip_voff < block->scope_off_opl) - { - mapped_identifier = 1; - space = module->space; - arch = module->arch; - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(rdi, LocationData, &all_location_data_size); - if(block->location_data_off + sizeof(RDI_LocationKind) <= all_location_data_size) - { - loc_kind = *((RDI_LocationKind *)(all_location_data + block->location_data_off)); - switch(loc_kind) - { - default:{mapped_identifier = 0;}break; - case RDI_LocationKind_ValBytecodeStream: goto bytecode_stream; - case RDI_LocationKind_AddrBytecodeStream: goto bytecode_stream; - bytecode_stream:; - { - U64 bytecode_size = 0; - U64 off_first = block->location_data_off + sizeof(RDI_LocationKind); - U64 off_opl = all_location_data_size; - for(U64 off = off_first, next_off = off_opl; - off < all_location_data_size; - off = next_off) - { - next_off = off_opl; - U8 op = all_location_data[off]; - if(op == 0) - { - break; - } - U16 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += (1 + p_size); - next_off = (off + 1 + p_size); - } - loc_bytecode = str8(all_location_data + off_first, bytecode_size); - }break; - case RDI_LocationKind_AddrRegPlusU16: - case RDI_LocationKind_AddrAddrRegPlusU16: - { - MemoryCopy(&loc_reg_u16, (all_location_data + block->location_data_off), sizeof(loc_reg_u16)); - }break; - case RDI_LocationKind_ValReg: - { - MemoryCopy(&loc_reg, (all_location_data + block->location_data_off), sizeof(loc_reg)); - }break; - } - } - } - } - } - } - - //- rjf: try registers - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register") - { - U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, token_string); - if(reg_num != 0) - { - reg_code = reg_num; - type_key = e_type_key_reg(e_parse_state->ctx->primary_module->arch, reg_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try register aliases - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("reg"), 0))) ProfScope("try to map name as register alias") - { - U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, token_string); - if(alias_num != 0) - { - alias_code = (REGS_AliasCode)alias_num; - type_key = e_type_key_reg_alias(e_parse_state->ctx->primary_module->arch, alias_code); - mapped_identifier = 1; - space = e_parse_state->ctx->ip_thread_space; - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try global variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("global"), 0))) ProfScope("try to map name as global variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - // NOTE(rjf): apparently, PDBs can be produced such that they - // also keep stale *GLOBAL VARIABLE SYMBOLS* around too. I - // don't know of a magic hash table fixup path in PDBs, so - // in this case, I'm going to prefer the latest-added global. - U32 match_idx = matches[matches_count-1]; - RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try thread variables - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("thread_variable"), 0))) ProfScope("try to map name as thread variable") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off)); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try procedures - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("procedure"), 0))) ProfScope("try to map name as procedure") - { - for(U64 module_idx = 0; module_idx < e_parse_state->ctx->modules_count; module_idx += 1) - { - E_Module *module = &e_parse_state->ctx->modules[module_idx]; - RDI_Parsed *rdi = module->rdi; - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first); - E_OpList oplist = {0}; - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff)); - loc_kind = RDI_LocationKind_ValBytecodeStream; - loc_bytecode = e_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx); - type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx); - mapped_identifier = 1; - space = module->space; - arch = module->arch; - break; - } - } - } - - //- rjf: try types - if(mapped_identifier == 0 && (resolution_qualifier.size == 0 || str8_match(resolution_qualifier, str8_lit("type"), 0))) ProfScope("try to map name as type") - { - type_key = e_leaf_type_from_name(token_string); - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - mapped_identifier = 1; - identifier_looks_like_type_expr = 1; - MemoryZeroStruct(&space); - arch = e_parse_state->ctx->primary_module->arch; - } - } - - //- rjf: try basic constants - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("true"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 1; - } - if(mapped_identifier == 0 && str8_match(token_string, str8_lit("false"), 0)) - { - mapped_identifier = 1; - identifier_is_constant_value = 1; - type_key = e_type_key_basic(E_TypeKind_Bool); - constant_value = 0; - } - - //- rjf: attach on map - if(mapped_identifier != 0) ProfScope("attach on map") - { - it += 1; - - // rjf: build atom - switch(loc_kind) - { - default: - { - if(identifier_is_constant_value) - { - atom = e_push_expr(arena, E_ExprKind_LeafBool, token_string.str); - atom->value.u64 = constant_value; - atom->type_key = type_key; - } - else if(identifier_looks_like_type_expr) - { - E_TokenArray type_parse_tokens = e_token_array_make_first_opl(it-1, it_opl); - E_Parse type_parse = e_parse_type_from_text_tokens(arena, text, &type_parse_tokens); - E_Expr *type = type_parse.exprs.last; - e_msg_list_concat_in_place(&result.msgs, &type_parse.msgs); - it = type_parse.last_token; - atom = type; - } - else if(reg_code != 0) - { - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[reg_code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else if(alias_code != 0) - { - REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_code]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_parse_state->ctx->primary_module->arch)[alias_slice.code]; - E_OpList oplist = {0}; - e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MissingInfo, token_string.str, "Missing location information for `%S`.", token_string); - } - }break; - case RDI_LocationKind_AddrBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_ValBytecodeStream: - { - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = loc_bytecode; - }break; - case RDI_LocationKind_AddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: - { - E_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, e_value_u64(loc_reg_u16.offset)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, e_value_u64(0)); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, e_value_u64(bit_size_from_arch(arch)/8)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Offset; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - case RDI_LocationKind_ValReg: - { - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(arch, loc_reg.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(arch)[regs_reg_code]; - E_OpList oplist = {0}; - U64 byte_size = (U64)reg_rng.byte_size; - U64 byte_pos = 0; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg.reg_code, byte_size, byte_pos); - e_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, e_value_u64(regread_param)); - atom = e_push_expr(arena, E_ExprKind_LeafBytecode, token_string.str); - atom->mode = E_Mode_Value; - atom->space = space; - atom->type_key = type_key; - atom->string = token_string; - atom->bytecode = e_bytecode_from_oplist(arena, &oplist); - }break; - } - - // rjf: implicit local lookup -> attach member access node - if(atom_implicit_member_name.size != 0 && atom != &e_expr_nil) - { - E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, atom_implicit_member_name.str); - member_expr->string = atom_implicit_member_name; - atom = e_push_expr(arena, E_ExprKind_MemberAccess, atom_implicit_member_name.str); - atom->space = space; - e_expr_push_child(atom, member_container); - e_expr_push_child(atom, member_expr); - } - } - - //- rjf: map failure -> attach as leaf identifier, to be resolved later - if(!mapped_identifier) - { - atom = e_push_expr(arena, E_ExprKind_LeafIdentifier, token_string.str); - atom->string = token_string; - it += 1; - } - }break; - - //- rjf: numeric => directly extract value - case E_TokenKind_Numeric: - { - U64 dot_pos = str8_find_needle(token_string, 0, str8_lit("."), 0); - it += 1; - - // rjf: no . => integral - if(dot_pos == token_string.size) - { - U64 val = 0; - try_u64_from_str8_c_rules(token_string, &val); - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = val; - break; - } - - // rjf: presence of . => double or float - if(dot_pos < token_string.size) - { - F64 val = f64_from_str8(token_string); - U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); - - // rjf: presence of f after . => f32 - if(f_pos < token_string.size) - { - atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); - atom->value.f32 = val; - } - - // rjf: no f => f64 - else - { - atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); - atom->value.f64 = val; - } - } - }break; - - //- rjf: char => extract char value - case E_TokenKind_CharLiteral: - { - it += 1; - if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') - { - String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); - String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); - U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; - atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); - atom->value.u64 = (U64)char_val; - } - else - { - e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); - } - }break; - - //- rjf: string => leaf string literal, or file path - case E_TokenKind_StringLiteral: - { - if(str8_match(resolution_qualifier, str8_lit("file"), 0) || - str8_match(resolution_qualifier, str8_lit("folder"), 0)) - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); - atom->string = string_value_raw; - it += 1; - } - else - { - String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); - String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); - atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); - atom->string = string_value_raw; - it += 1; - } - }break; + U64 val = 0; + try_u64_from_str8_c_rules(token_string, &val); + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = val; + break; } - //- rjf: upgrade atom w/ qualifier - if(atom != &e_expr_nil && resolution_qualifier.size != 0) + // rjf: presence of . => double or float + if(dot_pos < token_string.size) { - atom->qualifier = resolution_qualifier; + F64 val = f64_from_str8(token_string); + U64 f_pos = str8_find_needle(token_string, 0, str8_lit("f"), StringMatchFlag_CaseInsensitive); + + // rjf: presence of f after . => f32 + if(f_pos < token_string.size) + { + atom = e_push_expr(arena, E_ExprKind_LeafF32, token_string.str); + atom->value.f32 = val; + } + + // rjf: no f => f64 + else + { + atom = e_push_expr(arena, E_ExprKind_LeafF64, token_string.str); + atom->value.f64 = val; + } } } + + ////////////////////////// + //- rjf: leaf char literal + // + else if(token.kind == E_TokenKind_CharLiteral) + { + it += 1; + if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') + { + String8 char_literal_escaped = str8_skip(str8_chop(token_string, 1), 1); + String8 char_literal_raw = raw_from_escaped_str8(scratch.arena, char_literal_escaped); + U8 char_val = char_literal_raw.size > 0 ? char_literal_raw.str[0] : 0; + atom = e_push_expr(arena, E_ExprKind_LeafU64, token_string.str); + atom->value.u64 = (U64)char_val; + } + else + { + e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, token_string.str, "Malformed character literal."); + } + } + + ////////////////////////// + //- rjf: filesystem-qualified leaf string literal + // + else if(token.kind == E_TokenKind_StringLiteral && + (str8_match(resolution_qualifier, str8_lit("file"), 0) || + str8_match(resolution_qualifier, str8_lit("folder"), 0))) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafFilePath, token_string.str); + atom->string = string_value_raw; + it += 1; + } + + ////////////////////////// + //- rjf: leaf string literal + // + else if(token.kind == E_TokenKind_StringLiteral) + { + String8 string_value_escaped = str8_chop(str8_skip(token_string, 1), 1); + String8 string_value_raw = raw_from_escaped_str8(arena, string_value_escaped); + atom = e_push_expr(arena, E_ExprKind_LeafStringLiteral, token_string.str); + atom->string = string_value_raw; + it += 1; + } + + //- rjf: upgrade atom w/ qualifier + if(atom != &e_expr_nil && resolution_qualifier.size != 0) + { + atom->qualifier = resolution_qualifier; + } } + //////////////////////////// //- rjf: upgrade atom w/ postfix unaries + // if(atom != &e_expr_nil) for(;it < it_opl;) { - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); B32 is_postfix_unary = 0; @@ -1687,7 +1240,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to String8 member_name = {0}; B32 good_member_name = 0; { - E_Token member_name_maybe = e_token_at_it(it, tokens); + E_Token member_name_maybe = e_token_at_it(it, &tokens); String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); if(member_name_maybe.kind != E_TokenKind_Identifier) { @@ -1704,7 +1257,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to if(good_member_name) { E_Expr *member_container = atom; - E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafMember, member_name.str); + E_Expr *member_expr = e_push_expr(arena, E_ExprKind_LeafIdentifier, member_name.str); member_expr->string = member_name; atom = e_push_expr(arena, E_ExprKind_MemberAccess, token_string.str); e_expr_push_child(atom, member_container); @@ -1728,8 +1281,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; // rjf: parse indexing expression - E_TokenArray idx_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &idx_expr_parse_tokens, e_max_precedence, 1); + E_Parse idx_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); e_msg_list_concat_in_place(&result.msgs, &idx_expr_parse.msgs); it = idx_expr_parse.last_token; @@ -1745,7 +1297,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: expect ] { - E_Token close_brace_maybe = e_token_at_it(it, tokens); + E_Token close_brace_maybe = e_token_at_it(it, &tokens); String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); if(close_brace_maybe.kind != E_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) { @@ -1770,8 +1322,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_Expr *call_expr = e_push_expr(arena, E_ExprKind_Call, token_string.str); call_expr->string = callee_expr->string; e_expr_push_child(call_expr, callee_expr); - E_TokenArray args_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, &args_parse_tokens, e_max_precedence, max_U64); + E_Parse args_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &args_parse.msgs); it = args_parse.last_token; if(args_parse.exprs.first != &e_expr_nil) @@ -1784,7 +1335,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // rjf: expect ) { - E_Token close_paren_maybe = e_token_at_it(it, tokens); + E_Token close_paren_maybe = e_token_at_it(it, &tokens); String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); if(close_paren_maybe.kind != E_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) { @@ -1804,11 +1355,21 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } } - //- rjf: upgrade atom w/ previously parsed prefix unaries + //////////////////////////// + //- rjf: no `atom`, but we have a cast expression? -> just evaluate the type as the atom + // if(atom == &e_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != &e_expr_nil) { atom = first_prefix_unary->cast_expr; - for(PrefixUnaryNode *prefix_unary = first_prefix_unary->next; + first_prefix_unary = first_prefix_unary->next; + } + + //////////////////////////// + //- rjf: upgrade `atom` w/ previously parsed prefix unaries + // + if(atom != &e_expr_nil) + { + for(PrefixUnaryTask *prefix_unary = first_prefix_unary; prefix_unary != 0; prefix_unary = prefix_unary->next) { @@ -1821,31 +1382,18 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to e_expr_push_child(atom, rhs); } } - else if(atom == &e_expr_nil && first_prefix_unary != 0) + else if(first_prefix_unary != 0) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, last_prefix_unary->location, "Missing expression."); } - else - { - for(PrefixUnaryNode *prefix_unary = first_prefix_unary; - prefix_unary != 0; - prefix_unary = prefix_unary->next) - { - E_Expr *rhs = atom; - atom = e_push_expr(arena, prefix_unary->kind, prefix_unary->location); - if(prefix_unary->cast_expr != &e_expr_nil) - { - e_expr_push_child(atom, prefix_unary->cast_expr); - } - e_expr_push_child(atom, rhs); - } - } - //- rjf: parse complex operators + //////////////////////////// + //- rjf: parse complex operators to further extend `atom` + // if(atom != &e_expr_nil) for(;it < it_opl;) { E_Token *start_it = it; - E_Token token = e_token_at_it(it, tokens); + E_Token token = e_token_at_it(it, &tokens); String8 token_string = str8_substr(text, token.range); //- rjf: parse binaries @@ -1869,8 +1417,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to // precedence if(binary_precedence != 0 && binary_precedence <= max_precedence) { - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it+1, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, binary_precedence-1, 1); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it+1, it_opl), binary_precedence-1, 1); e_msg_list_concat_in_place(&result.msgs, &rhs_expr_parse.msgs); E_Expr *rhs = rhs_expr_parse.exprs.last; it = rhs_expr_parse.last_token; @@ -1895,8 +1442,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to it += 1; // rjf: parse middle expression - E_TokenArray middle_expr_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &middle_expr_tokens, e_max_precedence, 1); + E_Parse middle_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); it = middle_expr_parse.last_token; E_Expr *middle_expr = middle_expr_parse.exprs.last; e_msg_list_concat_in_place(&result.msgs, &middle_expr_parse.msgs); @@ -1910,7 +1456,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to E_Token colon_token = zero_struct; String8 colon_token_string = {0}; { - E_Token colon_token_maybe = e_token_at_it(it, tokens); + E_Token colon_token_maybe = e_token_at_it(it, &tokens); String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); if(colon_token_maybe.kind != E_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) { @@ -1926,8 +1472,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } // rjf: parse rhs - E_TokenArray rhs_expr_parse_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, &rhs_expr_parse_tokens, e_max_precedence, 1); + E_Parse rhs_expr_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, 1); if(got_colon) { it = rhs_expr_parse.last_token; @@ -1959,8 +1504,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to if(token.kind == E_TokenKind_Symbol && str8_match(token_string, str8_lit("=>"), 0)) { it += 1; - E_TokenArray tags_tokens = e_token_array_make_first_opl(it, it_opl); - E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, &tags_tokens, e_max_precedence, max_U64); + E_Parse tags_parse = e_parse_expr_from_text_tokens__prec(arena, text, e_token_array_make_first_opl(it, it_opl), e_max_precedence, max_U64); e_msg_list_concat_in_place(&result.msgs, &tags_parse.msgs); it = tags_parse.last_token; for(E_Expr *tag = tags_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) @@ -1998,7 +1542,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to } internal E_Parse -e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens) +e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens) { ProfBegin("parse '%.*s'", str8_varg(text)); E_Parse parse = e_parse_expr_from_text_tokens__prec(arena, text, tokens, e_max_precedence, max_U64); @@ -2011,7 +1555,7 @@ e_parse_expr_from_text(Arena *arena, String8 text) { Temp scratch = scratch_begin(&arena, 1); E_TokenArray tokens = e_token_array_from_text(scratch.arena, text); - E_Parse parse = e_parse_expr_from_text_tokens(arena, text, &tokens); + E_Parse parse = e_parse_expr_from_text_tokens(arena, text, tokens); scratch_end(scratch); return parse; } diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index a251ec3c..a414f01b 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -21,21 +21,9 @@ struct E_Parse typedef struct E_ParseCtx E_ParseCtx; struct E_ParseCtx { - // rjf: instruction pointer info - U64 ip_vaddr; - U64 ip_voff; - E_Space ip_thread_space; - - // rjf: modules E_Module *modules; U64 modules_count; E_Module *primary_module; - - // rjf: local identifier resolution maps - E_String2NumMap *regs_map; - E_String2NumMap *reg_alias_map; - E_String2NumMap *locals_map; // (within `rdis[rdis_primary_idx]`) - E_String2NumMap *member_map; // (within `rdis[rdis_primary_idx]`) }; //////////////////////////////// @@ -60,7 +48,7 @@ thread_static E_ParseState *e_parse_state = 0; //////////////////////////////// //~ rjf: Tokenization Functions -#define e_token_at_it(it, arr) (((it) < (arr)->v+(arr)->count) ? (*(it)) : e_token_zero()) +#define e_token_at_it(it, arr) (((arr)->v <= (it) && (it) < (arr)->v+(arr)->count) ? (*(it)) : e_token_zero()) internal E_Token e_token_zero(void); internal void e_token_chunk_list_push(Arena *arena, E_TokenChunkList *list, U64 chunk_size, E_Token *token); internal E_TokenArray e_token_array_from_chunk_list(Arena *arena, E_TokenChunkList *list); @@ -100,9 +88,9 @@ internal String8 e_string_from_expr(Arena *arena, E_Expr *expr); internal E_TypeKey e_leaf_type_from_name(String8 name); internal E_TypeKey e_type_from_expr(E_Expr *expr); internal void e_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, E_String2ExprMap *map, E_Expr *expr); -internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); -internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *tokens, S64 max_precedence, U64 max_chain_count); -internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray *tokens); +internal E_Parse e_parse_type_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); +internal E_Parse e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count); +internal E_Parse e_parse_expr_from_text_tokens(Arena *arena, String8 text, E_TokenArray tokens); internal E_Parse e_parse_expr_from_text(Arena *arena, String8 text); #endif // EVAL_PARSE_H diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 1801164b..045dd158 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -137,11 +137,6 @@ struct E_MemberCacheSlot typedef struct E_TypeCtx E_TypeCtx; struct E_TypeCtx { - // rjf: instruction pointer info - U64 ip_vaddr; - U64 ip_voff; // (within `primary_module`) - - // rjf: debug info E_Module *modules; U64 modules_count; E_Module *primary_module; diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index cb7cdfea..14af0ad1 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -134,7 +134,7 @@ U8 e_type_kind_basic_byte_size_table[56] = 0, }; -String8 e_expr_kind_strings[51] = +String8 e_expr_kind_strings[49] = { str8_lit_comp("Nil"), str8_lit_comp("Ref"), @@ -171,9 +171,7 @@ str8_lit_comp("LogOr"), str8_lit_comp("Ternary"), str8_lit_comp("Call"), str8_lit_comp("LeafBytecode"), -str8_lit_comp("LeafMember"), str8_lit_comp("LeafStringLiteral"), -str8_lit_comp("LeafBool"), str8_lit_comp("LeafU64"), str8_lit_comp("LeafF64"), str8_lit_comp("LeafF32"), @@ -189,7 +187,7 @@ str8_lit_comp("Define"), str8_lit_comp("Tag"), }; -E_OpInfo e_expr_kind_op_info_table[51] = +E_OpInfo e_expr_kind_op_info_table[49] = { { 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("") }, @@ -238,8 +236,6 @@ 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("") }, { 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_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("") }, { E_OpKind_Null, 0, str8_lit_comp("=>"), str8_lit_comp(","), str8_lit_comp("") }, }; diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 5bb4994c..5ccfe7e1 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -126,9 +126,7 @@ E_ExprKind_LogOr, E_ExprKind_Ternary, E_ExprKind_Call, E_ExprKind_LeafBytecode, -E_ExprKind_LeafMember, E_ExprKind_LeafStringLiteral, -E_ExprKind_LeafBool, E_ExprKind_LeafU64, E_ExprKind_LeafF64, E_ExprKind_LeafF32, @@ -165,8 +163,8 @@ C_LINKAGE_BEGIN extern String8 e_token_kind_strings[6]; extern String8 e_type_kind_basic_string_table[56]; extern U8 e_type_kind_basic_byte_size_table[56]; -extern String8 e_expr_kind_strings[51]; -extern E_OpInfo e_expr_kind_op_info_table[51]; +extern String8 e_expr_kind_strings[49]; +extern E_OpInfo e_expr_kind_op_info_table[49]; extern String8 e_interpretation_code_display_strings[11]; C_LINKAGE_END diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 7383b24d..7ceb35c3 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -519,7 +519,7 @@ ev_keyed_expr_push_tags(Arena *arena, EV_View *view, EV_Block *block, EV_Key key // rjf: push explicitly-attached tags (via key) next String8 tag_expr = push_str8_copy(arena, ev_view_rule_from_key(view, key)); E_TokenArray tag_expr_tokens = e_token_array_from_text(scratch.arena, tag_expr); - E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, &tag_expr_tokens); + E_Parse tag_expr_parse = e_parse_expr_from_text_tokens(arena, tag_expr, tag_expr_tokens); for(E_Expr *tag = tag_expr_parse.exprs.first, *next = &e_expr_nil; tag != &e_expr_nil; tag = next) { next = tag->next; diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index f099ec6c..3439589e 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -586,6 +586,30 @@ rdi_root_scope_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) return scope; } +RDI_PROC RDI_UDT * +rdi_container_udt_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) +{ + RDI_U64 idx = 0; + if(procedure->link_flags & RDI_LinkFlag_TypeScoped) + { + idx = procedure->container_idx; + } + RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, idx); + return udt; +} + +RDI_PROC RDI_Procedure * +rdi_container_procedure_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) +{ + RDI_U64 idx = 0; + if(procedure->link_flags & RDI_LinkFlag_ProcScoped) + { + idx = procedure->container_idx; + } + RDI_Procedure *container_procedure = rdi_element_from_name_idx(rdi, Procedures, idx); + return container_procedure; +} + RDI_PROC RDI_U64 rdi_first_voff_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure) { diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index 59cedfa5..4d3e40b4 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -182,6 +182,8 @@ RDI_PROC RDI_Procedure *rdi_procedure_from_name(RDI_Parsed *rdi, RDI_U8 *name, R RDI_PROC RDI_Procedure *rdi_procedure_from_name_cstr(RDI_Parsed *rdi, char *cstr); RDI_PROC RDI_U8 *rdi_name_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure, RDI_U64 *len_out); RDI_PROC RDI_Scope *rdi_root_scope_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); +RDI_PROC RDI_UDT *rdi_container_udt_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); +RDI_PROC RDI_Procedure *rdi_container_procedure_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); RDI_PROC RDI_U64 rdi_first_voff_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); RDI_PROC RDI_U64 rdi_opl_voff_from_procedure(RDI_Parsed *rdi, RDI_Procedure *procedure); RDI_PROC RDI_Procedure *rdi_procedure_from_voff(RDI_Parsed *rdi, RDI_U64 voff); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index e8be644f..eb543367 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -196,7 +196,7 @@ E_LOOKUP_INFO_FUNCTION_DEF(locals) E_LookupInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_state->ctx->locals_map); + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_state->ctx->locals_map); e_string2num_map_node_array_sort__in_place(&nodes); String8List exprs_filtered = {0}; for EachIndex(idx, nodes.count) @@ -11873,7 +11873,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as local if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 local_num = e_num_from_string(e_parse_state->ctx->locals_map, string); + U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string); if(local_num != 0) { mapped = 1; @@ -11884,7 +11884,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as member if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 member_num = e_num_from_string(e_parse_state->ctx->member_map, string); + U64 member_num = e_num_from_string(e_ir_state->ctx->member_map, string); if(member_num != 0) { mapped = 1; @@ -11895,7 +11895,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register if(!mapped) { - U64 reg_num = e_num_from_string(e_parse_state->ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); if(reg_num != 0) { mapped = 1; @@ -11906,7 +11906,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register alias if(!mapped) { - U64 alias_num = e_num_from_string(e_parse_state->ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); if(alias_num != 0) { mapped = 1; @@ -13479,8 +13479,6 @@ rd_frame(void) ProfScope("build eval type context") { E_TypeCtx *ctx = type_ctx; - ctx->ip_vaddr = rip_vaddr; - ctx->ip_voff = rip_voff; ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; @@ -13494,16 +13492,9 @@ rd_frame(void) ProfScope("build eval parse context") { E_ParseCtx *ctx = parse_ctx; - ctx->ip_vaddr = rip_vaddr; - ctx->ip_voff = rip_voff; - ctx->ip_thread_space = rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_CtrlEntity); ctx->modules = eval_modules; ctx->modules_count = eval_modules_count; ctx->primary_module = eval_modules_primary; - ctx->regs_map = ctrl_string2reg_from_arch(ctx->primary_module->arch); - ctx->reg_alias_map = ctrl_string2alias_from_arch(ctx->primary_module->arch); - ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); - ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); } e_select_parse_ctx(parse_ctx); @@ -13514,6 +13505,13 @@ rd_frame(void) if(e_ir_state != 0) { e_ir_state->ctx = 0; } { E_IRCtx *ctx = ir_ctx; + ctx->modules = eval_modules; + ctx->modules_count = eval_modules_count; + ctx->primary_module = eval_modules_primary; + ctx->regs_map = ctrl_string2reg_from_arch(ctx->primary_module->arch); + ctx->reg_alias_map = ctrl_string2alias_from_arch(ctx->primary_module->arch); + ctx->locals_map = d_query_cached_locals_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); + ctx->member_map = d_query_cached_member_map_from_dbgi_key_voff(&primary_dbgi_key, rip_voff); ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); ctx->lookup_rule_map = push_array(scratch.arena, E_LookupRuleMap, 1); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 8cdfb900..0b33bad5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -2501,7 +2501,7 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_color_from_name(str8_lit("code_local")), }; U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); - for(E_String2NumMapNode *n = e_parse_state->ctx->locals_map->first; n != 0; n = n->order_next) + for(E_String2NumMapNode *n = e_ir_state->ctx->locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; E_Eval local_eval = e_eval_from_string(scratch.arena, local_name);