// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)

#ifndef EVAL_VISUALIZATION_CORE_H
#define EVAL_VISUALIZATION_CORE_H

////////////////////////////////
//~ rjf: Key Type (Uniquely Refers To One Tree Node)

typedef struct EV_Key EV_Key;
struct EV_Key
{
  U64 parent_hash;
  U64 child_id;
};

////////////////////////////////
//~ rjf: Visualization State Type

//- rjf: expand hash table & tree

typedef struct EV_ExpandNode EV_ExpandNode;
struct EV_ExpandNode
{
  EV_ExpandNode *hash_next;
  EV_ExpandNode *hash_prev;
  EV_ExpandNode *first;
  EV_ExpandNode *last;
  EV_ExpandNode *next;
  EV_ExpandNode *prev;
  EV_ExpandNode *parent;
  EV_Key key;
  B32 expanded;
};

typedef struct EV_ExpandSlot EV_ExpandSlot;
struct EV_ExpandSlot
{
  EV_ExpandNode *first;
  EV_ExpandNode *last;
};

//- rjf: hash table for view rules

typedef struct EV_KeyViewRuleNode EV_KeyViewRuleNode;
struct EV_KeyViewRuleNode
{
  EV_KeyViewRuleNode *hash_next;
  EV_KeyViewRuleNode *hash_prev;
  EV_Key key;
  U8 *buffer;
  U64 buffer_cap;
  U64 buffer_string_size;
};

typedef struct EV_KeyViewRuleSlot EV_KeyViewRuleSlot;
struct EV_KeyViewRuleSlot
{
  EV_KeyViewRuleNode *first;
  EV_KeyViewRuleNode *last;
};

//- rjf: view state bundle

typedef struct EV_View EV_View;
struct EV_View
{
  Arena *arena;
  EV_ExpandSlot *expand_slots;
  U64 expand_slots_count;
  EV_ExpandNode *free_expand_node;
  EV_KeyViewRuleSlot *key_view_rule_slots;
  U64 key_view_rule_slots_count;
  EV_KeyViewRuleNode *free_key_view_rule_node;
};

////////////////////////////////
//~ rjf: View Rule Instance Types

typedef struct EV_ViewRule EV_ViewRule;
struct EV_ViewRule
{
  MD_Node *root;
};

typedef struct EV_ViewRuleNode EV_ViewRuleNode;
struct EV_ViewRuleNode
{
  EV_ViewRuleNode *next;
  EV_ViewRule v;
};

typedef struct EV_ViewRuleList EV_ViewRuleList;
struct EV_ViewRuleList
{
  EV_ViewRuleNode *first;
  EV_ViewRuleNode *last;
  U64 count;
};

////////////////////////////////
//~ rjf: Blocks

typedef enum EV_BlockKind
{
  EV_BlockKind_Null,              // empty
  EV_BlockKind_Root,              // root of tree or subtree; possibly-expandable expression.
  EV_BlockKind_Members,           // members of struct, class, union
  EV_BlockKind_EnumMembers,       // members of enum
  EV_BlockKind_Elements,          // elements of array
  EV_BlockKind_Canvas,            // escape hatch for arbitrary UI
  EV_BlockKind_DebugInfoTable,    // block of filtered debug info table elements
  EV_BlockKind_COUNT,
}
EV_BlockKind;

typedef struct EV_Block EV_Block;
struct EV_Block
{
  // rjf: kind & keys
  EV_BlockKind kind;
  EV_Key parent_key;
  EV_Key key;
  S32 depth;
  
  // rjf: evaluation info
  String8 string;
  E_Expr *expr;
  
  // rjf: info about ranges that this block spans
  Rng1U64 visual_idx_range;
  Rng1U64 semantic_idx_range;
  
  // rjf: visualization info extensions
  EV_ViewRuleList *view_rules;
  E_MemberArray members;
  E_EnumValArray enum_vals;
  RDI_SectionKind fzy_target;
  FZY_ItemArray fzy_backing_items;
};

typedef struct EV_BlockNode EV_BlockNode;
struct EV_BlockNode
{
  EV_BlockNode *next;
  EV_BlockNode *prev;
  EV_Block v;
};

typedef struct EV_BlockList EV_BlockList;
struct EV_BlockList
{
  EV_BlockNode *first;
  EV_BlockNode *last;
  U64 count;
  U64 total_visual_row_count;
  U64 total_semantic_row_count;
};

////////////////////////////////
//~ rjf: View Rule Info Types

typedef struct EV_ExpandInfo EV_ExpandInfo;
struct EV_ExpandInfo
{
  void *user_data;
  U64 row_count;
  B32 single_item; // all rows form a single "item" - a singular, but large, row
  B32 add_new_row; // also supports an 'add new row', as the final row, within `row_count`
};

typedef struct EV_ExpandRangeInfo EV_ExpandRangeInfo;
struct EV_ExpandRangeInfo
{
  U64 row_exprs_count;
  String8 *row_strings;
  E_Expr **row_exprs;
  E_Member **row_members;
};

#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(name) E_Expr *name(Arena *arena, E_Expr *expr, MD_Node *params)
#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name) ev_view_rule_expr_resolution__##name
#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name))

#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(name) EV_ExpandInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params)
#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_info__##name
#define EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(name))

#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(name) EV_ExpandRangeInfo name(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data)
#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name) ev_view_rule_expr_expand_range_info__##name
#define EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(name))

#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(name) U64 name(U64 num, void *user_data)
#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name) ev_view_rule_expr_expand_id_from_num_##name
#define EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(name))

#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(name) U64 name(U64 id, void *user_data)
#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name) ev_view_rule_expr_expand_num_from_id_##name
#define EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(name))

#define EV_VIEW_RULE_BLOCK_PROD_FUNCTION_SIG(name) void name(Arena *arena,                                      \
EV_View *view,                                     \
String8 filter,                                    \
EV_Key parent_key,                                 \
EV_Key key,                                        \
EV_ExpandNode *expand_node,                        \
String8 string,                                    \
E_Expr *expr,                                      \
EV_ViewRuleList *view_rules,                       \
MD_Node *view_params,                              \
S32 depth,                                         \
struct EV_BlockList *out)
#define EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(name) ev_view_rule_block_prod__##name
#define EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(name) internal EV_VIEW_RULE_BLOCK_PROD_FUNCTION_SIG(EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(name))

typedef EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_ViewRuleExprResolutionHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandInfoHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_SIG(EV_ViewRuleExprExpandRangeInfoHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_SIG(EV_ViewRuleExprExpandIDFromNumHookFunctionType);
typedef EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_SIG(EV_ViewRuleExprExpandNumFromIDHookFunctionType);
typedef EV_VIEW_RULE_BLOCK_PROD_FUNCTION_SIG(EV_ViewRuleBlockProdHookFunctionType);

typedef U32 EV_ViewRuleInfoFlags; // NOTE(rjf): see @view_rule_info
enum
{
  EV_ViewRuleInfoFlag_Inherited      = (1<<0),
  EV_ViewRuleInfoFlag_Expandable     = (1<<1),
};

typedef struct EV_ViewRuleInfo EV_ViewRuleInfo;
struct EV_ViewRuleInfo
{
  String8 string;
  EV_ViewRuleInfoFlags flags;
  EV_ViewRuleExprResolutionHookFunctionType *expr_resolution;
  EV_ViewRuleExprExpandInfoHookFunctionType *expr_expand_info;
  EV_ViewRuleExprExpandRangeInfoHookFunctionType *expr_expand_range_info;
  EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_id_from_num;
  EV_ViewRuleExprExpandIDFromNumHookFunctionType *expr_expand_num_from_id;
  EV_ViewRuleBlockProdHookFunctionType *block_prod;
};

typedef struct EV_ViewRuleInfoNode EV_ViewRuleInfoNode;
struct EV_ViewRuleInfoNode
{
  EV_ViewRuleInfoNode *next;
  EV_ViewRuleInfo v;
};

typedef struct EV_ViewRuleInfoSlot EV_ViewRuleInfoSlot;
struct EV_ViewRuleInfoSlot
{
  EV_ViewRuleInfoNode *first;
  EV_ViewRuleInfoNode *last;
};

typedef struct EV_ViewRuleInfoTable EV_ViewRuleInfoTable;
struct EV_ViewRuleInfoTable
{
  EV_ViewRuleInfoSlot *slots;
  U64 slots_count;
};

////////////////////////////////
//~ rjf: Blocks (v2)

typedef struct EV2_Block EV2_Block;
struct EV2_Block
{
  // rjf: links
  EV2_Block *first;
  EV2_Block *last;
  EV2_Block *next;
  EV2_Block *prev;
  EV2_Block *parent;
  
  // rjf: key
  EV_Key key;
  
  // rjf: split index, relative to parent's space
  U64 split_relative_idx;
  
  // rjf: expression / visualization info
  String8 string;
  E_Expr *expr;
  EV_ViewRuleList *view_rules;
  EV_ViewRuleInfo *expand_view_rule_info;
  MD_Node *expand_view_rule_params;
  void *expand_view_rule_info_user_data;
  
  // rjf: expansion info
  U64 row_count;
  B32 single_item;
};

typedef struct EV2_BlockTree EV2_BlockTree;
struct EV2_BlockTree
{
  EV2_Block *root;
  U64 total_row_count;
  U64 total_item_count;
};

typedef struct EV2_BlockRange EV2_BlockRange;
struct EV2_BlockRange
{
  EV2_Block *block;
  Rng1U64 range;
};

typedef struct EV2_BlockRangeNode EV2_BlockRangeNode;
struct EV2_BlockRangeNode
{
  EV2_BlockRangeNode *next;
  EV2_BlockRange v;
};

typedef struct EV2_BlockRangeList EV2_BlockRangeList;
struct EV2_BlockRangeList
{
  EV2_BlockRangeNode *first;
  EV2_BlockRangeNode *last;
  U64 count;
};

////////////////////////////////
//~ rjf: Rows (v2)

typedef struct EV2_Row EV2_Row;
struct EV2_Row
{
  EV2_Row *next;
  
  // rjf: block hierarchy info
  EV2_Block *block;
  EV_Key key;
  
  // rjf: row size/scroll info
  U64 visual_size;
  U64 visual_size_skipped;
  U64 visual_size_chopped;
  
  // rjf: expression / visualization info
  String8 string;
  E_Expr *expr;
  E_Member *member;
  EV_ViewRuleList *view_rules;
};

typedef struct EV2_WindowedRowList EV2_WindowedRowList;
struct EV2_WindowedRowList
{
  EV2_Row *first;
  EV2_Row *last;
  U64 count;
  U64 count_before_visual;
  U64 count_before_semantic;
};

////////////////////////////////
//~ rjf: Automatic Type -> View Rule Map Types

typedef struct EV_AutoViewRuleNode EV_AutoViewRuleNode;
struct EV_AutoViewRuleNode
{
  EV_AutoViewRuleNode *next;
  E_TypeKey key;
  String8 view_rule;
};

typedef struct EV_AutoViewRuleSlot EV_AutoViewRuleSlot;
struct EV_AutoViewRuleSlot
{
  EV_AutoViewRuleNode *first;
  EV_AutoViewRuleNode *last;
  U64 count;
};

typedef struct EV_AutoViewRuleTable EV_AutoViewRuleTable;
struct EV_AutoViewRuleTable
{
  EV_AutoViewRuleSlot *slots;
  U64 slots_count;
};

////////////////////////////////
//~ rjf: Generated Code

#include "generated/eval_visualization.meta.h"

////////////////////////////////
//~ rjf: Rows

typedef U32 EV_StringFlags;
enum
{
  EV_StringFlag_ReadOnlyDisplayRules = (1<<0),
  EV_StringFlag_PrettyNames          = (1<<1),
};

typedef struct EV_Row EV_Row;
struct EV_Row
{
  EV_Row *next;
  
  // rjf: block hierarchy info
  EV_BlockKind block_kind;
  S32 depth;
  EV_Key parent_key;
  EV_Key key;
  
  // rjf: row size/scroll info
  U64 size_in_rows;
  U64 skipped_size_in_rows;
  U64 chopped_size_in_rows;
  
  // rjf: evaluation expression
  String8 string;
  E_Member *member;
  E_Expr *expr;
  
  // rjf: view rule attachments
  EV_ViewRuleList *view_rules;
};

typedef struct EV_WindowedRowList EV_WindowedRowList;
struct EV_WindowedRowList
{
  EV_Row *first;
  EV_Row *last;
  U64 count;
  U64 count_before_visual;
  U64 count_before_semantic;
};

////////////////////////////////
//~ rjf: Nil/Identity View Rule Hooks

EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(identity);
EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_DEF(nil);
EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_DEF(nil);
EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_DEF(identity);
EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity);

////////////////////////////////
//~ rjf: Globals

global read_only EV_ViewRuleInfo ev_nil_view_rule_info =
{
  {0},
  0,
  EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(identity),
  EV_VIEW_RULE_EXPR_EXPAND_INFO_FUNCTION_NAME(nil),
  EV_VIEW_RULE_EXPR_EXPAND_RANGE_INFO_FUNCTION_NAME(nil),
  EV_VIEW_RULE_EXPR_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity),
  EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity),
};
thread_static EV_ViewRuleInfoTable *ev_view_rule_info_table = 0;
global read_only EV_ViewRuleList ev_nil_view_rule_list = {0};
thread_static EV_AutoViewRuleTable *ev_auto_view_rule_table = 0;
global read_only EV2_Block ev2_nil_block = {&ev2_nil_block, &ev2_nil_block, &ev2_nil_block, &ev2_nil_block, &ev2_nil_block, {0}, 0, {0}, &e_expr_nil, &ev_nil_view_rule_list, &ev_nil_view_rule_info};

////////////////////////////////
//~ rjf: Key Functions

internal EV_Key ev_key_make(U64 parent_hash, U64 child_id);
internal EV_Key ev_key_zero(void);
internal EV_Key ev_key_root(void);
internal B32 ev_key_match(EV_Key a, EV_Key b);
internal U64 ev_hash_from_seed_string(U64 seed, String8 string);
internal U64 ev_hash_from_key(EV_Key key);

////////////////////////////////
//~ rjf: Type Info Helpers

//- rjf: type info -> expandability/editablity
internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode);
internal B32 ev_type_key_is_editable(E_TypeKey type_key);

////////////////////////////////
//~ rjf: View Functions

//- rjf: creation / deletion
internal EV_View *ev_view_alloc(void);
internal void ev_view_release(EV_View *view);

//- rjf: lookups / mutations
internal EV_ExpandNode *ev_expand_node_from_key(EV_View *view, EV_Key key);
internal B32 ev_expansion_from_key(EV_View *view, EV_Key key);
internal String8 ev_view_rule_from_key(EV_View *view, EV_Key key);
internal void ev_key_set_expansion(EV_View *view, EV_Key parent_key, EV_Key key, B32 expanded);
internal void ev_key_set_view_rule(EV_View *view, EV_Key key, String8 view_rule_string);

////////////////////////////////
//~ rjf: View Rule Info Table Building / Selection / Lookups

internal void ev_view_rule_info_table_push(Arena *arena, EV_ViewRuleInfoTable *table, EV_ViewRuleInfo *info);
internal void ev_view_rule_info_table_push_builtins(Arena *arena, EV_ViewRuleInfoTable *table);
internal void ev_select_view_rule_info_table(EV_ViewRuleInfoTable *table);
internal EV_ViewRuleInfo *ev_view_rule_info_from_string(String8 string);

////////////////////////////////
//~ rjf: Automatic Type -> View Rule Table Building / Selection / Lookups

internal void ev_auto_view_rule_table_push_new(Arena *arena, EV_AutoViewRuleTable *table, E_TypeKey type_key, String8 view_rule);
internal void ev_select_auto_view_rule_table(EV_AutoViewRuleTable *table);
internal String8 ev_auto_view_rule_from_type_key(E_TypeKey type_key);

////////////////////////////////
//~ rjf: View Rule Instance List Building

internal void ev_view_rule_list_push_tree(Arena *arena, EV_ViewRuleList *list, MD_Node *root);
internal void ev_view_rule_list_push_string(Arena *arena, EV_ViewRuleList *list, String8 string);
internal EV_ViewRuleList *ev_view_rule_list_from_string(Arena *arena, String8 string);
internal EV_ViewRuleList *ev_view_rule_list_from_inheritance(Arena *arena, EV_ViewRuleList *src);
internal EV_ViewRuleList *ev_view_rule_list_copy(Arena *arena, EV_ViewRuleList *src);

////////////////////////////////
//~ rjf: View Rule Expression Resolution

internal E_Expr *ev_expr_from_expr_view_rules(Arena *arena, E_Expr *expr, EV_ViewRuleList *view_rules);

////////////////////////////////
//~ rjf: Block Building (v2)

internal EV2_BlockTree ev2_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules);
internal EV2_BlockTree ev2_block_tree_from_string(Arena *arena, EV_View *view, String8 filter, String8 string, EV_ViewRuleList *view_rules);
internal U64 ev2_depth_from_block(EV2_Block *block);

////////////////////////////////
//~ rjf: Block Coordinate Spaces (v2)

internal EV2_BlockRangeList ev2_block_range_list_from_tree(Arena *arena, EV2_BlockTree *block_tree);
internal EV2_BlockRange ev2_block_range_from_num(EV2_BlockRangeList *block_ranges, U64 num);
internal EV_Key ev2_key_from_num(EV2_BlockRangeList *block_ranges, U64 num);
internal U64    ev2_num_from_key(EV2_BlockRangeList *block_ranges, EV_Key key);

////////////////////////////////
//~ rjf: Row Building (v2)

internal EV2_WindowedRowList ev2_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 filter, EV2_BlockRangeList *block_ranges, Rng1U64 visible_range);
internal String8 ev2_expr_string_from_row(Arena *arena, EV2_Row *row, EV_StringFlags flags);
internal B32 ev2_row_is_expandable(EV2_Row *row);
internal B32 ev2_row_is_editable(EV2_Row *row);

////////////////////////////////
//~ rjf: Block Building

internal EV_Block *ev_block_begin(Arena *arena, EV_BlockKind kind, EV_Key parent_key, EV_Key key, S32 depth);
internal EV_Block *ev_block_split_and_continue(Arena *arena, EV_BlockList *list, EV_Block *split_block, U64 split_idx);
internal void ev_block_end(EV_BlockList *list, EV_Block *block);
internal void ev_append_expr_blocks__rec(Arena *arena, EV_View *view, String8 filter, EV_Key parent_key, EV_Key key, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, S32 depth, EV_BlockList *list_out);
internal EV_BlockList ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, String8 filter, EV_ViewRuleList *view_rules, String8 expr, EV_Key parent_key, EV_Key key, S32 depth);
internal void ev_block_list_concat__in_place(EV_BlockList *dst, EV_BlockList *to_push);

////////////////////////////////
//~ rjf: Block List <-> Row Coordinates

internal S64 ev_row_num_from_block_list_key(EV_BlockList *blocks, EV_Key key);
internal EV_Key ev_key_from_block_list_row_num(EV_BlockList *blocks, S64 row_num);
internal EV_Key ev_parent_key_from_block_list_row_num(EV_BlockList *blocks, S64 row_num);

////////////////////////////////
//~ rjf: Block * Index -> Expressions

internal E_Expr *ev_expr_from_block_index(Arena *arena, EV_Block *block, U64 index);

////////////////////////////////
//~ rjf: Row Lists

internal EV_Row *ev_row_list_push_new(Arena *arena, EV_View *view, EV_WindowedRowList *rows, EV_Block *block, EV_Key key, E_Expr *expr);
internal EV_WindowedRowList ev_windowed_row_list_from_block_list(Arena *arena, EV_View *view, Rng1S64 visible_range, EV_BlockList *blocks);
internal String8 ev_expr_string_from_row(Arena *arena, EV_Row *row, EV_StringFlags );
internal B32 ev_row_is_expandable(EV_Row *row);
internal B32 ev_row_is_editable(EV_Row *row);

////////////////////////////////
//~ rjf: Stringification

//- rjf: leaf stringification
internal String8 ev_string_from_ascii_value(Arena *arena, U8 val);
internal String8 ev_string_from_hresult_facility_code(U32 code);
internal String8 ev_string_from_hresult_code(U32 code);
internal String8 ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, E_Eval eval);
internal String8 ev_escaped_from_raw_string(Arena *arena, String8 raw);

#endif // EVAL_VISUALIZATION_CORE_H
