diff --git a/src/eval2/eval2.c b/src/eval/eval.c similarity index 97% rename from src/eval2/eval2.c rename to src/eval/eval.c index 83dcb9bc..55c1b7e7 100644 --- a/src/eval2/eval2.c +++ b/src/eval/eval.c @@ -4,7 +4,7 @@ //////////////////////////////// //~ rjf: Generated Code -#include "generated/eval2.meta.c" +#include "generated/eval.meta.c" //////////////////////////////// //~ rjf: Lexing/Parsing Data Tables diff --git a/src/eval2/eval2.h b/src/eval/eval.h similarity index 96% rename from src/eval2/eval2.h rename to src/eval/eval.h index 1c656b44..40c9dc87 100644 --- a/src/eval2/eval2.h +++ b/src/eval/eval.h @@ -7,7 +7,7 @@ //////////////////////////////// //~ rjf: Generated Code -#include "generated/eval2.meta.h" +#include "generated/eval.meta.h" //////////////////////////////// //~ rjf: Messages diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 59671cb1..d451f065 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -1,106 +1,186 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -@table(name num_children op_string) -// num_children - # of children packed after this node kind -// op_string - string for quick display of the operator -EVAL_ExprKindTable: -{ - { Nil 0 "" } - - { ArrayIndex 2 "[]" } - { MemberAccess 2 "." } - { Deref 1 "*" } - { Address 1 "&" } - - { Cast 2 "cast" } - { Sizeof 1 "sizeof" } - - { Neg 1 "-" } - { LogNot 1 "!" } - { BitNot 1 "~" } - { Mul 2 "*" } - { Div 2 "/" } - { Mod 2 "%" } - { Add 2 "+" } - { Sub 2 "-" } - { LShift 2 "<<" } - { RShift 2 ">>" } - { Less 2 "<" } - { LsEq 2 "<=" } - { Grtr 2 ">" } - { GrEq 2 ">=" } - { EqEq 2 "==" } - { NtEq 2 "!=" } - - { BitAnd 2 "&" } - { BitXor 2 "^" } - { BitOr 2 "|" } - { LogAnd 2 "&&" } - { LogOr 2 "||" } - - { Ternary 3 "? " } - - { LeafBytecode 0 "bytecode" } - { LeafMember 0 "member" } - { LeafU64 0 "U64" } - { LeafF64 0 "F64" } - { LeafF32 0 "F32" } - - { TypeIdent 0 "type_ident" } - { Ptr 1 "ptr" } - { Array 2 "array" } - { Func 1 "function" } - - { Define 2 "=" } - { LeafIdent 0 "leaf_ident" } -} - -@table(name display_string) -EVAL_ResultCodeTable: -{ - { Good "" } - { DivideByZero "Cannot divide by zero." } - { BadOp "Invalid operation." } - { BadOpTypes "Invalid operation types." } - { BadMemRead "Failed memory read." } - { BadRegRead "Failed register read." } - { BadFrameBase "Invalid frame base address." } - { BadModuleBase "Invalid module base address." } - { BadTLSBase "Invalid thread-local storage base address." } - { InsufficientStackSpace "Insufficient evaluation machine stack space." } - { MalformedBytecode "Malformed bytecode." } -} - -@enum(U32) EVAL_ExprKind: -{ - @expand(EVAL_ExprKindTable a) `$(a.name)`, - COUNT, -} - -@enum EVAL_ResultCode: -{ - @expand(EVAL_ResultCodeTable a) `$(a.name)`, - COUNT, -} - -@data(U8) eval_expr_kind_child_counts: -{ - @expand(EVAL_ExprKindTable a) `$(a.num_children)` -} - -@data(String8) -eval_expr_kind_strings: -{ - @expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.name)")` -} - -@data(String8) eval_result_code_display_strings: -{ - @expand(EVAL_ResultCodeTable a) `str8_lit_comp("$(a.display_string)")` -} - -@data(String8) eval_expr_op_strings: -{ - @expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.op_string)")` -} +// Copyright (c) 2024 Epic Games Tools +// Licensed under the MIT license (https://opensource.org/license/mit/) + +@table(name basic_string basic_byte_size) +// NOTE(rjf): basic_byte_size == 0xFF? => address sized +E_TypeKindTable: +{ + {Null "" 0 } + {Void "void" 0 } + {Handle "HANDLE" 0xFF } + {Char8 "char8" 1 } + {Char16 "char16" 2 } + {Char32 "char32" 4 } + {UChar8 "uchar8" 1 } + {UChar16 "uchar16" 2 } + {UChar32 "uchar32" 4 } + {U8 "U8" 1 } + {U16 "U16" 2 } + {U32 "U32" 4 } + {U64 "U64" 8 } + {U128 "U128" 16 } + {U256 "U256" 32 } + {U512 "U512" 64 } + {S8 "S8" 1 } + {S16 "S16" 2 } + {S32 "S32" 4 } + {S64 "S64" 8 } + {S128 "S128" 16 } + {S256 "S256" 32 } + {S512 "S512" 64 } + {Bool "bool" 1 } + {F16 "F16" 2 } + {F32 "F32" 4 } + {F32PP "F32PP" 4 } + {F48 "F48" 6 } + {F64 "F64" 8 } + {F80 "F80" 10 } + {F128 "F128" 16 } + {ComplexF32 "ComplexF32" 8 } + {ComplexF64 "ComplexF64" 16 } + {ComplexF80 "ComplexF80" 20 } + {ComplexF128 "ComplexF128" 32 } + {Modifier "" 0 } + {Ptr "" 0 } + {LRef "" 0 } + {RRef "" 0 } + {Array "" 0 } + {Function "" 0 } + {Method "" 0 } + {MemberPtr "" 0 } + {Struct "struct" 0 } + {Class "class" 0 } + {Union "union" 0 } + {Enum "enum" 0 } + {Alias "typedef" 0 } + {IncompleteStruct "struct" 0 } + {IncompleteUnion "union" 0 } + {IncompleteClass "class" 0 } + {IncompleteEnum "enum" 0 } + {Bitfield "" 0 } + {Variadic "" 0 } +} + +@table(name op_string) +E_ExprKindTable: +{ + { Nil "" } + + { ArrayIndex "[]" } + { MemberAccess "." } + { Deref "*" } + { Address "&" } + + { Cast "cast" } + { Sizeof "sizeof" } + + { Neg "-" } + { LogNot "!" } + { BitNot "~" } + { Mul "*" } + { Div "/" } + { Mod "%" } + { Add "+" } + { Sub "-" } + { LShift "<<" } + { RShift ">>" } + { Less "<" } + { LsEq "<=" } + { Grtr ">" } + { GrEq ">=" } + { EqEq "==" } + { NtEq "!=" } + + { BitAnd "&" } + { BitXor "^" } + { BitOr "|" } + { LogAnd "&&" } + { LogOr "||" } + + { Ternary "? " } + + { LeafBytecode "bytecode" } + { LeafMember "member" } + { LeafStringLiteral "string_literal" } + { LeafU64 "U64" } + { LeafF64 "F64" } + { LeafF32 "F32" } + + { TypeIdent "type_ident" } + { Ptr "ptr" } + { Array "array" } + { Func "function" } + + { Define "=" } + { LeafIdent "leaf_ident" } +} + +@table(name display_string) +E_InterpretationCodeTable: +{ + { Good "" } + { DivideByZero "Cannot divide by zero." } + { BadOp "Invalid operation." } + { BadOpTypes "Invalid operation types." } + { BadMemRead "Failed memory read." } + { BadRegRead "Failed register read." } + { BadFrameBase "Invalid frame base address." } + { BadModuleBase "Invalid module base address." } + { BadTLSBase "Invalid thread-local storage base address." } + { InsufficientStackSpace "Insufficient evaluation machine stack space." } + { MalformedBytecode "Malformed bytecode." } +} + +@enum E_TypeKind: +{ + @expand(E_TypeKindTable a) `$(a.name)`, + COUNT, + `FirstBasic = E_TypeKind_Void`, + `LastBasic = E_TypeKind_ComplexF128`, + `FirstInteger = E_TypeKind_Char8`, + `LastInteger = E_TypeKind_S512`, + `FirstSigned1 = E_TypeKind_Char8`, + `LastSigned1 = E_TypeKind_Char32`, + `FirstSigned2 = E_TypeKind_S8`, + `LastSigned2 = E_TypeKind_S512`, + `FirstIncomplete = E_TypeKind_IncompleteStruct`, + `LastIncomplete = E_TypeKind_IncompleteEnum`, +} + +@enum(U32) E_ExprKind: +{ + @expand(E_ExprKindTable a) `$(a.name)`, + COUNT, +} + +@enum E_InterpretationCode: +{ + @expand(E_InterpretationCodeTable a) `$(a.name)`, + COUNT, +} + +@data(String8) +e_expr_kind_strings: +{ + @expand(E_ExprKindTable a) `str8_lit_comp("$(a.name)")` +} + +@data(String8) e_interpretation_code_display_strings: +{ + @expand(E_InterpretationCodeTable a) `str8_lit_comp("$(a.display_string)")` +} + +@data(String8) e_expr_op_strings: +{ + @expand(E_ExprKindTable a) `str8_lit_comp("$(a.op_string)")` +} + +@data(U8) e_kind_basic_byte_size_table: +{ + @expand(E_TypeKindTable a) `$(a.basic_byte_size)`; +} + +@data(String8) e_kind_basic_string_table: +{ + @expand(E_TypeKindTable a) `str8_lit_comp("$(a.basic_string)")`; +} diff --git a/src/eval/eval_compiler.c b/src/eval/eval_compiler.c deleted file mode 100644 index d7342817..00000000 --- a/src/eval/eval_compiler.c +++ /dev/null @@ -1,1641 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ allen: EVAL Bytecode Helpers - -internal String8 -eval_bytecode_from_oplist(Arena *arena, EVAL_OpList *list){ - ProfBeginFunction(); - // allocate output - U64 size = list->encoded_size; - U8 *str = push_array_no_zero(arena, U8, size); - - // iterate loose op nodes - U8 *ptr = str; - U8 *opl = str + size; - for (EVAL_Op *op = list->first_op; - op != 0; - op = op->next){ - U32 opcode = op->opcode; - - switch (opcode){ - default: - { - // compute bytecode advance - U8 ctrlbits = rdi_eval_op_ctrlbits_table[opcode]; - U64 extra_byte_count = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - - U8 *next_ptr = ptr + 1 + extra_byte_count; - Assert(next_ptr <= opl); - - // fill bytecode - ptr[0] = opcode; - MemoryCopy(ptr + 1, &op->p, extra_byte_count); - - // advance output pointer - ptr = next_ptr; - }break; - - case EVAL_IRExtKind_Bytecode: - { - // compute bytecode advance - U64 size = op->bytecode.size; - U8 *next_ptr = ptr + size; - Assert(next_ptr <= opl); - - // fill bytecode - MemoryCopy(ptr, op->bytecode.str, size); - - // advance output pointer - ptr = next_ptr; - }break; - } - } - - // fill result - String8 result = {0}; - result.size = size; - result.str = str; - ProfEnd(); - return(result); -} - -internal void -eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RDI_EvalOp opcode, U64 p){ - U8 ctrlbits = rdi_eval_op_ctrlbits_table[opcode]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - - EVAL_Op *node = push_array_no_zero(arena, EVAL_Op, 1); - node->opcode = opcode; - node->p = p; - - SLLQueuePush(list->first_op, list->last_op, node); - list->op_count += 1; - list->encoded_size += 1 + p_size; -} - -internal void -eval_oplist_push_uconst(Arena *arena, EVAL_OpList *list, U64 x){ - if (x <= 0xFF){ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU8, x); - } - else if (x <= 0xFFFF){ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU16, x); - } - else if (x <= 0xFFFFFFFF){ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU32, x); - } - else{ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU64, x); - } -} - -internal void -eval_oplist_push_sconst(Arena *arena, EVAL_OpList *list, S64 x){ - if (-0x80 <= x && x <= 0x7F){ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU8, (U64)x); - eval_oplist_push_op(arena, list, RDI_EvalOp_TruncSigned, 8); - } - else if (-0x8000 <= x && x <= 0x7FFF){ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU16, (U64)x); - eval_oplist_push_op(arena, list, RDI_EvalOp_TruncSigned, 16); - } - else if (-0x80000000ll <= x && x <= 0x7FFFFFFFll){ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU32, (U64)x); - eval_oplist_push_op(arena, list, RDI_EvalOp_TruncSigned, 32); - } - else{ - eval_oplist_push_op(arena, list, RDI_EvalOp_ConstU64, (U64)x); - } -} - -internal void -eval_oplist_push_bytecode(Arena *arena, EVAL_OpList *list, String8 bytecode){ - EVAL_Op *node = push_array_no_zero(arena, EVAL_Op, 1); - node->opcode = EVAL_IRExtKind_Bytecode; - node->bytecode = bytecode; - SLLQueuePush(list->first_op, list->last_op, node); - list->op_count += 1; - list->encoded_size += bytecode.size; -} - -internal void -eval_oplist_concat_in_place(EVAL_OpList *left_dst, EVAL_OpList *right_destroyed){ - if (right_destroyed->first_op != 0){ - if (left_dst->first_op == 0){ - MemoryCopyStruct(left_dst, right_destroyed); - } - else{ - left_dst->last_op = right_destroyed->last_op; - left_dst->op_count += right_destroyed->op_count; - left_dst->encoded_size += right_destroyed->encoded_size; - } - MemoryZeroStruct(right_destroyed); - } -} - -//////////////////////////////// -//~ allen: EVAL Expression Info Functions - -internal RDI_EvalOp -eval_opcode_from_expr_kind(EVAL_ExprKind kind){ - RDI_EvalOp result = RDI_EvalOp_Stop; - switch (kind){ - case EVAL_ExprKind_Neg: result = RDI_EvalOp_Neg; break; - case EVAL_ExprKind_LogNot: result = RDI_EvalOp_LogNot; break; - case EVAL_ExprKind_BitNot: result = RDI_EvalOp_BitNot; break; - case EVAL_ExprKind_Mul: result = RDI_EvalOp_Mul; break; - case EVAL_ExprKind_Div: result = RDI_EvalOp_Div; break; - case EVAL_ExprKind_Mod: result = RDI_EvalOp_Mod; break; - case EVAL_ExprKind_Add: result = RDI_EvalOp_Add; break; - case EVAL_ExprKind_Sub: result = RDI_EvalOp_Sub; break; - case EVAL_ExprKind_LShift: result = RDI_EvalOp_LShift; break; - case EVAL_ExprKind_RShift: result = RDI_EvalOp_RShift; break; - case EVAL_ExprKind_Less: result = RDI_EvalOp_Less; break; - case EVAL_ExprKind_LsEq: result = RDI_EvalOp_LsEq; break; - case EVAL_ExprKind_Grtr: result = RDI_EvalOp_Grtr; break; - case EVAL_ExprKind_GrEq: result = RDI_EvalOp_GrEq; break; - case EVAL_ExprKind_EqEq: result = RDI_EvalOp_EqEq; break; - case EVAL_ExprKind_NtEq: result = RDI_EvalOp_NtEq; break; - case EVAL_ExprKind_BitAnd: result = RDI_EvalOp_BitAnd; break; - case EVAL_ExprKind_BitXor: result = RDI_EvalOp_BitXor; break; - case EVAL_ExprKind_BitOr: result = RDI_EvalOp_BitOr; break; - case EVAL_ExprKind_LogAnd: result = RDI_EvalOp_LogAnd; break; - case EVAL_ExprKind_LogOr: result = RDI_EvalOp_LogOr; break; - } - return(result); -} - -internal B32 -eval_expr_kind_is_comparison(EVAL_ExprKind kind){ - B32 result = 0; - switch (kind){ - case EVAL_ExprKind_EqEq: - case EVAL_ExprKind_NtEq: - case EVAL_ExprKind_Less: - case EVAL_ExprKind_Grtr: - case EVAL_ExprKind_LsEq: - case EVAL_ExprKind_GrEq: - { - result = 1; - }break; - } - return(result); -} - -//////////////////////////////// -//~ allen: EVAL Expression Constructors - -internal EVAL_Expr* -eval_expr(Arena *arena, EVAL_ExprKind kind, void *location, - EVAL_Expr *c0, EVAL_Expr *c1, EVAL_Expr *c2){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->kind = kind; - result->location = location; - result->children[0] = c0; - result->children[1] = c1; - result->children[2] = c2; - return(result); -} - -internal EVAL_Expr* -eval_expr_u64(Arena *arena, void *location, U64 u64){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->kind = EVAL_ExprKind_LeafU64; - result->location = location; - result->u64 = u64; - return(result); -} - -internal EVAL_Expr* -eval_expr_f64(Arena *arena, void *location, F64 f64){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->kind = EVAL_ExprKind_LeafF64; - result->location = location; - result->f64 = f64; - return(result); -} - -internal EVAL_Expr* -eval_expr_f32(Arena *arena, void *location, F32 f32){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->kind = EVAL_ExprKind_LeafF32; - result->location = location; - result->f32 = f32; - return(result); -} - -internal EVAL_Expr* -eval_expr_child_and_u64(Arena *arena, EVAL_ExprKind kind, void *location, - EVAL_Expr *child, U64 u64){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->kind = kind; - result->location = location; - result->child_and_constant.child = child; - result->child_and_constant.u64 = u64; - return(result); -} - -internal EVAL_Expr* -eval_expr_leaf_member(Arena *arena, void *location, String8 name){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->location = location; - result->kind = EVAL_ExprKind_LeafMember; - result->name = name; - return(result); -} - -internal EVAL_Expr* -eval_expr_leaf_ident(Arena *arena, void *location, String8 name) -{ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->location = location; - result->kind = EVAL_ExprKind_LeafIdent; - result->name = name; - return(result); -} - -internal EVAL_Expr* -eval_expr_leaf_bytecode(Arena *arena, void *location, TG_Key type_key, String8 bytecode, EVAL_EvalMode mode){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->location = location; - result->kind = EVAL_ExprKind_LeafBytecode; - result->type_key = type_key; - result->bytecode = bytecode; - result->mode = mode; - return(result); -} - -internal EVAL_Expr* -eval_expr_leaf_op_list(Arena *arena, void *location, TG_Key type_key, EVAL_OpList *ops, EVAL_EvalMode mode){ - String8 bytecode = eval_bytecode_from_oplist(arena, ops); - EVAL_Expr *result = eval_expr_leaf_bytecode(arena, location, type_key, bytecode, mode); - return(result); -} - -internal EVAL_Expr* -eval_expr_leaf_type(Arena *arena, void *location, TG_Key type_key){ - EVAL_Expr *result = push_array(arena, EVAL_Expr, 1); - result->location = location; - result->kind = EVAL_ExprKind_TypeIdent; - result->type_key = type_key; - return(result); -} - -//////////////////////////////// -//~ allen: EVAL Type Information Transformers - -internal RDI_EvalTypeGroup -eval_type_group_from_kind(TG_Kind kind){ - RDI_EvalTypeGroup result = 0; - switch (kind){ - default:{}break; - - case TG_Kind_Null: case TG_Kind_Void: - case TG_Kind_F16: case TG_Kind_F32PP: case TG_Kind_F48: - case TG_Kind_F80: case TG_Kind_F128: - case TG_Kind_ComplexF32: case TG_Kind_ComplexF64: - case TG_Kind_ComplexF80: case TG_Kind_ComplexF128: - case TG_Kind_Modifier: case TG_Kind_Array: - case TG_Kind_Struct: case TG_Kind_Class: case TG_Kind_Union: - case TG_Kind_Enum: case TG_Kind_Alias: - case TG_Kind_IncompleteStruct: case TG_Kind_IncompleteClass: - case TG_Kind_IncompleteUnion: case TG_Kind_IncompleteEnum: - case TG_Kind_Bitfield: case TG_Kind_Variadic: - result = RDI_EvalTypeGroup_Other; break; - - case TG_Kind_Handle: - case TG_Kind_UChar8: case TG_Kind_UChar16: case TG_Kind_UChar32: - case TG_Kind_U8: case TG_Kind_U16: case TG_Kind_U32: - case TG_Kind_U64: case TG_Kind_U128: case TG_Kind_U256: - case TG_Kind_U512: - case TG_Kind_Ptr: case TG_Kind_LRef: case TG_Kind_RRef: - case TG_Kind_Function: case TG_Kind_Method: case TG_Kind_MemberPtr: - result = RDI_EvalTypeGroup_U; break; - - case TG_Kind_Char8: case TG_Kind_Char16: case TG_Kind_Char32: - case TG_Kind_S8: case TG_Kind_S16: case TG_Kind_S32: - case TG_Kind_S64: case TG_Kind_S128: case TG_Kind_S256: - case TG_Kind_S512: - case TG_Kind_Bool: - result = RDI_EvalTypeGroup_S; break; - - case TG_Kind_F32: - result = RDI_EvalTypeGroup_F32; break; - - case TG_Kind_F64: - result = RDI_EvalTypeGroup_F64; break; - } - return(result); -} - -internal TG_Key -eval_type_unwrap_enum(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - TG_Key result = key; - for(B32 good = 1; good;) - { - TG_Kind kind = tg_kind_from_key(result); - if(kind == TG_Kind_Enum) - { - result = tg_direct_from_graph_rdi_key(graph, rdi, result); - } - else - { - good = 0; - } - } - return result; -} - -internal TG_Key -eval_type_promote(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key){ - TG_Key result = key; - TG_Kind kind = tg_kind_from_key(key); - if(kind == TG_Kind_Bool || - kind == TG_Kind_S8 || - kind == TG_Kind_S16 || - kind == TG_Kind_U8 || - kind == TG_Kind_U16) - { - result = tg_key_basic(TG_Kind_S32); - } - return result; -} - -internal TG_Key -eval_type_coerce(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r){ - Assert(eval_kind_is_basic_or_enum(tg_kind_from_key(l)) && - eval_kind_is_basic_or_enum(tg_kind_from_key(r))); - - // replace enums with corresponding ints - TG_Key lt = eval_type_unwrap_enum(graph, rdi, l); - TG_Key rt = eval_type_unwrap_enum(graph, rdi, r); - - // first promote each - TG_Key lp = eval_type_promote(graph, rdi, lt); - TG_Key rp = eval_type_promote(graph, rdi, rt); - TG_Kind lk = tg_kind_from_key(lp); - TG_Kind rk = tg_kind_from_key(rp); - - TG_Key result = l; - return(result); -} - -internal B32 -eval_type_match(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r){ - B32 result = 0; - - // unwrap - TG_Key lu = tg_unwrapped_from_graph_rdi_key(graph, rdi, l); - TG_Key ru = tg_unwrapped_from_graph_rdi_key(graph, rdi, r); - - if (tg_key_match(lu, ru)){ - result = 1; - } - else{ - TG_Kind luk = tg_kind_from_key(lu); - TG_Kind ruk = tg_kind_from_key(ru); - if (luk == ruk){ - switch (luk){ - default: - { - result = 1; - }break; - - case TG_Kind_Ptr: - case TG_Kind_LRef: - case TG_Kind_RRef: - { - TG_Key lud = tg_direct_from_graph_rdi_key(graph, rdi, lu); - TG_Key rud = tg_direct_from_graph_rdi_key(graph, rdi, ru); - if (eval_type_match(graph, rdi, lud, rud)){ - result = 1; - } - }break; - - case TG_Kind_MemberPtr: - { - TG_Key lud = tg_direct_from_graph_rdi_key(graph, rdi, lu); - TG_Key rud = tg_direct_from_graph_rdi_key(graph, rdi, ru); - TG_Key luo = tg_owner_from_graph_rdi_key(graph, rdi, lu); - TG_Key ruo = tg_owner_from_graph_rdi_key(graph, rdi, ru); - if (eval_type_match(graph, rdi, lud, rud) && - eval_type_match(graph, rdi, luo, ruo)){ - result = 1; - } - }break; - - case TG_Kind_Array: - { - Temp scratch = scratch_begin(0, 0); - TG_Type *lt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, l); - TG_Type *rt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, r); - if(lt->count == rt->count && eval_type_match(graph, rdi, lt->direct_type_key, rt->direct_type_key)) - { - result = 1; - } - scratch_end(scratch); - }break; - - case TG_Kind_Function: - { - Temp scratch = scratch_begin(0, 0); - TG_Type *lt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, l); - TG_Type *rt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, r); - if (lt->count == rt->count && eval_type_match(graph, rdi, lt->direct_type_key, rt->direct_type_key)) - { - B32 params_match = 1; - TG_Key *lp = lt->param_type_keys; - TG_Key *rp = rt->param_type_keys; - U64 count = lt->count; - for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1) - { - if(!eval_type_match(graph, rdi, *lp, *rp)) - { - params_match = 0; - break; - } - } - result = params_match; - } - scratch_end(scratch); - }break; - - case TG_Kind_Method: - { - Temp scratch = scratch_begin(0, 0); - TG_Type *lt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, l); - TG_Type *rt = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, r); - if (lt->count == rt->count && - eval_type_match(graph, rdi, lt->direct_type_key, rt->direct_type_key) && - eval_type_match(graph, rdi, lt->owner_type_key, rt->owner_type_key)) - { - B32 params_match = 1; - TG_Key *lp = lt->param_type_keys; - TG_Key *rp = rt->param_type_keys; - U64 count = lt->count; - for(U64 i = 0; i < count; i += 1, lp += 1, rp += 1) - { - if(!eval_type_match(graph, rdi, *lp, *rp)) - { - params_match = 0; - break; - } - } - result = params_match; - } - scratch_end(scratch); - }break; - } - } - } - - return(result); -} - -internal B32 -eval_kind_is_integer(TG_Kind kind){ - B32 result = (TG_Kind_FirstInteger <= kind && kind <= TG_Kind_LastInteger); - return(result); -} - -internal B32 -eval_kind_is_signed(TG_Kind kind){ - B32 result = ((TG_Kind_FirstSigned1 <= kind && kind <= TG_Kind_LastSigned1) || - (TG_Kind_FirstSigned2 <= kind && kind <= TG_Kind_LastSigned2)); - return(result); -} - -internal B32 -eval_kind_is_basic_or_enum(TG_Kind kind){ - B32 result = ((TG_Kind_FirstBasic <= kind && kind <= TG_Kind_LastBasic) || - kind == TG_Kind_Enum); - return(result); -} - - -//////////////////////////////// -//~ allen: EVAL IR-Tree Constructors - -internal EVAL_IRTree* -eval_irtree_const_u(Arena *arena, U64 v){ - // choose encoding op - RDI_EvalOp op = RDI_EvalOp_ConstU64; - if (v < 0x100){ - op = RDI_EvalOp_ConstU8; - } - else if (v < 0x10000){ - op = RDI_EvalOp_ConstU16; - } - else if (v < 0x100000000){ - op = RDI_EvalOp_ConstU32; - } - - // make the tree node - EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1); - result->op = op; - result->p = v; - return(result); -} - -internal EVAL_IRTree* -eval_irtree_unary_op(Arena *arena, RDI_EvalOp op, - RDI_EvalTypeGroup group, EVAL_IRTree *c){ - EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1); - result->op = op; - result->p = group; - result->children[0] = c; - return(result); -} - -internal EVAL_IRTree* -eval_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, - EVAL_IRTree *l, EVAL_IRTree *r){ - EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1); - result->op = op; - result->p = group; - result->children[0] = l; - result->children[1] = r; - return(result); -} - -internal EVAL_IRTree* -eval_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, EVAL_IRTree *l, EVAL_IRTree *r){ - EVAL_IRTree *result = eval_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, l, r); - return(result); -} - -internal EVAL_IRTree* -eval_irtree_conditional(Arena *arena, EVAL_IRTree *c, EVAL_IRTree *l, EVAL_IRTree *r){ - EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1); - result->op = RDI_EvalOp_Cond; - result->children[0] = c; - result->children[1] = l; - result->children[2] = r; - return(result); -} - -internal EVAL_IRTree* -eval_irtree_bytecode_no_copy(Arena *arena, String8 bytecode){ - EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1); - result->op = EVAL_IRExtKind_Bytecode; - result->bytecode = bytecode; - return(result); -} - -//////////////////////////////// -//~ allen: EVAL IR-Tree High Level Helpers - -internal EVAL_IRTree* -eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key){ - U64 byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key); - EVAL_IRTree *result = &eval_irtree_nil; - if (0 < byte_size && byte_size <= 8){ - // build the read node - EVAL_IRTree *read_node = push_array(arena, EVAL_IRTree, 1); - read_node->op = RDI_EvalOp_MemRead; - read_node->p = byte_size; - read_node->children[0] = c; - - // build a signed trunc node if needed - U64 bit_size = byte_size << 3; - EVAL_IRTree *with_trunc = read_node; - TG_Kind kind = tg_kind_from_key(type_key); - if (bit_size < 64 && eval_kind_is_signed(kind)){ - with_trunc = push_array(arena, EVAL_IRTree, 1); - with_trunc->op = RDI_EvalOp_TruncSigned; - with_trunc->p = bit_size; - with_trunc->children[0] = read_node; - } - - // set result - result = with_trunc; - } - else{ - // TODO: unexpected path - } - return(result); -} - -internal EVAL_IRTree* -eval_irtree_convert_lo(Arena *arena, EVAL_IRTree *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in){ - EVAL_IRTree *result = push_array(arena, EVAL_IRTree, 1); - result->op = RDI_EvalOp_Convert; - result->p = in | (out << 8); - result->children[0] = c; - return(result); -} - -internal EVAL_IRTree* -eval_irtree_trunc(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key){ - EVAL_IRTree *result = c; - U64 byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key); - if (byte_size < 64){ - RDI_EvalOp op = RDI_EvalOp_Trunc; - TG_Kind kind = tg_kind_from_key(type_key); - if (eval_kind_is_signed(kind)){ - op = RDI_EvalOp_TruncSigned; - } - U64 bit_size = byte_size << 3; - result = push_array(arena, EVAL_IRTree, 1); - result->op = op; - result->p = bit_size; - result->children[0] = c; - } - return(result); -} - -internal EVAL_IRTree* -eval_irtree_convert_hi(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key out, TG_Key in){ - EVAL_IRTree *result = c; - TG_Kind in_kind = tg_kind_from_key(in); - TG_Kind out_kind = tg_kind_from_key(out); - U8 in_group = eval_type_group_from_kind(in_kind); - U8 out_group = eval_type_group_from_kind(out_kind); - U32 conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group); - if(conversion_rule == RDI_EvalConversionKind_Legal) - { - result = eval_irtree_convert_lo(arena, result, out_group, in_group); - } - U64 in_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, in); - U64 out_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, out); - if(out_byte_size < in_byte_size && eval_kind_is_integer(out_kind)) - { - result = eval_irtree_trunc(arena, graph, rdi, result, out); - } - return(result); -} - -internal EVAL_IRTree* -eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_EvalMode from_mode, - EVAL_IRTree *tree, TG_Key type_key){ - EVAL_IRTree *result = tree; - switch (from_mode){ - default:{}break; - case EVAL_EvalMode_Addr: - { - result = eval_irtree_mem_read_type(arena, graph, rdi, tree, type_key); - }break; - case EVAL_EvalMode_Reg: - { - result = eval_irtree_unary_op(arena, RDI_EvalOp_RegReadDyn, RDI_EvalTypeGroup_U, tree); - }break; - } - return(result); -} - -//////////////////////////////// -//~ allen: EVAL Compiler Phases - -internal void -eval_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, EVAL_String2ExprMap *map, EVAL_Expr *expr, EVAL_ErrorList *eout) -{ - switch(expr->kind) - { - default: - { - U64 children_count = eval_expr_kind_child_counts[expr->kind]; - for(U64 idx = 0; idx < children_count; idx += 1) - { - eval_push_leaf_ident_exprs_from_expr__in_place(arena, map, expr->children[idx], eout); - } - }break; - case EVAL_ExprKind_Define: - { - EVAL_Expr *exprl = expr->children[0]; - EVAL_Expr *exprr = expr->children[1]; - if(exprl->kind == EVAL_ExprKind_LeafIdent) - { - eval_string2expr_map_insert(arena, map, exprl->name, exprr); - } - }break; - } -} - -internal TG_Key -eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_Expr *expr, EVAL_ErrorList *eout){ - TG_Key result = zero_struct; - - EVAL_ExprKind kind = expr->kind; - switch (kind){ - default: - { - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Expected type expression."); - }break; - - case EVAL_ExprKind_TypeIdent: - { - result = expr->type_key; - }break; - - case EVAL_ExprKind_Ptr: - { - TG_Key direct_type_key = eval_type_from_type_expr(arena, graph, rdi, expr->children[0], eout); - result = tg_cons_type_make(graph, TG_Kind_Ptr, direct_type_key, 0); - }break; - - case EVAL_ExprKind_Array: - { - EVAL_Expr *child_expr = expr->child_and_constant.child; - TG_Key direct_type_key = eval_type_from_type_expr(arena, graph, rdi, child_expr, eout); - result = tg_cons_type_make(graph, TG_Kind_Array, direct_type_key, expr->child_and_constant.u64); - }break; - - case EVAL_ExprKind_Func: - { - // TODO(rjf): old type graph code is below: -#if 0 - TG_Type *ret_type = eval_type_from_type_expr(arena, graph, expr->children[0], eout); - // TODO(allen): decision: do we do the extra work to preserve full function type info? - result = tg_type_func(graph, ret_type, 0, 0); -#endif - }break; - } - - return(result); -} - -internal EVAL_IRTreeAndType -eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout) -{ - ProfBeginFunction(); - EVAL_IRTreeAndType result = {0}; - result.tree = &eval_irtree_nil; - - EVAL_ExprKind kind = expr->kind; - switch(kind) - { - default: - { - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "(internal) Undefined expression kind (%u).", kind); - }break; - - case EVAL_ExprKind_ArrayIndex: - { - EVAL_Expr *exprl = expr->children[0]; - EVAL_Expr *exprr = expr->children[1]; - - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout); - EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout); - - if (l.tree->op != 0 && r.tree->op != 0){ - TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key); - TG_Key r_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, r.type_key); - TG_Kind l_restype_kind = tg_kind_from_key(l_restype); - TG_Kind r_restype_kind = tg_kind_from_key(r_restype); - if(eval_kind_is_basic_or_enum(r_restype_kind)) - { - r_restype = eval_type_unwrap_enum(graph, rdi, r_restype); - r_restype_kind = tg_kind_from_key(r_restype); - } - - // analyze situation - B32 can_generate = 0; - B32 l_resolve = 0; - TG_Key direct_type = zero_struct; - U64 direct_type_size = 0; - if (!eval_kind_is_integer(r_restype_kind)){ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprr->location, "Cannot index with this type."); - } - else{ - direct_type = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype); - direct_type_size = tg_byte_size_from_graph_rdi_key(graph, rdi, direct_type); - if (l_restype_kind == TG_Kind_Ptr){ - if (direct_type_size == 0){ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprr->location, "Cannot index into pointers of zero-sized types."); - } - else{ - can_generate = 1; - if (l.mode != EVAL_EvalMode_Value){ - l_resolve = 1; - } - } - } - else if (l_restype_kind == TG_Kind_Array){ - if (l.mode == EVAL_EvalMode_Addr){ - if (direct_type_size == 0){ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprl->location, "Cannot index into arrays of zero-sized types."); - } - else{ - can_generate = 1; - } - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprl->location, "(Not supported) Cannot index into array without base address."); - } - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprl->location, "Cannot index into this type."); - } - } - - // generate ir tree - if (can_generate){ - // how to compute the index - EVAL_IRTree *index_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype); - if (direct_type_size > 1){ - EVAL_IRTree *const_tree = eval_irtree_const_u(arena, direct_type_size); - index_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Mul, index_tree, const_tree); - } - - // how to compute the base address - EVAL_IRTree *base_tree = l.tree; - if (l_resolve){ - base_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, base_tree, l_restype); - } - - // how to compute the final address - EVAL_IRTree *new_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Add, index_tree, base_tree); - - // fill result - result.tree = new_tree; - result.type_key = direct_type; - result.mode = EVAL_EvalMode_Addr; - } - } - }break; - - case EVAL_ExprKind_MemberAccess: - { - EVAL_Expr *exprl = expr->children[0]; - EVAL_Expr *exprr = expr->children[1]; - - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout); - - if (l.tree->op != 0 && !tg_key_match(tg_key_zero(), l.type_key)){ - TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key); - TG_Kind l_restype_kind = tg_kind_from_key(l_restype); - - // determine which type to use - TG_Key check_type_key = l_restype; - TG_Kind check_type_kind = l_restype_kind; - if (l_restype_kind == TG_Kind_Ptr || l_restype_kind == TG_Kind_LRef || l_restype_kind == TG_Kind_RRef){ - check_type_key = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype); - check_type_kind = tg_kind_from_key(check_type_key); - } - - // switch to handle - switch(check_type_kind) - { - default: - { - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); - }break; - - case TG_Kind_Struct: - case TG_Kind_Class: - case TG_Kind_Union: - { - // analyze situation - B32 can_generate = 0; - TG_Key r_type = zero_struct; - U32 r_off = 0; - B32 l_resolve = 0; - - // determine how to treat left - B32 l_good = 0; - if (l_restype_kind == TG_Kind_Ptr || l_restype_kind == TG_Kind_LRef || l_restype_kind == TG_Kind_RRef){ - l_good = 1; - l_resolve = 1; - } - else{ - if (l.mode == EVAL_EvalMode_Addr){ - l_good = 1; - } - else if(l.mode == EVAL_EvalMode_Reg) - { - l_good = 1; - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprl->location, - "(Not supported) Cannot access member without a base address or register location."); - } - } - - // right must be identifier - B32 r_good = 0; - if (exprr->kind == EVAL_ExprKind_LeafMember){ - r_good = 1; - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprr->location, - "(internal) Expected a leaf member in member access."); - } - - if (l_good && r_good){ - Temp scratch = scratch_begin(&arena, 1); - TG_MemberArray check_type_members = tg_data_members_from_graph_rdi_key(scratch.arena, graph, rdi, check_type_key); - - // lookup member - String8 member_name = exprr->name; - TG_Member *match = 0; - for(U64 member_idx = 0; member_idx < check_type_members.count; member_idx += 1) - { - TG_Member *member = &check_type_members.v[member_idx]; - if(str8_match(member->name, member_name, 0)) - { - match = member; - break; - } - } - - // extract member info - if (match != 0){ - can_generate = 1; - r_type = match->type_key; - r_off = match->off; - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprr->location, "Could not find a member named '%S' in type.", member_name); - } - - scratch_end(scratch); - } - - // generate ir tree - if (can_generate){ - EVAL_IRTree *new_tree = l.tree; - EVAL_EvalMode mode = l.mode; - if (l_resolve){ - new_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, new_tree, l_restype); - mode = EVAL_EvalMode_Addr; - } - if (r_off != 0){ - EVAL_IRTree *const_tree = eval_irtree_const_u(arena, r_off); - new_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); - } - - // fill result - result.tree = new_tree; - result.type_key = r_type; - result.mode = mode; - } - }break; - } - - } - }break; - - case EVAL_ExprKind_Deref: - { - EVAL_Expr *exprc = expr->children[0]; - - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout); - - if (c.tree->op != 0){ - TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key); - TG_Kind c_restype_kind = tg_kind_from_key(c_restype); - TG_Key c_restype_direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, c_restype); - U64 c_restype_direct_size = tg_byte_size_from_graph_rdi_key(graph, rdi, c_restype_direct); - - // analyze situation - B32 can_generate = 0; - B32 c_resolve = 0; - if (c_restype_kind == TG_Kind_Ptr || - c_restype_kind == TG_Kind_LRef || - c_restype_kind == TG_Kind_RRef){ - if (c_restype_direct_size == 0){ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprc->location, "Cannot dereference pointers of zero-sized types."); - } - else{ - can_generate = 1; - c_resolve = 1; - } - } - else if (c_restype_kind == TG_Kind_Array){ - if (c.mode == EVAL_EvalMode_Addr){ - if (c_restype_direct_size == 0){ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprc->location, "Cannot dereference arrays of zero-sized types."); - } - else{ - can_generate = 1; - } - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprc->location, "(Not supported) Cannot dereference array without base address."); - } - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, exprc->location, "Cannot dereference this type."); - } - - // generate ir tree - if (can_generate){ - EVAL_IRTree *new_tree = c.tree; - if (c_resolve){ - new_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype); - } - - // fill result - result.tree = new_tree; - result.type_key = c_restype_direct; - result.mode = EVAL_EvalMode_Addr; - } - } - }break; - - case EVAL_ExprKind_Address: - { - EVAL_Expr *exprc = expr->children[0]; - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout); - if(c.tree->op != 0 && !tg_key_match(c.type_key, tg_key_zero())) - { - TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key); - TG_Kind c_restype_kind = tg_kind_from_key(c_restype); - - // analyze situation - B32 can_generate = 0; - if(c.mode == EVAL_EvalMode_Addr) - { - can_generate = 1; - } - - // generate ir tree - if(can_generate) - { - EVAL_IRTree *new_tree = c.tree; - TG_Key ptr_type = tg_cons_type_make(graph, TG_Kind_Ptr, c_restype, 0); - - // fill result - result.tree = new_tree; - result.type_key = ptr_type; - result.mode = EVAL_EvalMode_Value; - } - } - }break; - - case EVAL_ExprKind_Cast: - { - EVAL_Expr *exprl = expr->children[0]; - EVAL_Expr *exprr = expr->children[1]; - - TG_Key cast_type_key = eval_type_from_type_expr(arena, graph, rdi, exprl, eout); - TG_Kind cast_type_kind = tg_kind_from_key(cast_type_key); - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout); - - if(cast_type_kind != TG_Kind_Null && c.tree->op != 0) - { - TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key); - TG_Kind c_restype_kind = tg_kind_from_key(c_restype); - U64 c_restype_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, c_restype); - U64 cast_type_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, cast_type_key); - - // analyze situation - U8 in_group = eval_type_group_from_kind(c_restype_kind); - U8 out_group = eval_type_group_from_kind(cast_type_kind); - RDI_EvalConversionKind conversion_rule = rdi_eval_conversion_kind_from_typegroups(in_group, out_group); - - // generate tree - switch(conversion_rule) - { - case RDI_EvalConversionKind_Noop: - case RDI_EvalConversionKind_Legal: - { - EVAL_IRTree *in_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype); - - EVAL_IRTree *new_tree = in_tree; - if (conversion_rule == RDI_EvalConversionKind_Legal){ - new_tree = eval_irtree_convert_lo(arena, in_tree, out_group, in_group); - } - if (cast_type_byte_size < c_restype_byte_size && eval_kind_is_integer(cast_type_kind)){ - new_tree = eval_irtree_trunc(arena, graph, rdi, in_tree, cast_type_key); - } - - result.tree = new_tree; - result.type_key = cast_type_key; - result.mode = EVAL_EvalMode_Value; - }break; - - default: - { - String8 text = str8_lit("(internal) unknown conversion rule"); - if (conversion_rule < RDI_EvalConversionKind_COUNT){ - text.str = rdi_explanation_string_from_eval_conversion_kind(conversion_rule, &text.size); - } - eval_error(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, text); - }break; - } - } - }break; - - case EVAL_ExprKind_Sizeof: - { - EVAL_Expr *exprc = expr->children[0]; - - // analyze situation - TG_Key type_key = zero_struct; - switch (exprc->kind){ - // size of type expression - case EVAL_ExprKind_TypeIdent: - case EVAL_ExprKind_Ptr: - case EVAL_ExprKind_Array: - case EVAL_ExprKind_Func: - { - type_key = eval_type_from_type_expr(arena, graph, rdi, exprc, eout); - }break; - - // size of value expression - default: - { - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout); - type_key = c.type_key; - }break; - } - B32 can_generate = 0; - U64 size = 0; - TG_Kind type_kind = tg_kind_from_key(type_key); - if (type_kind != TG_Kind_Null){ - can_generate = 1; - size = tg_byte_size_from_graph_rdi_key(graph, rdi, type_key); - } - - // generate ir tree - if(can_generate) - { - EVAL_IRTree *new_tree = eval_irtree_const_u(arena, size); - result.tree = new_tree; - result.type_key = tg_key_basic(TG_Kind_U64); - result.mode = EVAL_EvalMode_Value; - } - }break; - - case EVAL_ExprKind_Neg: - case EVAL_ExprKind_LogNot: - case EVAL_ExprKind_BitNot: - { - EVAL_Expr *exprc = expr->children[0]; - - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout); - if (c.tree->op != 0){ - TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key); - TG_Key p_type = eval_type_promote(graph, rdi, c_restype); - TG_Kind c_restype_kind = tg_kind_from_key(c_restype); - - // analyze situation - B32 can_generate = 0; - RDI_EvalOp op = eval_opcode_from_expr_kind(kind); - U8 c_group = eval_type_group_from_kind(c_restype_kind); - if (!rdi_eval_op_typegroup_are_compatible(op, c_group)){ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Cannot use this operator on this type."); - } - else{ - can_generate = 1; - } - - // generate ir tree - if (can_generate){ - EVAL_IRTree *in_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype); - in_tree = eval_irtree_convert_hi(arena, graph, rdi, in_tree, p_type, c_restype); - - EVAL_IRTree *new_tree = eval_irtree_unary_op(arena, op, c_group, in_tree); - - result.tree = new_tree; - result.type_key = p_type; - result.mode = EVAL_EvalMode_Value; - } - } - }break; - - case EVAL_ExprKind_Mul: - case EVAL_ExprKind_Div: - case EVAL_ExprKind_Mod: - case EVAL_ExprKind_Add: - case EVAL_ExprKind_Sub: - case EVAL_ExprKind_LShift: - case EVAL_ExprKind_RShift: - case EVAL_ExprKind_Less: - case EVAL_ExprKind_LsEq: - case EVAL_ExprKind_Grtr: - case EVAL_ExprKind_GrEq: - case EVAL_ExprKind_EqEq: - case EVAL_ExprKind_NtEq: - case EVAL_ExprKind_BitAnd: - case EVAL_ExprKind_BitXor: - case EVAL_ExprKind_BitOr: - case EVAL_ExprKind_LogAnd: - case EVAL_ExprKind_LogOr: - { - //- setup & dispatch - EVAL_Expr *exprl = expr->children[0]; - EVAL_Expr *exprr = expr->children[1]; - - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout); - EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout); - - if (l.tree->op != 0 && r.tree->op != 0){ - TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key); - TG_Key r_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, r.type_key); - TG_Kind l_restype_kind = tg_kind_from_key(l_restype); - TG_Kind r_restype_kind = tg_kind_from_key(r_restype); - - //- rjf: decay register types to basics - if(l_restype.kind == TG_KeyKind_Reg) - { - l_restype = tg_key_basic(TG_Kind_U64); - l_restype_kind = tg_kind_from_key(l_restype); - } - if(r_restype.kind == TG_KeyKind_Reg) - { - r_restype = tg_key_basic(TG_Kind_U64); - r_restype_kind = tg_kind_from_key(r_restype); - } - - RDI_EvalOp op = eval_opcode_from_expr_kind(kind); - - //- pointer decay - B32 l_is_pointer = (l_restype_kind == TG_Kind_Ptr); - B32 l_is_decay = (l_restype_kind == TG_Kind_Array && l.mode == EVAL_EvalMode_Addr); - B32 l_is_pointer_like = (l_is_pointer || l_is_decay); - - B32 r_is_pointer = (r_restype_kind == TG_Kind_Ptr); - B32 r_is_decay = (r_restype_kind == TG_Kind_Array && r.mode == EVAL_EvalMode_Addr); - B32 r_is_pointer_like = (r_is_pointer || r_is_decay); - - //- determine arithmetic path -#define EVAL_ArithPath_Normal 0 -#define EVAL_ArithPath_PtrAdd 1 -#define EVAL_ArithPath_PtrSub 2 - - B32 ptr_arithmetic_mul_rptr = 0; - U32 arith_path = EVAL_ArithPath_Normal; - if (kind == EVAL_ExprKind_Add){ - if (l_is_pointer_like && eval_kind_is_integer(r_restype_kind)){ - arith_path = EVAL_ArithPath_PtrAdd; - } - if (l_is_pointer_like && eval_kind_is_integer(l_restype_kind)){ - arith_path = EVAL_ArithPath_PtrAdd; - ptr_arithmetic_mul_rptr = 1; - } - } - else if (kind == EVAL_ExprKind_Sub){ - if (l_is_pointer_like && eval_kind_is_integer(r_restype_kind)){ - arith_path = EVAL_ArithPath_PtrAdd; - } - if (l_is_pointer_like && r_is_pointer_like){ - TG_Key l_restype_direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype); - TG_Key r_restype_direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, r_restype); - U64 l_restype_direct_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, l_restype_direct); - U64 r_restype_direct_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, r_restype_direct); - if (l_restype_direct_byte_size == r_restype_direct_byte_size){ - arith_path = EVAL_ArithPath_PtrSub; - } - } - } - - //- specific arithmetic handlers - - switch (arith_path){ - case EVAL_ArithPath_Normal: - { - // analyze situation - B32 is_comparison = eval_expr_kind_is_comparison(kind); - B32 both_basic = (eval_kind_is_basic_or_enum(l_restype_kind) && - eval_kind_is_basic_or_enum(r_restype_kind)); - - TG_Key cv_type_key = zero_struct; - if (both_basic){ - cv_type_key = eval_type_coerce(graph, rdi, l_restype, r_restype); - } - else if (is_comparison && eval_type_match(graph, rdi, l_restype, r_restype)){ - cv_type_key = l_restype; - } - - TG_Kind cv_type_kind = tg_kind_from_key(cv_type_key); - U8 cv_group = eval_type_group_from_kind(cv_type_kind); - - B32 can_generate = 0; - if (rdi_eval_op_typegroup_are_compatible(op, cv_group)){ - can_generate = 1; - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Cannot use this operator on this type."); - } - - // generate ir tree - if (can_generate){ - TG_Key final_type_key = cv_type_key; - if (is_comparison){ - final_type_key = tg_key_basic(TG_Kind_Bool); - } - - EVAL_IRTree *l_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, l.tree, l_restype); - l_tree = eval_irtree_convert_hi(arena, graph, rdi, l_tree, cv_type_key, l_restype); - - EVAL_IRTree *r_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype); - r_tree = eval_irtree_convert_hi(arena, graph, rdi, r_tree, cv_type_key, r_restype); - - EVAL_IRTree *new_tree = eval_irtree_binary_op(arena, op, cv_group, l_tree, r_tree); - - result.tree = new_tree; - result.type_key = final_type_key; - result.mode = EVAL_EvalMode_Value; - } - }break; - - case EVAL_ArithPath_PtrAdd: - { - // setup which side is the pointer - EVAL_IRTreeAndType *ptr = &l; - EVAL_IRTreeAndType *integer = &r; - B32 ptr_is_decay = l_is_decay; - if (ptr_arithmetic_mul_rptr){ - ptr = &r; - integer = &l; - ptr_is_decay = r_is_decay; - } - - TG_Key direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, ptr->type_key); - U64 direct_type_size = tg_byte_size_from_graph_rdi_key(graph, rdi, direct); - - // generate ir tree - EVAL_IRTree *ptr_tree = ptr->tree; - if (!ptr_is_decay){ - ptr_tree = eval_irtree_resolve_to_value(arena, graph, rdi, ptr->mode, ptr_tree, ptr->type_key); - } - - EVAL_IRTree *integer_tree = eval_irtree_resolve_to_value(arena, graph, rdi, integer->mode, integer->tree, integer->type_key); - if (direct_type_size > 1){ - EVAL_IRTree *const_tree = eval_irtree_const_u(arena, direct_type_size); - integer_tree = eval_irtree_binary_op_u(arena, RDI_EvalOp_Mul, integer_tree, const_tree); - } - - TG_Key ptr_type = ptr->type_key; - if (ptr_is_decay){ - ptr_type = tg_cons_type_make(graph, TG_Kind_Ptr, direct, 0); - } - - EVAL_IRTree *new_tree = eval_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, ptr_tree, integer_tree); - - result.tree = new_tree; - result.type_key = ptr_type; - result.mode = EVAL_EvalMode_Value; - }break; - - case EVAL_ArithPath_PtrSub: - { - TG_Key direct = tg_unwrapped_direct_from_graph_rdi_key(graph, rdi, l_restype); - U64 direct_type_size = tg_byte_size_from_graph_rdi_key(graph, rdi, direct); - - // generate ir tree - EVAL_IRTree *l_tree = l.tree; - if (!l_is_decay){ - l_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, l.tree, l_restype); - } - - EVAL_IRTree *r_tree = r.tree; - if (!r_is_decay){ - r_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype); - } - - EVAL_IRTree *op_tree = eval_irtree_binary_op(arena, op, RDI_EvalTypeGroup_U, l_tree, r_tree); - - EVAL_IRTree *new_tree = op_tree; - if (direct_type_size > 1){ - EVAL_IRTree *const_tree = eval_irtree_const_u(arena, direct_type_size); - new_tree = eval_irtree_binary_op(arena, RDI_EvalOp_Div, RDI_EvalTypeGroup_U, new_tree, const_tree); - } - - result.tree = new_tree; - result.type_key = tg_key_basic(TG_Kind_U64); - result.mode = EVAL_EvalMode_Value; - }break; - } - } - }break; - - case EVAL_ExprKind_Ternary: - { - EVAL_Expr *exprc = expr->children[0]; - EVAL_Expr *exprl = expr->children[1]; - EVAL_Expr *exprr = expr->children[2]; - - EVAL_IRTreeAndType c = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprc, eout); - EVAL_IRTreeAndType l = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprl, eout); - EVAL_IRTreeAndType r = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, exprr, eout); - - if (l.tree->op != 0 && r.tree->op != 0 && c.tree->op != 0){ - - TG_Key c_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, c.type_key); - TG_Key l_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, l.type_key); - TG_Key r_restype = tg_unwrapped_from_graph_rdi_key(graph, rdi, r.type_key); - TG_Kind c_restype_kind = tg_kind_from_key(c_restype); - TG_Kind l_restype_kind = tg_kind_from_key(l_restype); - TG_Kind r_restype_kind = tg_kind_from_key(r_restype); - - // analyze situation - B32 can_generate = 0; - TG_Key final_type = zero_struct; - if (eval_kind_is_integer(c_restype_kind)){ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Conditional term must be an integer type."); - } - else{ - if (eval_kind_is_basic_or_enum(l_restype_kind) && - eval_kind_is_basic_or_enum(r_restype_kind)){ - can_generate = 1; - final_type = eval_type_coerce(graph, rdi, l_restype, r_restype); - } - else{ - if (eval_type_match(graph, rdi, l_restype, r_restype)){ - if (l_restype_kind == TG_Kind_Ptr){ - can_generate = 1; - final_type = l_restype; - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "(Not supported) Conditional value not basic type or pointer."); - } - } - else{ - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Left and right terms must have matching types."); - } - } - } - - // generate ir tree - if (can_generate){ - EVAL_IRTree *c_tree = eval_irtree_resolve_to_value(arena, graph, rdi, c.mode, c.tree, c_restype); - - EVAL_IRTree *l_tree = eval_irtree_resolve_to_value(arena, graph, rdi, l.mode, l.tree, l_restype); - l_tree = eval_irtree_convert_hi(arena, graph, rdi, l_tree, final_type, l_restype); - - EVAL_IRTree *r_tree = eval_irtree_resolve_to_value(arena, graph, rdi, r.mode, r.tree, r_restype); - r_tree = eval_irtree_convert_hi(arena, graph, rdi, r_tree, final_type, r_restype); - - EVAL_IRTree *new_tree = eval_irtree_conditional(arena, c_tree, l_tree, r_tree); - - result.tree = new_tree; - result.type_key = final_type; - result.mode = EVAL_EvalMode_Value; - } - } - }break; - - case EVAL_ExprKind_LeafBytecode: - { - EVAL_IRTree *new_tree = eval_irtree_bytecode_no_copy(arena, expr->bytecode); - TG_Key final_type_key = expr->type_key; - EVAL_EvalMode mode = expr->mode; - - result.tree = new_tree; - result.type_key = final_type_key; - result.mode = mode; - }break; - - case EVAL_ExprKind_LeafMember: - { - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "(internal) Leaf member not expected here."); - }break; - - case EVAL_ExprKind_LeafU64: - { - U64 val = expr->u64; - EVAL_IRTree *new_tree = eval_irtree_const_u(arena, val); - - TG_Key type_key = zero_struct; - if (val <= max_S32){ - type_key = tg_key_basic(TG_Kind_S32); - } - else if (val <= max_S64){ - type_key = tg_key_basic(TG_Kind_S64); - } - else{ - type_key = tg_key_basic(TG_Kind_U64); - } - - result.tree = new_tree; - result.type_key = type_key; - result.mode = EVAL_EvalMode_Value; - }break; - - case EVAL_ExprKind_LeafF64: - { - U64 val = expr->u64; - EVAL_IRTree *new_tree = eval_irtree_const_u(arena, val); - - result.tree = new_tree; - result.type_key = tg_key_basic(TG_Kind_F64); - result.mode = EVAL_EvalMode_Value; - }break; - - case EVAL_ExprKind_LeafF32: - { - U32 val = expr->u32; - EVAL_IRTree *new_tree = eval_irtree_const_u(arena, val); - - result.tree = new_tree; - result.type_key = tg_key_basic(TG_Kind_F32); - result.mode = EVAL_EvalMode_Value; - }break; - - case EVAL_ExprKind_TypeIdent: - { - result.tree = &eval_irtree_nil; - result.type_key = expr->type_key; - result.mode = EVAL_EvalMode_NULL; - }break; - case EVAL_ExprKind_Ptr: - case EVAL_ExprKind_Array: - case EVAL_ExprKind_Func: - { - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Type expression not expected."); - }break; - - case EVAL_ExprKind_Define: - { - if(expr->children[0]->kind != EVAL_ExprKind_LeafIdent) - { - eval_errorf(arena, eout, EVAL_ErrorKind_MalformedInput, expr->location, "Left side of assignment must be an identifier."); - } - result = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, expr->children[1], eout); - }break; - case EVAL_ExprKind_LeafIdent: - { - String8 name = expr->name; - EVAL_Expr *leaf_ident_expr = eval_expr_from_string(leaf_ident_expr_map, name); - if(leaf_ident_expr == &eval_expr_nil) - { - eval_errorf(arena, eout, EVAL_ErrorKind_ResolutionFailure, expr->location, "\"%S\" could not be found.", name); - } - else - { - eval_string2expr_map_inc_poison(leaf_ident_expr_map, name); - result = eval_irtree_and_type_from_expr(arena, graph, rdi, leaf_ident_expr_map, leaf_ident_expr, eout); - eval_string2expr_map_dec_poison(leaf_ident_expr_map, name); - } - }break; - } - - ProfEnd(); - return(result); -} - -internal void -eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out){ - ProfBeginFunction(); - U32 op = tree->op; - switch (op){ - case RDI_EvalOp_Stop: - case RDI_EvalOp_Skip: - { - // TODO: error - invalid ir-tree op - }break; - - case EVAL_IRExtKind_Bytecode: - { - eval_oplist_push_bytecode(arena, out, tree->bytecode); - }break; - - case RDI_EvalOp_Cond: - { - // split out each of the children - EVAL_OpList prt_cond = {0}; - eval_oplist_from_irtree(arena, tree->children[0], &prt_cond); - - EVAL_OpList prt_left = {0}; - eval_oplist_from_irtree(arena, tree->children[1], &prt_left); - - EVAL_OpList prt_right = {0}; - eval_oplist_from_irtree(arena, tree->children[2], &prt_right); - - // put together like so: - // 1. , Op_Cond (sizeof(2)) - // 2. , Op_Skip (sizeof(3)) - // 3. - // 4. - - // modify prt_right in place to create step 2 - eval_oplist_push_op(arena, &prt_right, RDI_EvalOp_Skip, prt_left.encoded_size); - - // merge 1 into out - eval_oplist_concat_in_place(out, &prt_cond); - eval_oplist_push_op(arena, out, RDI_EvalOp_Cond, prt_right.encoded_size); - - // merge 2 into out - eval_oplist_concat_in_place(out, &prt_right); - - // merge 3 into out - eval_oplist_concat_in_place(out, &prt_left); - }break; - - default: - { - if (op >= RDI_EvalOp_COUNT){ - // TODO: error - invalid ir-tree op - } - else{ - // handle all children - U8 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U64 child_count = RDI_POPN_FROM_CTRLBITS(ctrlbits); - EVAL_IRTree**child = tree->children; - for (U64 i = 0; i < child_count; i += 1, child += 1){ - eval_oplist_from_irtree(arena, *child, out); - } - - // emit op to compute this node - eval_oplist_push_op(arena, out, (RDI_EvalOp)tree->op, tree->p); - } - }break; - } - ProfEnd(); -} diff --git a/src/eval/eval_compiler.h b/src/eval/eval_compiler.h deleted file mode 100644 index 50aa2885..00000000 --- a/src/eval/eval_compiler.h +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_COMPILER_H -#define EVAL_COMPILER_H - -//////////////////////////////// -//~ allen: EVAL Bytecode Helpers - -internal String8 eval_bytecode_from_oplist(Arena *arena, EVAL_OpList *list); - -internal void eval_oplist_push_op(Arena *arena, EVAL_OpList *list, RDI_EvalOp op, U64 p); -internal void eval_oplist_push_uconst(Arena *arena, EVAL_OpList *list, U64 x); -internal void eval_oplist_push_sconst(Arena *arena, EVAL_OpList *list, S64 x); - -internal void eval_oplist_push_bytecode(Arena *arena, EVAL_OpList *list, String8 bytecode); - -internal void eval_oplist_concat_in_place(EVAL_OpList *left_dst, EVAL_OpList *right_destroyed); - -//////////////////////////////// -//~ allen: EVAL Expression Info Functions - -internal RDI_EvalOp eval_opcode_from_expr_kind(EVAL_ExprKind kind); -internal B32 eval_expr_kind_is_comparison(EVAL_ExprKind kind); - -//////////////////////////////// -//~ allen: EVAL Expression Constructors - -internal EVAL_Expr* eval_expr(Arena *arena, EVAL_ExprKind kind, void *location, EVAL_Expr *c0, EVAL_Expr *c1, EVAL_Expr *c2); -internal EVAL_Expr* eval_expr_u64(Arena *arena, void *location, U64 u64); -internal EVAL_Expr* eval_expr_f64(Arena *arena, void *location, F64 f64); -internal EVAL_Expr* eval_expr_f32(Arena *arena, void *location, F32 f32); -internal EVAL_Expr* eval_expr_child_and_u64(Arena *arena, EVAL_ExprKind kind, void *location, EVAL_Expr *child, U64 u64); -internal EVAL_Expr* eval_expr_leaf_member(Arena *arena, void *location, String8 name); -internal EVAL_Expr* eval_expr_leaf_ident(Arena *arena, void *location, String8 name); -internal EVAL_Expr* eval_expr_leaf_bytecode(Arena *arena, void *location, TG_Key type_key, String8 bytecode, EVAL_EvalMode mode); -internal EVAL_Expr* eval_expr_leaf_op_list(Arena *arena, void *location, TG_Key type_key, EVAL_OpList *ops, EVAL_EvalMode mode); -internal EVAL_Expr* eval_expr_leaf_type(Arena *arena, void *location, TG_Key type_key); - -//////////////////////////////// -//~ allen: EVAL Type Information Transformers - -internal RDI_EvalTypeGroup eval_type_group_from_kind(TG_Kind kind); - -internal TG_Key eval_type_unwrap_enum(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Key eval_type_promote(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Key eval_type_coerce(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r); - -internal B32 eval_type_match(TG_Graph *graph, RDI_Parsed *rdi, TG_Key l, TG_Key r); - -internal B32 eval_kind_is_integer(TG_Kind kind); -internal B32 eval_kind_is_signed(TG_Kind kind); -internal B32 eval_kind_is_basic_or_enum(TG_Kind kind); - -//////////////////////////////// -//~ allen: EVAL IR-Tree Constructors - -internal EVAL_IRTree* eval_irtree_const_u(Arena *arena, U64 v); -internal EVAL_IRTree* eval_irtree_unary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, EVAL_IRTree *c); -internal EVAL_IRTree* eval_irtree_binary_op(Arena *arena, RDI_EvalOp op, RDI_EvalTypeGroup group, EVAL_IRTree *l, EVAL_IRTree *r); -internal EVAL_IRTree* eval_irtree_binary_op_u(Arena *arena, RDI_EvalOp op, EVAL_IRTree *l, EVAL_IRTree *r); -internal EVAL_IRTree* eval_irtree_conditional(Arena *arena, EVAL_IRTree *c, EVAL_IRTree *l, EVAL_IRTree *r); -internal EVAL_IRTree* eval_irtree_bytecode_no_copy(Arena *arena, String8 bytecode); - -//////////////////////////////// -//~ allen: EVAL IR-Tree High Level Helpers - -internal EVAL_IRTree* eval_irtree_mem_read_type(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key); -internal EVAL_IRTree* eval_irtree_convert_lo(Arena *arena, EVAL_IRTree *c, RDI_EvalTypeGroup out, RDI_EvalTypeGroup in); -internal EVAL_IRTree* eval_irtree_trunc(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key type_key); -internal EVAL_IRTree* eval_irtree_convert_hi(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_IRTree *c, TG_Key out, TG_Key in); -internal EVAL_IRTree* eval_irtree_resolve_to_value(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_EvalMode from_mode, EVAL_IRTree *tree, TG_Key type_key); - -//////////////////////////////// -//~ allen: EVAL Compiler Phases - -internal void eval_push_leaf_ident_exprs_from_expr__in_place(Arena *arena, EVAL_String2ExprMap *map, EVAL_Expr *expr, EVAL_ErrorList *eout); -internal TG_Key eval_type_from_type_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_Expr *expr, EVAL_ErrorList *eout); -internal EVAL_IRTreeAndType eval_irtree_and_type_from_expr(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, EVAL_String2ExprMap *leaf_ident_expr_map, EVAL_Expr *expr, EVAL_ErrorList *eout); -internal void eval_oplist_from_irtree(Arena *arena, EVAL_IRTree *tree, EVAL_OpList *out); - -#endif //EVAL_COMPILER_H diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c deleted file mode 100644 index 23d14855..00000000 --- a/src/eval/eval_core.c +++ /dev/null @@ -1,254 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Generated Code - -#include "generated/eval.meta.c" - -//////////////////////////////// -//~ rjf: Basic Functions - -internal U64 -eval_hash_from_string(String8 string) -{ - U64 result = 5381; - for(U64 i = 0; i < string.size; i += 1) - { - result = ((result << 5) + result) + string.str[i]; - } - return result; -} - -//////////////////////////////// -//~ rjf: Error List Building Functions - -internal void -eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text){ - EVAL_Error *error = push_array_no_zero(arena, EVAL_Error, 1); - SLLQueuePush(list->first, list->last, error); - list->count += 1; - list->max_kind = Max(kind, list->max_kind); - error->kind = kind; - error->location = location; - error->text = text; -} - -internal void -eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...){ - va_list args; - va_start(args, fmt); - String8 text = push_str8fv(arena, fmt, args); - va_end(args); - eval_error(arena, list, kind, location, text); -} - -internal void -eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push){ - if (dst->last != 0){ - if (to_push->last != 0){ - dst->last->next = to_push->first; - dst->last = to_push->last; - dst->count += to_push->count; - } - } - else{ - *dst = *to_push; - } - MemoryZeroStruct(to_push); -} - -//////////////////////////////// -//~ rjf: Map Functions - -//- rjf: string -> num - -internal EVAL_String2NumMap -eval_string2num_map_make(Arena *arena, U64 slot_count) -{ - EVAL_String2NumMap map = {0}; - map.slots_count = slot_count; - map.slots = push_array(arena, EVAL_String2NumMapSlot, map.slots_count); - return map; -} - -internal void -eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num) -{ - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - EVAL_String2NumMapNode *existing_node = 0; - for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0) && node->num == num) - { - existing_node = node; - break; - } - } - if(existing_node == 0) - { - EVAL_String2NumMapNode *node = push_array(arena, EVAL_String2NumMapNode, 1); - SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); - SLLQueuePush_N(map->first, map->last, node, order_next); - node->string = push_str8_copy(arena, string); - node->num = num; - map->node_count += 1; - } -} - -internal U64 -eval_num_from_string(EVAL_String2NumMap *map, String8 string) -{ - U64 num = 0; - if(map->slots_count != 0) - { - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - EVAL_String2NumMapNode *existing_node = 0; - for(EVAL_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0)) - { - existing_node = node; - break; - } - } - if(existing_node != 0) - { - num = existing_node->num; - } - } - return num; -} - -internal EVAL_String2NumMapNodeArray -eval_string2num_map_node_array_from_map(Arena *arena, EVAL_String2NumMap *map) -{ - EVAL_String2NumMapNodeArray result = {0}; - result.count = map->node_count; - result.v = push_array(arena, EVAL_String2NumMapNode *, result.count); - U64 idx = 0; - for(EVAL_String2NumMapNode *n = map->first; n != 0; n = n->order_next, idx += 1) - { - result.v[idx] = n; - } - return result; -} - -internal int -eval_string2num_map_node_qsort_compare__num_ascending(EVAL_String2NumMapNode **a, EVAL_String2NumMapNode **b) -{ - int result = 0; - if(a[0]->num < b[0]->num) - { - result = -1; - } - else if(a[0]->num > b[0]->num) - { - result = +1; - } - return result; -} - -internal void -eval_string2num_map_node_array_sort__in_place(EVAL_String2NumMapNodeArray *array) -{ - quick_sort(array->v, array->count, sizeof(array->v[0]), eval_string2num_map_node_qsort_compare__num_ascending); -} - -//- rjf: string -> expr - -internal EVAL_String2ExprMap -eval_string2expr_map_make(Arena *arena, U64 slot_count) -{ - EVAL_String2ExprMap map = {0}; - map.slots_count = slot_count; - map.slots = push_array(arena, EVAL_String2ExprMapSlot, map.slots_count); - return map; -} - -internal void -eval_string2expr_map_insert(Arena *arena, EVAL_String2ExprMap *map, String8 string, EVAL_Expr *expr) -{ - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - EVAL_String2ExprMapNode *existing_node = 0; - for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first; - node != 0; - node = node->hash_next) - { - if(str8_match(node->string, string, 0)) - { - existing_node = node; - break; - } - } - if(existing_node == 0) - { - EVAL_String2ExprMapNode *node = push_array(arena, EVAL_String2ExprMapNode, 1); - SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); - node->string = push_str8_copy(arena, string); - existing_node = node; - } - existing_node->expr = expr; -} - -internal void -eval_string2expr_map_inc_poison(EVAL_String2ExprMap *map, String8 string) -{ - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first; - node != 0; - node = node->hash_next) - { - if(str8_match(node->string, string, 0)) - { - node->poison_count += 1; - break; - } - } -} - -internal void -eval_string2expr_map_dec_poison(EVAL_String2ExprMap *map, String8 string) -{ - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first; - node != 0; - node = node->hash_next) - { - if(str8_match(node->string, string, 0) && node->poison_count > 0) - { - node->poison_count -= 1; - break; - } - } -} - -internal EVAL_Expr * -eval_expr_from_string(EVAL_String2ExprMap *map, String8 string) -{ - EVAL_Expr *expr = &eval_expr_nil; - if(map->slots_count != 0) - { - U64 hash = eval_hash_from_string(string); - U64 slot_idx = hash%map->slots_count; - EVAL_String2ExprMapNode *existing_node = 0; - for(EVAL_String2ExprMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next) - { - if(str8_match(node->string, string, 0) && node->poison_count == 0) - { - existing_node = node; - break; - } - } - if(existing_node != 0) - { - expr = existing_node->expr; - } - } - return expr; -} diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h deleted file mode 100644 index f9ae23c2..00000000 --- a/src/eval/eval_core.h +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_CORE_H -#define EVAL_CORE_H - -//////////////////////////////// -//~ rjf: Errors - -typedef enum EVAL_ErrorKind -{ - EVAL_ErrorKind_Null, - EVAL_ErrorKind_MalformedInput, - EVAL_ErrorKind_MissingInfo, - EVAL_ErrorKind_ResolutionFailure, - EVAL_ErrorKind_InterpretationError, - EVAL_ErrorKind_COUNT -} -EVAL_ErrorKind; - -typedef struct EVAL_Error EVAL_Error; -struct EVAL_Error -{ - EVAL_Error *next; - EVAL_ErrorKind kind; - void *location; - String8 text; -}; - -typedef struct EVAL_ErrorList EVAL_ErrorList; -struct EVAL_ErrorList -{ - EVAL_Error *first; - EVAL_Error *last; - EVAL_ErrorKind max_kind; - U64 count; -}; - -//////////////////////////////// -//~ rjf: Operation Types - -enum -{ - EVAL_IRExtKind_Bytecode = RDI_EvalOp_COUNT, - EVAL_IRExtKind_COUNT -}; - -typedef struct EVAL_Op EVAL_Op; -struct EVAL_Op -{ - EVAL_Op *next; - RDI_EvalOp opcode; - union - { - U64 p; - String8 bytecode; - }; -}; - -typedef struct EVAL_OpList EVAL_OpList; -struct EVAL_OpList -{ - EVAL_Op *first_op; - EVAL_Op *last_op; - U32 op_count; - U32 encoded_size; -}; - -//////////////////////////////// -//~ rjf: Generated Code - -#include "eval/generated/eval.meta.h" - -//////////////////////////////// -//~ rjf: Expression Tree Types - -typedef enum EVAL_EvalMode -{ - EVAL_EvalMode_NULL, - EVAL_EvalMode_Value, - EVAL_EvalMode_Addr, - EVAL_EvalMode_Reg -} -EVAL_EvalMode; - -typedef struct EVAL_Expr EVAL_Expr; -struct EVAL_Expr -{ - EVAL_ExprKind kind; - void *location; - union - { - EVAL_Expr *children[3]; - U32 u32; - U64 u64; - F32 f32; - F64 f64; - struct - { - EVAL_Expr *child; - U64 u64; - } child_and_constant; - String8 name; - struct - { - TG_Key type_key; - String8 bytecode; - EVAL_EvalMode mode; - }; - }; -}; - -//////////////////////////////// -//~ rjf: IR Tree Types - -typedef struct EVAL_IRTree EVAL_IRTree; -struct EVAL_IRTree{ - RDI_EvalOp op; - EVAL_IRTree *children[3]; - union{ - U64 p; - String8 bytecode; - }; -}; - -typedef struct EVAL_IRTreeAndType EVAL_IRTreeAndType; -struct EVAL_IRTreeAndType{ - EVAL_IRTree *tree; - TG_Key type_key; - EVAL_EvalMode mode; -}; - -//////////////////////////////// -//~ rjf: Map Types - -//- rjf: string -> num - -typedef struct EVAL_String2NumMapNode EVAL_String2NumMapNode; -struct EVAL_String2NumMapNode -{ - EVAL_String2NumMapNode *order_next; - EVAL_String2NumMapNode *hash_next; - String8 string; - U64 num; -}; - -typedef struct EVAL_String2NumMapNodeArray EVAL_String2NumMapNodeArray; -struct EVAL_String2NumMapNodeArray -{ - EVAL_String2NumMapNode **v; - U64 count; -}; - -typedef struct EVAL_String2NumMapSlot EVAL_String2NumMapSlot; -struct EVAL_String2NumMapSlot -{ - EVAL_String2NumMapNode *first; - EVAL_String2NumMapNode *last; -}; - -typedef struct EVAL_String2NumMap EVAL_String2NumMap; -struct EVAL_String2NumMap -{ - U64 slots_count; - U64 node_count; - EVAL_String2NumMapSlot *slots; - EVAL_String2NumMapNode *first; - EVAL_String2NumMapNode *last; -}; - -//- rjf: string -> expr - -typedef struct EVAL_String2ExprMapNode EVAL_String2ExprMapNode; -struct EVAL_String2ExprMapNode -{ - EVAL_String2ExprMapNode *hash_next; - String8 string; - EVAL_Expr *expr; - U64 poison_count; -}; - -typedef struct EVAL_String2ExprMapSlot EVAL_String2ExprMapSlot; -struct EVAL_String2ExprMapSlot -{ - EVAL_String2ExprMapNode *first; - EVAL_String2ExprMapNode *last; -}; - -typedef struct EVAL_String2ExprMap EVAL_String2ExprMap; -struct EVAL_String2ExprMap -{ - U64 slots_count; - EVAL_String2ExprMapSlot *slots; -}; - -//////////////////////////////// -//~ rjf: Globals - -global read_only EVAL_Expr eval_expr_nil = {0}; -global read_only EVAL_IRTree eval_irtree_nil = {0}; - -//////////////////////////////// -//~ rjf: Basic Functions - -internal U64 eval_hash_from_string(String8 string); - -//////////////////////////////// -//~ rjf: Error List Building Functions - -internal void eval_error(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, String8 text); -internal void eval_errorf(Arena *arena, EVAL_ErrorList *list, EVAL_ErrorKind kind, void *location, char *fmt, ...); -internal void eval_error_list_concat_in_place(EVAL_ErrorList *dst, EVAL_ErrorList *to_push); - -//////////////////////////////// -//~ rjf: Map Functions - -//- rjf: string -> num -internal EVAL_String2NumMap eval_string2num_map_make(Arena *arena, U64 slot_count); -internal void eval_string2num_map_insert(Arena *arena, EVAL_String2NumMap *map, String8 string, U64 num); -internal U64 eval_num_from_string(EVAL_String2NumMap *map, String8 string); -internal EVAL_String2NumMapNodeArray eval_string2num_map_node_array_from_map(Arena *arena, EVAL_String2NumMap *map); -internal int eval_string2num_map_node_qsort_compare__num_ascending(EVAL_String2NumMapNode **a, EVAL_String2NumMapNode **b); -internal void eval_string2num_map_node_array_sort__in_place(EVAL_String2NumMapNodeArray *array); - -//- rjf: string -> expr -internal EVAL_String2ExprMap eval_string2expr_map_make(Arena *arena, U64 slot_count); -internal void eval_string2expr_map_insert(Arena *arena, EVAL_String2ExprMap *map, String8 string, EVAL_Expr *expr); -internal void eval_string2expr_map_inc_poison(EVAL_String2ExprMap *map, String8 string); -internal void eval_string2expr_map_dec_poison(EVAL_String2ExprMap *map, String8 string); -internal EVAL_Expr *eval_expr_from_string(EVAL_String2ExprMap *map, String8 string); - -#endif // EVAL_CORE_H diff --git a/src/eval/eval_decode.c b/src/eval/eval_decode.c deleted file mode 100644 index db66481f..00000000 --- a/src/eval/eval_decode.c +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -// NOTE(allen): Eval Decode Function - -internal void -eval_print_decode_from_bytecode(FILE *out, String8 bytecode){ - U8 *ptr = bytecode.str; - U8 *opl = bytecode.str + bytecode.size; - - for (;ptr < opl;){ - // consume opcode - SYMS_EvalOp op = (SYMS_EvalOp)*ptr; - if (op >= SYMS_EvalOp_COUNT){ - fprintf(out, "decode error: undefined op code\n"); - goto done; - } - U8 ctrlbits = syms_eval_opcode_ctrlbits[op]; - ptr += 1; - - // decode - U64 imm = 0; - U32 decode_size = (ctrlbits >> SYMS_EvalOpCtrlBits_DecodeShft)&SYMS_EvalOpCtrlBits_DecodeMask; - { - U8 *next_ptr = ptr + decode_size; - if (next_ptr > opl){ - fprintf(out, "decode error: expected constant goes past the end of bytecode\n"); - goto done; - } - // TODO(allen): to improve this: - // gaurantee 8 bytes padding after the end of serialized bytecode - // read 8 bytes and mask - switch (decode_size){ - case 1: imm = *ptr; break; - case 2: imm = *(U16*)ptr; break; - case 4: imm = *(U32*)ptr; break; - case 8: imm = *(U64*)ptr; break; - } - ptr = next_ptr; - } - - // op string & control bits - SYMS_String8 op_string = syms_eval_opcode_strings[op]; - - // print - fprintf(out, "%.*s 0x%llx\n", str8_varg(op_string), imm); - } - done:; -} diff --git a/src/eval/eval_decode.h b/src/eval/eval_decode.h deleted file mode 100644 index 4db739e5..00000000 --- a/src/eval/eval_decode.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_DECODE_H -#define EVAL_DECODE_H - -//////////////////////////////// -// NOTE(allen): Eval Decode Function - -internal void eval_print_decode_from_bytecode(FILE *out, String8 bytecode); - -#endif //EVAL_DECODE_H diff --git a/src/eval/eval_inc.c b/src/eval/eval_inc.c deleted file mode 100644 index 6a880fff..00000000 --- a/src/eval/eval_inc.c +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#include "eval/eval_core.c" -#include "eval/eval_compiler.c" -#include "eval/eval_machine.c" -#include "eval/eval_parser.c" diff --git a/src/eval/eval_inc.h b/src/eval/eval_inc.h deleted file mode 100644 index b0a74c09..00000000 --- a/src/eval/eval_inc.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_INC_H -#define EVAL_INC_H - -#include "eval/eval_core.h" -#include "eval/eval_compiler.h" -#include "eval/eval_machine.h" -#include "eval/eval_parser.h" - -#endif // EVAL_INC_H diff --git a/src/eval/eval_machine.c b/src/eval/eval_machine.c deleted file mode 100644 index 2e1cff13..00000000 --- a/src/eval/eval_machine.c +++ /dev/null @@ -1,648 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ allen: Eval Machine Functions - -internal EVAL_Result -eval_interpret(EVAL_Machine *machine, String8 bytecode) -{ - ProfBeginFunction(); - EVAL_Result result = {0}; - - // TODO(allen): We could scan the bytecode and figure out the - // maximum depth of the stack - Temp scratch = scratch_begin(0, 0); - U64 stack_cap = 128; - EVAL_Slot *stack = push_array_no_zero(scratch.arena, EVAL_Slot, stack_cap); - - U64 stack_count = 0; - U8 *ptr = bytecode.str; - U8 *opl = bytecode.str + bytecode.size; - - for (;ptr < opl;){ - // consume opcode - RDI_EvalOp op = (RDI_EvalOp)*ptr; - if (op >= RDI_EvalOp_COUNT){ - result.code = EVAL_ResultCode_BadOp; - goto done; - } - U8 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - ptr += 1; - - // decode - U64 imm = 0; - { - U32 decode_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - U8 *next_ptr = ptr + decode_size; - if (next_ptr > opl){ - result.code = EVAL_ResultCode_BadOp; - goto done; - } - // TODO(allen): to improve this: - // gaurantee 8 bytes padding after the end of serialized bytecode - // read 8 bytes and mask - switch (decode_size){ - case 1: imm = *ptr; break; - case 2: imm = *(U16*)ptr; break; - case 4: imm = *(U32*)ptr; break; - case 8: imm = *(U64*)ptr; break; - } - ptr = next_ptr; - } - - // pop - EVAL_Slot *svals = 0; - { - U32 pop_count = RDI_POPN_FROM_CTRLBITS(ctrlbits); - if (pop_count > stack_count){ - result.code = EVAL_ResultCode_BadOp; - goto done; - } - if (pop_count <= stack_count){ - stack_count -= pop_count; - svals = stack + stack_count; - } - } - - // interpret - EVAL_Slot nval = {0}; - switch (op){ - case RDI_EvalOp_Stop: - { - goto done; - }break; - - case RDI_EvalOp_Noop: - { - // do nothing - }break; - - case RDI_EvalOp_Cond: - { - if (svals[0].u64){ - ptr += imm; - } - }break; - - case RDI_EvalOp_Skip: - { - ptr += imm; - }break; - - case RDI_EvalOp_MemRead: - { - U64 addr = svals[0].u64; - U64 size = imm; - B32 good_read = 0; - if (machine->memory_read != 0 && - machine->memory_read(machine->u, &nval, addr, size)){ - good_read = 1; - } - if (!good_read){ - result.code = EVAL_ResultCode_BadMemRead; - goto done; - } - }break; - - case RDI_EvalOp_RegRead: - { - U8 rdi_reg_code = (imm&0x0000FF)>>0; - U8 byte_size = (imm&0x00FF00)>>8; - U8 byte_off = (imm&0xFF0000)>>16; - REGS_RegCode base_reg_code = regs_reg_code_from_arch_rdi_code(machine->arch, rdi_reg_code); - REGS_Rng rng = regs_reg_code_rng_table_from_architecture(machine->arch)[base_reg_code]; - U64 off = (U64)rng.byte_off + byte_off; - U64 size = (U64)byte_size; - if (off + size <= machine->reg_size){ - MemoryCopy(&nval, (U8*)machine->reg_data + off, size); - } - else{ - result.code = EVAL_ResultCode_BadRegRead; - goto done; - } - }break; - - case RDI_EvalOp_RegReadDyn: - { - U64 off = svals[0].u64; - U64 size = bit_size_from_arch(machine->arch)/8; - if (off + size <= machine->reg_size){ - MemoryCopy(&nval, (U8*)machine->reg_data + off, size); - } - else{ - result.code = EVAL_ResultCode_BadRegRead; - goto done; - } - }break; - - case RDI_EvalOp_FrameOff: - { - if (machine->frame_base != 0){ - nval.u64 = *machine->frame_base + imm; - } - else{ - result.code = EVAL_ResultCode_BadFrameBase; - goto done; - } - }break; - - case RDI_EvalOp_ModuleOff: - { - if (machine->module_base != 0){ - nval.u64 = *machine->module_base + imm; - } - else{ - result.code = EVAL_ResultCode_BadModuleBase; - goto done; - } - }break; - - case RDI_EvalOp_TLSOff: - { - if (machine->tls_base != 0){ - nval.u64 = *machine->tls_base + imm; - } - else{ - result.code = EVAL_ResultCode_BadTLSBase; - goto done; - } - }break; - - case RDI_EvalOp_ConstU8: - case RDI_EvalOp_ConstU16: - case RDI_EvalOp_ConstU32: - case RDI_EvalOp_ConstU64: - { - nval.u64 = imm; - }break; - - case RDI_EvalOp_Abs: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.f32 = svals[0].f32; - if (svals[0].f32 < 0){ - nval.f32 = -svals[0].f32; - } - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.f64 = svals[0].f64; - if (svals[0].f64 < 0){ - nval.f64 = -svals[0].f64; - } - } - else{ - nval.s64 = svals[0].s64; - if (svals[0].s64 < 0){ - nval.s64 = -svals[0].s64; - } - } - }break; - - case RDI_EvalOp_Neg: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.f32 = -svals[0].f32; - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.f64 = -svals[0].f64; - } - else{ - nval.u64 = (~svals[0].u64) + 1; - } - }break; - - case RDI_EvalOp_Add: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.f32 = svals[0].f32 + svals[1].f32; - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.f64 = svals[0].f64 + svals[1].f64; - } - else{ - nval.u64 = svals[0].u64 + svals[1].u64; - } - }break; - - case RDI_EvalOp_Sub: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.f32 = svals[0].f32 - svals[1].f32; - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.f64 = svals[0].f64 - svals[1].f64; - } - else{ - nval.u64 = svals[0].u64 - svals[1].u64; - } - }break; - - case RDI_EvalOp_Mul: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.f32 = svals[0].f32*svals[1].f32; - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.f64 = svals[0].f64*svals[1].f64; - } - else{ - nval.u64 = svals[0].u64*svals[1].u64; - } - }break; - - case RDI_EvalOp_Div: - { - if (imm == RDI_EvalTypeGroup_F32){ - if (svals[1].f32 != 0.f){ - nval.f32 = svals[0].f32/svals[1].f32; - } - else - { - result.code = EVAL_ResultCode_DivideByZero; - goto done; - } - } - else if (imm == RDI_EvalTypeGroup_F64){ - if (svals[1].f64 != 0.){ - nval.f64 = svals[0].f64/svals[1].f64; - } - else - { - result.code = EVAL_ResultCode_DivideByZero; - goto done; - } - } - else if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - if (svals[1].u64 != 0){ - nval.u64 = svals[0].u64/svals[1].u64; - } - else - { - result.code = EVAL_ResultCode_DivideByZero; - goto done; - } - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_Mod: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - if (svals[1].u64 != 0){ - nval.u64 = svals[0].u64%svals[1].u64; - } - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_LShift: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = svals[0].u64 << svals[1].u64; - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_RShift: - { - if (imm == RDI_EvalTypeGroup_U){ - nval.u64 = svals[0].u64 >> svals[1].u64; - } - else if (imm == RDI_EvalTypeGroup_S){ - nval.u64 = svals[0].s64 >> svals[1].u64; - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_BitAnd: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = svals[0].u64&svals[1].u64; - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_BitOr: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = svals[0].u64|svals[1].u64; - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_BitXor: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = svals[0].u64^svals[1].u64; - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_BitNot: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = ~svals[0].u64; - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_LogAnd: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = (svals[0].u64 && svals[1].u64); - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_LogOr: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = (svals[0].u64 || svals[1].u64); - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_LogNot: - { - if (imm == RDI_EvalTypeGroup_U || - imm == RDI_EvalTypeGroup_S){ - nval.u64 = (!svals[0].u64); - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_EqEq: - { - nval.u64 = (svals[0].u64 == svals[1].u64); - }break; - - case RDI_EvalOp_NtEq: - { - nval.u64 = (svals[0].u64 != svals[1].u64); - }break; - - case RDI_EvalOp_LsEq: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.u64 = (svals[0].f32 <= svals[1].f32); - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.u64 = (svals[0].f64 <= svals[1].f64); - } - else if (imm == RDI_EvalTypeGroup_U){ - nval.u64 = (svals[0].u64 <= svals[1].u64); - } - else if (imm == RDI_EvalTypeGroup_S){ - nval.u64 = (svals[0].s64 <= svals[1].s64); - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_GrEq: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.u64 = (svals[0].f32 >= svals[1].f32); - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.u64 = (svals[0].f64 >= svals[1].f64); - } - else if (imm == RDI_EvalTypeGroup_U){ - nval.u64 = (svals[0].u64 >= svals[1].u64); - } - else if (imm == RDI_EvalTypeGroup_S){ - nval.u64 = (svals[0].s64 >= svals[1].s64); - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_Less: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.u64 = (svals[0].f32 < svals[1].f32); - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.u64 = (svals[0].f64 < svals[1].f64); - } - else if (imm == RDI_EvalTypeGroup_U){ - nval.u64 = (svals[0].u64 < svals[1].u64); - } - else if (imm == RDI_EvalTypeGroup_S){ - nval.u64 = (svals[0].s64 < svals[1].s64); - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_Grtr: - { - if (imm == RDI_EvalTypeGroup_F32){ - nval.u64 = (svals[0].f32 > svals[1].f32); - } - else if (imm == RDI_EvalTypeGroup_F64){ - nval.u64 = (svals[0].f64 > svals[1].f64); - } - else if (imm == RDI_EvalTypeGroup_U){ - nval.u64 = (svals[0].u64 > svals[1].u64); - } - else if (imm == RDI_EvalTypeGroup_S){ - nval.u64 = (svals[0].s64 > svals[1].s64); - } - else{ - result.code = EVAL_ResultCode_BadOpTypes; - goto done; - } - }break; - - case RDI_EvalOp_Trunc: - { - if (0 < imm){ - U64 mask = 0; - if (imm < 64){ - mask = max_U64 >> (64 - imm); - } - nval.u64 = svals[0].u64&mask; - } - }break; - - case RDI_EvalOp_TruncSigned: - { - if (0 < imm){ - U64 mask = 0; - if (imm < 64){ - mask = max_U64 >> (64 - imm); - } - U64 high = 0; - if (svals[0].u64 & (1 << (imm - 1))){ - high = ~mask; - } - nval.u64 = high|(svals[0].u64&mask); - } - }break; - - case RDI_EvalOp_Convert: - { - U32 in = imm&0xFF; - U32 out = (imm >> 8)&0xFF; - if (in != out){ - switch (in + out*RDI_EvalTypeGroup_COUNT){ - case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT: - { - nval.u64 = (U64)svals[0].f32; - }break; - case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_U*RDI_EvalTypeGroup_COUNT: - { - nval.u64 = (U64)svals[0].f64; - }break; - - case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT: - { - nval.s64 = (S64)svals[0].f32; - }break; - case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_S*RDI_EvalTypeGroup_COUNT: - { - nval.s64 = (S64)svals[0].f64; - }break; - - case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT: - { - nval.f32 = (F32)svals[0].u64; - }break; - case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT: - { - nval.f32 = (F32)svals[0].s64; - }break; - case RDI_EvalTypeGroup_F64 + RDI_EvalTypeGroup_F32*RDI_EvalTypeGroup_COUNT: - { - nval.f32 = (F32)svals[0].f64; - }break; - - case RDI_EvalTypeGroup_U + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT: - { - nval.f64 = (F64)svals[0].u64; - }break; - case RDI_EvalTypeGroup_S + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT: - { - nval.f64 = (F64)svals[0].s64; - }break; - case RDI_EvalTypeGroup_F32 + RDI_EvalTypeGroup_F64*RDI_EvalTypeGroup_COUNT: - { - nval.f64 = (F64)svals[0].f32; - }break; - } - } - }break; - - case RDI_EvalOp_Pick: - { - if (stack_count > imm){ - nval = stack[stack_count - imm - 1]; - } - else{ - result.code = EVAL_ResultCode_BadOp; - goto done; - } - }break; - - case RDI_EvalOp_Pop: - { - // do nothing - the pop is handled by the control bits - }break; - - case RDI_EvalOp_Insert: - { - if (stack_count > imm){ - if (imm > 0){ - EVAL_Slot tval = stack[stack_count - 1]; - EVAL_Slot *dst = stack + stack_count - 1 - imm; - EVAL_Slot *shift = dst + 1; - MemoryCopy(shift, dst, imm*sizeof(EVAL_Slot)); - *dst = tval; - } - } - else{ - result.code = EVAL_ResultCode_BadOp; - goto done; - } - }break; - } - - // push - { - U64 push_count = RDI_PUSHN_FROM_CTRLBITS(ctrlbits); - if (push_count == 1){ - if (stack_count < stack_cap){ - stack[stack_count] = nval; - stack_count += 1; - } - else{ - result.code = EVAL_ResultCode_InsufficientStackSpace; - goto done; - } - } - } - - } - done:; - - if (stack_count == 1){ - result.value = stack[0]; - } - else if(result.code == EVAL_ResultCode_Good){ - result.code = EVAL_ResultCode_MalformedBytecode; - } - - scratch_end(scratch); - ProfEnd(); - return(result); -} \ No newline at end of file diff --git a/src/eval/eval_machine.h b/src/eval/eval_machine.h deleted file mode 100644 index 71340092..00000000 --- a/src/eval/eval_machine.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL2_MACHINE_H -#define EVAL2_MACHINE_H - -//////////////////////////////// -//~ allen: Eval Machine Types - -typedef B32 EVAL_MemoryRead(void *u, void *out, U64 addr, U64 size); - -typedef struct EVAL_Machine EVAL_Machine; -struct EVAL_Machine -{ - void *u; - Architecture arch; - EVAL_MemoryRead *memory_read; - void *reg_data; - U64 reg_size; - U64 *module_base; - U64 *frame_base; - U64 *tls_base; -}; - -typedef union EVAL_Slot EVAL_Slot; -union EVAL_Slot -{ - U64 u256[4]; - U64 u128[2]; - U64 u64; - S64 s64; - F64 f64; - F32 f32; -}; - -typedef struct EVAL_Result EVAL_Result; -struct EVAL_Result -{ - EVAL_Slot value; - EVAL_ResultCode code; -}; - -//////////////////////////////// -//~ allen: Eval Machine Functions - -internal EVAL_Result eval_interpret(EVAL_Machine *machine, String8 bytecode); - -#endif //EVAL2_MACHINE_H diff --git a/src/eval/eval_parser.c b/src/eval/eval_parser.c deleted file mode 100644 index 11cf14c1..00000000 --- a/src/eval/eval_parser.c +++ /dev/null @@ -1,1444 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Tables - -global read_only String8 eval_g_multichar_symbol_strings[] = -{ - str8_lit_comp("<<"), - str8_lit_comp(">>"), - str8_lit_comp("->"), - str8_lit_comp("<="), - str8_lit_comp(">="), - str8_lit_comp("=="), - str8_lit_comp("!="), - str8_lit_comp("&&"), - str8_lit_comp("||"), -}; - -global read_only struct {EVAL_ExprKind kind; String8 string; S64 precedence;} eval_g_unary_prefix_op_table[] = -{ - // { EVAL_ExprKind_???, str8_lit_comp("+"), 2 }, - { EVAL_ExprKind_Neg, str8_lit_comp("-"), 2 }, - { EVAL_ExprKind_LogNot, str8_lit_comp("!"), 2 }, - { EVAL_ExprKind_Deref, str8_lit_comp("*"), 2 }, - { EVAL_ExprKind_Address,str8_lit_comp("&"), 2 }, - { EVAL_ExprKind_Sizeof, str8_lit_comp("sizeof"), 2 }, - // { EVAL_ExprKind_Alignof, str8_lit_comp("_Alignof"), 2 }, -}; - -global read_only struct {EVAL_ExprKind kind; String8 string; S64 precedence;} eval_g_binary_op_table[] = -{ - { EVAL_ExprKind_Mul, str8_lit_comp("*"), 3 }, - { EVAL_ExprKind_Div, str8_lit_comp("/"), 3 }, - { EVAL_ExprKind_Mod, str8_lit_comp("%"), 3 }, - { EVAL_ExprKind_Add, str8_lit_comp("+"), 4 }, - { EVAL_ExprKind_Sub, str8_lit_comp("-"), 4 }, - { EVAL_ExprKind_LShift, str8_lit_comp("<<"), 5 }, - { EVAL_ExprKind_RShift, str8_lit_comp(">>"), 5 }, - { EVAL_ExprKind_Less, str8_lit_comp("<"), 6 }, - { EVAL_ExprKind_LsEq, str8_lit_comp("<="), 6 }, - { EVAL_ExprKind_Grtr, str8_lit_comp(">"), 6 }, - { EVAL_ExprKind_GrEq, str8_lit_comp(">="), 6 }, - { EVAL_ExprKind_EqEq, str8_lit_comp("=="), 7 }, - { EVAL_ExprKind_NtEq, str8_lit_comp("!="), 7 }, - { EVAL_ExprKind_BitAnd, str8_lit_comp("&"), 8 }, - { EVAL_ExprKind_BitXor, str8_lit_comp("^"), 9 }, - { EVAL_ExprKind_BitOr, str8_lit_comp("|"), 10 }, - { EVAL_ExprKind_LogAnd, str8_lit_comp("&&"), 11 }, - { EVAL_ExprKind_LogOr, str8_lit_comp("||"), 12 }, - { EVAL_ExprKind_Define, str8_lit_comp("="), 13 }, -}; - -global read_only S64 eval_g_max_precedence = 15; - -//////////////////////////////// -//~ rjf: Map Building Fast Paths - -internal EVAL_String2NumMap * -eval_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) -{ - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: gather scopes to walk - typedef struct Task Task; - struct Task - { - Task *next; - RDI_Scope *scope; - }; - Task *first_task = 0; - Task *last_task = 0; - - //- rjf: voff -> tightest scope - RDI_Scope *tightest_scope = 0; - { - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - Task *task = push_array(scratch.arena, Task, 1); - task->scope = scope; - SLLQueuePush(first_task, last_task, task); - tightest_scope = scope; - } - - //- rjf: voff-1 -> scope - if(voff > 0) - { - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff-1); - RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - if(scope != tightest_scope) - { - Task *task = push_array(scratch.arena, Task, 1); - task->scope = scope; - SLLQueuePush(first_task, last_task, task); - } - } - - //- rjf: tightest scope -> walk up the tree & build tasks for each parent scope - if(tightest_scope != 0) - { - RDI_Scope *nil_scope = rdi_element_from_name_idx(rdi, Scopes, 0); - for(RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, tightest_scope->parent_scope_idx); - scope != 0 && scope != nil_scope; - scope = rdi_element_from_name_idx(rdi, Scopes, scope->parent_scope_idx)) - { - Task *task = push_array(scratch.arena, Task, 1); - task->scope = scope; - SLLQueuePush(first_task, last_task, task); - } - } - - //- rjf: build blank map - EVAL_String2NumMap *map = push_array(arena, EVAL_String2NumMap, 1); - *map = eval_string2num_map_make(arena, 1024); - - //- rjf: accumulate locals for all tasks - for(Task *task = first_task; task != 0; task = task->next) - { - RDI_Scope *scope = task->scope; - if(scope != 0) - { - U32 local_opl_idx = scope->local_first + scope->local_count; - for(U32 local_idx = scope->local_first; local_idx < local_opl_idx; local_idx += 1) - { - RDI_Local *local_var = rdi_element_from_name_idx(rdi, Locals, local_idx); - U64 local_name_size = 0; - U8 *local_name_str = rdi_string_from_idx(rdi, local_var->name_string_idx, &local_name_size); - String8 name = push_str8_copy(arena, str8(local_name_str, local_name_size)); - eval_string2num_map_insert(arena, map, name, (U64)local_idx+1); - } - } - } - - scratch_end(scratch); - return map; -} - -internal EVAL_String2NumMap * -eval_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) -{ - //- rjf: voff -> tightest scope - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_ScopeVMap, voff); - RDI_Scope *tightest_scope = rdi_element_from_name_idx(rdi, Scopes, scope_idx); - - //- rjf: tightest scope -> procedure - U32 proc_idx = tightest_scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, proc_idx); - - //- rjf: procedure -> udt - U32 udt_idx = procedure->container_idx; - RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, udt_idx); - - //- rjf: build blank map - EVAL_String2NumMap *map = push_array(arena, EVAL_String2NumMap, 1); - *map = eval_string2num_map_make(arena, 64); - - //- rjf: udt -> fill member map - if(!(udt->flags & RDI_UDTFlag_EnumMembers)) - { - U64 data_member_num = 1; - for(U32 member_idx = udt->member_first; - member_idx < udt->member_first+udt->member_count; - member_idx += 1) - { - RDI_Member *m = rdi_element_from_name_idx(rdi, Members, member_idx); - if(m->kind == RDI_MemberKind_DataField) - { - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, m->name_string_idx, &name.size); - eval_string2num_map_insert(arena, map, name, data_member_num); - data_member_num += 1; - } - } - } - - return map; -} - -//////////////////////////////// -//~ rjf: Tokenization Functions - -internal EVAL_Token -eval_token_zero(void) -{ - EVAL_Token token = zero_struct; - return token; -} - -internal void -eval_token_chunk_list_push(Arena *arena, EVAL_TokenChunkList *list, U64 chunk_size, EVAL_Token *token) -{ - EVAL_TokenChunkNode *node = list->last; - if(node == 0 || node->count >= node->cap) - { - node = push_array(arena, EVAL_TokenChunkNode, 1); - SLLQueuePush(list->first, list->last, node); - node->cap = chunk_size; - node->v = push_array_no_zero(arena, EVAL_Token, node->cap); - list->node_count += 1; - } - MemoryCopyStruct(&node->v[node->count], token); - node->count += 1; - list->total_count += 1; -} - -internal EVAL_TokenArray -eval_token_array_from_chunk_list(Arena *arena, EVAL_TokenChunkList *list) -{ - EVAL_TokenArray array = {0}; - array.count = list->total_count; - array.v = push_array_no_zero(arena, EVAL_Token, array.count); - U64 idx = 0; - for(EVAL_TokenChunkNode *node = list->first; node != 0; node = node->next) - { - MemoryCopy(array.v+idx, node->v, sizeof(EVAL_Token)*node->count); - } - return array; -} - -internal EVAL_TokenArray -eval_token_array_from_text(Arena *arena, String8 text) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(&arena, 1); - - //- rjf: lex loop - EVAL_TokenChunkList tokens = {0}; - U64 active_token_start_idx = 0; - EVAL_TokenKind active_token_kind = EVAL_TokenKind_Null; - B32 active_token_kind_started_with_tick = 0; - B32 escaped = 0; - for(U64 idx = 0, advance = 0; idx <= text.size; idx += advance) - { - U8 byte = (idx+0 < text.size) ? text.str[idx+0] : 0; - U8 byte_next = (idx+1 < text.size) ? text.str[idx+1] : 0; - U8 byte_next2= (idx+2 < text.size) ? text.str[idx+2] : 0; - advance = 1; - B32 token_formed = 0; - U64 token_end_idx_pad = 0; - switch(active_token_kind) - { - //- rjf: no active token -> seek token starter - default: - { - if(char_is_alpha(byte) || byte == '_' || byte == '`' || byte == '$') - { - active_token_kind = EVAL_TokenKind_Identifier; - active_token_start_idx = idx; - active_token_kind_started_with_tick = (byte == '`'); - } - else if(char_is_digit(byte, 10) || (byte == '.' && char_is_digit(byte_next, 10))) - { - active_token_kind = EVAL_TokenKind_Numeric; - active_token_start_idx = idx; - } - else if(byte == '"') - { - active_token_kind = EVAL_TokenKind_StringLiteral; - active_token_start_idx = idx; - } - else if(byte == '\'') - { - active_token_kind = EVAL_TokenKind_CharLiteral; - active_token_start_idx = idx; - } - else if(byte == '~' || byte == '!' || byte == '%' || byte == '^' || - byte == '&' || byte == '*' || byte == '(' || byte == ')' || - byte == '-' || byte == '=' || byte == '+' || byte == '[' || - byte == ']' || byte == '{' || byte == '}' || byte == ':' || - byte == ';' || byte == ',' || byte == '.' || byte == '<' || - byte == '>' || byte == '/' || byte == '?' || byte == '|') - { - active_token_kind = EVAL_TokenKind_Symbol; - active_token_start_idx = idx; - } - }break; - - //- rjf: active tokens -> seek enders - case EVAL_TokenKind_Identifier: - { - if(byte == ':' && byte_next == ':' && (char_is_alpha(byte_next2) || byte_next2 == '_' || byte_next2 == '<')) - { - // NOTE(rjf): encountering C++-style namespaces - skip over scope resolution symbol - // & keep going. - advance = 2; - } - else if((byte == '\'' || byte == '`') && active_token_kind_started_with_tick) - { - // NOTE(rjf): encountering ` -> ' or ` -> ` style identifier escapes - active_token_kind_started_with_tick = 0; - advance = 1; - } - else if(byte == '<') - { - // NOTE(rjf): encountering C++-style templates - try to find ender. if no ender found, - // assume this is an operator & just consume the identifier part. - S64 nest = 1; - for(U64 idx2 = idx+1; idx2 <= text.size; idx2 += 1) - { - if(idx2 < text.size && text.str[idx2] == '<') - { - nest += 1; - } - else if(idx2 < text.size && text.str[idx2] == '>') - { - nest -= 1; - if(nest == 0) - { - advance = (idx2+1-idx); - break; - } - } - else if(idx2 == text.size && nest != 0) - { - token_formed = 1; - advance = 0; - break; - } - } - } - else if(!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '_' && !active_token_kind_started_with_tick && byte != '@' && byte != '$') - { - advance = 0; - token_formed = 1; - } - }break; - case EVAL_TokenKind_Numeric: - { - if(!char_is_alpha(byte) && !char_is_digit(byte, 10) && byte != '.') - { - advance = 0; - token_formed = 1; - } - }break; - case EVAL_TokenKind_StringLiteral: - { - if(escaped == 0 && byte == '\\') - { - escaped = 1; - } - else if(escaped) - { - escaped = 0; - } - else if(escaped == 0 && byte == '"') - { - advance = 1; - token_formed = 1; - token_end_idx_pad = 1; - } - }break; - case EVAL_TokenKind_CharLiteral: - { - if(escaped == 0 && byte == '\\') - { - escaped = 1; - } - else if(escaped) - { - escaped = 0; - } - else if(escaped == 0 && byte == '\'') - { - advance = 1; - token_formed = 1; - token_end_idx_pad = 1; - } - }break; - case EVAL_TokenKind_Symbol: - { - if(byte != '~' && byte != '!' && byte != '%' && byte != '^' && - byte != '&' && byte != '*' && byte != '(' && byte != ')' && - byte != '-' && byte != '=' && byte != '+' && byte != '[' && - byte != ']' && byte != '{' && byte != '}' && byte != ':' && - byte != ';' && byte != ',' && byte != '.' && byte != '<' && - byte != '>' && byte != '/' && byte != '?' && byte != '|') - { - advance = 0; - token_formed = 1; - } - }break; - } - - //- rjf: token formed -> push new formed token(s) - if(token_formed) - { - // rjf: non-symbols *or* symbols of only 1-length can be immediately - // pushed as a token - if(active_token_kind != EVAL_TokenKind_Symbol || idx==active_token_start_idx+1) - { - EVAL_Token token = {active_token_kind, r1u64(active_token_start_idx, idx+token_end_idx_pad)}; - eval_token_chunk_list_push(scratch.arena, &tokens, 256, &token); - } - - // rjf: symbolic strings matching `--` mean the remainder of the string - // is reserved for external usage. the rest of the stream should not - // be tokenized. - else if(idx == active_token_start_idx+2 && text.str[active_token_start_idx] == '-' && text.str[active_token_start_idx+1] == '-') - { - break; - } - - // rjf: if we got a symbol string of N>1 characters, then we need to - // apply the maximum-munch rule, and produce M<=N tokens, where each - // formed token is the maximum size possible, given the legal - // >1-length symbol strings. - else - { - U64 advance2 = 0; - for(U64 idx2 = active_token_start_idx; idx2 < idx; idx2 += advance2) - { - advance2 = 1; - for(U64 multichar_symbol_idx = 0; - multichar_symbol_idx < ArrayCount(eval_g_multichar_symbol_strings); - multichar_symbol_idx += 1) - { - String8 multichar_symbol_string = eval_g_multichar_symbol_strings[multichar_symbol_idx]; - String8 part_of_token = str8_substr(text, r1u64(idx2, idx2+multichar_symbol_string.size)); - if(str8_match(part_of_token, multichar_symbol_string, 0)) - { - advance2 = multichar_symbol_string.size; - break; - } - } - EVAL_Token token = {active_token_kind, r1u64(idx2, idx2+advance2)}; - eval_token_chunk_list_push(scratch.arena, &tokens, 256, &token); - } - } - - // rjf: reset for subsequent tokens. - active_token_kind = EVAL_TokenKind_Null; - } - } - - //- rjf: chunk list -> array & return - EVAL_TokenArray array = eval_token_array_from_chunk_list(arena, &tokens); - scratch_end(scratch); - ProfEnd(); - return array; -} - -internal EVAL_TokenArray -eval_token_array_make_first_opl(EVAL_Token *first, EVAL_Token *opl) -{ - EVAL_TokenArray array = {first, (U64)(opl-first)}; - return array; -} - -//////////////////////////////// -//~ rjf: Parser Functions - -internal TG_Key -eval_leaf_type_from_name(RDI_Parsed *rdi, String8 name) -{ - TG_Key key = zero_struct; - B32 found = 0; - { - RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Types); - 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, name.str, name.size); - if(node != 0) - { - U32 match_count = 0; - U32 *matches = rdi_matches_from_map_node(rdi, node, &match_count); - if(match_count != 0) - { - RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, matches[0]); - found = type_node->kind != RDI_TypeKind_NULL; - key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)matches[0]); - } - } - } - if(!found) - { -#define Case(str) (str8_match(name, str8_lit(str), 0)) - if(Case("u8") || Case("uint8") || Case("uint8_t") || Case("uchar8") || Case("U8")) - { - key = tg_key_basic(TG_Kind_U8); - } - else if(Case("u16") || Case("uint16") || Case("uint16_t") || Case("uchar16") || Case("U16")) - { - key = tg_key_basic(TG_Kind_U16); - } - else if(Case("u32") || Case("uint32") || Case("uint32_t") || Case("uchar32") || Case("U32") || Case("uint")) - { - key = tg_key_basic(TG_Kind_U32); - } - else if(Case("u64") || Case("uint64") || Case("uint64_t") || Case("U64")) - { - key = tg_key_basic(TG_Kind_U64); - } - else if(Case("s8") || Case("b8") || Case("B8") || Case("i8") || Case("int8") || Case("int8_t") || Case("char8") || Case("S8")) - { - key = tg_key_basic(TG_Kind_S8); - } - else if(Case("s16") ||Case("b16") || Case("B16") || Case("i16") || Case("int16") || Case("int16_t") || Case("char16") || Case("S16")) - { - key = tg_key_basic(TG_Kind_S16); - } - else if(Case("s32") || Case("b32") || Case("B32") || Case("i32") || Case("int32") || Case("int32_t") || Case("char32") || Case("S32") || Case("int")) - { - key = tg_key_basic(TG_Kind_S32); - } - else if(Case("s64") || Case("b64") || Case("B64") || Case("i64") || Case("int64") || Case("int64_t") || Case("S64")) - { - key = tg_key_basic(TG_Kind_S64); - } - else if(Case("void")) - { - key = tg_key_basic(TG_Kind_Void); - } - else if(Case("bool")) - { - key = tg_key_basic(TG_Kind_Bool); - } - else if(Case("float") || Case("f32") || Case("F32") || Case("r32") || Case("R32")) - { - key = tg_key_basic(TG_Kind_F32); - } - else if(Case("double") || Case("f64") || Case("F64") || Case("r64") || Case("R64")) - { - key = tg_key_basic(TG_Kind_F64); - } -#undef Case - } - return key; -} - -internal EVAL_ParseResult -eval_parse_type_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens) -{ - EVAL_ParseResult parse = eval_parse_result_nil; - EVAL_Token *token_it = tokens->v; - - //- rjf: parse unsigned marker - B32 unsigned_marker = 0; - { - EVAL_Token token = eval_token_at_it(token_it, tokens); - if(token.kind == EVAL_TokenKind_Identifier) - { - String8 token_string = str8_substr(text, token.range); - if(str8_match(token_string, str8_lit("unsigned"), 0)) - { - token_it += 1; - unsigned_marker = 1; - } - } - } - - //- rjf: parse base type - { - EVAL_Token token = eval_token_at_it(token_it, tokens); - if(token.kind == EVAL_TokenKind_Identifier) - { - String8 token_string = str8_substr(text, token.range); - TG_Key type_key = eval_leaf_type_from_name(ctx->rdi, token_string); - if(!tg_key_match(tg_key_zero(), type_key)) - { - token_it += 1; - - // rjf: apply unsigned marker to base type - if(unsigned_marker) switch(tg_kind_from_key(type_key)) - { - default:{}break; - case TG_Kind_Char8: {type_key = tg_key_basic(TG_Kind_UChar8);}break; - case TG_Kind_Char16:{type_key = tg_key_basic(TG_Kind_UChar16);}break; - case TG_Kind_Char32:{type_key = tg_key_basic(TG_Kind_UChar32);}break; - case TG_Kind_S8: {type_key = tg_key_basic(TG_Kind_U8);}break; - case TG_Kind_S16: {type_key = tg_key_basic(TG_Kind_U16);}break; - case TG_Kind_S32: {type_key = tg_key_basic(TG_Kind_U32);}break; - case TG_Kind_S64: {type_key = tg_key_basic(TG_Kind_U64);}break; - case TG_Kind_S128:{type_key = tg_key_basic(TG_Kind_U128);}break; - case TG_Kind_S256:{type_key = tg_key_basic(TG_Kind_U256);}break; - case TG_Kind_S512:{type_key = tg_key_basic(TG_Kind_U512);}break; - } - - // rjf: construct leaf type - parse.expr = eval_expr_leaf_type(arena, token_string.str, type_key); - } - } - } - - //- rjf: parse extensions - if(parse.expr != &eval_expr_nil) - { - for(;;) - { - EVAL_Token token = eval_token_at_it(token_it, tokens); - if(token.kind != EVAL_TokenKind_Symbol) - { - break; - } - String8 token_string = str8_substr(text, token.range); - if(str8_match(token_string, str8_lit("*"), 0)) - { - token_it += 1; - parse.expr = eval_expr(arena, EVAL_ExprKind_Ptr, token_string.str, parse.expr, &eval_expr_nil, &eval_expr_nil); - } - else - { - break; - } - } - } - - //- rjf: fill parse & end - parse.last_token = token_it; - return parse; -} - -internal EVAL_ParseResult -eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens, S64 max_precedence) -{ - ProfBeginFunction(); - Temp scratch = scratch_begin(&arena, 1); - EVAL_Token *it = tokens->v; - EVAL_Token *it_opl = tokens->v + tokens->count; - EVAL_ParseResult result = eval_parse_result_nil; - - //- rjf: parse prefix unaries - typedef struct PrefixUnaryNode PrefixUnaryNode; - struct PrefixUnaryNode - { - PrefixUnaryNode *next; - EVAL_ExprKind kind; - EVAL_Expr *cast_expr; - void *location; - }; - PrefixUnaryNode *first_prefix_unary = 0; - PrefixUnaryNode *last_prefix_unary = 0; - { - for(;it < it_opl;) - { - EVAL_Token *start_it = it; - EVAL_Token token = eval_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - S64 prefix_unary_precedence = 0; - EVAL_ExprKind prefix_unary_kind = 0; - EVAL_Expr *cast_expr = &eval_expr_nil; - void *location = 0; - - // rjf: try op table - for(U64 idx = 0; idx < ArrayCount(eval_g_unary_prefix_op_table); idx += 1) - { - if(str8_match(token_string, eval_g_unary_prefix_op_table[idx].string, 0)) - { - prefix_unary_precedence = eval_g_unary_prefix_op_table[idx].precedence; - prefix_unary_kind = eval_g_unary_prefix_op_table[idx].kind; - break; - } - } - - // rjf: consume valid op - if(prefix_unary_precedence != 0) - { - location = token_string.str; - it += 1; - } - - // rjf: try casting expression - if(prefix_unary_precedence == 0 && str8_match(token_string, str8_lit("("), 0)) - { - EVAL_Token some_type_identifier_maybe = eval_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 == EVAL_TokenKind_Identifier) - { - TG_Key type_key = eval_leaf_type_from_name(ctx->rdi, some_type_identifier_maybe_string); - if(!tg_key_match(type_key, tg_key_zero()) || str8_match(some_type_identifier_maybe_string, str8_lit("unsigned"), 0)) - { - // rjf: move past open paren - it += 1; - - // rjf: parse type expr - EVAL_TokenArray type_parse_tokens = eval_token_array_make_first_opl(it, it_opl); - EVAL_ParseResult type_parse = eval_parse_type_from_text_tokens(arena, ctx, text, &type_parse_tokens); - EVAL_Expr *type = type_parse.expr; - eval_error_list_concat_in_place(&result.errors, &type_parse.errors); - it = type_parse.last_token; - location = token_string.str; - - // rjf: expect ) - EVAL_Token close_paren_maybe = eval_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != EVAL_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Missing )."); - } - - // rjf: consume ) - else - { - it += 1; - } - - // rjf: fill - prefix_unary_precedence = 2; - prefix_unary_kind = EVAL_ExprKind_Cast; - cast_expr = type; - } - } - } - - // rjf: break if we got no operators - if(prefix_unary_precedence == 0) - { - break; - } - - // rjf: break if the token node iterator has not changed - if(it == start_it) - { - break; - } - - // rjf: push prefix unary if we got one - { - PrefixUnaryNode *op_n = push_array(scratch.arena, PrefixUnaryNode, 1); - op_n->kind = prefix_unary_kind; - op_n->cast_expr = cast_expr; - op_n->location = location; - SLLQueuePushFront(first_prefix_unary, last_prefix_unary, op_n); - } - } - } - - //- rjf: parse atom - EVAL_Expr *atom = &eval_expr_nil; - String8 atom_implicit_member_name = {0}; - if(it < it_opl) - { - EVAL_Token token = eval_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - - //- rjf: descent to nested expression - if(token.kind == EVAL_TokenKind_Symbol && str8_match(token_string, str8_lit("("), 0)) - { - // rjf: skip ( - it += 1; - - // rjf: parse () contents - EVAL_TokenArray nested_parse_tokens = eval_token_array_make_first_opl(it, it_opl); - EVAL_ParseResult nested_parse = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, &nested_parse_tokens, eval_g_max_precedence); - eval_error_list_concat_in_place(&result.errors, &nested_parse.errors); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: expect ) - EVAL_Token close_paren_maybe = eval_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != EVAL_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit(")"), 0)) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Missing )."); - } - - // rjf: consume ) - else - { - it += 1; - } - } - - //- rjf: descent to assembly-style dereference sub-expression - else if(token.kind == EVAL_TokenKind_Symbol && str8_match(token_string, str8_lit("["), 0)) - { - // rjf: skip [ - it += 1; - - // rjf: parse [] contents - EVAL_TokenArray nested_parse_tokens = eval_token_array_make_first_opl(it, it_opl); - EVAL_ParseResult nested_parse = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, &nested_parse_tokens, eval_g_max_precedence); - eval_error_list_concat_in_place(&result.errors, &nested_parse.errors); - atom = nested_parse.expr; - it = nested_parse.last_token; - - // rjf: build cast-to-U64*, and dereference operators - atom = eval_expr(arena, EVAL_ExprKind_Cast, token_string.str, eval_expr_leaf_type(arena, token_string.str, tg_cons_type_make(ctx->type_graph, TG_Kind_Ptr, tg_key_basic(TG_Kind_U64), 0)), atom, &eval_expr_nil); - atom = eval_expr(arena, EVAL_ExprKind_Deref, token_string.str, atom, &eval_expr_nil, &eval_expr_nil); - - // rjf: expect ] - EVAL_Token close_paren_maybe = eval_token_at_it(it, tokens); - String8 close_paren_maybe_string = str8_substr(text, close_paren_maybe.range); - if(close_paren_maybe.kind != EVAL_TokenKind_Symbol || !str8_match(close_paren_maybe_string, str8_lit("]"), 0)) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Missing ]."); - } - - // rjf: consume ) - else - { - it += 1; - } - } - - //- rjf: leaf (identifier, literal) - else if(token.kind != EVAL_TokenKind_Symbol) - { - switch(token.kind) - { - //- rjf: identifier => name resolution - default: - case EVAL_TokenKind_Identifier: - { - B32 mapped_identifier = 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}; - REGS_RegCode reg_code = 0; - REGS_AliasCode alias_code = 0; - TG_Key type_key = zero_struct; - String8 local_lookup_string = token_string; - - //- rjf: form namespaceified fallback versions of this lookup string - String8List namespaceified_token_strings = {0}; - { - U64 scope_idx = rdi_vmap_idx_from_section_kind_voff(ctx->rdi, RDI_SectionKind_ScopeVMap, ctx->ip_voff); - RDI_Scope *scope = rdi_element_from_name_idx(ctx->rdi, Scopes, scope_idx); - U64 proc_idx = scope->proc_idx; - RDI_Procedure *procedure = rdi_element_from_name_idx(ctx->rdi, Procedures, proc_idx); - U64 name_size = 0; - U8 *name_ptr = rdi_string_from_idx(ctx->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) - { - U64 data_member_num = eval_num_from_string(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) - { - U64 local_num = eval_num_from_string(ctx->locals_map, local_lookup_string); - if(local_num != 0) - { - mapped_identifier = 1; - identifier_type_is_possibly_dynamically_overridden = 1; - RDI_Local *local_var = rdi_element_from_name_idx(ctx->rdi, Locals, local_num-1); - RDI_TypeNode *type_node = rdi_element_from_name_idx(ctx->rdi, TypeNodes, local_var->type_idx); - type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)local_var->type_idx); - - // 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(ctx->rdi, LocationBlocks, loc_block_idx); - if(block->scope_off_first <= ctx->ip_voff && ctx->ip_voff < block->scope_off_opl) - { - U64 all_location_data_size = 0; - U8 *all_location_data = rdi_table_from_name(ctx->rdi, LocationData, &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_AddrBytecodeStream: - case RDI_LocationKind_ValBytecodeStream: - { - U8 *bytecode_base = all_location_data + block->location_data_off + sizeof(RDI_LocationKind); - U64 bytecode_size = 0; - for(U64 idx = 0; idx < all_location_data_size; idx += 1) - { - U8 op = bytecode_base[idx]; - if(op == 0) - { - break; - } - U8 ctrlbits = rdi_eval_op_ctrlbits_table[op]; - U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits); - bytecode_size += 1+p_size; - } - loc_bytecode = str8(bytecode_base, 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) - { - U64 reg_num = eval_num_from_string(ctx->regs_map, token_string); - if(reg_num != 0) - { - reg_code = reg_num; - mapped_identifier = 1; - type_key = tg_key_reg(ctx->arch, reg_code); - } - } - - //- rjf: try register aliases - if(mapped_identifier == 0) - { - U64 alias_num = eval_num_from_string(ctx->reg_alias_map, token_string); - if(alias_num != 0) - { - alias_code = (REGS_AliasCode)alias_num; - type_key = tg_key_reg_alias(ctx->arch, alias_code); - mapped_identifier = 1; - } - } - - //- rjf: try global variables - if(mapped_identifier == 0) - { - RDI_NameMap *name_map = rdi_element_from_name_idx(ctx->rdi, NameMaps, RDI_NameMapKind_GlobalVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(ctx->rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(ctx->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(ctx->rdi, GlobalVariables, match_idx); - EVAL_OpList oplist = {0}; - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ModuleOff, global_var->voff); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = eval_bytecode_from_oplist(arena, &oplist); - U32 type_idx = global_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(ctx->rdi, TypeNodes, type_idx); - type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)type_idx); - mapped_identifier = 1; - } - } - - //- rjf: try thread variables - if(mapped_identifier == 0) - { - RDI_NameMap *name_map = rdi_element_from_name_idx(ctx->rdi, NameMaps, RDI_NameMapKind_ThreadVariables); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(ctx->rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(ctx->rdi, ThreadVariables, match_idx); - EVAL_OpList oplist = {0}; - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, thread_var->tls_off); - loc_kind = RDI_LocationKind_AddrBytecodeStream; - loc_bytecode = eval_bytecode_from_oplist(arena, &oplist); - U32 type_idx = thread_var->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(ctx->rdi, TypeNodes, type_idx); - type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)type_idx); - mapped_identifier = 1; - } - } - - //- rjf: try procedures - if(mapped_identifier == 0) - { - RDI_NameMap *name_map = rdi_element_from_name_idx(ctx->rdi, NameMaps, RDI_NameMapKind_Procedures); - RDI_ParsedNameMap parsed_name_map = {0}; - rdi_parsed_from_name_map(ctx->rdi, name_map, &parsed_name_map); - RDI_NameMapNode *node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, token_string.str, token_string.size); - U32 matches_count = 0; - U32 *matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count); - for(String8Node *n = namespaceified_token_strings.first; - n != 0 && matches_count == 0; - n = n->next) - { - node = rdi_name_map_lookup(ctx->rdi, &parsed_name_map, n->string.str, n->string.size); - matches_count = 0; - matches = rdi_matches_from_map_node(ctx->rdi, node, &matches_count); - } - if(matches_count != 0) - { - U32 match_idx = matches[0]; - RDI_Procedure *procedure = rdi_element_from_name_idx(ctx->rdi, Procedures, match_idx); - RDI_Scope *scope = rdi_element_from_name_idx(ctx->rdi, Scopes, procedure->root_scope_idx); - U64 voff = *rdi_element_from_name_idx(ctx->rdi, ScopeVOffData, scope->voff_range_first); - EVAL_OpList oplist = {0}; - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ModuleOff, voff); - loc_kind = RDI_LocationKind_ValBytecodeStream; - loc_bytecode = eval_bytecode_from_oplist(arena, &oplist); - U32 type_idx = procedure->type_idx; - RDI_TypeNode *type_node = rdi_element_from_name_idx(ctx->rdi, TypeNodes, type_idx); - type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), (U64)type_idx); - mapped_identifier = 1; - } - } - - //- rjf: try types - if(mapped_identifier == 0) - { - type_key = eval_leaf_type_from_name(ctx->rdi, token_string); - if(!tg_key_match(tg_key_zero(), type_key)) - { - mapped_identifier = 1; - identifier_looks_like_type_expr = 1; - } - } - - //- rjf: attach on map - if(mapped_identifier != 0) - { - it += 1; - - // rjf: build atom - switch(loc_kind) - { - default: - { - if(identifier_looks_like_type_expr) - { - EVAL_TokenArray type_parse_tokens = eval_token_array_make_first_opl(it-1, it_opl); - EVAL_ParseResult type_parse = eval_parse_type_from_text_tokens(arena, ctx, text, &type_parse_tokens); - EVAL_Expr *type = type_parse.expr; - eval_error_list_concat_in_place(&result.errors, &type_parse.errors); - it = type_parse.last_token; - atom = type; - } - else if(reg_code != 0) - { - REGS_Rng reg_rng = regs_reg_code_rng_table_from_architecture(ctx->arch)[reg_code]; - EVAL_OpList oplist = {0}; - eval_oplist_push_uconst(arena, &oplist, reg_rng.byte_off); - atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Reg); - } - else if(alias_code != 0) - { - REGS_Slice alias_slice = regs_alias_code_slice_table_from_architecture(ctx->arch)[alias_code]; - REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_architecture(ctx->arch)[alias_slice.code]; - EVAL_OpList oplist = {0}; - eval_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off); - atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Reg); - } - else - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MissingInfo, token_string.str, "Missing location information for \"%S\".", token_string); - } - }break; - case RDI_LocationKind_AddrBytecodeStream: - { - atom = eval_expr_leaf_bytecode(arena, token_string.str, type_key, loc_bytecode, EVAL_EvalMode_Addr); - }break; - case RDI_LocationKind_ValBytecodeStream: - { - atom = eval_expr_leaf_bytecode(arena, token_string.str, type_key, loc_bytecode, EVAL_EvalMode_Value); - }break; - case RDI_LocationKind_AddrRegPlusU16: - { - EVAL_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(ctx->arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, regread_param); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, loc_reg_u16.offset); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, 0); - atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Addr); - }break; - case RDI_LocationKind_AddrAddrRegPlusU16: - { - EVAL_OpList oplist = {0}; - U64 byte_size = bit_size_from_arch(ctx->arch)/8; - U64 regread_param = RDI_EncodeRegReadParam(loc_reg_u16.reg_code, byte_size, 0); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, regread_param); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU16, loc_reg_u16.offset); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_Add, 0); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_MemRead, bit_size_from_arch(ctx->arch)/8); - atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Addr); - }break; - case RDI_LocationKind_ValReg: - { - REGS_RegCode regs_reg_code = regs_reg_code_from_arch_rdi_code(ctx->arch, loc_reg.reg_code); - REGS_Rng reg_rng = regs_reg_code_rng_table_from_architecture(ctx->arch)[regs_reg_code]; - EVAL_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); - eval_oplist_push_op(arena, &oplist, RDI_EvalOp_RegRead, regread_param); - atom = eval_expr_leaf_op_list(arena, token_string.str, type_key, &oplist, EVAL_EvalMode_Value); - }break; - } - - // rjf: implicit local lookup -> attach member access node - if(atom_implicit_member_name.size != 0) - { - EVAL_Expr *member_expr = eval_expr_leaf_member(arena, atom_implicit_member_name.str, atom_implicit_member_name); - atom = eval_expr(arena, EVAL_ExprKind_MemberAccess, atom_implicit_member_name.str, atom, member_expr, &eval_expr_nil); - } - } - - //- rjf: map failure -> attach as leaf identifier, to be resolved later - if(!mapped_identifier) - { - atom = eval_expr_leaf_ident(arena, token_string.str, token_string); - it += 1; - } - }break; - - //- rjf: numeric => directly extract value - case EVAL_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 = eval_expr_u64(arena, token_string.str, 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 = eval_expr_f32(arena, token_string.str, (F32)val); - } - - // rjf: no f => f64 - else - { - atom = eval_expr_f64(arena, token_string.str, val); - } - } - }break; - - //- rjf: char => extract char value - case EVAL_TokenKind_CharLiteral: - { - it += 1; - if(token_string.size > 1 && token_string.str[0] == '\'' && token_string.str[1] != '\'') - { - U8 char_val = token_string.str[1]; - atom = eval_expr_u64(arena, token_string.str, char_val); - } - else - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Malformed character literal."); - } - }break; - - // rjf: string => invalid - case EVAL_TokenKind_StringLiteral: - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "String literals are not supported."); - it += 1; - }break; - - } - } - } - - //- rjf: upgrade atom w/ postfix unaries - if(atom != &eval_expr_nil) for(;it < it_opl;) - { - EVAL_Token token = eval_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - B32 is_postfix_unary = 0; - - // rjf: dot/arrow operator - if(token.kind == EVAL_TokenKind_Symbol && - (str8_match(token_string, str8_lit("."), 0) || - str8_match(token_string, str8_lit("->"), 0))) - { - is_postfix_unary = 1; - - // rjf: advance past operator - it += 1; - - // rjf: expect member name - String8 member_name = {0}; - B32 good_member_name = 0; - { - EVAL_Token member_name_maybe = eval_token_at_it(it, tokens); - String8 member_name_maybe_string = str8_substr(text, member_name_maybe.range); - if(member_name_maybe.kind != EVAL_TokenKind_Identifier) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Expected member name after %S.", token_string); - } - else - { - member_name = member_name_maybe_string; - good_member_name = 1; - } - } - - // rjf: produce lookup member expr - if(good_member_name) - { - EVAL_Expr *member_expr = eval_expr_leaf_member(arena, member_name.str, member_name); - atom = eval_expr(arena, EVAL_ExprKind_MemberAccess, token_string.str, atom, member_expr, &eval_expr_nil); - } - - // rjf: increment past good member names - if(good_member_name) - { - it += 1; - } - } - - // rjf: array index - if(token.kind == EVAL_TokenKind_Symbol && - str8_match(token_string, str8_lit("["), 0)) - { - is_postfix_unary = 1; - - // rjf: advance past [ - it += 1; - - // rjf: parse indexing expression - EVAL_TokenArray idx_expr_parse_tokens = eval_token_array_make_first_opl(it, it_opl); - EVAL_ParseResult idx_expr_parse = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, &idx_expr_parse_tokens, eval_g_max_precedence); - eval_error_list_concat_in_place(&result.errors, &idx_expr_parse.errors); - it = idx_expr_parse.last_token; - - // rjf: valid indexing expression => produce index expr - if(idx_expr_parse.expr != &eval_expr_nil) - { - atom = eval_expr(arena, EVAL_ExprKind_ArrayIndex, token_string.str, atom, idx_expr_parse.expr, &eval_expr_nil); - } - - // rjf: expect ] - { - EVAL_Token close_brace_maybe = eval_token_at_it(it, tokens); - String8 close_brace_maybe_string = str8_substr(text, close_brace_maybe.range); - if(close_brace_maybe.kind != EVAL_TokenKind_Symbol || !str8_match(close_brace_maybe_string, str8_lit("]"), 0)) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Unclosed [."); - } - else - { - it += 1; - } - } - } - - // rjf: quit if this doesn't look like any patterns of postfix unary we know - if(!is_postfix_unary) - { - break; - } - } - - //- rjf: upgrade atom w/ previously parsed prefix unaries - if(atom == &eval_expr_nil && first_prefix_unary != 0 && first_prefix_unary->cast_expr != 0) - { - atom = first_prefix_unary->cast_expr; - for(PrefixUnaryNode *prefix_unary = first_prefix_unary->next; - prefix_unary != 0; - prefix_unary = prefix_unary->next) - { - atom = eval_expr(arena, prefix_unary->kind, prefix_unary->location, - prefix_unary->cast_expr != &eval_expr_nil ? prefix_unary->cast_expr : atom, - prefix_unary->cast_expr != &eval_expr_nil ? atom : &eval_expr_nil, - &eval_expr_nil); - } - } - else if(atom == 0 && first_prefix_unary != 0) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, last_prefix_unary->location, "Missing expression."); - } - else - { - for(PrefixUnaryNode *prefix_unary = first_prefix_unary; prefix_unary != 0; prefix_unary = prefix_unary->next) - { - atom = eval_expr(arena, prefix_unary->kind, prefix_unary->location, - prefix_unary->cast_expr != &eval_expr_nil ? prefix_unary->cast_expr : atom, - prefix_unary->cast_expr != &eval_expr_nil ? atom : &eval_expr_nil, - &eval_expr_nil); - } - } - - //- rjf: parse complex operators - if(atom != &eval_expr_nil) for(;it < it_opl;) - { - EVAL_Token *start_it = it; - EVAL_Token token = eval_token_at_it(it, tokens); - String8 token_string = str8_substr(text, token.range); - - //- rjf: parse binaries - { - // rjf: first try to find a matching binary operator - S64 binary_precedence = 0; - EVAL_ExprKind binary_kind = 0; - for(U64 idx = 0; idx < ArrayCount(eval_g_binary_op_table); idx += 1) - { - if(str8_match(token_string, eval_g_binary_op_table[idx].string, 0)) - { - binary_precedence = eval_g_binary_op_table[idx].precedence; - binary_kind = eval_g_binary_op_table[idx].kind; - break; - } - } - - // rjf: if we got a valid binary precedence, and it's not to be handled by - // a caller, then we need to parse the right-hand-side with a tighter - // precedence - if(binary_precedence != 0 && binary_precedence <= max_precedence) - { - EVAL_TokenArray rhs_expr_parse_tokens = eval_token_array_make_first_opl(it+1, it_opl); - EVAL_ParseResult rhs_expr_parse = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, &rhs_expr_parse_tokens, binary_precedence-1); - eval_error_list_concat_in_place(&result.errors, &rhs_expr_parse.errors); - EVAL_Expr *rhs = rhs_expr_parse.expr; - it = rhs_expr_parse.last_token; - if(rhs == &eval_expr_nil) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Missing right-hand-side of %S.", token_string); - } - else - { - atom = eval_expr(arena, binary_kind, token_string.str, atom, rhs, &eval_expr_nil); - } - } - } - - //- rjf: parse ternaries - { - if(token.kind == EVAL_TokenKind_Symbol && str8_match(token_string, str8_lit("?"), 0) && 13 <= max_precedence) - { - // rjf: parse middle expression - EVAL_TokenArray middle_expr_tokens = eval_token_array_make_first_opl(it, it_opl); - EVAL_ParseResult middle_expr_parse = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, &middle_expr_tokens, eval_g_max_precedence); - it = middle_expr_parse.last_token; - EVAL_Expr *middle_expr = middle_expr_parse.expr; - eval_error_list_concat_in_place(&result.errors, &middle_expr_parse.errors); - if(middle_expr_parse.expr == &eval_expr_nil) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Expected expression after ?."); - } - - // rjf: expect : - B32 got_colon = 0; - EVAL_Token colon_token = zero_struct; - String8 colon_token_string = {0}; - { - EVAL_Token colon_token_maybe = eval_token_at_it(it, tokens); - String8 colon_token_maybe_string = str8_substr(text, colon_token_maybe.range); - if(colon_token_maybe.kind != EVAL_TokenKind_Symbol || !str8_match(colon_token_maybe_string, str8_lit(":"), 0)) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, token_string.str, "Expected : after ?."); - } - else - { - got_colon = 1; - colon_token = colon_token_maybe; - colon_token_string = colon_token_maybe_string; - it += 1; - } - } - - // rjf: parse rhs - EVAL_TokenArray rhs_expr_parse_tokens = eval_token_array_make_first_opl(it, it_opl); - EVAL_ParseResult rhs_expr_parse = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, &rhs_expr_parse_tokens, eval_g_max_precedence); - if(got_colon) - { - it = rhs_expr_parse.last_token; - eval_error_list_concat_in_place(&result.errors, &rhs_expr_parse.errors); - if(rhs_expr_parse.expr == &eval_expr_nil) - { - eval_errorf(arena, &result.errors, EVAL_ErrorKind_MalformedInput, colon_token_string.str, "Expected expression after :."); - } - } - - // rjf: build ternary - atom = eval_expr(arena, EVAL_ExprKind_Ternary, token_string.str, atom, middle_expr_parse.expr, rhs_expr_parse.expr); - } - } - - // rjf: if we parsed nothing successfully, we're done - if(it == start_it) - { - break; - } - } - - //- rjf: fill result & return - result.last_token = it; - result.expr = atom; - scratch_end(scratch); - ProfEnd(); - return result; -} - -internal EVAL_ParseResult -eval_parse_expr_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens) -{ - EVAL_ParseResult result = eval_parse_expr_from_text_tokens__prec(arena, ctx, text, tokens, eval_g_max_precedence); - return result; -} diff --git a/src/eval/eval_parser.h b/src/eval/eval_parser.h deleted file mode 100644 index f2ed9167..00000000 --- a/src/eval/eval_parser.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_PARSER_H -#define EVAL_PARSER_H - -//////////////////////////////// -//~ rjf: Token Types - -typedef enum EVAL_TokenKind -{ - EVAL_TokenKind_Null, - EVAL_TokenKind_Identifier, - EVAL_TokenKind_Numeric, - EVAL_TokenKind_StringLiteral, - EVAL_TokenKind_CharLiteral, - EVAL_TokenKind_Symbol, - EVAL_TokenKind_COUNT -} -EVAL_TokenKind; - -typedef struct EVAL_Token EVAL_Token; -struct EVAL_Token -{ - EVAL_TokenKind kind; - Rng1U64 range; -}; - -typedef struct EVAL_TokenChunkNode EVAL_TokenChunkNode; -struct EVAL_TokenChunkNode -{ - EVAL_TokenChunkNode *next; - EVAL_Token *v; - U64 count; - U64 cap; -}; - -typedef struct EVAL_TokenChunkList EVAL_TokenChunkList; -struct EVAL_TokenChunkList -{ - EVAL_TokenChunkNode *first; - EVAL_TokenChunkNode *last; - U64 node_count; - U64 total_count; -}; - -typedef struct EVAL_TokenArray EVAL_TokenArray; -struct EVAL_TokenArray -{ - EVAL_Token *v; - U64 count; -}; - -//////////////////////////////// -//~ rjf: Parser Types - -typedef struct EVAL_ParseResult EVAL_ParseResult; -struct EVAL_ParseResult -{ - EVAL_Token *last_token; - EVAL_Expr *expr; - EVAL_ErrorList errors; -}; - -typedef struct EVAL_ParseCtx EVAL_ParseCtx; -struct EVAL_ParseCtx -{ - Architecture arch; - U64 ip_voff; - RDI_Parsed *rdi; - TG_Graph *type_graph; - EVAL_String2NumMap *regs_map; - EVAL_String2NumMap *reg_alias_map; - EVAL_String2NumMap *locals_map; - EVAL_String2NumMap *member_map; -}; - -//////////////////////////////// -//~ rjf: Globals - -read_only global EVAL_String2NumMap eval_string2num_map_nil = {0}; -read_only global EVAL_String2ExprMap eval_string2expr_map_nil = {0}; -global read_only EVAL_ParseResult eval_parse_result_nil = {0, &eval_expr_nil}; - -//////////////////////////////// -//~ rjf: Debug-Info-Driven Map Building Fast Paths - -internal EVAL_String2NumMap *eval_push_locals_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); -internal EVAL_String2NumMap *eval_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); - -//////////////////////////////// -//~ rjf: Tokenization Functions - -#define eval_token_at_it(it, arr) (((it) < (arr)->v+(arr)->count) ? (*(it)) : eval_token_zero()) -internal EVAL_Token eval_token_zero(void); -internal void eval_token_chunk_list_push(Arena *arena, EVAL_TokenChunkList *list, U64 chunk_size, EVAL_Token *token); -internal EVAL_TokenArray eval_token_array_from_chunk_list(Arena *arena, EVAL_TokenChunkList *list); -internal EVAL_TokenArray eval_token_array_from_text(Arena *arena, String8 text); -internal EVAL_TokenArray eval_token_array_make_first_opl(EVAL_Token *first, EVAL_Token *opl); - -//////////////////////////////// -//~ rjf: Parser Functions - -internal TG_Key eval_leaf_type_from_name(RDI_Parsed *rdi, String8 name); -internal EVAL_ParseResult eval_parse_type_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens); -internal EVAL_ParseResult eval_parse_expr_from_text_tokens__prec(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens, S64 max_precedence); -internal EVAL_ParseResult eval_parse_expr_from_text_tokens(Arena *arena, EVAL_ParseCtx *ctx, String8 text, EVAL_TokenArray *tokens); - -#endif // EVAL_PARSER_H diff --git a/src/eval/generated/eval.meta.c b/src/eval/generated/eval.meta.c index faaad5f7..d80be985 100644 --- a/src/eval/generated/eval.meta.c +++ b/src/eval/generated/eval.meta.c @@ -4,51 +4,7 @@ //- GENERATED CODE C_LINKAGE_BEGIN -U8 eval_expr_kind_child_counts[40] = -{ -0, -2, -2, -1, -1, -2, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -3, -0, -0, -0, -0, -0, -0, -1, -2, -1, -2, -0, -}; - -String8 eval_expr_kind_strings[40] = +String8 e_expr_kind_strings[41] = { str8_lit_comp("Nil"), str8_lit_comp("ArrayIndex"), @@ -81,6 +37,7 @@ str8_lit_comp("LogOr"), str8_lit_comp("Ternary"), str8_lit_comp("LeafBytecode"), str8_lit_comp("LeafMember"), +str8_lit_comp("LeafStringLiteral"), str8_lit_comp("LeafU64"), str8_lit_comp("LeafF64"), str8_lit_comp("LeafF32"), @@ -92,7 +49,7 @@ str8_lit_comp("Define"), str8_lit_comp("LeafIdent"), }; -String8 eval_result_code_display_strings[11] = +String8 e_interpretation_code_display_strings[11] = { str8_lit_comp(""), str8_lit_comp("Cannot divide by zero."), @@ -107,7 +64,7 @@ str8_lit_comp("Insufficient evaluation machine stack space."), str8_lit_comp("Malformed bytecode."), }; -String8 eval_expr_op_strings[40] = +String8 e_expr_op_strings[41] = { str8_lit_comp(""), str8_lit_comp("[]"), @@ -140,6 +97,7 @@ str8_lit_comp("||"), str8_lit_comp("? "), str8_lit_comp("bytecode"), str8_lit_comp("member"), +str8_lit_comp("string_literal"), str8_lit_comp("U64"), str8_lit_comp("F64"), str8_lit_comp("F32"), @@ -151,5 +109,121 @@ str8_lit_comp("="), str8_lit_comp("leaf_ident"), }; +U8 e_kind_basic_byte_size_table[54] = +{ +0, +0, +0xFF, +1, +2, +4, +1, +2, +4, +1, +2, +4, +8, +16, +32, +64, +1, +2, +4, +8, +16, +32, +64, +1, +2, +4, +4, +6, +8, +10, +16, +8, +16, +20, +32, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +0, +}; + +String8 e_kind_basic_string_table[54] = +{ +str8_lit_comp(""), +str8_lit_comp("void"), +str8_lit_comp("HANDLE"), +str8_lit_comp("char8"), +str8_lit_comp("char16"), +str8_lit_comp("char32"), +str8_lit_comp("uchar8"), +str8_lit_comp("uchar16"), +str8_lit_comp("uchar32"), +str8_lit_comp("U8"), +str8_lit_comp("U16"), +str8_lit_comp("U32"), +str8_lit_comp("U64"), +str8_lit_comp("U128"), +str8_lit_comp("U256"), +str8_lit_comp("U512"), +str8_lit_comp("S8"), +str8_lit_comp("S16"), +str8_lit_comp("S32"), +str8_lit_comp("S64"), +str8_lit_comp("S128"), +str8_lit_comp("S256"), +str8_lit_comp("S512"), +str8_lit_comp("bool"), +str8_lit_comp("F16"), +str8_lit_comp("F32"), +str8_lit_comp("F32PP"), +str8_lit_comp("F48"), +str8_lit_comp("F64"), +str8_lit_comp("F80"), +str8_lit_comp("F128"), +str8_lit_comp("ComplexF32"), +str8_lit_comp("ComplexF64"), +str8_lit_comp("ComplexF80"), +str8_lit_comp("ComplexF128"), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp(""), +str8_lit_comp("struct"), +str8_lit_comp("class"), +str8_lit_comp("union"), +str8_lit_comp("enum"), +str8_lit_comp("typedef"), +str8_lit_comp("struct"), +str8_lit_comp("union"), +str8_lit_comp("class"), +str8_lit_comp("enum"), +str8_lit_comp(""), +str8_lit_comp(""), +}; + C_LINKAGE_END diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 21d545d6..5ed8f26c 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -6,73 +6,144 @@ #ifndef EVAL_META_H #define EVAL_META_H -typedef U32 EVAL_ExprKind; -typedef enum EVAL_ExprKindEnum +typedef enum E_TypeKind { -EVAL_ExprKind_Nil, -EVAL_ExprKind_ArrayIndex, -EVAL_ExprKind_MemberAccess, -EVAL_ExprKind_Deref, -EVAL_ExprKind_Address, -EVAL_ExprKind_Cast, -EVAL_ExprKind_Sizeof, -EVAL_ExprKind_Neg, -EVAL_ExprKind_LogNot, -EVAL_ExprKind_BitNot, -EVAL_ExprKind_Mul, -EVAL_ExprKind_Div, -EVAL_ExprKind_Mod, -EVAL_ExprKind_Add, -EVAL_ExprKind_Sub, -EVAL_ExprKind_LShift, -EVAL_ExprKind_RShift, -EVAL_ExprKind_Less, -EVAL_ExprKind_LsEq, -EVAL_ExprKind_Grtr, -EVAL_ExprKind_GrEq, -EVAL_ExprKind_EqEq, -EVAL_ExprKind_NtEq, -EVAL_ExprKind_BitAnd, -EVAL_ExprKind_BitXor, -EVAL_ExprKind_BitOr, -EVAL_ExprKind_LogAnd, -EVAL_ExprKind_LogOr, -EVAL_ExprKind_Ternary, -EVAL_ExprKind_LeafBytecode, -EVAL_ExprKind_LeafMember, -EVAL_ExprKind_LeafU64, -EVAL_ExprKind_LeafF64, -EVAL_ExprKind_LeafF32, -EVAL_ExprKind_TypeIdent, -EVAL_ExprKind_Ptr, -EVAL_ExprKind_Array, -EVAL_ExprKind_Func, -EVAL_ExprKind_Define, -EVAL_ExprKind_LeafIdent, -EVAL_ExprKind_COUNT, -} EVAL_ExprKindEnum; +E_TypeKind_Null, +E_TypeKind_Void, +E_TypeKind_Handle, +E_TypeKind_Char8, +E_TypeKind_Char16, +E_TypeKind_Char32, +E_TypeKind_UChar8, +E_TypeKind_UChar16, +E_TypeKind_UChar32, +E_TypeKind_U8, +E_TypeKind_U16, +E_TypeKind_U32, +E_TypeKind_U64, +E_TypeKind_U128, +E_TypeKind_U256, +E_TypeKind_U512, +E_TypeKind_S8, +E_TypeKind_S16, +E_TypeKind_S32, +E_TypeKind_S64, +E_TypeKind_S128, +E_TypeKind_S256, +E_TypeKind_S512, +E_TypeKind_Bool, +E_TypeKind_F16, +E_TypeKind_F32, +E_TypeKind_F32PP, +E_TypeKind_F48, +E_TypeKind_F64, +E_TypeKind_F80, +E_TypeKind_F128, +E_TypeKind_ComplexF32, +E_TypeKind_ComplexF64, +E_TypeKind_ComplexF80, +E_TypeKind_ComplexF128, +E_TypeKind_Modifier, +E_TypeKind_Ptr, +E_TypeKind_LRef, +E_TypeKind_RRef, +E_TypeKind_Array, +E_TypeKind_Function, +E_TypeKind_Method, +E_TypeKind_MemberPtr, +E_TypeKind_Struct, +E_TypeKind_Class, +E_TypeKind_Union, +E_TypeKind_Enum, +E_TypeKind_Alias, +E_TypeKind_IncompleteStruct, +E_TypeKind_IncompleteUnion, +E_TypeKind_IncompleteClass, +E_TypeKind_IncompleteEnum, +E_TypeKind_Bitfield, +E_TypeKind_Variadic, +E_TypeKind_COUNT, +E_TypeKind_FirstBasic = E_TypeKind_Void, +E_TypeKind_LastBasic = E_TypeKind_ComplexF128, +E_TypeKind_FirstInteger = E_TypeKind_Char8, +E_TypeKind_LastInteger = E_TypeKind_S512, +E_TypeKind_FirstSigned1 = E_TypeKind_Char8, +E_TypeKind_LastSigned1 = E_TypeKind_Char32, +E_TypeKind_FirstSigned2 = E_TypeKind_S8, +E_TypeKind_LastSigned2 = E_TypeKind_S512, +E_TypeKind_FirstIncomplete = E_TypeKind_IncompleteStruct, +E_TypeKind_LastIncomplete = E_TypeKind_IncompleteEnum, +} E_TypeKind; -typedef enum EVAL_ResultCode +typedef U32 E_ExprKind; +typedef enum E_ExprKindEnum { -EVAL_ResultCode_Good, -EVAL_ResultCode_DivideByZero, -EVAL_ResultCode_BadOp, -EVAL_ResultCode_BadOpTypes, -EVAL_ResultCode_BadMemRead, -EVAL_ResultCode_BadRegRead, -EVAL_ResultCode_BadFrameBase, -EVAL_ResultCode_BadModuleBase, -EVAL_ResultCode_BadTLSBase, -EVAL_ResultCode_InsufficientStackSpace, -EVAL_ResultCode_MalformedBytecode, -EVAL_ResultCode_COUNT, -} EVAL_ResultCode; +E_ExprKind_Nil, +E_ExprKind_ArrayIndex, +E_ExprKind_MemberAccess, +E_ExprKind_Deref, +E_ExprKind_Address, +E_ExprKind_Cast, +E_ExprKind_Sizeof, +E_ExprKind_Neg, +E_ExprKind_LogNot, +E_ExprKind_BitNot, +E_ExprKind_Mul, +E_ExprKind_Div, +E_ExprKind_Mod, +E_ExprKind_Add, +E_ExprKind_Sub, +E_ExprKind_LShift, +E_ExprKind_RShift, +E_ExprKind_Less, +E_ExprKind_LsEq, +E_ExprKind_Grtr, +E_ExprKind_GrEq, +E_ExprKind_EqEq, +E_ExprKind_NtEq, +E_ExprKind_BitAnd, +E_ExprKind_BitXor, +E_ExprKind_BitOr, +E_ExprKind_LogAnd, +E_ExprKind_LogOr, +E_ExprKind_Ternary, +E_ExprKind_LeafBytecode, +E_ExprKind_LeafMember, +E_ExprKind_LeafStringLiteral, +E_ExprKind_LeafU64, +E_ExprKind_LeafF64, +E_ExprKind_LeafF32, +E_ExprKind_TypeIdent, +E_ExprKind_Ptr, +E_ExprKind_Array, +E_ExprKind_Func, +E_ExprKind_Define, +E_ExprKind_LeafIdent, +E_ExprKind_COUNT, +} E_ExprKindEnum; + +typedef enum E_InterpretationCode +{ +E_InterpretationCode_Good, +E_InterpretationCode_DivideByZero, +E_InterpretationCode_BadOp, +E_InterpretationCode_BadOpTypes, +E_InterpretationCode_BadMemRead, +E_InterpretationCode_BadRegRead, +E_InterpretationCode_BadFrameBase, +E_InterpretationCode_BadModuleBase, +E_InterpretationCode_BadTLSBase, +E_InterpretationCode_InsufficientStackSpace, +E_InterpretationCode_MalformedBytecode, +E_InterpretationCode_COUNT, +} E_InterpretationCode; C_LINKAGE_BEGIN -extern U8 eval_expr_kind_child_counts[40]; -extern String8 eval_expr_kind_strings[40]; -extern String8 eval_result_code_display_strings[11]; -extern String8 eval_expr_op_strings[40]; +extern String8 e_expr_kind_strings[41]; +extern String8 e_interpretation_code_display_strings[11]; +extern String8 e_expr_op_strings[41]; +extern U8 e_kind_basic_byte_size_table[54]; +extern String8 e_kind_basic_string_table[54]; C_LINKAGE_END diff --git a/src/eval2/eval2.mdesk b/src/eval2/eval2.mdesk deleted file mode 100644 index d451f065..00000000 --- a/src/eval2/eval2.mdesk +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -@table(name basic_string basic_byte_size) -// NOTE(rjf): basic_byte_size == 0xFF? => address sized -E_TypeKindTable: -{ - {Null "" 0 } - {Void "void" 0 } - {Handle "HANDLE" 0xFF } - {Char8 "char8" 1 } - {Char16 "char16" 2 } - {Char32 "char32" 4 } - {UChar8 "uchar8" 1 } - {UChar16 "uchar16" 2 } - {UChar32 "uchar32" 4 } - {U8 "U8" 1 } - {U16 "U16" 2 } - {U32 "U32" 4 } - {U64 "U64" 8 } - {U128 "U128" 16 } - {U256 "U256" 32 } - {U512 "U512" 64 } - {S8 "S8" 1 } - {S16 "S16" 2 } - {S32 "S32" 4 } - {S64 "S64" 8 } - {S128 "S128" 16 } - {S256 "S256" 32 } - {S512 "S512" 64 } - {Bool "bool" 1 } - {F16 "F16" 2 } - {F32 "F32" 4 } - {F32PP "F32PP" 4 } - {F48 "F48" 6 } - {F64 "F64" 8 } - {F80 "F80" 10 } - {F128 "F128" 16 } - {ComplexF32 "ComplexF32" 8 } - {ComplexF64 "ComplexF64" 16 } - {ComplexF80 "ComplexF80" 20 } - {ComplexF128 "ComplexF128" 32 } - {Modifier "" 0 } - {Ptr "" 0 } - {LRef "" 0 } - {RRef "" 0 } - {Array "" 0 } - {Function "" 0 } - {Method "" 0 } - {MemberPtr "" 0 } - {Struct "struct" 0 } - {Class "class" 0 } - {Union "union" 0 } - {Enum "enum" 0 } - {Alias "typedef" 0 } - {IncompleteStruct "struct" 0 } - {IncompleteUnion "union" 0 } - {IncompleteClass "class" 0 } - {IncompleteEnum "enum" 0 } - {Bitfield "" 0 } - {Variadic "" 0 } -} - -@table(name op_string) -E_ExprKindTable: -{ - { Nil "" } - - { ArrayIndex "[]" } - { MemberAccess "." } - { Deref "*" } - { Address "&" } - - { Cast "cast" } - { Sizeof "sizeof" } - - { Neg "-" } - { LogNot "!" } - { BitNot "~" } - { Mul "*" } - { Div "/" } - { Mod "%" } - { Add "+" } - { Sub "-" } - { LShift "<<" } - { RShift ">>" } - { Less "<" } - { LsEq "<=" } - { Grtr ">" } - { GrEq ">=" } - { EqEq "==" } - { NtEq "!=" } - - { BitAnd "&" } - { BitXor "^" } - { BitOr "|" } - { LogAnd "&&" } - { LogOr "||" } - - { Ternary "? " } - - { LeafBytecode "bytecode" } - { LeafMember "member" } - { LeafStringLiteral "string_literal" } - { LeafU64 "U64" } - { LeafF64 "F64" } - { LeafF32 "F32" } - - { TypeIdent "type_ident" } - { Ptr "ptr" } - { Array "array" } - { Func "function" } - - { Define "=" } - { LeafIdent "leaf_ident" } -} - -@table(name display_string) -E_InterpretationCodeTable: -{ - { Good "" } - { DivideByZero "Cannot divide by zero." } - { BadOp "Invalid operation." } - { BadOpTypes "Invalid operation types." } - { BadMemRead "Failed memory read." } - { BadRegRead "Failed register read." } - { BadFrameBase "Invalid frame base address." } - { BadModuleBase "Invalid module base address." } - { BadTLSBase "Invalid thread-local storage base address." } - { InsufficientStackSpace "Insufficient evaluation machine stack space." } - { MalformedBytecode "Malformed bytecode." } -} - -@enum E_TypeKind: -{ - @expand(E_TypeKindTable a) `$(a.name)`, - COUNT, - `FirstBasic = E_TypeKind_Void`, - `LastBasic = E_TypeKind_ComplexF128`, - `FirstInteger = E_TypeKind_Char8`, - `LastInteger = E_TypeKind_S512`, - `FirstSigned1 = E_TypeKind_Char8`, - `LastSigned1 = E_TypeKind_Char32`, - `FirstSigned2 = E_TypeKind_S8`, - `LastSigned2 = E_TypeKind_S512`, - `FirstIncomplete = E_TypeKind_IncompleteStruct`, - `LastIncomplete = E_TypeKind_IncompleteEnum`, -} - -@enum(U32) E_ExprKind: -{ - @expand(E_ExprKindTable a) `$(a.name)`, - COUNT, -} - -@enum E_InterpretationCode: -{ - @expand(E_InterpretationCodeTable a) `$(a.name)`, - COUNT, -} - -@data(String8) -e_expr_kind_strings: -{ - @expand(E_ExprKindTable a) `str8_lit_comp("$(a.name)")` -} - -@data(String8) e_interpretation_code_display_strings: -{ - @expand(E_InterpretationCodeTable a) `str8_lit_comp("$(a.display_string)")` -} - -@data(String8) e_expr_op_strings: -{ - @expand(E_ExprKindTable a) `str8_lit_comp("$(a.op_string)")` -} - -@data(U8) e_kind_basic_byte_size_table: -{ - @expand(E_TypeKindTable a) `$(a.basic_byte_size)`; -} - -@data(String8) e_kind_basic_string_table: -{ - @expand(E_TypeKindTable a) `str8_lit_comp("$(a.basic_string)")`; -} diff --git a/src/eval2/generated/eval2.meta.c b/src/eval2/generated/eval2.meta.c deleted file mode 100644 index d80be985..00000000 --- a/src/eval2/generated/eval2.meta.c +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - -C_LINKAGE_BEGIN -String8 e_expr_kind_strings[41] = -{ -str8_lit_comp("Nil"), -str8_lit_comp("ArrayIndex"), -str8_lit_comp("MemberAccess"), -str8_lit_comp("Deref"), -str8_lit_comp("Address"), -str8_lit_comp("Cast"), -str8_lit_comp("Sizeof"), -str8_lit_comp("Neg"), -str8_lit_comp("LogNot"), -str8_lit_comp("BitNot"), -str8_lit_comp("Mul"), -str8_lit_comp("Div"), -str8_lit_comp("Mod"), -str8_lit_comp("Add"), -str8_lit_comp("Sub"), -str8_lit_comp("LShift"), -str8_lit_comp("RShift"), -str8_lit_comp("Less"), -str8_lit_comp("LsEq"), -str8_lit_comp("Grtr"), -str8_lit_comp("GrEq"), -str8_lit_comp("EqEq"), -str8_lit_comp("NtEq"), -str8_lit_comp("BitAnd"), -str8_lit_comp("BitXor"), -str8_lit_comp("BitOr"), -str8_lit_comp("LogAnd"), -str8_lit_comp("LogOr"), -str8_lit_comp("Ternary"), -str8_lit_comp("LeafBytecode"), -str8_lit_comp("LeafMember"), -str8_lit_comp("LeafStringLiteral"), -str8_lit_comp("LeafU64"), -str8_lit_comp("LeafF64"), -str8_lit_comp("LeafF32"), -str8_lit_comp("TypeIdent"), -str8_lit_comp("Ptr"), -str8_lit_comp("Array"), -str8_lit_comp("Func"), -str8_lit_comp("Define"), -str8_lit_comp("LeafIdent"), -}; - -String8 e_interpretation_code_display_strings[11] = -{ -str8_lit_comp(""), -str8_lit_comp("Cannot divide by zero."), -str8_lit_comp("Invalid operation."), -str8_lit_comp("Invalid operation types."), -str8_lit_comp("Failed memory read."), -str8_lit_comp("Failed register read."), -str8_lit_comp("Invalid frame base address."), -str8_lit_comp("Invalid module base address."), -str8_lit_comp("Invalid thread-local storage base address."), -str8_lit_comp("Insufficient evaluation machine stack space."), -str8_lit_comp("Malformed bytecode."), -}; - -String8 e_expr_op_strings[41] = -{ -str8_lit_comp(""), -str8_lit_comp("[]"), -str8_lit_comp("."), -str8_lit_comp("*"), -str8_lit_comp("&"), -str8_lit_comp("cast"), -str8_lit_comp("sizeof"), -str8_lit_comp("-"), -str8_lit_comp("!"), -str8_lit_comp("~"), -str8_lit_comp("*"), -str8_lit_comp("/"), -str8_lit_comp("%"), -str8_lit_comp("+"), -str8_lit_comp("-"), -str8_lit_comp("<<"), -str8_lit_comp(">>"), -str8_lit_comp("<"), -str8_lit_comp("<="), -str8_lit_comp(">"), -str8_lit_comp(">="), -str8_lit_comp("=="), -str8_lit_comp("!="), -str8_lit_comp("&"), -str8_lit_comp("^"), -str8_lit_comp("|"), -str8_lit_comp("&&"), -str8_lit_comp("||"), -str8_lit_comp("? "), -str8_lit_comp("bytecode"), -str8_lit_comp("member"), -str8_lit_comp("string_literal"), -str8_lit_comp("U64"), -str8_lit_comp("F64"), -str8_lit_comp("F32"), -str8_lit_comp("type_ident"), -str8_lit_comp("ptr"), -str8_lit_comp("array"), -str8_lit_comp("function"), -str8_lit_comp("="), -str8_lit_comp("leaf_ident"), -}; - -U8 e_kind_basic_byte_size_table[54] = -{ -0, -0, -0xFF, -1, -2, -4, -1, -2, -4, -1, -2, -4, -8, -16, -32, -64, -1, -2, -4, -8, -16, -32, -64, -1, -2, -4, -4, -6, -8, -10, -16, -8, -16, -20, -32, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -}; - -String8 e_kind_basic_string_table[54] = -{ -str8_lit_comp(""), -str8_lit_comp("void"), -str8_lit_comp("HANDLE"), -str8_lit_comp("char8"), -str8_lit_comp("char16"), -str8_lit_comp("char32"), -str8_lit_comp("uchar8"), -str8_lit_comp("uchar16"), -str8_lit_comp("uchar32"), -str8_lit_comp("U8"), -str8_lit_comp("U16"), -str8_lit_comp("U32"), -str8_lit_comp("U64"), -str8_lit_comp("U128"), -str8_lit_comp("U256"), -str8_lit_comp("U512"), -str8_lit_comp("S8"), -str8_lit_comp("S16"), -str8_lit_comp("S32"), -str8_lit_comp("S64"), -str8_lit_comp("S128"), -str8_lit_comp("S256"), -str8_lit_comp("S512"), -str8_lit_comp("bool"), -str8_lit_comp("F16"), -str8_lit_comp("F32"), -str8_lit_comp("F32PP"), -str8_lit_comp("F48"), -str8_lit_comp("F64"), -str8_lit_comp("F80"), -str8_lit_comp("F128"), -str8_lit_comp("ComplexF32"), -str8_lit_comp("ComplexF64"), -str8_lit_comp("ComplexF80"), -str8_lit_comp("ComplexF128"), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp("struct"), -str8_lit_comp("class"), -str8_lit_comp("union"), -str8_lit_comp("enum"), -str8_lit_comp("typedef"), -str8_lit_comp("struct"), -str8_lit_comp("union"), -str8_lit_comp("class"), -str8_lit_comp("enum"), -str8_lit_comp(""), -str8_lit_comp(""), -}; - -C_LINKAGE_END - diff --git a/src/eval2/generated/eval2.meta.h b/src/eval2/generated/eval2.meta.h deleted file mode 100644 index 161936bb..00000000 --- a/src/eval2/generated/eval2.meta.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - -#ifndef EVAL2_META_H -#define EVAL2_META_H - -typedef enum E_TypeKind -{ -E_TypeKind_Null, -E_TypeKind_Void, -E_TypeKind_Handle, -E_TypeKind_Char8, -E_TypeKind_Char16, -E_TypeKind_Char32, -E_TypeKind_UChar8, -E_TypeKind_UChar16, -E_TypeKind_UChar32, -E_TypeKind_U8, -E_TypeKind_U16, -E_TypeKind_U32, -E_TypeKind_U64, -E_TypeKind_U128, -E_TypeKind_U256, -E_TypeKind_U512, -E_TypeKind_S8, -E_TypeKind_S16, -E_TypeKind_S32, -E_TypeKind_S64, -E_TypeKind_S128, -E_TypeKind_S256, -E_TypeKind_S512, -E_TypeKind_Bool, -E_TypeKind_F16, -E_TypeKind_F32, -E_TypeKind_F32PP, -E_TypeKind_F48, -E_TypeKind_F64, -E_TypeKind_F80, -E_TypeKind_F128, -E_TypeKind_ComplexF32, -E_TypeKind_ComplexF64, -E_TypeKind_ComplexF80, -E_TypeKind_ComplexF128, -E_TypeKind_Modifier, -E_TypeKind_Ptr, -E_TypeKind_LRef, -E_TypeKind_RRef, -E_TypeKind_Array, -E_TypeKind_Function, -E_TypeKind_Method, -E_TypeKind_MemberPtr, -E_TypeKind_Struct, -E_TypeKind_Class, -E_TypeKind_Union, -E_TypeKind_Enum, -E_TypeKind_Alias, -E_TypeKind_IncompleteStruct, -E_TypeKind_IncompleteUnion, -E_TypeKind_IncompleteClass, -E_TypeKind_IncompleteEnum, -E_TypeKind_Bitfield, -E_TypeKind_Variadic, -E_TypeKind_COUNT, -E_TypeKind_FirstBasic = E_TypeKind_Void, -E_TypeKind_LastBasic = E_TypeKind_ComplexF128, -E_TypeKind_FirstInteger = E_TypeKind_Char8, -E_TypeKind_LastInteger = E_TypeKind_S512, -E_TypeKind_FirstSigned1 = E_TypeKind_Char8, -E_TypeKind_LastSigned1 = E_TypeKind_Char32, -E_TypeKind_FirstSigned2 = E_TypeKind_S8, -E_TypeKind_LastSigned2 = E_TypeKind_S512, -E_TypeKind_FirstIncomplete = E_TypeKind_IncompleteStruct, -E_TypeKind_LastIncomplete = E_TypeKind_IncompleteEnum, -} E_TypeKind; - -typedef U32 E_ExprKind; -typedef enum E_ExprKindEnum -{ -E_ExprKind_Nil, -E_ExprKind_ArrayIndex, -E_ExprKind_MemberAccess, -E_ExprKind_Deref, -E_ExprKind_Address, -E_ExprKind_Cast, -E_ExprKind_Sizeof, -E_ExprKind_Neg, -E_ExprKind_LogNot, -E_ExprKind_BitNot, -E_ExprKind_Mul, -E_ExprKind_Div, -E_ExprKind_Mod, -E_ExprKind_Add, -E_ExprKind_Sub, -E_ExprKind_LShift, -E_ExprKind_RShift, -E_ExprKind_Less, -E_ExprKind_LsEq, -E_ExprKind_Grtr, -E_ExprKind_GrEq, -E_ExprKind_EqEq, -E_ExprKind_NtEq, -E_ExprKind_BitAnd, -E_ExprKind_BitXor, -E_ExprKind_BitOr, -E_ExprKind_LogAnd, -E_ExprKind_LogOr, -E_ExprKind_Ternary, -E_ExprKind_LeafBytecode, -E_ExprKind_LeafMember, -E_ExprKind_LeafStringLiteral, -E_ExprKind_LeafU64, -E_ExprKind_LeafF64, -E_ExprKind_LeafF32, -E_ExprKind_TypeIdent, -E_ExprKind_Ptr, -E_ExprKind_Array, -E_ExprKind_Func, -E_ExprKind_Define, -E_ExprKind_LeafIdent, -E_ExprKind_COUNT, -} E_ExprKindEnum; - -typedef enum E_InterpretationCode -{ -E_InterpretationCode_Good, -E_InterpretationCode_DivideByZero, -E_InterpretationCode_BadOp, -E_InterpretationCode_BadOpTypes, -E_InterpretationCode_BadMemRead, -E_InterpretationCode_BadRegRead, -E_InterpretationCode_BadFrameBase, -E_InterpretationCode_BadModuleBase, -E_InterpretationCode_BadTLSBase, -E_InterpretationCode_InsufficientStackSpace, -E_InterpretationCode_MalformedBytecode, -E_InterpretationCode_COUNT, -} E_InterpretationCode; - -C_LINKAGE_BEGIN -extern String8 e_expr_kind_strings[41]; -extern String8 e_interpretation_code_display_strings[11]; -extern String8 e_expr_op_strings[41]; -extern U8 e_kind_basic_byte_size_table[54]; -extern String8 e_kind_basic_string_table[54]; - -C_LINKAGE_END - -#endif // EVAL2_META_H diff --git a/src/raddbg/raddbg_main.c b/src/raddbg/raddbg_main.c index 2675bafd..a82cdd92 100644 --- a/src/raddbg/raddbg_main.c +++ b/src/raddbg/raddbg_main.c @@ -50,13 +50,11 @@ #include "rdi_from_pdb/rdi_from_pdb.h" #include "regs/regs.h" #include "regs/rdi/regs_rdi.h" -//#include "type_graph/type_graph.h" #include "dbgi/dbgi.h" #include "dasm_cache/dasm_cache.h" #include "fuzzy_search/fuzzy_search.h" #include "demon/demon_inc.h" -//#include "eval/eval_inc.h" -#include "eval2/eval2.h" +#include "eval/eval.h" #include "ctrl/ctrl_inc.h" #include "font_provider/font_provider_inc.h" #include "render/render_inc.h" @@ -91,13 +89,11 @@ #include "rdi_from_pdb/rdi_from_pdb.c" #include "regs/regs.c" #include "regs/rdi/regs_rdi.c" -//#include "type_graph/type_graph.c" #include "dbgi/dbgi.c" #include "dasm_cache/dasm_cache.c" #include "fuzzy_search/fuzzy_search.c" #include "demon/demon_inc.c" -//#include "eval/eval_inc.c" -#include "eval2/eval2.c" +#include "eval/eval.c" #include "ctrl/ctrl_inc.c" #include "font_provider/font_provider_inc.c" #include "render/render_inc.c" diff --git a/src/type_graph/generated/type_graph.meta.c b/src/type_graph/generated/type_graph.meta.c deleted file mode 100644 index 28920951..00000000 --- a/src/type_graph/generated/type_graph.meta.c +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - -C_LINKAGE_BEGIN -U8 tg_kind_basic_byte_size_table[54] = -{ -0, -0, -0xFF, -1, -2, -4, -1, -2, -4, -1, -2, -4, -8, -16, -32, -64, -1, -2, -4, -8, -16, -32, -64, -1, -2, -4, -4, -6, -8, -10, -16, -8, -16, -20, -32, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -}; - -String8 tg_kind_basic_string_table[54] = -{ -str8_lit_comp(""), -str8_lit_comp("void"), -str8_lit_comp("HANDLE"), -str8_lit_comp("char8"), -str8_lit_comp("char16"), -str8_lit_comp("char32"), -str8_lit_comp("uchar8"), -str8_lit_comp("uchar16"), -str8_lit_comp("uchar32"), -str8_lit_comp("U8"), -str8_lit_comp("U16"), -str8_lit_comp("U32"), -str8_lit_comp("U64"), -str8_lit_comp("U128"), -str8_lit_comp("U256"), -str8_lit_comp("U512"), -str8_lit_comp("S8"), -str8_lit_comp("S16"), -str8_lit_comp("S32"), -str8_lit_comp("S64"), -str8_lit_comp("S128"), -str8_lit_comp("S256"), -str8_lit_comp("S512"), -str8_lit_comp("bool"), -str8_lit_comp("F16"), -str8_lit_comp("F32"), -str8_lit_comp("F32PP"), -str8_lit_comp("F48"), -str8_lit_comp("F64"), -str8_lit_comp("F80"), -str8_lit_comp("F128"), -str8_lit_comp("ComplexF32"), -str8_lit_comp("ComplexF64"), -str8_lit_comp("ComplexF80"), -str8_lit_comp("ComplexF128"), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp(""), -str8_lit_comp("struct"), -str8_lit_comp("class"), -str8_lit_comp("union"), -str8_lit_comp("enum"), -str8_lit_comp("typedef"), -str8_lit_comp("struct"), -str8_lit_comp("union"), -str8_lit_comp("class"), -str8_lit_comp("enum"), -str8_lit_comp(""), -str8_lit_comp(""), -}; - -C_LINKAGE_END - diff --git a/src/type_graph/generated/type_graph.meta.h b/src/type_graph/generated/type_graph.meta.h deleted file mode 100644 index b5676da1..00000000 --- a/src/type_graph/generated/type_graph.meta.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//- GENERATED CODE - -#ifndef TYPE_GRAPH_META_H -#define TYPE_GRAPH_META_H - -typedef enum TG_Kind -{ -TG_Kind_Null, -TG_Kind_Void, -TG_Kind_Handle, -TG_Kind_Char8, -TG_Kind_Char16, -TG_Kind_Char32, -TG_Kind_UChar8, -TG_Kind_UChar16, -TG_Kind_UChar32, -TG_Kind_U8, -TG_Kind_U16, -TG_Kind_U32, -TG_Kind_U64, -TG_Kind_U128, -TG_Kind_U256, -TG_Kind_U512, -TG_Kind_S8, -TG_Kind_S16, -TG_Kind_S32, -TG_Kind_S64, -TG_Kind_S128, -TG_Kind_S256, -TG_Kind_S512, -TG_Kind_Bool, -TG_Kind_F16, -TG_Kind_F32, -TG_Kind_F32PP, -TG_Kind_F48, -TG_Kind_F64, -TG_Kind_F80, -TG_Kind_F128, -TG_Kind_ComplexF32, -TG_Kind_ComplexF64, -TG_Kind_ComplexF80, -TG_Kind_ComplexF128, -TG_Kind_Modifier, -TG_Kind_Ptr, -TG_Kind_LRef, -TG_Kind_RRef, -TG_Kind_Array, -TG_Kind_Function, -TG_Kind_Method, -TG_Kind_MemberPtr, -TG_Kind_Struct, -TG_Kind_Class, -TG_Kind_Union, -TG_Kind_Enum, -TG_Kind_Alias, -TG_Kind_IncompleteStruct, -TG_Kind_IncompleteUnion, -TG_Kind_IncompleteClass, -TG_Kind_IncompleteEnum, -TG_Kind_Bitfield, -TG_Kind_Variadic, -TG_Kind_COUNT, -TG_Kind_FirstBasic = TG_Kind_Void, -TG_Kind_LastBasic = TG_Kind_ComplexF128, -TG_Kind_FirstInteger = TG_Kind_Char8, -TG_Kind_LastInteger = TG_Kind_S512, -TG_Kind_FirstSigned1 = TG_Kind_Char8, -TG_Kind_LastSigned1 = TG_Kind_Char32, -TG_Kind_FirstSigned2 = TG_Kind_S8, -TG_Kind_LastSigned2 = TG_Kind_S512, -TG_Kind_FirstIncomplete = TG_Kind_IncompleteStruct, -TG_Kind_LastIncomplete = TG_Kind_IncompleteEnum, -} TG_Kind; - -C_LINKAGE_BEGIN -extern U8 tg_kind_basic_byte_size_table[54]; -extern String8 tg_kind_basic_string_table[54]; - -C_LINKAGE_END - -#endif // TYPE_GRAPH_META_H diff --git a/src/type_graph/type_graph.c b/src/type_graph/type_graph.c deleted file mode 100644 index 06fcfa84..00000000 --- a/src/type_graph/type_graph.c +++ /dev/null @@ -1,1357 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Generated Code - -#include "generated/type_graph.meta.c" - -//////////////////////////////// -//~ rjf: Basic Helpers - -internal U64 -tg_hash_from_string(U64 seed, String8 string) -{ - U64 result = seed; - for(U64 idx = 0; idx < string.size; idx += 1) - { - result = ((result<<5)+result) + string.str[idx]; - } - return result; -} - -internal int -tg_qsort_compare_members_offset(TG_Member *a, TG_Member *b) -{ - int result = 0; - if(a->off < b->off) - { - result = -1; - } - else if(a->off > b->off) - { - result = +1; - } - return result; -} - -internal void -tg_key_list_push(Arena *arena, TG_KeyList *list, TG_Key key) -{ - TG_KeyNode *n = push_array(arena, TG_KeyNode, 1); - n->v = key; - SLLQueuePush(list->first, list->last, n); - list->count += 1; -} - -internal TG_KeyList -tg_key_list_copy(Arena *arena, TG_KeyList *src) -{ - TG_KeyList dst = {0}; - for(TG_KeyNode *n = src->first; n != 0; n = n->next) - { - tg_key_list_push(arena, &dst, n->v); - } - return dst; -} - -//////////////////////////////// -//~ rjf: RADDBG <-> TG Enum Conversions - -internal TG_Kind -tg_kind_from_rdi_type_kind(RDI_TypeKind kind) -{ - TG_Kind result = TG_Kind_Null; - switch(kind) - { - default:{}break; - case RDI_TypeKind_Void: {result = TG_Kind_Void;}break; - case RDI_TypeKind_Handle: {result = TG_Kind_Handle;}break; - case RDI_TypeKind_Char8: {result = TG_Kind_Char8;}break; - case RDI_TypeKind_Char16: {result = TG_Kind_Char16;}break; - case RDI_TypeKind_Char32: {result = TG_Kind_Char32;}break; - case RDI_TypeKind_UChar8: {result = TG_Kind_UChar8;}break; - case RDI_TypeKind_UChar16: {result = TG_Kind_UChar16;}break; - case RDI_TypeKind_UChar32: {result = TG_Kind_UChar32;}break; - case RDI_TypeKind_U8: {result = TG_Kind_U8;}break; - case RDI_TypeKind_U16: {result = TG_Kind_U16;}break; - case RDI_TypeKind_U32: {result = TG_Kind_U32;}break; - case RDI_TypeKind_U64: {result = TG_Kind_U64;}break; - case RDI_TypeKind_U128: {result = TG_Kind_U128;}break; - case RDI_TypeKind_U256: {result = TG_Kind_U256;}break; - case RDI_TypeKind_U512: {result = TG_Kind_U512;}break; - case RDI_TypeKind_S8: {result = TG_Kind_S8;}break; - case RDI_TypeKind_S16: {result = TG_Kind_S16;}break; - case RDI_TypeKind_S32: {result = TG_Kind_S32;}break; - case RDI_TypeKind_S64: {result = TG_Kind_S64;}break; - case RDI_TypeKind_S128: {result = TG_Kind_S128;}break; - case RDI_TypeKind_S256: {result = TG_Kind_S256;}break; - case RDI_TypeKind_S512: {result = TG_Kind_S512;}break; - case RDI_TypeKind_Bool: {result = TG_Kind_Bool;}break; - case RDI_TypeKind_F16: {result = TG_Kind_F16;}break; - case RDI_TypeKind_F32: {result = TG_Kind_F32;}break; - case RDI_TypeKind_F32PP: {result = TG_Kind_F32PP;}break; - case RDI_TypeKind_F48: {result = TG_Kind_F48;}break; - case RDI_TypeKind_F64: {result = TG_Kind_F64;}break; - case RDI_TypeKind_F80: {result = TG_Kind_F80;}break; - case RDI_TypeKind_F128: {result = TG_Kind_F128;}break; - case RDI_TypeKind_ComplexF32: {result = TG_Kind_ComplexF32;}break; - case RDI_TypeKind_ComplexF64: {result = TG_Kind_ComplexF64;}break; - case RDI_TypeKind_ComplexF80: {result = TG_Kind_ComplexF80;}break; - case RDI_TypeKind_ComplexF128: {result = TG_Kind_ComplexF128;}break; - case RDI_TypeKind_Modifier: {result = TG_Kind_Modifier;}break; - case RDI_TypeKind_Ptr: {result = TG_Kind_Ptr;}break; - case RDI_TypeKind_LRef: {result = TG_Kind_LRef;}break; - case RDI_TypeKind_RRef: {result = TG_Kind_RRef;}break; - case RDI_TypeKind_Array: {result = TG_Kind_Array;}break; - case RDI_TypeKind_Function: {result = TG_Kind_Function;}break; - case RDI_TypeKind_Method: {result = TG_Kind_Method;}break; - case RDI_TypeKind_MemberPtr: {result = TG_Kind_MemberPtr;}break; - case RDI_TypeKind_Struct: {result = TG_Kind_Struct;}break; - case RDI_TypeKind_Class: {result = TG_Kind_Class;}break; - case RDI_TypeKind_Union: {result = TG_Kind_Union;}break; - case RDI_TypeKind_Enum: {result = TG_Kind_Enum;}break; - case RDI_TypeKind_Alias: {result = TG_Kind_Alias;}break; - case RDI_TypeKind_IncompleteStruct: {result = TG_Kind_IncompleteStruct;}break; - case RDI_TypeKind_IncompleteUnion: {result = TG_Kind_IncompleteUnion;}break; - case RDI_TypeKind_IncompleteClass: {result = TG_Kind_IncompleteClass;}break; - case RDI_TypeKind_IncompleteEnum: {result = TG_Kind_IncompleteEnum;}break; - case RDI_TypeKind_Bitfield: {result = TG_Kind_Bitfield;}break; - case RDI_TypeKind_Variadic: {result = TG_Kind_Variadic;}break; - } - return result; -} - -internal TG_MemberKind -tg_member_kind_from_rdi_member_kind(RDI_MemberKind kind) -{ - TG_MemberKind result = TG_MemberKind_Null; - switch(kind) - { - default:{}break; - case RDI_MemberKind_DataField: {result = TG_MemberKind_DataField;}break; - case RDI_MemberKind_StaticData: {result = TG_MemberKind_StaticData;}break; - case RDI_MemberKind_Method: {result = TG_MemberKind_Method;}break; - case RDI_MemberKind_StaticMethod: {result = TG_MemberKind_StaticMethod;}break; - case RDI_MemberKind_VirtualMethod: {result = TG_MemberKind_VirtualMethod;}break; - case RDI_MemberKind_VTablePtr: {result = TG_MemberKind_VTablePtr;}break; - case RDI_MemberKind_Base: {result = TG_MemberKind_Base;}break; - case RDI_MemberKind_VirtualBase: {result = TG_MemberKind_VirtualBase;}break; - case RDI_MemberKind_NestedType: {result = TG_MemberKind_NestedType;}break; - } - return result; -} - -//////////////////////////////// -//~ rjf: Key Type Functions - -internal TG_Key -tg_key_zero(void) -{ - TG_Key key = zero_struct; - return key; -} - -internal TG_Key -tg_key_basic(TG_Kind kind) -{ - TG_Key key = {TG_KeyKind_Basic}; - key.u32[0] = (U32)kind; - return key; -} - -internal TG_Key -tg_key_ext(TG_Kind kind, U64 id) -{ - TG_Key key = {TG_KeyKind_Ext}; - key.u32[0] = (U32)kind; - if(TG_Kind_FirstBasic <= kind && kind <= TG_Kind_LastBasic) - { - key.kind = TG_KeyKind_Basic; - } - else - { - key.u64[0] = id; - } - return key; -} - -internal TG_Key -tg_key_reg(Architecture arch, REGS_RegCode code) -{ - TG_Key key = {TG_KeyKind_Reg}; - key.u32[0] = (U32)arch; - key.u64[0] = (U64)code; - return key; -} - -internal TG_Key -tg_key_reg_alias(Architecture arch, REGS_AliasCode code) -{ - TG_Key key = {TG_KeyKind_RegAlias}; - key.u32[0] = (U32)arch; - key.u64[0] = (U64)code; - return key; -} - -internal B32 -tg_key_match(TG_Key a, TG_Key b) -{ - B32 result = MemoryMatchStruct(&a, &b); - return result; -} - -//////////////////////////////// -//~ rjf: Graph Construction API - -internal TG_Graph * -tg_graph_begin(U64 address_size, U64 slot_count) -{ - if(tg_build_arena == 0) - { - tg_build_arena = arena_alloc(); - } - else - { - arena_clear(tg_build_arena); - } - TG_Graph *graph = push_array(tg_build_arena, TG_Graph, 1); - graph->address_size = address_size; - graph->content_hash_slots_count = slot_count; - graph->content_hash_slots = push_array(tg_build_arena, TG_Slot, graph->content_hash_slots_count); - graph->key_hash_slots_count = slot_count; - graph->key_hash_slots = push_array(tg_build_arena, TG_Slot, graph->key_hash_slots_count); - return graph; -} - -internal TG_Key -tg_cons_type_make(TG_Graph *graph, TG_Kind kind, TG_Key direct_type_key, U64 u64) -{ - U32 buffer[] = - { - (U32)kind, - (U32)direct_type_key.kind, - (U32)direct_type_key.u32[0], - (U32)((direct_type_key.u64[0] & 0x00000000ffffffffull)>> 0), - (U32)((direct_type_key.u64[0] & 0xffffffff00000000ull)>>32), - (U32)((u64 & 0x00000000ffffffffull)>> 0), - (U32)((u64 & 0xffffffff00000000ull)>> 32), - }; - U64 content_hash = tg_hash_from_string(5381, str8((U8 *)buffer, sizeof(buffer))); - U64 content_slot_idx = content_hash%graph->content_hash_slots_count; - TG_Slot *content_slot = &graph->content_hash_slots[content_slot_idx]; - TG_Node *node = 0; - for(TG_Node *n = content_slot->first; n != 0; n = n->content_hash_next) - { - if(n->cons_type.kind == kind && tg_key_match(n->cons_type.direct_type_key, direct_type_key)) - { - node = n; - break; - } - } - TG_Key result = zero_struct; - if(node == 0) - { - TG_Key key = {TG_KeyKind_Cons}; - key.u32[0] = (U32)kind; - key.u64[0] = graph->cons_id_gen; - U64 key_hash = tg_hash_from_string(5381, str8_struct(&key)); - U64 key_slot_idx = key_hash%graph->key_hash_slots_count; - TG_Slot *key_slot = &graph->key_hash_slots[key_slot_idx]; - graph->cons_id_gen += 1; - TG_Node *node = push_array(tg_build_arena, TG_Node, 1); - SLLQueuePush_N(content_slot->first, content_slot->last, node, content_hash_next); - SLLQueuePush_N(key_slot->first, key_slot->last, node, key_hash_next); - node->key = key; - node->cons_type.kind = kind; - node->cons_type.direct_type_key = direct_type_key; - node->cons_type.u64 = u64; - result = key; - } - else - { - result = node->key; - } - return result; -} - -//////////////////////////////// -//~ rjf: Graph Introspection API - -internal TG_Type * -tg_type_from_graph_rdi_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - TG_Type *type = &tg_type_nil; - U64 reg_byte_count = 0; - { - switch(key.kind) - { - default:{}break; - - //- rjf: basic type keys - case TG_KeyKind_Basic: - { - TG_Kind kind = (TG_Kind)key.u32[0]; - if(TG_Kind_FirstBasic <= kind && kind <= TG_Kind_LastBasic) - { - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->name = tg_kind_basic_string_table[kind]; - type->byte_size = tg_kind_basic_byte_size_table[kind]; - } - }break; - - //- rjf: constructed type keys - case TG_KeyKind_Cons: - { - U64 key_hash = tg_hash_from_string(5381, str8_struct(&key)); - U64 key_slot_idx = key_hash%graph->key_hash_slots_count; - TG_Slot *key_slot = &graph->key_hash_slots[key_slot_idx]; - for(TG_Node *node = key_slot->first; node != 0; node = node->key_hash_next) - { - if(tg_key_match(node->key, key)) - { - TG_ConsType *cons_type = &node->cons_type; - type = push_array(arena, TG_Type, 1); - type->kind = cons_type->kind; - type->direct_type_key = cons_type->direct_type_key; - type->count = cons_type->u64; - switch(type->kind) - { - default: - { - type->byte_size = graph->address_size; - }break; - case TG_Kind_Array: - { - U64 ptee_size = tg_byte_size_from_graph_rdi_key(graph, rdi, cons_type->direct_type_key); - type->byte_size = ptee_size * type->count; - }break; - } - } - } - }break; - - //- rjf: external (raddbg) type keys - case TG_KeyKind_Ext: - { - U64 type_node_idx = key.u64[0]; - RDI_TypeNode *rdi_type = rdi_element_from_name_idx(rdi, TypeNodes, type_node_idx); - if(rdi_type->kind != RDI_TypeKind_NULL) - { - TG_Kind kind = tg_kind_from_rdi_type_kind(rdi_type->kind); - - //- rjf: record types => unpack name * members & produce - if(RDI_TypeKind_FirstRecord <= rdi_type->kind && rdi_type->kind <= RDI_TypeKind_LastRecord) - { - // rjf: unpack name - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, rdi_type->user_defined.name_string_idx, &name.size); - - // rjf: unpack UDT info - RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, rdi_type->user_defined.udt_idx); - - // rjf: unpack members - TG_Member *members = 0; - U32 members_count = 0; - { - members_count = udt->member_count; - members = push_array(arena, TG_Member, members_count); - if(members_count != 0) - { - for(U32 member_idx = udt->member_first; - member_idx < udt->member_first+udt->member_count; - member_idx += 1) - { - RDI_Member *src = rdi_element_from_name_idx(rdi, Members, member_idx); - TG_Kind member_type_kind = TG_Kind_Null; - RDI_TypeNode *member_type = rdi_element_from_name_idx(rdi, TypeNodes, src->type_idx); - member_type_kind = tg_kind_from_rdi_type_kind(member_type->kind); - TG_Member *dst = &members[member_idx-udt->member_first]; - dst->kind = tg_member_kind_from_rdi_member_kind(src->kind); - dst->type_key = tg_key_ext(member_type_kind, (U64)src->type_idx); - dst->name.str = rdi_string_from_idx(rdi, src->name_string_idx, &dst->name.size); - dst->off = (U64)src->off; - } - } - } - - // rjf: produce - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->name = push_str8_copy(arena, name); - type->byte_size = (U64)rdi_type->byte_size; - type->count = members_count; - type->members = members; - } - - //- rjf: enum types => unpack name * values & produce - else if(rdi_type->kind == RDI_TypeKind_Enum) - { - // rjf: unpack name - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, rdi_type->user_defined.name_string_idx, &name.size); - - // rjf: unpack direct type - TG_Key direct_type_key = zero_struct; - if(rdi_type->user_defined.direct_type_idx < type_node_idx) - { - RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->user_defined.direct_type_idx); - TG_Kind direct_type_kind = tg_kind_from_rdi_type_kind(direct_type_node->kind); - direct_type_key = tg_key_ext(direct_type_kind, (U64)rdi_type->user_defined.direct_type_idx); - } - - // rjf: unpack members - TG_EnumVal *enum_vals = 0; - U32 enum_vals_count = 0; - { - U32 udt_idx = rdi_type->user_defined.udt_idx; - RDI_UDT *udt = rdi_element_from_name_idx(rdi, UDTs, udt_idx); - enum_vals_count = udt->member_count; - enum_vals = push_array(arena, TG_EnumVal, enum_vals_count); - for(U32 member_idx = udt->member_first; - member_idx < udt->member_first+udt->member_count; - member_idx += 1) - { - RDI_EnumMember *src = rdi_element_from_name_idx(rdi, EnumMembers, member_idx); - TG_EnumVal *dst = &enum_vals[member_idx-udt->member_first]; - dst->name.str = rdi_string_from_idx(rdi, src->name_string_idx, &dst->name.size); - dst->val = src->val; - } - } - - // rjf: produce - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->name = push_str8_copy(arena, name); - type->byte_size = (U64)rdi_type->byte_size; - type->count = enum_vals_count; - type->enum_vals = enum_vals; - type->direct_type_key = direct_type_key; - } - - //- rjf: constructed types - else if(RDI_TypeKind_FirstConstructed <= rdi_type->kind && rdi_type->kind <= RDI_TypeKind_LastConstructed) - { - // rjf: unpack direct type - B32 direct_type_is_good = 0; - TG_Key direct_type_key = zero_struct; - U64 direct_type_byte_size = 0; - if(rdi_type->constructed.direct_type_idx < type_node_idx) - { - RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->constructed.direct_type_idx); - TG_Kind direct_type_kind = tg_kind_from_rdi_type_kind(direct_type_node->kind); - direct_type_key = tg_key_ext(direct_type_kind, (U64)rdi_type->constructed.direct_type_idx); - direct_type_is_good = 1; - direct_type_byte_size = (U64)direct_type_node->byte_size; - } - - // rjf: construct based on kind - switch(rdi_type->kind) - { - case RDI_TypeKind_Modifier: - { - TG_Flags flags = 0; - if(rdi_type->flags & RDI_TypeModifierFlag_Const) - { - flags |= TG_Flag_Const; - } - if(rdi_type->flags & RDI_TypeModifierFlag_Volatile) - { - flags |= TG_Flag_Volatile; - } - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->direct_type_key = direct_type_key; - type->byte_size = direct_type_byte_size; - type->flags = flags; - }break; - case RDI_TypeKind_Ptr: - case RDI_TypeKind_LRef: - case RDI_TypeKind_RRef: - { - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->direct_type_key = direct_type_key; - type->byte_size = graph->address_size; - }break; - - case RDI_TypeKind_Array: - { - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->direct_type_key = direct_type_key; - type->count = rdi_type->constructed.count; - type->byte_size = direct_type_byte_size * type->count; - }break; - case RDI_TypeKind_Function: - { - U32 count = rdi_type->constructed.count; - U32 idx_run_first = rdi_type->constructed.param_idx_run_first; - U32 check_count = 0; - U32 *idx_run = rdi_idx_run_from_first_count(rdi, idx_run_first, count, &check_count); - if(check_count == count) - { - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->byte_size = graph->address_size; - type->direct_type_key = direct_type_key; - type->count = count; - type->param_type_keys = push_array_no_zero(arena, TG_Key, type->count); - for(U32 idx = 0; idx < type->count; idx += 1) - { - U32 param_type_idx = idx_run[idx]; - if(param_type_idx < type_node_idx) - { - RDI_TypeNode *param_type_node = rdi_element_from_name_idx(rdi, TypeNodes, param_type_idx); - TG_Kind param_kind = tg_kind_from_rdi_type_kind(param_type_node->kind); - type->param_type_keys[idx] = tg_key_ext(param_kind, (U64)param_type_idx); - } - else - { - break; - } - } - } - }break; - case RDI_TypeKind_Method: - { - // NOTE(rjf): for methods, the `direct` type points at the owner type. - // the return type, instead of being encoded via the `direct` type, is - // encoded via the first parameter. - U32 count = rdi_type->constructed.count; - U32 idx_run_first = rdi_type->constructed.param_idx_run_first; - U32 check_count = 0; - U32 *idx_run = rdi_idx_run_from_first_count(rdi, idx_run_first, count, &check_count); - if(check_count == count) - { - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->byte_size = graph->address_size; - type->owner_type_key = direct_type_key; - type->count = count; - type->param_type_keys = push_array_no_zero(arena, TG_Key, type->count); - for(U32 idx = 0; idx < type->count; idx += 1) - { - U32 param_type_idx = idx_run[idx]; - if(param_type_idx < type_node_idx) - { - RDI_TypeNode *param_type_node = rdi_element_from_name_idx(rdi, TypeNodes, param_type_idx); - TG_Kind param_kind = tg_kind_from_rdi_type_kind(param_type_node->kind); - type->param_type_keys[idx] = tg_key_ext(param_kind, (U64)param_type_idx); - } - else - { - break; - } - } - if(type->count > 0) - { - type->direct_type_key = type->param_type_keys[0]; - type->count -= 1; - type->param_type_keys += 1; - } - } - }break; - case RDI_TypeKind_MemberPtr: - { - // rjf: unpack owner type - TG_Key owner_type_key = zero_struct; - if(rdi_type->constructed.owner_type_idx < type_node_idx) - { - RDI_TypeNode *owner_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->constructed.owner_type_idx); - TG_Kind owner_type_kind = tg_kind_from_rdi_type_kind(owner_type_node->kind); - owner_type_key = tg_key_ext(owner_type_kind, (U64)rdi_type->constructed.owner_type_idx); - } - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->byte_size = graph->address_size; - type->owner_type_key = owner_type_key; - type->direct_type_key = direct_type_key; - }break; - } - } - - //- rjf: alias types - else if(rdi_type->kind == RDI_TypeKind_Alias) - { - // rjf: unpack name - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, rdi_type->user_defined.name_string_idx, &name.size); - - // rjf: unpack direct type - TG_Key direct_type_key = zero_struct; - U64 direct_type_byte_size = 0; - if(rdi_type->user_defined.direct_type_idx < type_node_idx) - { - RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->user_defined.direct_type_idx); - TG_Kind direct_type_kind = tg_kind_from_rdi_type_kind(direct_type_node->kind); - direct_type_key = tg_key_ext(direct_type_kind, (U64)rdi_type->user_defined.direct_type_idx); - direct_type_byte_size = direct_type_node->byte_size; - } - - // rjf: produce - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->name = push_str8_copy(arena, name); - type->byte_size = direct_type_byte_size; - type->direct_type_key = direct_type_key; - } - - //- rjf: bitfields - else if(RDI_TypeKind_Bitfield == rdi_type->kind) - { - // rjf: unpack direct type - TG_Key direct_type_key = zero_struct; - U64 direct_type_byte_size = 0; - if(rdi_type->bitfield.direct_type_idx < type_node_idx) - { - RDI_TypeNode *direct_type_node = rdi_element_from_name_idx(rdi, TypeNodes, rdi_type->bitfield.direct_type_idx); - TG_Kind direct_type_kind = tg_kind_from_rdi_type_kind(direct_type_node->kind); - direct_type_key = tg_key_ext(direct_type_kind, (U64)rdi_type->bitfield.direct_type_idx); - direct_type_byte_size = direct_type_node->byte_size; - } - - // rjf: produce - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->byte_size = direct_type_byte_size; - type->direct_type_key = direct_type_key; - type->off = (U32)rdi_type->bitfield.off; - type->count = (U64)rdi_type->bitfield.size; - } - - //- rjf: incomplete types - else if(RDI_TypeKind_FirstIncomplete <= rdi_type->kind && rdi_type->kind <= RDI_TypeKind_LastIncomplete) - { - // rjf: unpack name - String8 name = {0}; - name.str = rdi_string_from_idx(rdi, rdi_type->user_defined.name_string_idx, &name.size); - - // rjf: produce - type = push_array(arena, TG_Type, 1); - type->kind = kind; - type->name = push_str8_copy(arena, name); - } - - } - }break; - - //- rjf: reg type keys - case TG_KeyKind_Reg: - { - Architecture arch = (Architecture)key.u32[0]; - REGS_RegCode code = (REGS_RegCode)key.u64[0]; - REGS_Rng rng = regs_reg_code_rng_table_from_architecture(arch)[code]; - reg_byte_count = (U64)rng.byte_size; - }goto build_reg_type; - case TG_KeyKind_RegAlias: - { - Architecture arch = (Architecture)key.u32[0]; - REGS_AliasCode code = (REGS_AliasCode)key.u64[0]; - REGS_Slice slice = regs_alias_code_slice_table_from_architecture(arch)[code]; - reg_byte_count = (U64)slice.byte_size; - }goto build_reg_type; - build_reg_type: - { - Temp scratch = scratch_begin(&arena, 1); - type = push_array(arena, TG_Type, 1); - type->kind = TG_Kind_Union; - type->name = push_str8f(arena, "reg_%I64u_bit", reg_byte_count*8); - type->byte_size = (U64)reg_byte_count; - - // rjf: build register type members - TG_MemberList members = {0}; - { - // rjf: build exact-sized members - { - if(type->byte_size == 16) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u128"); - mem->type_key = tg_key_basic(TG_Kind_U128); - } - if(type->byte_size == 8) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u64"); - mem->type_key = tg_key_basic(TG_Kind_U64); - } - if(type->byte_size == 4) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u32"); - mem->type_key = tg_key_basic(TG_Kind_U32); - } - if(type->byte_size == 2) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u16"); - mem->type_key = tg_key_basic(TG_Kind_U16); - } - if(type->byte_size == 1) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u8"); - mem->type_key = tg_key_basic(TG_Kind_U8); - } - } - - // rjf: build arrays for subdivisions - { - if(type->byte_size > 16 && type->byte_size%16 == 0) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u128s"); - mem->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_U128), reg_byte_count/16); - } - if(type->byte_size > 8 && type->byte_size%8 == 0) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u64s"); - mem->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_U64), reg_byte_count/8); - } - if(type->byte_size > 4 && type->byte_size%4 == 0) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u32s"); - mem->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_U32), reg_byte_count/4); - } - if(type->byte_size > 2 && type->byte_size%2 == 0) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u16s"); - mem->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_U16), reg_byte_count/2); - } - if(type->byte_size > 1) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("u8s"); - mem->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_U8), reg_byte_count); - } - if(type->byte_size > 4 && type->byte_size%4 == 0) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("f32s"); - mem->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_F32), reg_byte_count/4); - } - if(type->byte_size > 8 && type->byte_size%8 == 0) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - SLLQueuePush(members.first, members.last, n); - members.count += 1; - TG_Member *mem = &n->v; - mem->kind = TG_MemberKind_DataField; - mem->name = str8_lit("f64s"); - mem->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_F64), reg_byte_count/8); - } - } - } - - // rjf: commit members - type->count = members.count; - type->members = push_array_no_zero(arena, TG_Member, members.count); - U64 idx = 0; - for(TG_MemberNode *n = members.first; n != 0; n = n->next, idx += 1) - { - MemoryCopyStruct(&type->members[idx], &n->v); - } - - scratch_end(scratch); - }break; - } - } - return type; -} - -internal TG_Key -tg_direct_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - TG_Key result = zero_struct; - switch(key.kind) - { - default:{}break; - case TG_KeyKind_Ext: - case TG_KeyKind_Cons: - { - Temp scratch = scratch_begin(0, 0); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - result = type->direct_type_key; - scratch_end(scratch); - }break; - } - return result; -} - -internal TG_Key -tg_unwrapped_direct_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - key = tg_unwrapped_from_graph_rdi_key(graph, rdi, key); - key = tg_direct_from_graph_rdi_key(graph, rdi, key); - key = tg_unwrapped_from_graph_rdi_key(graph, rdi, key); - return key; -} - -internal TG_Key -tg_owner_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - TG_Key result = zero_struct; - switch(key.kind) - { - default:{}break; - case TG_KeyKind_Ext: - case TG_KeyKind_Cons: - { - Temp scratch = scratch_begin(0, 0); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - result = type->owner_type_key; - scratch_end(scratch); - }break; - } - return result; -} - -internal TG_Key -tg_ptee_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - TG_Key result = key; - B32 passed_ptr = 0; - for(;;) - { - TG_Kind kind = tg_kind_from_key(result); - result = tg_direct_from_graph_rdi_key(graph, rdi, result); - if(kind == TG_Kind_Ptr || kind == TG_Kind_LRef || kind == TG_Kind_RRef) - { - passed_ptr = 1; - } - TG_Kind next_kind = tg_kind_from_key(result); - if(passed_ptr && - next_kind != TG_Kind_IncompleteStruct && - next_kind != TG_Kind_IncompleteUnion && - next_kind != TG_Kind_IncompleteEnum && - next_kind != TG_Kind_IncompleteClass && - next_kind != TG_Kind_Alias && - next_kind != TG_Kind_Modifier) - { - break; - } - if(kind == TG_Kind_Null) - { - break; - } - } - return result; -} - -internal TG_Key -tg_unwrapped_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - TG_Key result = key; - for(B32 good = 1; good;) - { - TG_Kind kind = tg_kind_from_key(result); - if((TG_Kind_FirstIncomplete <= kind && kind <= TG_Kind_LastIncomplete) || - kind == TG_Kind_Modifier || - kind == TG_Kind_Alias) - { - result = tg_direct_from_graph_rdi_key(graph, rdi, result); - } - else - { - good = 0; - } - } - return result; -} - -internal U64 -tg_byte_size_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - U64 result = 0; - switch(key.kind) - { - default:{}break; - case TG_KeyKind_Basic: - { - TG_Kind kind = (TG_Kind)key.u32[0]; - result = tg_kind_basic_byte_size_table[kind]; - }break; - case TG_KeyKind_Ext: - case TG_KeyKind_Cons: - { - Temp scratch = scratch_begin(0, 0); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - result = type->byte_size; - scratch_end(scratch); - }break; - } - return result; -} - -internal TG_Kind -tg_kind_from_key(TG_Key key) -{ - TG_Kind kind = TG_Kind_Null; - switch(key.kind) - { - default:{}break; - case TG_KeyKind_Basic: {kind = (TG_Kind)key.u32[0];}break; - case TG_KeyKind_Ext: {kind = (TG_Kind)key.u32[0];}break; - case TG_KeyKind_Cons: {kind = (TG_Kind)key.u32[0];}break; - case TG_KeyKind_Reg: {kind = TG_Kind_Union;}break; - case TG_KeyKind_RegAlias:{kind = TG_Kind_Union;}break; - } - return kind; -} - -internal TG_Member * -tg_member_copy(Arena *arena, TG_Member *src) -{ - TG_Member *dst = push_array(arena, TG_Member, 1); - MemoryCopyStruct(dst, src); - dst->name = push_str8_copy(arena, src->name); - dst->inheritance_key_chain = tg_key_list_copy(arena, &src->inheritance_key_chain); - return dst; -} - -internal TG_MemberArray -tg_members_from_graph_rdi_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - TG_MemberArray result = {0}; - Temp scratch = scratch_begin(&arena, 1); - { - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - if(type->members != 0) - { - result.count = type->count; - result.v = push_array_no_zero(arena, TG_Member, result.count); - MemoryCopy(result.v, type->members, sizeof(TG_Member)*result.count); - for(U64 idx = 0; idx < result.count; idx += 1) - { - result.v[idx].name = push_str8_copy(arena, result.v[idx].name); - } - } - } - scratch_end(scratch); - return result; -} - -internal TG_MemberArray -tg_data_members_from_graph_rdi_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - Temp scratch = scratch_begin(&arena, 1); - TG_Kind root_type_kind = tg_kind_from_key(key); - - //- rjf: walk type tree; gather members list - TG_MemberList members_list = {0}; - B32 members_need_offset_sort = 0; - { - TG_Type *root_type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - typedef struct Task Task; - struct Task - { - Task *next; - U64 base_off; - TG_KeyList inheritance_chain; - TG_Key type_key; - TG_Type *type; - }; - Task start_task = {0, 0, {0}, key, root_type}; - Task *first_task = &start_task; - Task *last_task = &start_task; - for(Task *task = first_task; task != 0; task = task->next) - { - TG_Type *type = task->type; - if(type->members != 0) - { - U64 last_member_off = 0; - for(U64 member_idx = 0; member_idx < type->count; member_idx += 1) - { - if(type->members[member_idx].kind == TG_MemberKind_DataField) - { - TG_MemberNode *n = push_array(scratch.arena, TG_MemberNode, 1); - MemoryCopyStruct(&n->v, &type->members[member_idx]); - n->v.off += task->base_off; - n->v.inheritance_key_chain = task->inheritance_chain; - SLLQueuePush(members_list.first, members_list.last, n); - members_list.count += 1; - members_need_offset_sort = members_need_offset_sort || (n->v.off < last_member_off); - last_member_off = n->v.off; - } - else if(type->members[member_idx].kind == TG_MemberKind_Base) - { - Task *t = push_array(scratch.arena, Task, 1); - t->base_off = type->members[member_idx].off + task->base_off; - t->inheritance_chain = tg_key_list_copy(scratch.arena, &task->inheritance_chain); - tg_key_list_push(scratch.arena, &t->inheritance_chain, type->members[member_idx].type_key); - t->type_key = type->members[member_idx].type_key; - t->type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, type->members[member_idx].type_key); - SLLQueuePush(first_task, last_task, t); - members_need_offset_sort = 1; - } - } - } - } - } - - //- rjf: convert to array - TG_MemberArray members = {0}; - { - members.count = members_list.count; - members.v = push_array(arena, TG_Member, members.count); - U64 idx = 0; - for(TG_MemberNode *n = members_list.first; n != 0; n = n->next) - { - MemoryCopyStruct(&members.v[idx], &n->v); - members.v[idx].name = push_str8_copy(arena, members.v[idx].name); - members.v[idx].inheritance_key_chain = tg_key_list_copy(arena, &members.v[idx].inheritance_key_chain); - idx += 1; - } - } - - //- rjf: sort array by offset if needed - if(members_need_offset_sort) - { - quick_sort(members.v, members.count, sizeof(TG_Member), tg_qsort_compare_members_offset); - } - - //- rjf: find all padding instances - typedef struct PaddingNode PaddingNode; - struct PaddingNode - { - PaddingNode *next; - U64 off; - U64 size; - U64 prev_member_idx; - }; - PaddingNode *first_padding = 0; - PaddingNode *last_padding = 0; - U64 padding_count = 0; - if(root_type_kind == TG_Kind_Struct || root_type_kind == TG_Kind_Class) - { - for(U64 idx = 0; idx < members.count; idx += 1) - { - TG_Member *member = &members.v[idx]; - if(idx+1 < members.count) - { - U64 member_byte_size = tg_byte_size_from_graph_rdi_key(graph, rdi, member->type_key); - Rng1U64 member_byte_range = r1u64(member->off, member->off + member_byte_size); - if(member[1].off > member_byte_range.max) - { - PaddingNode *n = push_array(scratch.arena, PaddingNode, 1); - SLLQueuePush(first_padding, last_padding, n); - n->off = member_byte_range.max; - n->size = member[1].off - member_byte_range.max; - n->prev_member_idx = idx; - padding_count += 1; - } - } - } - } - - //- rjf: produce new members array, if we have any padding - if(padding_count != 0) - { - TG_MemberArray new_members = {0}; - new_members.count = members.count + padding_count; - new_members.v = push_array(arena, TG_Member, new_members.count); - MemoryCopy(new_members.v, members.v, sizeof(TG_Member)*members.count); - U64 padding_idx = 0; - for(PaddingNode *n = first_padding; n != 0; n = n->next) - { - if(members.count+padding_idx > n->prev_member_idx+1) - { - MemoryCopy(new_members.v + n->prev_member_idx + padding_idx + 2, - new_members.v + n->prev_member_idx + padding_idx + 1, - sizeof(TG_Member) * (members.count + padding_idx - (n->prev_member_idx + padding_idx + 1))); - } - TG_Member *padding_member = &new_members.v[n->prev_member_idx+padding_idx+1]; - MemoryZeroStruct(padding_member); - padding_member->kind = TG_MemberKind_Padding; - padding_member->type_key = tg_cons_type_make(graph, TG_Kind_Array, tg_key_basic(TG_Kind_U8), n->size); - padding_member->off = n->off; - padding_member->name = str8_lit("padding"); - padding_idx += 1; - } - members = new_members; - } - - scratch_end(scratch); - return members; -} - -internal void -tg_lhs_string_from_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key, String8List *out, U32 prec, B32 skip_return) -{ - String8 keyword = {0}; - TG_Kind kind = tg_kind_from_key(key); - switch(kind) - { - default: - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); - str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); - }break; - - case TG_Kind_Bitfield: - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - tg_lhs_string_from_key(arena, graph, rdi, type->direct_type_key, out, prec, skip_return); - str8_list_pushf(arena, out, ": %I64u", type->count); - scratch_end(scratch); - }break; - - case TG_Kind_Modifier: - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - TG_Key direct = type->direct_type_key; - tg_lhs_string_from_key(arena, graph, rdi, direct, out, 1, skip_return); - if(type->flags & TG_Flag_Const) - { - str8_list_push(arena, out, str8_lit("const ")); - } - if(type->flags & TG_Flag_Volatile) - { - str8_list_push(arena, out, str8_lit("volatile ")); - } - scratch_end(scratch); - }break; - - case TG_Kind_Variadic: - { - str8_list_push(arena, out, str8_lit("...")); - }break; - - case TG_Kind_Struct: - case TG_Kind_Union: - case TG_Kind_Enum: - case TG_Kind_Class: - case TG_Kind_Alias: - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); - str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); - }break; - - case TG_Kind_IncompleteStruct: keyword = str8_lit("struct"); goto fwd_udt; - case TG_Kind_IncompleteUnion: keyword = str8_lit("union"); goto fwd_udt; - case TG_Kind_IncompleteEnum: keyword = str8_lit("enum"); goto fwd_udt; - case TG_Kind_IncompleteClass: keyword = str8_lit("class"); goto fwd_udt; - fwd_udt:; - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - str8_list_push(arena, out, keyword); - str8_list_push(arena, out, str8_lit(" ")); - str8_list_push(arena, out, push_str8_copy(arena, type->name)); - str8_list_push(arena, out, str8_lit(" ")); - scratch_end(scratch); - }break; - - case TG_Kind_Array: - { - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_lhs_string_from_key(arena, graph, rdi, direct, out, 2, skip_return); - if(prec == 1) - { - str8_list_push(arena, out, str8_lit("(")); - } - }break; - - case TG_Kind_Function: - { - if(!skip_return) - { - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_lhs_string_from_key(arena, graph, rdi, direct, out, 2, 0); - } - if(prec == 1) - { - str8_list_push(arena, out, str8_lit("(")); - } - }break; - - case TG_Kind_Ptr: - { - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_lhs_string_from_key(arena, graph, rdi, direct, out, 1, skip_return); - str8_list_push(arena, out, str8_lit("*")); - }break; - - case TG_Kind_LRef: - { - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_lhs_string_from_key(arena, graph, rdi, direct, out, 1, skip_return); - str8_list_push(arena, out, str8_lit("&")); - }break; - - case TG_Kind_RRef: - { - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_lhs_string_from_key(arena, graph, rdi, direct, out, 1, skip_return); - str8_list_push(arena, out, str8_lit("&&")); - }break; - - case TG_Kind_MemberPtr: - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - TG_Key direct = type->direct_type_key; - tg_lhs_string_from_key(arena, graph, rdi, direct, out, 1, skip_return); - TG_Type *container = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, type->owner_type_key); - if(container->kind != TG_Kind_Null) - { - str8_list_push(arena, out, push_str8_copy(arena, container->name)); - } - else - { - str8_list_push(arena, out, str8_lit("")); - } - str8_list_push(arena, out, str8_lit("::*")); - scratch_end(scratch); - }break; - } -} - -internal void -tg_rhs_string_from_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key, String8List *out, U32 prec) -{ - TG_Kind kind = tg_kind_from_key(key); - switch(kind) - { - default:{}break; - - case TG_Kind_Bitfield: - { - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_rhs_string_from_key(arena, graph, rdi, direct, out, prec); - }break; - - case TG_Kind_Modifier: - case TG_Kind_Ptr: - case TG_Kind_LRef: - case TG_Kind_RRef: - case TG_Kind_MemberPtr: - { - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_rhs_string_from_key(arena, graph, rdi, direct, out, 1); - }break; - - case TG_Kind_Array: - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - if(prec == 1) - { - str8_list_push(arena, out, str8_lit(")")); - } - String8 count_str = str8_from_u64(arena, type->count, 10, 0, 0); - str8_list_push(arena, out, str8_lit("[")); - str8_list_push(arena, out, count_str); - str8_list_push(arena, out, str8_lit("]")); - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_rhs_string_from_key(arena, graph, rdi, direct, out, 2); - scratch_end(scratch); - }break; - - case TG_Kind_Function: - { - Temp scratch = scratch_begin(&arena, 1); - TG_Type *type = tg_type_from_graph_rdi_key(scratch.arena, graph, rdi, key); - if(prec == 1) - { - str8_list_push(arena, out, str8_lit(")")); - } - - // parameters - if(type->count == 0) - { - str8_list_push(arena, out, str8_lit("(void)")); - } - else - { - str8_list_push(arena, out, str8_lit("(")); - U64 param_count = type->count; - TG_Key *param_type_keys = type->param_type_keys; - for(U64 param_idx = 0; param_idx < param_count; param_idx += 1) - { - TG_Key param_type_key = param_type_keys[param_idx]; - String8 param_str = tg_string_from_key(arena, graph, rdi, param_type_key); - String8 param_str_trimmed = str8_skip_chop_whitespace(param_str); - str8_list_push(arena, out, param_str_trimmed); - if(param_idx+1 < param_count) - { - str8_list_push(arena, out, str8_lit(", ")); - } - } - str8_list_push(arena, out, str8_lit(")")); - } - TG_Key direct = tg_direct_from_graph_rdi_key(graph, rdi, key); - tg_rhs_string_from_key(arena, graph, rdi, direct, out, 2); - scratch_end(scratch); - }break; - } -} - -internal String8 -tg_string_from_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key) -{ - Temp scratch = scratch_begin(&arena, 1); - String8List list = {0}; - tg_lhs_string_from_key(scratch.arena, graph, rdi, key, &list, 0, 0); - tg_rhs_string_from_key(scratch.arena, graph, rdi, key, &list, 0); - String8 result = str8_list_join(arena, &list, 0); - scratch_end(scratch); - return result; -} diff --git a/src/type_graph/type_graph.h b/src/type_graph/type_graph.h deleted file mode 100644 index 61ecee41..00000000 --- a/src/type_graph/type_graph.h +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef TYPE_GRAPH_H -#define TYPE_GRAPH_H - -//////////////////////////////// -//~ rjf: Generated Code - -#include "generated/type_graph.meta.h" - -//////////////////////////////// -//~ rjf: Key Types - -typedef enum TG_KeyKind -{ - TG_KeyKind_Null, - TG_KeyKind_Basic, - TG_KeyKind_Ext, - TG_KeyKind_Cons, - TG_KeyKind_Reg, - TG_KeyKind_RegAlias, -} -TG_KeyKind; - -typedef struct TG_Key TG_Key; -struct TG_Key -{ - TG_KeyKind kind; - U32 u32[1]; // basic -> type_kind; cons -> type_kind; ext -> type_kind; reg -> arch - U64 u64[1]; // ext -> unique id; cons -> idx; reg -> code -}; - -typedef struct TG_KeyNode TG_KeyNode; -struct TG_KeyNode -{ - TG_KeyNode *next; - TG_Key v; -}; - -typedef struct TG_KeyList TG_KeyList; -struct TG_KeyList -{ - TG_KeyNode *first; - TG_KeyNode *last; - U64 count; -}; - -//////////////////////////////// -//~ rjf: Graph Types - -typedef struct TG_ConsType TG_ConsType; -struct TG_ConsType -{ - TG_Kind kind; - TG_Key direct_type_key; - U64 u64; -}; - -typedef struct TG_Node TG_Node; -struct TG_Node -{ - TG_Node *key_hash_next; - TG_Node *content_hash_next; - TG_Key key; - TG_ConsType cons_type; -}; - -typedef struct TG_Slot TG_Slot; -struct TG_Slot -{ - TG_Node *first; - TG_Node *last; -}; - -typedef struct TG_Graph TG_Graph; -struct TG_Graph -{ - U64 address_size; - U64 cons_id_gen; - U64 content_hash_slots_count; - TG_Slot *content_hash_slots; - U64 key_hash_slots_count; - TG_Slot *key_hash_slots; -}; - -//////////////////////////////// -//~ rjf: Extracted Info Types - -typedef enum TG_MemberKind -{ - TG_MemberKind_Null, - TG_MemberKind_DataField, - TG_MemberKind_StaticData, - TG_MemberKind_Method, - TG_MemberKind_StaticMethod, - TG_MemberKind_VirtualMethod, - TG_MemberKind_VTablePtr, - TG_MemberKind_Base, - TG_MemberKind_VirtualBase, - TG_MemberKind_NestedType, - TG_MemberKind_Padding, - TG_MemberKind_COUNT -} -TG_MemberKind; - -typedef U32 TG_Flags; -enum -{ - TG_Flag_Const = (1<<0), - TG_Flag_Volatile = (1<<1), -}; - -typedef struct TG_Member TG_Member; -struct TG_Member -{ - TG_MemberKind kind; - TG_Key type_key; - String8 name; - U64 off; - TG_KeyList inheritance_key_chain; -}; - -typedef struct TG_MemberNode TG_MemberNode; -struct TG_MemberNode -{ - TG_MemberNode *next; - TG_Member v; -}; - -typedef struct TG_MemberList TG_MemberList; -struct TG_MemberList -{ - TG_MemberNode *first; - TG_MemberNode *last; - U64 count; -}; - -typedef struct TG_MemberArray TG_MemberArray; -struct TG_MemberArray -{ - TG_Member *v; - U64 count; -}; - -typedef struct TG_EnumVal TG_EnumVal; -struct TG_EnumVal -{ - String8 name; - U64 val; -}; - -typedef struct TG_EnumValArray TG_EnumValArray; -struct TG_EnumValArray -{ - TG_EnumVal *v; - U64 count; -}; - -typedef struct TG_Type TG_Type; -struct TG_Type -{ - TG_Kind kind; - TG_Flags flags; - String8 name; - U64 byte_size; - U64 count; - U32 off; - TG_Key direct_type_key; - TG_Key owner_type_key; - TG_Key *param_type_keys; - TG_Member *members; - TG_EnumVal *enum_vals; -}; - -//////////////////////////////// -//~ rjf: Globals - -global read_only TG_Type tg_type_nil = -{ - /* kind */ TG_Kind_Null, - /* flags */ 0, - /* name */ {(U8*)"???",3}, -}; - -global read_only TG_Type tg_type_variadic = -{ - /* kind */ TG_Kind_Variadic, - /* flags */ 0, - /* name */ {(U8*)"...",3}, -}; - -thread_static Arena *tg_build_arena = 0; - -//////////////////////////////// -//~ rjf: Basic Helpers - -internal U64 tg_hash_from_string(U64 seed, String8 string); -internal int tg_qsort_compare_members_offset(TG_Member *a, TG_Member *b); -internal void tg_key_list_push(Arena *arena, TG_KeyList *list, TG_Key key); -internal TG_KeyList tg_key_list_copy(Arena *arena, TG_KeyList *src); - -//////////////////////////////// -//~ rjf: RADDBG <-> TG Enum Conversions - -internal TG_Kind tg_kind_from_rdi_type_kind(RDI_TypeKind kind); -internal TG_MemberKind tg_member_kind_from_rdi_member_kind(RDI_MemberKind kind); - -//////////////////////////////// -//~ rjf: Key Type Functions - -internal TG_Key tg_key_zero(void); -internal TG_Key tg_key_basic(TG_Kind kind); -internal TG_Key tg_key_ext(TG_Kind kind, U64 id); -internal TG_Key tg_key_reg(Architecture arch, REGS_RegCode code); -internal TG_Key tg_key_reg_alias(Architecture arch, REGS_AliasCode code); -internal B32 tg_key_match(TG_Key a, TG_Key b); - -//////////////////////////////// -//~ rjf: Graph Construction API - -internal TG_Graph *tg_graph_begin(U64 address_size, U64 slot_count); -internal TG_Key tg_cons_type_make(TG_Graph *graph, TG_Kind kind, TG_Key direct_type_key, U64 u64); - -//////////////////////////////// -//~ rjf: Graph Introspection API - -internal TG_Type *tg_type_from_graph_rdi_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Key tg_direct_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Key tg_unwrapped_direct_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Key tg_owner_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Key tg_ptee_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Key tg_unwrapped_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal U64 tg_byte_size_from_graph_rdi_key(TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_Kind tg_kind_from_key(TG_Key key); -internal TG_Member *tg_member_copy(Arena *arena, TG_Member *src); -internal TG_MemberArray tg_members_from_graph_rdi_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal TG_MemberArray tg_data_members_from_graph_rdi_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); -internal void tg_lhs_string_from_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key, String8List *out, U32 prec, B32 skip_return); -internal void tg_rhs_string_from_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key, String8List *out, U32 prec); -internal String8 tg_string_from_key(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi, TG_Key key); - -#endif // TYPE_GRAPH_H diff --git a/src/type_graph/type_graph.mdesk b/src/type_graph/type_graph.mdesk deleted file mode 100644 index 73eb9f3d..00000000 --- a/src/type_graph/type_graph.mdesk +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Tables - -@table(name basic_string basic_byte_size) -// NOTE(rjf): basic_byte_size == 0xFF? => address sized -TG_KindTable: -{ - {Null "" 0 } - {Void "void" 0 } - {Handle "HANDLE" 0xFF } - {Char8 "char8" 1 } - {Char16 "char16" 2 } - {Char32 "char32" 4 } - {UChar8 "uchar8" 1 } - {UChar16 "uchar16" 2 } - {UChar32 "uchar32" 4 } - {U8 "U8" 1 } - {U16 "U16" 2 } - {U32 "U32" 4 } - {U64 "U64" 8 } - {U128 "U128" 16 } - {U256 "U256" 32 } - {U512 "U512" 64 } - {S8 "S8" 1 } - {S16 "S16" 2 } - {S32 "S32" 4 } - {S64 "S64" 8 } - {S128 "S128" 16 } - {S256 "S256" 32 } - {S512 "S512" 64 } - {Bool "bool" 1 } - {F16 "F16" 2 } - {F32 "F32" 4 } - {F32PP "F32PP" 4 } - {F48 "F48" 6 } - {F64 "F64" 8 } - {F80 "F80" 10 } - {F128 "F128" 16 } - {ComplexF32 "ComplexF32" 8 } - {ComplexF64 "ComplexF64" 16 } - {ComplexF80 "ComplexF80" 20 } - {ComplexF128 "ComplexF128" 32 } - {Modifier "" 0 } - {Ptr "" 0 } - {LRef "" 0 } - {RRef "" 0 } - {Array "" 0 } - {Function "" 0 } - {Method "" 0 } - {MemberPtr "" 0 } - {Struct "struct" 0 } - {Class "class" 0 } - {Union "union" 0 } - {Enum "enum" 0 } - {Alias "typedef" 0 } - {IncompleteStruct "struct" 0 } - {IncompleteUnion "union" 0 } - {IncompleteClass "class" 0 } - {IncompleteEnum "enum" 0 } - {Bitfield "" 0 } - {Variadic "" 0 } -} - -//////////////////////////////// -//~ rjf: Generators - -@enum TG_Kind: -{ - @expand(TG_KindTable a) `$(a.name)`, - COUNT, - `FirstBasic = TG_Kind_Void`, - `LastBasic = TG_Kind_ComplexF128`, - `FirstInteger = TG_Kind_Char8`, - `LastInteger = TG_Kind_S512`, - `FirstSigned1 = TG_Kind_Char8`, - `LastSigned1 = TG_Kind_Char32`, - `FirstSigned2 = TG_Kind_S8`, - `LastSigned2 = TG_Kind_S512`, - `FirstIncomplete = TG_Kind_IncompleteStruct`, - `LastIncomplete = TG_Kind_IncompleteEnum`, -} - -@data(U8) tg_kind_basic_byte_size_table: -{ - @expand(TG_KindTable a) `$(a.basic_byte_size)`; -} - -@data(String8) tg_kind_basic_string_table: -{ - @expand(TG_KindTable a) `str8_lit_comp("$(a.basic_string)")`; -}