From 7b830bc5845a88c02eeb8f83d5ebf74536af37b8 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 25 Sep 2021 21:55:26 -0700 Subject: [PATCH] [example] resolve map's case in value to an enumerant pointer --- examples/type_metadata/generated/meta_types.c | 6 +-- examples/type_metadata/generated/meta_types.h | 6 +-- examples/type_metadata/type_metadata.c | 46 ++++++++++++++++--- examples/type_metadata/type_metadata.h | 5 +- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/examples/type_metadata/generated/meta_types.c b/examples/type_metadata/generated/meta_types.c index a1c71c2..576838f 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:744 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:776 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:783 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:815 TypeInfoEnumerant Shape_members[3] = { {"Circle", 6, 1}, {"Segment", 7, 2}, {"Polygon", 7, 3}, }; -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:819 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:851 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}; diff --git a/examples/type_metadata/generated/meta_types.h b/examples/type_metadata/generated/meta_types.h index 6f6f35b..b744781 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:612 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:644 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:696 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:728 TypeInfo* type_info_from_shape(Shape v); U32 max_slot_from_shape(Shape v); -// generated by W:/metadesk/examples/type_metadata/type_metadata.c:728 +// generated by W:/metadesk/examples/type_metadata/type_metadata.c:760 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 ae8396f..2cc2ce0 100644 --- a/examples/type_metadata/type_metadata.c +++ b/examples/type_metadata/type_metadata.c @@ -63,6 +63,24 @@ gen_type_resolve_error(MD_Node *reference) "could not resolve type name '%.*s'", MD_S8VArg(reference->string)); } +GEN_TypeEnumerant* +gen_enumerant_from_name(GEN_TypeInfo *enum_type, MD_String8 name) +{ + GEN_TypeEnumerant *result = 0; + for (GEN_TypeEnumerant *enumerant = enum_type->first_enumerant; + enumerant != 0; + enumerant = enumerant->next) + { + if (MD_S8Match(name, enumerant->node->string, 0)) + { + result = enumerant; + break; + } + } + return(result); +} + + //~ analyzers ///////////////////////////////////////////////////////////////// void @@ -533,8 +551,9 @@ gen_equip_map_cases(void) goto skip_case; } - // check that in is a value of in_type - if (!MD_NodeHasChild(in_type->node, in->string, 0)) + // get enumerant from in_type + GEN_TypeEnumerant *in_enumerant = gen_enumerant_from_name(in_type, in->string); + if (in_enumerant == 0) { MD_CodeLoc loc = MD_CodeLocFromNode(in); MD_PrintMessageFmt(error_file, loc, MD_MessageKind_Error, @@ -548,7 +567,7 @@ gen_equip_map_cases(void) if (got_list) { GEN_MapCase *map_case = MD_PushArray(arena, GEN_MapCase, 1); - map_case->in = in; + map_case->in_enumerant = in_enumerant; map_case->out = out; MD_QueuePush(first_case, last_case, map_case); case_count += 1; @@ -580,7 +599,8 @@ gen_check_duplicate_cases(void) node != 0; node = node->next) { - MD_String8 name = node->in->string; + GEN_TypeEnumerant *enumerant = node->in_enumerant; + MD_String8 name = enumerant->node->string; for (GEN_MapCase *check = map->first_case; check != 0; check = check->next) @@ -589,16 +609,28 @@ gen_check_duplicate_cases(void) { break; } - if (MD_S8Match(name, check->in->string, 0)) + if (enumerant == check->in_enumerant) { - MD_CodeLoc my_loc = MD_CodeLocFromNode(node->in); - MD_CodeLoc og_loc = MD_CodeLocFromNode(check->in); + 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; + } } } } diff --git a/examples/type_metadata/type_metadata.h b/examples/type_metadata/type_metadata.h index 6383f73..c720616 100644 --- a/examples/type_metadata/type_metadata.h +++ b/examples/type_metadata/type_metadata.h @@ -81,17 +81,20 @@ typedef struct GEN_MapCase GEN_MapCase; struct GEN_MapCase { GEN_MapCase *next; - MD_Node *in; + GEN_TypeEnumerant *in_enumerant; MD_Node *out; }; //~ helpers /////////////////////////////////////////////////////////////////// MD_Node* gen_get_child_value(MD_Node *parent, MD_String8 child_name); + GEN_TypeInfo* gen_resolve_type_info_from_string(MD_String8 name); GEN_TypeInfo* gen_resolve_type_info_from_referencer(MD_Node *reference); void gen_type_resolve_error(MD_Node *reference); +GEN_TypeEnumerant* gen_enumerant_from_name(GEN_TypeInfo *enum_type, MD_String8 name); + //~ analyzers ///////////////////////////////////////////////////////////////// void gen_gather_types_and_maps(MD_Node *list); void gen_check_duplicate_member_names(void);