582 lines
23 KiB
C
582 lines
23 KiB
C
|
static MD_Map cg_tbl_top_level_node_grid_map = {0};
|
||
|
static MD_Map cg_tbl_top_level_table_header_map = {0};
|
||
|
|
||
|
static MD_Map cg_tbl_layer_map_gen = {0};
|
||
|
static MD_Map cg_tbl_layer_map_gen_enum = {0};
|
||
|
static MD_Map cg_tbl_layer_map_gen_data = {0};
|
||
|
|
||
|
static MD_String8 cg_tbl_tag__table = MD_S8LitComp("table");
|
||
|
static MD_String8 cg_tbl_tag__table_gen = MD_S8LitComp("table_gen");
|
||
|
static MD_String8 cg_tbl_tag__table_gen_enum = MD_S8LitComp("table_gen_enum");
|
||
|
static MD_String8 cg_tbl_tag__table_gen_data = MD_S8LitComp("table_gen_data");
|
||
|
|
||
|
static CG_NodeArray
|
||
|
CG_NodeArrayMake(MD_u64 count)
|
||
|
{
|
||
|
CG_NodeArray result = {0};
|
||
|
result.count = count;
|
||
|
result.v = MD_PushArrayZero(cg_arena, MD_Node *, result.count);
|
||
|
for(MD_u64 idx = 0; idx < result.count; idx += 1)
|
||
|
{
|
||
|
result.v[idx] = MD_NilNode();
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static CG_NodeGrid
|
||
|
CG_GridFromNode(MD_Node *node)
|
||
|
{
|
||
|
CG_NodeGrid grid = {0};
|
||
|
|
||
|
//- rjf: determine dimensions
|
||
|
MD_u64 row_count = 0;
|
||
|
MD_u64 column_count = 0;
|
||
|
{
|
||
|
for(MD_EachNode(row, node->first_child))
|
||
|
{
|
||
|
row_count += 1;
|
||
|
MD_u64 cell_count_this_row = MD_ChildCountFromNode(row);
|
||
|
column_count = MD_Max(cell_count_this_row, column_count);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//- rjf: allocate cells / row parents
|
||
|
{
|
||
|
grid.cells = CG_NodeArrayMake(row_count * column_count);
|
||
|
grid.row_parents = CG_NodeArrayMake(row_count);
|
||
|
}
|
||
|
|
||
|
//- rjf: fill cells
|
||
|
{
|
||
|
MD_u64 row_idx = 0;
|
||
|
for(MD_EachNode(row, node->first_child))
|
||
|
{
|
||
|
MD_u64 col_idx = 0;
|
||
|
grid.row_parents.v[row_idx] = row;
|
||
|
for(MD_EachNode(cell, row->first_child))
|
||
|
{
|
||
|
grid.cells.v[row_idx * column_count + col_idx] = cell;
|
||
|
col_idx += 1;
|
||
|
}
|
||
|
row_idx += 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return grid;
|
||
|
}
|
||
|
|
||
|
static CG_TableHeader
|
||
|
CG_TableHeaderFromTag(MD_Node *tag)
|
||
|
{
|
||
|
CG_TableHeader result = {0};
|
||
|
result.column_count = MD_ChildCountFromNode(tag);
|
||
|
result.column_descs = MD_PushArrayZero(cg_arena, CG_ColumnDesc, result.column_count);
|
||
|
MD_u64 idx = 0;
|
||
|
for(MD_EachNode(column_node, tag->first_child))
|
||
|
{
|
||
|
result.column_descs[idx].kind = CG_ColumnKind_Default;
|
||
|
result.column_descs[idx].name = column_node->string;
|
||
|
MD_Node *check_for_tag = MD_TagFromString(column_node, MD_S8Lit("check_for_tag"), 0);
|
||
|
if(!MD_NodeIsNil(check_for_tag))
|
||
|
{
|
||
|
result.column_descs[idx].kind = CG_ColumnKind_CheckForTag;
|
||
|
result.column_descs[idx].tag_string = check_for_tag->first_child->string;
|
||
|
}
|
||
|
MD_Node *default_value = MD_TagFromString(column_node, MD_S8Lit("default"), 0);
|
||
|
if(!MD_NodeIsNil(default_value))
|
||
|
{
|
||
|
result.column_descs[idx].default_value = default_value->first_child->string;
|
||
|
}
|
||
|
idx += 1;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static MD_u64
|
||
|
CG_RowChildIndexFromColumnName(CG_TableHeader *header, MD_String8 column_name)
|
||
|
{
|
||
|
MD_u64 result = 0;
|
||
|
for(MD_u64 idx = 0; idx < header->column_count; idx += 1)
|
||
|
{
|
||
|
if(MD_S8Match(header->column_descs[idx].name, column_name, 0))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if(header->column_descs[idx].kind == CG_ColumnKind_Default)
|
||
|
{
|
||
|
result += 1;
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static MD_i64
|
||
|
CG_TableExprEvaluate_Numeric(CG_ExpandInfo *info, MD_Expr *expr)
|
||
|
{
|
||
|
MD_i64 result = 0;
|
||
|
CG_TableOp op = expr->op ? expr->op->op_id : CG_TableOp_Null;
|
||
|
switch(op)
|
||
|
{
|
||
|
case CG_TableOp_Equal:
|
||
|
case CG_TableOp_IsNotEqual:
|
||
|
{
|
||
|
MD_ArenaTemp scratch = MD_GetScratch(0, 0);
|
||
|
MD_String8List left_strs = {0};
|
||
|
MD_String8List right_strs = {0};
|
||
|
CG_TableExprEvaluate_String(info, expr->left, &left_strs);
|
||
|
CG_TableExprEvaluate_String(info, expr->right, &right_strs);
|
||
|
MD_String8 left_str = MD_S8ListJoin(scratch.arena, left_strs, 0);
|
||
|
MD_String8 right_str = MD_S8ListJoin(scratch.arena, right_strs, 0);
|
||
|
result = MD_S8Match(left_str, right_str, 0);
|
||
|
if(op == CG_TableOp_IsNotEqual)
|
||
|
{
|
||
|
result = !result;
|
||
|
}
|
||
|
MD_ReleaseScratch(scratch);
|
||
|
}break;
|
||
|
|
||
|
case CG_TableOp_BooleanAnd:
|
||
|
case CG_TableOp_BooleanOr:
|
||
|
{
|
||
|
MD_i64 left = CG_TableExprEvaluate_Numeric(info, expr->left);
|
||
|
MD_i64 right = CG_TableExprEvaluate_Numeric(info, expr->right);
|
||
|
switch(op)
|
||
|
{
|
||
|
case CG_TableOp_BooleanAnd: result = left && right; break;
|
||
|
case CG_TableOp_BooleanOr: result = left || right; break;
|
||
|
}
|
||
|
}break;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
CG_TableExprEvaluate_String(CG_ExpandInfo *info, MD_Expr *expr, MD_String8List *out)
|
||
|
{
|
||
|
CG_TableOp op = expr->op ? expr->op->op_id : CG_TableOp_Null;
|
||
|
switch(op)
|
||
|
{
|
||
|
default:
|
||
|
case CG_TableOp_Null:
|
||
|
{
|
||
|
MD_S8ListPush(cg_arena, out, expr->md_node->string);
|
||
|
}break;
|
||
|
|
||
|
case CG_TableOp_Dot:
|
||
|
{
|
||
|
MD_Expr *label_expr = expr->left;
|
||
|
MD_Expr *column_query_expr = expr->right;
|
||
|
MD_Node *label_node = label_expr->md_node;
|
||
|
MD_Node *column_query_node = column_query_expr->md_node;
|
||
|
MD_String8 label = label_node->string;
|
||
|
MD_String8 column_query = column_query_node->string;
|
||
|
MD_b32 column_query_is_by_expand_idx = MD_S8Match(column_query_node->string, MD_S8Lit("_it"), 0);
|
||
|
MD_b32 column_query_is_by_name = !column_query_is_by_expand_idx && column_query_node->flags & MD_NodeFlag_Identifier;
|
||
|
MD_b32 column_query_is_by_index = column_query_node->flags & MD_NodeFlag_Numeric;
|
||
|
|
||
|
// rjf: find which expansion this label refers to, grab its iterator
|
||
|
CG_ExpandIter *iter = 0;
|
||
|
for(CG_ExpandIter *it = info->first_expand_iter; it != 0; it = it->next)
|
||
|
{
|
||
|
if(MD_S8Match(it->label, label, 0))
|
||
|
{
|
||
|
iter = it;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// rjf: error on invalid label
|
||
|
if(iter == 0)
|
||
|
{
|
||
|
MD_PrintMessageFmt(stderr, MD_CodeLocFromNode(label_node), MD_MessageKind_Error, "Expansion label \"%S\" was not found as referring to a valid @expand tag.", label);
|
||
|
}
|
||
|
|
||
|
// rjf: generate strings from iterator's table
|
||
|
if(iter != 0)
|
||
|
{
|
||
|
CG_NodeGrid *grid = iter->grid;
|
||
|
CG_TableHeader *header = iter->header;
|
||
|
MD_Node *row = grid->row_parents.v[iter->idx];
|
||
|
|
||
|
// rjf: grab the cell string given the row & column_query
|
||
|
MD_String8 cell_string = {0};
|
||
|
{
|
||
|
// NOTE(rjf): expansion index counter
|
||
|
if(column_query_is_by_expand_idx)
|
||
|
{
|
||
|
MD_i64 index = iter->idx;
|
||
|
cell_string = MD_S8Fmt(cg_arena, "%" PRIu64 "", index);
|
||
|
}
|
||
|
|
||
|
// NOTE(rjf): by-name index (look into table header)
|
||
|
else if(column_query_is_by_name && header != 0)
|
||
|
{
|
||
|
MD_u64 column_idx = 0;
|
||
|
CG_ColumnDesc *column = 0;
|
||
|
for(MD_u64 col_idx = 0; col_idx < header->column_count; col_idx += 1)
|
||
|
{
|
||
|
if(MD_S8Match(header->column_descs[col_idx].name, column_query, 0))
|
||
|
{
|
||
|
column = &header->column_descs[col_idx];
|
||
|
column_idx = col_idx;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
MD_u64 row_child_idx = CG_RowChildIndexFromColumnName(header, column_query);
|
||
|
|
||
|
// rjf: error on invalid column
|
||
|
if(column == 0)
|
||
|
{
|
||
|
MD_PrintMessageFmt(stderr, MD_CodeLocFromNode(column_query_node), MD_MessageKind_Error, "Column query \"%S\" did not map to a valid column for expansion label \"%S\".", column_query, label);
|
||
|
}
|
||
|
|
||
|
if(column != 0)
|
||
|
{
|
||
|
switch(column->kind)
|
||
|
{
|
||
|
default:
|
||
|
case CG_ColumnKind_Default:
|
||
|
{
|
||
|
MD_Node *cell_node = MD_ChildFromIndex(row, row_child_idx);
|
||
|
cell_string = cell_node->string;
|
||
|
if(MD_S8Match(cell_node->raw_string, MD_S8Lit("."), 0))
|
||
|
{
|
||
|
cell_string = column->default_value;
|
||
|
}
|
||
|
}break;
|
||
|
|
||
|
case CG_ColumnKind_CheckForTag:
|
||
|
{
|
||
|
MD_b32 has_tag = MD_NodeHasTag(row, column->tag_string, 0);
|
||
|
cell_string = has_tag ? MD_S8Lit("1") : MD_S8Lit("0");
|
||
|
}break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// NOTE(rjf): by-index (grab nth child of row)
|
||
|
else if(column_query_is_by_index)
|
||
|
{
|
||
|
MD_i64 index = MD_CStyleIntFromString(column_query);
|
||
|
cell_string = MD_ChildFromIndex(row, index)->string;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
MD_S8ListPush(cg_arena, out, cell_string);
|
||
|
}
|
||
|
|
||
|
}break;
|
||
|
|
||
|
case CG_TableOp_Bump:
|
||
|
{
|
||
|
MD_u64 dst = MD_CStyleIntFromString(expr->unary_operand->md_node->string);
|
||
|
MD_u64 src = out->total_size;
|
||
|
MD_u64 spaces_to_print = dst - src;
|
||
|
if(dst > src)
|
||
|
{
|
||
|
for(MD_u64 space_idx = 0; space_idx < spaces_to_print; space_idx += 1)
|
||
|
{
|
||
|
MD_S8ListPush(cg_arena, out, MD_S8Lit(" "));
|
||
|
}
|
||
|
}
|
||
|
}break;
|
||
|
|
||
|
case CG_TableOp_CheckIfTrue:
|
||
|
{
|
||
|
MD_i64 check_val = CG_TableExprEvaluate_Numeric(info, expr->left);
|
||
|
if(check_val)
|
||
|
{
|
||
|
CG_TableExprEvaluate_String(info, expr->right, out);
|
||
|
}
|
||
|
}break;
|
||
|
|
||
|
case CG_TableOp_Concat:
|
||
|
{
|
||
|
CG_TableExprEvaluate_String(info, expr->left, out);
|
||
|
CG_TableExprEvaluate_String(info, expr->right, out);
|
||
|
}break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
CG_LoopExpansionDimension(CG_ExpandIter *it, CG_ExpandInfo *info, MD_String8List *out)
|
||
|
{
|
||
|
if(it->next)
|
||
|
{
|
||
|
for(MD_u64 idx = 0; idx < it->count; idx += 1)
|
||
|
{
|
||
|
it->idx = idx;
|
||
|
CG_LoopExpansionDimension(it->next, info, out);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(MD_u64 idx = 0; idx < it->count; idx += 1)
|
||
|
{
|
||
|
it->idx = idx;
|
||
|
MD_String8List expansion_strs = {0};
|
||
|
MD_u64 start_idx = 0;
|
||
|
for(MD_u64 char_idx = 0; char_idx <= info->strexpr.size; char_idx += 1)
|
||
|
{
|
||
|
MD_b32 is_expr_marker = info->strexpr.str[char_idx] == '$';
|
||
|
|
||
|
// rjf: push regular string contents
|
||
|
if(char_idx == info->strexpr.size || is_expr_marker)
|
||
|
{
|
||
|
MD_String8 normal_string_chunk = MD_S8Substring(info->strexpr, start_idx, char_idx);
|
||
|
MD_String8 escaped = CG_EscapedFromString(cg_arena, normal_string_chunk);
|
||
|
MD_S8ListPush(cg_arena, &expansion_strs, escaped);
|
||
|
}
|
||
|
|
||
|
// rjf: handle expansion
|
||
|
if(is_expr_marker)
|
||
|
{
|
||
|
MD_String8 expr_string = MD_S8Skip(info->strexpr, char_idx+1);
|
||
|
{
|
||
|
MD_i64 paren_nest = 0;
|
||
|
for(MD_u64 expr_str_char_idx = 0; expr_str_char_idx < expr_string.size; expr_str_char_idx += 1)
|
||
|
{
|
||
|
if(expr_string.str[expr_str_char_idx] == '(')
|
||
|
{
|
||
|
paren_nest += 1;
|
||
|
}
|
||
|
else if(expr_string.str[expr_str_char_idx] == ')')
|
||
|
{
|
||
|
paren_nest -= 1;
|
||
|
if(paren_nest == 0)
|
||
|
{
|
||
|
expr_string.size = expr_str_char_idx+1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
MD_ParseResult parse = MD_ParseOneNode(cg_arena, expr_string, 0);
|
||
|
MD_Node *node = parse.node;
|
||
|
MD_ExprParseResult expr_parse = MD_ExprParse(cg_arena, &info->expr_op_table, node->first_child, MD_NilNode());
|
||
|
MD_Expr *expr = expr_parse.expr;
|
||
|
CG_TableExprEvaluate_String(info, expr, &expansion_strs);
|
||
|
MD_String8 parsed_string = MD_S8Substring(info->strexpr, char_idx+1, char_idx+1+parse.string_advance);
|
||
|
parsed_string = MD_S8ChopWhitespace(parsed_string);
|
||
|
start_idx = char_idx+1+parsed_string.size;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// rjf: push expansion string to output list
|
||
|
MD_String8 expansion_str = MD_S8ListJoin(cg_arena, expansion_strs, 0);
|
||
|
MD_S8ListPush(cg_arena, out, expansion_str);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static MD_String8List
|
||
|
CG_GenStringListFromNode(MD_ExprOprTable expr_op_table, MD_Node *gen)
|
||
|
{
|
||
|
MD_String8List result = {0};
|
||
|
MD_ArenaTemp scratch = MD_GetScratch(0, 0);
|
||
|
|
||
|
for(MD_EachNode(strexpr, gen->first_child))
|
||
|
{
|
||
|
//- rjf: build expansion iterator list
|
||
|
CG_ExpandIter *first_iter = 0;
|
||
|
CG_ExpandIter *last_iter = 0;
|
||
|
{
|
||
|
for(MD_EachNode(tag, strexpr->first_tag))
|
||
|
{
|
||
|
if(MD_S8Match(tag->string, MD_S8Lit("expand"), 0))
|
||
|
{
|
||
|
MD_Node *table_name_node = MD_ChildFromIndex(tag, 0);
|
||
|
MD_Node *label_node = MD_ChildFromIndex(tag, 1);
|
||
|
MD_String8 table_name = table_name_node->string;
|
||
|
MD_String8 label = label_node->string;
|
||
|
|
||
|
// rjf: grab the table associated with table_name
|
||
|
CG_NodeGrid *grid = 0;
|
||
|
{
|
||
|
MD_MapSlot *slot = MD_MapLookup(&cg_tbl_top_level_node_grid_map, MD_MapKeyStr(table_name));
|
||
|
if(slot != 0)
|
||
|
{
|
||
|
grid = slot->val;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// rjf: grab the table header associated with table_name
|
||
|
CG_TableHeader *header = 0;
|
||
|
{
|
||
|
MD_MapSlot *slot = MD_MapLookup(&cg_tbl_top_level_table_header_map, MD_MapKeyStr(table_name));
|
||
|
if(slot != 0)
|
||
|
{
|
||
|
header = slot->val;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// rjf: make iterator node if we got a grid
|
||
|
if(grid != 0)
|
||
|
{
|
||
|
CG_ExpandIter *iter = MD_PushArrayZero(scratch.arena, CG_ExpandIter, 1);
|
||
|
MD_QueuePush(first_iter, last_iter, iter);
|
||
|
iter->grid = grid;
|
||
|
iter->header = header;
|
||
|
iter->label = label;
|
||
|
iter->count = grid->row_parents.count;
|
||
|
}
|
||
|
|
||
|
// rjf: print out an error if grid is 0
|
||
|
if(grid == 0)
|
||
|
{
|
||
|
MD_PrintMessageFmt(stderr, MD_CodeLocFromNode(tag), MD_MessageKind_Error, "Table \"%S\" was not found.", table_name);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//- rjf: generate string list for this strexpr & push to result
|
||
|
if(first_iter != 0)
|
||
|
{
|
||
|
CG_ExpandInfo info = {0};
|
||
|
{
|
||
|
info.strexpr = strexpr->string;
|
||
|
info.first_expand_iter = first_iter;
|
||
|
info.expr_op_table = expr_op_table;
|
||
|
}
|
||
|
CG_LoopExpansionDimension(first_iter, &info, &result);
|
||
|
}
|
||
|
//- rjf: generate non-expansion strings
|
||
|
else
|
||
|
{
|
||
|
MD_String8 escaped = CG_EscapedFromString(cg_arena, strexpr->string);
|
||
|
MD_S8ListPush(cg_arena, &result, escaped);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
MD_ReleaseScratch(scratch);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
CG_TBL_Generate(MD_Node *file_list)
|
||
|
{
|
||
|
//- rjf: initialize all maps
|
||
|
cg_tbl_top_level_node_grid_map = MD_MapMake(cg_arena);
|
||
|
cg_tbl_top_level_table_header_map = MD_MapMake(cg_arena);
|
||
|
cg_tbl_layer_map_gen = MD_MapMake(cg_arena);
|
||
|
cg_tbl_layer_map_gen_enum = MD_MapMake(cg_arena);
|
||
|
cg_tbl_layer_map_gen_data = MD_MapMake(cg_arena);
|
||
|
|
||
|
//- rjf: build table expression operator table
|
||
|
MD_ExprOprTable table_expr_op_table = {0};
|
||
|
{
|
||
|
MD_ExprOprList ops_list = {0};
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Binary, 10, MD_S8Lit("."), CG_TableOp_Dot, 0);
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Prefix, 9, MD_S8Lit("=>"), CG_TableOp_Bump, 0);
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Binary, 6, MD_S8Lit("??"), CG_TableOp_CheckIfTrue, 0);
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Binary, 7, MD_S8Lit(".."), CG_TableOp_Concat, 0);
|
||
|
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Binary, 8, MD_S8Lit("=="), CG_TableOp_Equal, 0);
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Binary, 8, MD_S8Lit("!="), CG_TableOp_IsNotEqual, 0);
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Binary, 5, MD_S8Lit("&&"), CG_TableOp_BooleanAnd, 0);
|
||
|
MD_ExprOprPush(cg_arena, &ops_list, MD_ExprOprKind_Binary, 4, MD_S8Lit("||"), CG_TableOp_BooleanOr, 0);
|
||
|
table_expr_op_table = MD_ExprBakeOprTableFromList(cg_arena, &ops_list);
|
||
|
}
|
||
|
|
||
|
//- rjf: gather phase
|
||
|
for(MD_EachNode(file_ref, file_list->first_child))
|
||
|
{
|
||
|
MD_Node *file = MD_ResolveNodeFromReference(file_ref);
|
||
|
MD_String8 layer_name = file->string;
|
||
|
MD_MapKey layer_key = MD_MapKeyStr(layer_name);
|
||
|
for(MD_EachNode(node, file->first_child))
|
||
|
{
|
||
|
MD_Node *table_tag = MD_TagFromString(node, cg_tbl_tag__table, 0);
|
||
|
if(!MD_NodeIsNil(table_tag))
|
||
|
{
|
||
|
CG_NodeGrid *grid = MD_PushArrayZero(cg_arena, CG_NodeGrid, 1);
|
||
|
*grid = CG_GridFromNode(node);
|
||
|
MD_MapOverwrite(cg_arena, &cg_tbl_top_level_node_grid_map, MD_MapKeyStr(node->string), grid);
|
||
|
CG_TableHeader *header = MD_PushArrayZero(cg_arena, CG_TableHeader, 1);
|
||
|
*header = CG_TableHeaderFromTag(table_tag);
|
||
|
MD_MapOverwrite(cg_arena, &cg_tbl_top_level_table_header_map, MD_MapKeyStr(node->string), header);
|
||
|
}
|
||
|
if(MD_NodeHasTag(node, cg_tbl_tag__table_gen, 0))
|
||
|
{
|
||
|
MD_MapInsert(cg_arena, &cg_tbl_layer_map_gen, layer_key, node);
|
||
|
}
|
||
|
if(MD_NodeHasTag(node, cg_tbl_tag__table_gen_enum, 0))
|
||
|
{
|
||
|
MD_MapInsert(cg_arena, &cg_tbl_layer_map_gen_enum, layer_key, node);
|
||
|
}
|
||
|
if(MD_NodeHasTag(node, cg_tbl_tag__table_gen_data, 0))
|
||
|
{
|
||
|
MD_MapInsert(cg_arena, &cg_tbl_layer_map_gen_data, layer_key, node);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//- rjf: generation phase
|
||
|
for(MD_EachNode(file_ref, file_list->first_child))
|
||
|
{
|
||
|
MD_Node *file = MD_ResolveNodeFromReference(file_ref);
|
||
|
MD_String8 layer_name = file->string;
|
||
|
MD_MapKey layer_key = MD_MapKeyStr(layer_name);
|
||
|
|
||
|
//- rjf: generate all table enums
|
||
|
for(MD_MapSlot *slot = MD_MapLookup(&cg_tbl_layer_map_gen_enum, layer_key);
|
||
|
slot != 0;
|
||
|
slot = MD_MapScan(slot->next, layer_key))
|
||
|
{
|
||
|
MD_Node *gen = (MD_Node *)slot->val;
|
||
|
CG_FilePair f = CG_FilePairFromNode(gen);
|
||
|
FILE *file = CG_FileFromNodePair(gen, &f);
|
||
|
fprintf(file, "enum %.*s\n{\n", MD_S8VArg(gen->string));
|
||
|
MD_String8List gen_strings = CG_GenStringListFromNode(table_expr_op_table, gen);
|
||
|
MD_StringJoin join = { MD_S8Lit(""), MD_S8Lit("\n"), MD_S8Lit("") };
|
||
|
MD_String8 gen_string = MD_S8ListJoin(cg_arena, gen_strings, &join);
|
||
|
fprintf(file, "%.*s", MD_S8VArg(gen_string));
|
||
|
fprintf(file, "\n};\n\n");
|
||
|
}
|
||
|
|
||
|
//- rjf: generate all data tables
|
||
|
for(MD_MapSlot *slot = MD_MapLookup(&cg_tbl_layer_map_gen_data, layer_key);
|
||
|
slot != 0;
|
||
|
slot = MD_MapScan(slot->next, layer_key))
|
||
|
{
|
||
|
MD_Node *gen = (MD_Node *)slot->val;
|
||
|
MD_Node *tag = MD_TagFromString(gen, cg_tbl_tag__table_gen_data, 0);
|
||
|
MD_Node *data_table_type_node = tag->first_child;
|
||
|
MD_String8 data_table_type = data_table_type_node->string;
|
||
|
MD_String8List gen_strings = CG_GenStringListFromNode(table_expr_op_table, gen);
|
||
|
|
||
|
MD_String8 h_decl_specifier = MD_S8Lit("extern");
|
||
|
|
||
|
CG_FilePair f = CG_FilePairFromNode(gen);
|
||
|
fprintf(f.h, "%.*s %.*s %.*s[%" PRIu64 "];\n\n", MD_S8VArg(h_decl_specifier), MD_S8VArg(data_table_type), MD_S8VArg(gen->string), gen_strings.node_count);
|
||
|
|
||
|
fprintf(f.c, "%.*s %.*s[%" PRIu64 "] =\n{\n", MD_S8VArg(data_table_type), MD_S8VArg(gen->string), gen_strings.node_count);
|
||
|
MD_StringJoin join = { MD_S8Lit(""), MD_S8Lit("\n"), MD_S8Lit("") };
|
||
|
MD_String8 gen_string = MD_S8ListJoin(cg_arena, gen_strings, &join);
|
||
|
fprintf(f.c, "%.*s", MD_S8VArg(gen_string));
|
||
|
fprintf(f.c, "\n};\n");
|
||
|
fprintf(f.c, "\n");
|
||
|
}
|
||
|
|
||
|
//- rjf: generate all general generations
|
||
|
for(MD_MapSlot *slot = MD_MapLookup(&cg_tbl_layer_map_gen, layer_key);
|
||
|
slot != 0;
|
||
|
slot = MD_MapScan(slot->next, layer_key))
|
||
|
{
|
||
|
MD_Node *gen = (MD_Node *)slot->val;
|
||
|
CG_FilePair f = CG_FilePairFromNode(gen);
|
||
|
FILE *file = CG_FileFromNodePair(gen, &f);
|
||
|
MD_String8List gen_strings = CG_GenStringListFromNode(table_expr_op_table, gen);
|
||
|
MD_StringJoin join = { MD_S8Lit(""), MD_S8Lit("\n"), MD_S8Lit("") };
|
||
|
MD_String8 gen_string = MD_S8ListJoin(cg_arena, gen_strings, &join);
|
||
|
fprintf(file, "%.*s", MD_S8VArg(gen_string));
|
||
|
fprintf(file, "\n\n");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|