diff --git a/examples/type_metadata/generated/meta_types.c b/examples/type_metadata/generated/meta_types.c index 6ddac0d..cab719e 100644 --- a/examples/type_metadata/generated/meta_types.c +++ b/examples/type_metadata/generated/meta_types.c @@ -1,4 +1,4 @@ -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:773 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:826 TypeInfoMember Circle_members[2] = { {"r", 1, -1, &F32_type_info}, {"pos", 3, -1, &V2F32_type_info}, @@ -14,14 +14,14 @@ TypeInfoMember RoundedPolygon_members[3] = { {"p", 1, 1, &V2F32_type_info}, }; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:812 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:865 TypeInfoEnumerant Shape_members[3] = { {"Circle", 6, 1}, {"Segment", 7, 2}, {"Polygon", 7, 3}, }; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:848 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:901 TypeInfo U32_type_info = {TypeKind_Basic, "U32", 3, 4, 0, 0}; TypeInfo F32_type_info = {TypeKind_Basic, "F32", 3, 4, 0, 0}; TypeInfo V2F32_type_info = {TypeKind_Basic, "V2F32", 5, 8, 0, 0}; @@ -30,7 +30,7 @@ TypeInfo RoundedSegment_type_info = {TypeKind_Struct, "RoundedSegment", 14, 3, R TypeInfo RoundedPolygon_type_info = {TypeKind_Struct, "RoundedPolygon", 14, 3, RoundedPolygon_members, 0}; TypeInfo Shape_type_info = {TypeKind_Enum, "Shape", 5, 3, Shape_members, &U32_type_info}; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:908 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:961 TypeInfo* type_info_from_shape(Shape v) { @@ -66,15 +66,15 @@ default: { result = 0; }break; -case Shape_Polygon: -{ -result = 12; -}break; case Shape_Circle: case Shape_Segment: { result = 64; }break; +case Shape_Polygon: +{ +result = 12; +}break; } return(result); } diff --git a/examples/type_metadata/generated/meta_types.h b/examples/type_metadata/generated/meta_types.h index 88c3c16..b06b5ec 100644 --- a/examples/type_metadata/generated/meta_types.h +++ b/examples/type_metadata/generated/meta_types.h @@ -1,6 +1,6 @@ #if !defined(META_TYPES_H) #define META_TYPES_H -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:642 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:695 typedef struct Circle Circle; struct Circle { @@ -29,11 +29,11 @@ Shape_Segment = 2, Shape_Polygon = 3, }; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:726 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:779 TypeInfo* type_info_from_shape(Shape v); U32 max_slot_from_shape(Shape v); -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:757 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:810 extern TypeInfo U32_type_info; extern TypeInfo F32_type_info; extern TypeInfo V2F32_type_info; diff --git a/examples/type_metadata/type_metadata.c b/examples/type_metadata/type_metadata.c index 5698b91..7a020ed 100644 --- a/examples/type_metadata/type_metadata.c +++ b/examples/type_metadata/type_metadata.c @@ -592,44 +592,97 @@ gen_check_duplicate_cases(void) map != 0; map = map->next) { - - for (GEN_MapCase *node = map->first_case; - node != 0; - node = node->next) + if (map->types_are_good) { - GEN_TypeEnumerant *enumerant = node->in_enumerant; - MD_String8 name = enumerant->node->string; - for (GEN_MapCase *check = map->first_case; - check != 0; - check = check->next) + + for (GEN_MapCase *node = map->first_case; + node != 0; + node = node->next) { - if (node == check) + GEN_TypeEnumerant *enumerant = node->in_enumerant; + MD_String8 name = enumerant->node->string; + for (GEN_MapCase *check = map->first_case; + check != 0; + check = check->next) { - break; - } - if (enumerant == check->in_enumerant) - { - MD_CodeLoc my_loc = MD_CodeLocFromNode(enumerant->node); - MD_CodeLoc og_loc = MD_CodeLocFromNode(check->in_enumerant->node); - MD_PrintMessageFmt(error_file, my_loc, MD_MessageKind_Error, - "'%.*s' is already defined", MD_S8VArg(name)); - MD_PrintMessageFmt(error_file, og_loc, MD_MessageKind_Note, - "see previous definition of '%.*s'", MD_S8VArg(name)); - break; - } - if (enumerant->value == check->in_enumerant->value) - { - MD_CodeLoc my_loc = MD_CodeLocFromNode(enumerant->node); - MD_CodeLoc og_loc = MD_CodeLocFromNode(check->in_enumerant->node); - MD_PrintMessageFmt(error_file, my_loc, MD_MessageKind_Error, - "'%.*s' has value %d which is already defined", - MD_S8VArg(name), enumerant->value); - MD_PrintMessageFmt(error_file, og_loc, MD_MessageKind_Note, - "see previous definition '%.*s'", - MD_S8VArg(check->in_enumerant->node->string)); - break; + if (node == check) + { + break; + } + if (enumerant == check->in_enumerant) + { + MD_CodeLoc my_loc = MD_CodeLocFromNode(enumerant->node); + MD_CodeLoc og_loc = MD_CodeLocFromNode(check->in_enumerant->node); + MD_PrintMessageFmt(error_file, my_loc, MD_MessageKind_Error, + "'%.*s' is already defined", MD_S8VArg(name)); + MD_PrintMessageFmt(error_file, og_loc, MD_MessageKind_Note, + "see previous definition of '%.*s'", MD_S8VArg(name)); + break; + } + if (enumerant->value == check->in_enumerant->value) + { + MD_CodeLoc my_loc = MD_CodeLocFromNode(enumerant->node); + MD_CodeLoc og_loc = MD_CodeLocFromNode(check->in_enumerant->node); + MD_PrintMessageFmt(error_file, my_loc, MD_MessageKind_Error, + "'%.*s' has value %d which is already defined", + MD_S8VArg(name), enumerant->value); + MD_PrintMessageFmt(error_file, og_loc, MD_MessageKind_Note, + "see previous definition '%.*s'", + MD_S8VArg(check->in_enumerant->node->string)); + break; + } } } + + } + } +} + +void +gen_check_complete_map_cases(void) +{ + for (GEN_MapInfo *map = first_map; + map != 0; + map = map->next) + { + if (map->types_are_good && map->is_complete) + { + int printed_message_for_this_map = 0; + + GEN_TypeInfo *in_type = map->in; + for (GEN_TypeEnumerant *enumerant = in_type->first_enumerant; + enumerant != 0; + enumerant = enumerant->next) + { + // TODO deduplicate + int enumerant_has_case = 0; + for (GEN_MapCase *map_case = map->first_case; + map_case != 0; + map_case = map_case->next) + { + if (map_case->in_enumerant == enumerant) + { + enumerant_has_case = 1; + break; + } + } + + if (!enumerant_has_case) + { + if (!printed_message_for_this_map) + { + printed_message_for_this_map = 1; + MD_CodeLoc map_loc = MD_CodeLocFromNode(map->node); + MD_PrintMessage(error_file, map_loc, MD_MessageKind_Warning, + MD_S8Lit("map marked as complete is missing a case (or more)")); + } + MD_String8 enumerant_name = enumerant->node->string; + MD_CodeLoc enumerant_loc = MD_CodeLocFromNode(enumerant->node); + MD_PrintMessageFmt(error_file, enumerant_loc, MD_MessageKind_Note, + "see enumerant '%.*s'", MD_S8VArg(enumerant_name)); + } + } + } } } @@ -959,6 +1012,7 @@ gen_function_definitions_from_maps(FILE *out) enumerant != 0; enumerant = enumerant->next) { + // TODO deduplicate int enumerant_has_explicit_case = 0; for (GEN_MapCase *map_case = map->first_case; map_case != 0; @@ -1078,7 +1132,7 @@ main(int argc, char **argv) gen_equip_map_in_out_types(); gen_equip_map_cases(); gen_check_duplicate_cases(); - // TODO check 'complete' + gen_check_complete_map_cases(); // generate header file { diff --git a/examples/type_metadata/type_metadata.h b/examples/type_metadata/type_metadata.h index a3a64c0..d3b062f 100644 --- a/examples/type_metadata/type_metadata.h +++ b/examples/type_metadata/type_metadata.h @@ -105,6 +105,7 @@ void gen_equip_enum_members(void); void gen_equip_map_in_out_types(void); void gen_equip_map_cases(void); void gen_check_duplicate_cases(void); +void gen_check_complete_map_cases(void); //~ generators //////////////////////////////////////////////////////////////// void gen_type_definitions_from_types(FILE *out);