/* * Mr. 4th Dimention - Allen Webster * * 30.05.2018 * * Generate config parser procedures. * */ // TOP #include #include "../4ed_defines.h" #include "4ed_meta_generate_parser.h" #define ConfigOpClassList(M) \ M(ConfigVar , 1, Operations) \ M(CompoundMember , 1, Operations) \ M(TypedArrayStep , 0, Operations) \ M(TypedArrayCount , 0, Types ) \ M(TypedArrayRefernceList , 0, Types ) \ #define ConfigRValueTypeList(M) \ M(LValue , lvalue ) \ M(Boolean , bool ) \ M(Integer , int ) \ M(Float , float ) \ M(String , string ) \ M(Character, character) \ M(Compound , compound ) \ M(NoType , no_type ) \ enum{ #define ENUM(N,C,I) OpClass_##N, ConfigOpClassList(ENUM) #undef ENUM OpClass_COUNT, }; Op_Class op_class_array[] = { #define MEMBER(N,C,I) {OpClassIterate_##I}, ConfigOpClassList(MEMBER) #undef MEMBER }; enum{ #define ENUM(N,P) Type_##N, ConfigRValueTypeList(ENUM) #undef ENUM Type_COUNT, }; char *type_names[Type_COUNT] = { #define MEMBER(N,P) #N, ConfigRValueTypeList(MEMBER) #undef MEMBER }; char *type_proc_names[Type_COUNT] = { #define MEMBER(N,P) #P, ConfigRValueTypeList(MEMBER) #undef MEMBER }; Operation operations[] = { {Type_NoType , "has" , 0 , 0 , 0, 0, 0, 0}, {Type_Boolean, "bool" , "boolean" , "bool32" , 0, 0, 0, 0}, {Type_Integer, "int" , "integer" , "int32_t" , 0, 0, 0, 0}, {Type_Integer, "uint" , "uinteger", "uint32_t", 0, 0, 0, 0}, {Type_String , "string", "string" , "String" , 0, 0, 0, 0}, {Type_String, "placed_string", "string", "String", ", char *space, int32_t space_size", ", space, space_size", 0, "" "if (success){\n" "String str = *var_out;\n" "*var_out = make_string_cap(space, 0, space_size);\n" "copy(var_out, str);\n" "}\n", }, {Type_Character, "char" , "character", "char" , 0, 0, 0, 0}, {Type_Compound , "compound", "compound" , "Config_Compound*", 0, 0, 0, 0}, }; void print_config_var(FILE *out, Operation *op){ fprintf(out, "static bool32\n"); fprintf(out, "config_%s_var(", op->proc_name); fprintf(out, "Config *config, String var_name, int32_t subscript"); if (op->output_type != 0){ fprintf(out, ", %s* var_out", op->output_type); } if (op->extra_params != 0){ fprintf(out, "%s", op->extra_params); } fprintf(out, "){\n"); if (op->code_before != 0){ fprintf(out, "%s", op->code_before); } fprintf(out, "Config_Get_Result result = config_var(config, var_name, subscript);\n"); if (op->output_type != 0){ fprintf(out, "if (result.success){\n"); fprintf(out, "*var_out = result.%s;\n", op->result_type); fprintf(out, "}\n"); } if (op->code_after != 0){ fprintf(out, "bool32 success = result.success;\n"); fprintf(out, "%s", op->code_after); } fprintf(out, "return(result.success);\n"); fprintf(out, "}\n\n"); fprintf(out, "static bool32\n"); fprintf(out, "config_%s_var(", op->proc_name); fprintf(out, "Config *config, char *var_name, int32_t subscript"); if (op->output_type != 0){ fprintf(out, ", %s* var_out", op->output_type); } if (op->extra_params != 0){ fprintf(out, "%s", op->extra_params); } fprintf(out, "){\n"); if (op->code_before != 0){ fprintf(out, "%s", op->code_before); } fprintf(out, "String var_name_str = make_string_slowly(var_name);\n"); fprintf(out, "Config_Get_Result result = config_var(config, var_name_str, subscript);\n"); if (op->output_type != 0){ fprintf(out, "if (result.success){\n"); fprintf(out, "*var_out = result.%s;\n", op->result_type); fprintf(out, "}\n"); } if (op->code_after != 0){ fprintf(out, "bool32 success = result.success;\n"); fprintf(out, "%s", op->code_after); } fprintf(out, "return(result.success);\n"); fprintf(out, "}\n\n"); } void print_compound_member(FILE *out, Operation *op){ fprintf(out, "static bool32\n"); fprintf(out, "config_compound_%s_member(", op->proc_name); fprintf(out, "Config *config, Config_Compound *compound,\n"); fprintf(out, "String var_name, int32_t index"); if (op->output_type != 0){ fprintf(out, ", %s* var_out", op->output_type); } if (op->extra_params != 0){ fprintf(out, "%s", op->extra_params); } fprintf(out, "){\n"); if (op->code_before != 0){ fprintf(out, "%s", op->code_before); } fprintf(out, "Config_Get_Result result = config_compound_member(config, compound, var_name, index);\n"); fprintf(out, "bool32 success = result.success && result.type == ConfigRValueType_%s;\n", type_names[op->r_type]); if (op->output_type != 0){ fprintf(out, "if (success){\n"); fprintf(out, "*var_out = result.%s;\n", op->result_type); fprintf(out, "}\n"); } if (op->code_after != 0){ fprintf(out, "%s", op->code_after); } fprintf(out, "return(success);\n"); fprintf(out, "}\n\n"); fprintf(out, "static bool32\n"); fprintf(out, "config_compound_%s_member(", op->proc_name); fprintf(out, "Config *config, Config_Compound *compound,\n"); fprintf(out, "char *var_name, int32_t index"); if (op->output_type != 0){ fprintf(out, ", %s* var_out", op->output_type); } if (op->extra_params != 0){ fprintf(out, "%s", op->extra_params); } fprintf(out, "){\n"); fprintf(out, "String var_name_str = make_string_slowly(var_name);\n"); if (op->code_before != 0){ fprintf(out, "%s", op->code_before); } fprintf(out, "Config_Get_Result result = config_compound_member(config, compound, var_name_str, index);\n"); fprintf(out, "bool32 success = result.success && result.type == ConfigRValueType_%s;\n", type_names[op->r_type]); if (op->output_type != 0){ fprintf(out, "if (success){\n"); fprintf(out, "*var_out = result.%s;\n", op->result_type); fprintf(out, "}\n"); } if (op->code_after != 0){ fprintf(out, "%s", op->code_after); } fprintf(out, "return(success);\n"); fprintf(out, "}\n\n"); } void print_typed_array(FILE *out, Operation *op){ fprintf(out, "static Iteration_Step_Result\n"); fprintf(out, "typed_%s_array_iteration_step(", op->proc_name); fprintf(out, "Config *config, Config_Compound *compound, int32_t index"); if (op->output_type != 0){ fprintf(out, ", %s* var_out", op->output_type); } if (op->extra_params != 0){ fprintf(out, "\n%s", op->extra_params); } fprintf(out, "){\n"); if (op->code_before != 0){ fprintf(out, "%s", op->code_before); } fprintf(out, "Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_%s, index);\n", type_names[op->r_type]); if (op->output_type != 0 || op->code_after != 0){ fprintf(out, "bool32 success = (result.step == Iteration_Good);\n"); } if (op->output_type != 0){ fprintf(out, "if (success){\n"); fprintf(out, "*var_out = result.get.%s;\n", op->result_type); fprintf(out, "}\n"); } if (op->code_after != 0){ fprintf(out, "%s", op->code_after); } fprintf(out, "return(result.step);\n"); fprintf(out, "}\n\n"); } void print_typed_array_count(FILE *out, int32_t r_type){ if (r_type == Type_LValue){ return; } fprintf(out, "static int32_t\n"); fprintf(out, "typed_%s_array_get_count(", type_proc_names[r_type]); fprintf(out, "Config *config, Config_Compound *compound){\n"); fprintf(out, "int32_t count = typed_array_get_count(config, compound, ConfigRValueType_%s);\n", type_names[r_type]); fprintf(out, "return(count);\n"); fprintf(out, "}\n\n"); } void print_typed_array_reference_list(FILE *out, int32_t r_type){ if (r_type == Type_LValue){ return; } fprintf(out, "static Config_Get_Result_List\n"); fprintf(out, "typed_%s_array_reference_list(", type_proc_names[r_type]); fprintf(out, "Partition *arena, Config *config, Config_Compound *compound){\n"); fprintf(out, "Config_Get_Result_List list = " "typed_array_reference_list(arena, config, compound, ConfigRValueType_%s);\n", type_names[r_type]); fprintf(out, "return(list);\n"); fprintf(out, "}\n\n"); } void print_config_queries(void){ FILE *out = stdout; for (int32_t i = 0; i < OpClass_COUNT; ++i){ Op_Class *op_class = &op_class_array[i]; switch (op_class->iteration_type){ case OpClassIterate_Operations: { Operation *op = operations; for (int32_t j = 0; j < ArrayCount(operations); ++j, ++op){ switch (i){ case OpClass_ConfigVar: { print_config_var(out, op); }break; case OpClass_CompoundMember: { print_compound_member(out, op); }break; case OpClass_TypedArrayStep: { print_typed_array(out, op); }break; } fflush(out); } }break; case OpClassIterate_Types: { for (int32_t j = 0; j < Type_COUNT; ++j){ switch (i){ case OpClass_TypedArrayCount: { print_typed_array_count(out, j); }break; case OpClass_TypedArrayRefernceList: { print_typed_array_reference_list(out, j); }break; } fflush(out); } }break; } } } int main(void){ print_config_queries(); return(0); } // BOTTOM