// Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) #ifndef METAGEN_H #define METAGEN_H //////////////////////////////// //~ rjf: Message Type typedef struct MG_Msg MG_Msg; struct MG_Msg { String8 location; String8 kind; String8 msg; }; typedef struct MG_MsgNode MG_MsgNode; struct MG_MsgNode { MG_MsgNode *next; MG_Msg v; }; typedef struct MG_MsgList MG_MsgList; struct MG_MsgList { MG_MsgNode *first; MG_MsgNode *last; U64 count; }; //////////////////////////////// //~ rjf: Parse Artifact Types typedef struct MG_FileParse MG_FileParse; struct MG_FileParse { MD_Node *root; }; typedef struct MG_FileParseNode MG_FileParseNode; struct MG_FileParseNode { MG_FileParseNode *next; MG_FileParse v; }; typedef struct MG_FileParseList MG_FileParseList; struct MG_FileParseList { MG_FileParseNode *first; MG_FileParseNode *last; U64 count; }; //////////////////////////////// //~ rjf: Map Type typedef struct MG_MapNode MG_MapNode; struct MG_MapNode { MG_MapNode *next; String8 key; void *val; }; typedef struct MG_MapSlot MG_MapSlot; struct MG_MapSlot { MG_MapNode *first; MG_MapNode *last; }; typedef struct MG_Map MG_Map; struct MG_Map { MG_MapSlot *slots; U64 slots_count; }; //////////////////////////////// //~ rjf: String Expression Types typedef enum MG_StrExprOpKind { MG_StrExprOpKind_Null, MG_StrExprOpKind_Prefix, MG_StrExprOpKind_Postfix, MG_StrExprOpKind_Binary, MG_StrExprOpKind_COUNT } MG_StrExprOpKind; typedef enum MG_StrExprOp { MG_StrExprOp_Null, #define MG_StrExprOp_FirstString MG_StrExprOp_Dot MG_StrExprOp_Dot, MG_StrExprOp_ExpandIfTrue, MG_StrExprOp_Concat, MG_StrExprOp_BumpToColumn, #define MG_StrExprOp_LastString MG_StrExprOp_BumpToColumn #define MG_StrExprOp_FirstNumeric MG_StrExprOp_Add MG_StrExprOp_Add, MG_StrExprOp_Subtract, MG_StrExprOp_Multiply, MG_StrExprOp_Divide, MG_StrExprOp_Modulo, MG_StrExprOp_LeftShift, MG_StrExprOp_RightShift, MG_StrExprOp_BitwiseAnd, MG_StrExprOp_BitwiseOr, MG_StrExprOp_BitwiseXor, MG_StrExprOp_BitwiseNegate, MG_StrExprOp_BooleanAnd, MG_StrExprOp_BooleanOr, MG_StrExprOp_BooleanNot, MG_StrExprOp_Equals, MG_StrExprOp_DoesNotEqual, #define MG_StrExprOp_LastNumeric MG_StrExprOp_DoesNotEqual MG_StrExprOp_COUNT, } MG_StrExprOp; typedef struct MG_StrExpr MG_StrExpr; struct MG_StrExpr { MG_StrExpr *parent; MG_StrExpr *left; MG_StrExpr *right; MG_StrExprOp op; MD_Node *node; }; typedef struct MG_StrExprParseResult MG_StrExprParseResult; struct MG_StrExprParseResult { MG_StrExpr *root; MD_MsgList msgs; MD_Node *next_node; }; //////////////////////////////// //~ rjf: Table Generation Types typedef struct MG_NodeArray MG_NodeArray; struct MG_NodeArray { MD_Node **v; U64 count; }; typedef struct MG_NodeGrid MG_NodeGrid; struct MG_NodeGrid { U64 x_stride; U64 y_stride; MG_NodeArray cells; MG_NodeArray row_parents; }; typedef enum MG_ColumnKind { MG_ColumnKind_DirectCell, MG_ColumnKind_CheckForTag, MG_ColumnKind_TagChild, MG_ColumnKind_COUNT } MG_ColumnKind; typedef struct MG_ColumnDesc MG_ColumnDesc; struct MG_ColumnDesc { String8 name; MG_ColumnKind kind; String8 tag_name; }; typedef struct MG_ColumnDescArray MG_ColumnDescArray; struct MG_ColumnDescArray { U64 count; MG_ColumnDesc *v; }; typedef struct MG_TableExpandTask MG_TableExpandTask; struct MG_TableExpandTask { MG_TableExpandTask *next; String8 expansion_label; MG_NodeGrid *grid; MG_ColumnDescArray column_descs; U64 count; U64 idx; }; typedef struct MG_TableExpandInfo MG_TableExpandInfo; struct MG_TableExpandInfo { MG_TableExpandTask *first_expand_task; String8 missing_value_fallback; }; //////////////////////////////// //~ rjf: Main Output Path Types typedef struct MG_Layer MG_Layer; struct MG_Layer { String8 key; B32 is_library; String8 gen_folder_name; String8 h_name_override; String8 c_name_override; String8List enums; String8List structs; String8List h_functions; String8List h_tables; String8List h_catchall; String8List h_header; String8List h_footer; String8List c_functions; String8List c_tables; String8List c_catchall; String8List c_header; String8List c_footer; }; typedef struct MG_LayerNode MG_LayerNode; struct MG_LayerNode { MG_LayerNode *next; MG_Layer v; }; typedef struct MG_LayerSlot MG_LayerSlot; struct MG_LayerSlot { MG_LayerNode *first; MG_LayerNode *last; }; typedef struct MG_State MG_State; struct MG_State { U64 slots_count; MG_LayerSlot *slots; }; //////////////////////////////// //~ rjf: Globals global Arena *mg_arena = 0; global MG_State *mg_state = 0; read_only global MG_StrExpr mg_str_expr_nil = {&mg_str_expr_nil, &mg_str_expr_nil, &mg_str_expr_nil}; //////////////////////////////// //~ rjf: Basic Helpers internal U64 mg_hash_from_string(String8 string); internal TxtPt mg_txt_pt_from_string_off(String8 string, U64 off); //////////////////////////////// //~ rjf: Message Lists internal void mg_msg_list_push(Arena *arena, MG_MsgList *msgs, MG_Msg *msg); //////////////////////////////// //~ rjf: String Escaping internal String8 mg_escaped_from_str8(Arena *arena, String8 string); //////////////////////////////// //~ rjf: String Wrapping internal String8List mg_wrapped_lines_from_string(Arena *arena, String8 string, U64 first_line_max_width, U64 max_width, U64 wrap_indent); //////////////////////////////// //~ rjf: C-String-Izing internal String8 mg_c_string_literal_from_multiline_string(String8 string); internal String8 mg_c_array_literal_contents_from_data(String8 data); //////////////////////////////// //~ rjf: Map Functions internal MG_Map mg_push_map(Arena *arena, U64 slot_count); internal void *mg_map_ptr_from_string(MG_Map *map, String8 string); internal void mg_map_insert_ptr(Arena *arena, MG_Map *map, String8 string, void *val); //////////////////////////////// //~ rjf: String Expression Parsing internal MG_StrExpr *mg_push_str_expr(Arena *arena, MG_StrExprOp op, MD_Node *node); internal MG_StrExprParseResult mg_str_expr_parse_from_first_opl__min_prec(Arena *arena, MD_Node *first, MD_Node *opl, S8 min_prec); internal MG_StrExprParseResult mg_str_expr_parse_from_first_opl(Arena *arena, MD_Node *first, MD_Node *opl); internal MG_StrExprParseResult mg_str_expr_parse_from_root(Arena *arena, MD_Node *root); //////////////////////////////// //~ rjf: Table Generation Functions internal MG_NodeArray mg_node_array_make(Arena *arena, U64 count); internal MG_NodeArray mg_child_array_from_node(Arena *arena, MD_Node *node); internal MG_NodeGrid mg_node_grid_make_from_node(Arena *arena, MD_Node *root); internal MG_NodeArray mg_row_from_index(MG_NodeGrid grid, U64 index); internal MG_NodeArray mg_column_from_index(Arena *arena, MG_NodeGrid grid, U64 index); internal MD_Node *mg_node_from_grid_xy(MG_NodeGrid grid, U64 x, U64 y); internal MG_ColumnDescArray mg_column_desc_array_make(Arena *arena, U64 count, MG_ColumnDesc *descs); internal MG_ColumnDescArray mg_column_desc_array_from_tag(Arena *arena, MD_Node *tag); internal U64 mg_column_index_from_name(MG_ColumnDescArray descs, String8 name); internal String8 mg_string_from_row_desc_idx(MD_Node *row_parent, MG_ColumnDescArray descs, U64 idx); internal S64 mg_eval_table_expand_expr__numeric(MG_StrExpr *expr, MG_TableExpandInfo *info); internal void mg_eval_table_expand_expr__string(Arena *arena, MG_StrExpr *expr, MG_TableExpandInfo *info, String8List *out); internal void mg_loop_table_column_expansion(Arena *arena, String8 strexpr, MG_TableExpandInfo *info, MG_TableExpandTask *task, String8List *out); internal String8List mg_string_list_from_table_gen(Arena *arena, MG_Map grid_name_map, MG_Map grid_column_desc_map, String8 fallback, MD_Node *gen); //////////////////////////////// //~ rjf: Layer Lookup Functions internal String8 mg_layer_key_from_path(String8 path); internal MG_Layer *mg_layer_from_key(String8 key); #endif //METAGEN_H