From 20cd955cc9d92e85562d633e2165eaaeaf38ed08 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 30 Jun 2026 14:20:15 -0700 Subject: [PATCH] eval2: first pass at type_key -> string path --- src/eval2/eval2.c | 219 +++++++++++++++++++++++++++++++++++++ src/eval2/eval2.h | 5 + src/scratch/ryan_scratch.c | 3 +- 3 files changed, 226 insertions(+), 1 deletion(-) diff --git a/src/eval2/eval2.c b/src/eval2/eval2.c index 55435871..fd15cdd8 100644 --- a/src/eval2/eval2.c +++ b/src/eval2/eval2.c @@ -751,6 +751,35 @@ e2_mask_count_from_type_key(E2_TypeKey k) return result; } +internal U64 +e2_array_count_from_type_key(E2_TypeKey k) +{ + U64 result = 0; + if(e2_type_kind_from_key(k) == E2_TypeKind_Array) + { + switch(k.kind) + { + case E2_TypeKeyKind_Null:{}break; + case E2_TypeKeyKind_Basic:{}break; + case E2_TypeKeyKind_DbgInfo: + { + E2_DbgInfo *dbgi = e2_dbgi_from_type_key(k); + U32 dbgi_type_idx = e2_dbgi_type_idx_from_key(k); + RDI_TypeNode *type_node = rdi_element_from_name_idx(dbgi->rdi, TypeNodes, dbgi_type_idx); + result = type_node->constructed.count; + }break; + case E2_TypeKeyKind_Cons: + { + U64 id = e2_cons_type_id_from_key(k); + E2_ConsTypeNode *node = e2_cons_type_node_from_id(id); + result = node->params.count; + }break; + case E2_TypeKeyKind_Reg:{}break; + } + } + return result; +} + internal Arch e2_arch_from_type_key(E2_TypeKey k) { @@ -780,6 +809,196 @@ e2_arch_from_type_key(E2_TypeKey k) return arch; } +internal String8 +e2_name_from_type_key(Arena *arena, E2_TypeKey k) +{ + String8 result = {0}; + switch(k.kind) + { + case E2_TypeKeyKind_Null:{}break; + case E2_TypeKeyKind_Basic: + { + E2_TypeKind kind = e2_type_kind_from_key(k); + if(E2_TypeKind_FirstBasic <= kind && kind <= E2_TypeKind_LastBasic) + { + result = e2_type_kind_basic_string_table[kind]; + } + }break; + case E2_TypeKeyKind_DbgInfo: + { + E2_DbgInfo *dbgi = e2_dbgi_from_type_key(k); + U32 type_idx = e2_dbgi_type_idx_from_key(k); + RDI_TypeNode *type_node = rdi_element_from_name_idx(dbgi->rdi, TypeNodes, type_idx); + result = fully_qualified_str8_from_rdi_type(arena, dbgi->rdi, type_node); + }break; + case E2_TypeKeyKind_Cons: + { + U64 id = e2_cons_type_id_from_key(k); + E2_ConsTypeNode *node = e2_cons_type_node_from_id(id); + result = node->params.name; + }break; + case E2_TypeKeyKind_Reg: + { + U64 byte_size = e2_byte_size_from_type_key(k); + result = str8f(arena, "register_%I64u", byte_size*8); + }break; + } + return result; +} + +//- rjf: type key -> string + +internal String8 +e2_string_from_type_key(Arena *arena, E2_TypeKey key) +{ + String8 result = {0}; + { + typedef struct Task Task; + struct Task + { + Task *next; + E2_TypeKey key; + U32 prec; + B32 did_direct; + }; + Task start_task = {0, key}; + Task *top_task = &start_task; + Task *free_task = 0; + Temp scratch = scratch_begin(&arena, 1); + String8List lhs = {0}; + String8List rhs = {0}; + for(;top_task != 0;) + { + //- rjf: unpack type + E2_TypeKey key = top_task->key; + E2_TypeKind kind = e2_type_kind_from_key(key); + E2_TypeKey direct = e2_type_key_direct(key); + String8 name = e2_name_from_type_key(scratch.arena, key); + U64 prec = top_task->prec; + B32 did_direct = top_task->did_direct; + + //- rjf: push string for this task + U32 next_prec = 0; + switch(kind) + { + default: + { + String8 keyword = {0}; + if(E2_TypeKind_FirstIncomplete <= kind && kind <= E2_TypeKind_LastIncomplete) + { + switch(kind) + { + default:{}break; + case E2_TypeKind_IncompleteStruct:{keyword = s("struct");}break; + case E2_TypeKind_IncompleteUnion: {keyword = s("union");}break; + case E2_TypeKind_IncompleteClass: {keyword = s("class");}break; + case E2_TypeKind_IncompleteEnum: {keyword = s("enum");}break; + } + } + if(keyword.size != 0) + { + str8_list_pushf(scratch.arena, &lhs, "%S ", keyword); + } + str8_list_push(scratch.arena, &lhs, name); + }break; + case E2_TypeKind_Ptr: + if(!did_direct) + { + next_prec = 1; + } + else if(did_direct) + { + str8_list_push(scratch.arena, &lhs, s("*")); + }break; + case E2_TypeKind_LRef: + if(did_direct) + { + str8_list_push(scratch.arena, &lhs, s("&")); + }break; + case E2_TypeKind_RRef: + if(did_direct) + { + str8_list_push(scratch.arena, &lhs, s("&&")); + }break; + case E2_TypeKind_Array: + if(!did_direct) + { + next_prec = 2; + } + else + { + U64 count = e2_array_count_from_type_key(key); + if(prec == 1) + { + str8_list_push(scratch.arena, &lhs, s("(")); + str8_list_push(scratch.arena, &rhs, s(")")); + } + str8_list_pushf(scratch.arena, &rhs, "[%I64u]", count); + }break; + case E2_TypeKind_Function: + if(!did_direct) + { + next_prec = 2; + } + else + { + U64 count = e2_array_count_from_type_key(key); + if(prec == 1) + { + str8_list_push(scratch.arena, &lhs, s("(")); + str8_list_push(scratch.arena, &rhs, s(")")); + } + // TODO(rjf): params here + str8_list_pushf(scratch.arena, &rhs, "(...)"); + }break; + case E2_TypeKind_Bitfield: + if(did_direct) + { + U64 mask_count = e2_mask_count_from_type_key(key); + str8_list_pushf(scratch.arena, &rhs, ": %I64u", mask_count); + }break; + case E2_TypeKind_Variadic: + { + str8_list_push(scratch.arena, &lhs, s("...")); + }break; + } + + //- rjf: did direct, or we don't have a direct key? -> we're done with this type, pop + if(did_direct || e2_type_key_match(direct, e2_type_key_zero())) + { + Task *popped = top_task; + SLLStackPop(top_task); + SLLStackPush(free_task, popped); + } + + //- rjf: didn't do direct? -> push new task for direct type + else + { + top_task->did_direct = 1; + Task *t = free_task; + if(t != 0) + { + SLLStackPop(free_task); + } + else + { + t = push_array_no_zero(scratch.arena, Task, 1); + } + MemoryZeroStruct(t); + SLLStackPush(top_task, t); + t->key = direct; + t->prec = next_prec; + } + } + String8List parts = {0}; + str8_list_concat_in_place(&parts, &lhs); + str8_list_concat_in_place(&parts, &rhs); + result = str8_list_join(arena, &parts, 0); + scratch_end(scratch); + } + return result; +} + //- rjf: type deep matches internal B32 diff --git a/src/eval2/eval2.h b/src/eval2/eval2.h index ff912ad5..1479c7ca 100644 --- a/src/eval2/eval2.h +++ b/src/eval2/eval2.h @@ -611,7 +611,12 @@ internal U32 e2_dbgi_type_idx_from_key(E2_TypeKey k); internal U64 e2_cons_type_id_from_key(E2_TypeKey k); internal U64 e2_shift_from_type_key(E2_TypeKey k); internal U64 e2_mask_count_from_type_key(E2_TypeKey k); +internal U64 e2_array_count_from_type_key(E2_TypeKey k); internal Arch e2_arch_from_type_key(E2_TypeKey k); +internal String8 e2_name_from_type_key(Arena *arena, E2_TypeKey k); + +//- rjf: type key -> string +internal String8 e2_string_from_type_key(Arena *arena, E2_TypeKey key); //- rjf: type deep matches internal B32 e2_type_deep_match(E2_TypeKey l, E2_TypeKey r); diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index 1c7618a6..84c2256d 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -213,7 +213,7 @@ entry_point(CmdLine *cmdline) String8 msgs_string = str8_list_join(scratch.arena, &msgs, &join); // rjf: log - String8 log = str8f(scratch.arena, "%S -> %I64d (f32: %f) (f64: %f) *%s* %s%S\n", + String8 log = str8f(scratch.arena, "%S -> %I64d (f32: %f) (f64: %f) *%s* (type: %S) %s%S\n", strings[idx], val.s64, val.f32, @@ -221,6 +221,7 @@ entry_point(CmdLine *cmdline) irtree->mode == E2_Mode_Type ? "type" : irtree->mode == E2_Mode_Value ? "value" : "address", + e2_string_from_type_key(scratch.arena, irtree->type_key), msgs_string.size != 0 ? " // " : "", msgs_string); raddbg_log("%S", log); printf("%.*s", str8_varg(log));