From e5e699c05f8d89e176cb8f7c2487f5341fd17db6 Mon Sep 17 00:00:00 2001 From: Doyle Date: Sat, 23 Feb 2019 01:54:27 +1100 Subject: [PATCH] Unify linked list for cpp decls --- Code/DqnReflect.h | 271 ++++++++++++++++++++++--------------- Data/DqnReflect_TestData.h | 8 +- 2 files changed, 164 insertions(+), 115 deletions(-) diff --git a/Code/DqnReflect.h b/Code/DqnReflect.h index fef0c96..081d781 100644 --- a/Code/DqnReflect.h +++ b/Code/DqnReflect.h @@ -4,12 +4,28 @@ #define DQN_REFLECT #define DQN_REFLECT_META(...) +enum struct DqnReflect_StructMemberMetadataType { String, Int, Float }; + +struct DqnReflect_StructMemberMetadata +{ + DqnReflect_StructMemberMetadataType type; + union + { + char *str_val; + int int_val; + float flt_val; + }; +}; + struct DqnReflect_StructMember { char const *type; int type_len; char const *name; int name_len; + + DqnReflect_StructMemberMetadata *metadata; + int metadata_len; }; struct DqnReflect_Struct @@ -136,7 +152,7 @@ struct StringLiteral template struct LinkedList { - T data; + T value; LinkedList *next; }; @@ -360,11 +376,21 @@ struct CPPReflectMetadataEntry }; using CPPReflectMetadataArray = FixedArray; -struct CPPEnumValuesLinkedList + +template +struct CPPDeclLinkedList { - StringLiteral value; - CPPReflectMetadataArray metadata_array; - CPPEnumValuesLinkedList *next; + CPPReflectMetadataArray metadata_array; + T value; + CPPDeclLinkedList *next; +}; + +struct CPPVariableDecl +{ + StringLiteral type; + StringLiteral name; + b32 is_array; + int array_len; }; struct CPPTokeniser @@ -511,6 +537,23 @@ CPPReflectMetadataArray ParseCPPReflectMeta(CPPTokeniser *tokeniser) return result; } +struct CPPDeclToMetaValue +{ + StringLiteral cpp_decl; + StringLiteral value; +}; + +// i.e. DataType cpp_decl DQN_REFLECT_META(key = value, key2 = value2, ...); +struct MetadataEntry +{ + StringLiteral key; + FixedArray cpp_decl_to_val; +}; + +void WriteMetadataReflectionMethods() +{ +} + void ParseCPPEnum(CPPTokeniser *tokeniser) { CPPToken token = CPPTokeniser_NextToken(tokeniser); @@ -530,44 +573,37 @@ void ParseCPPEnum(CPPTokeniser *tokeniser) if (!ExpectToken(token, CPPTokenType::Identifier)) return; - CPPToken const enum_name = token; - token = CPPTokeniser_NextToken(tokeniser); + int original_indent_level = tokeniser->indent_level; + CPPToken const enum_name = token; + token = CPPTokeniser_NextToken(tokeniser); if (!ExpectToken(token, CPPTokenType::LeftBrace)) return; - b32 has_metadata = false; - CPPEnumValuesLinkedList *start_enum_value_token = nullptr, *enum_value_token = nullptr; + CPPDeclLinkedList *enum_members = nullptr; MemArenaScopedRegion mem_region = MemArena_MakeScopedRegion(&global_main_arena); - for (token = CPPTokeniser_NextToken(tokeniser); - token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::SemiColon; - token = CPPTokeniser_NextToken(tokeniser)) + { - if (token.type == CPPTokenType::Identifier) + CPPDeclLinkedList *link_iterator = nullptr; + for (token = CPPTokeniser_NextToken(tokeniser); + tokeniser->indent_level != original_indent_level && token.type != CPPTokenType::EndOfStream; + token = CPPTokeniser_NextToken(tokeniser)) { - CPPToken enum_value = token; - CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - CPPReflectMetadataArray metadata_array = {}; - if (IsIdentifierToken(peek_token, STR_LITERAL("DQN_REFLECT_META"))) + if (token.type == CPPTokenType::Identifier) { - has_metadata = true; - metadata_array = ParseCPPReflectMeta(tokeniser); - } + auto *link = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPDeclLinkedList); + *link = {}; + if (!link_iterator) enum_members = link; // Set members to first linked list entry + else link_iterator->next = link; + link_iterator = link; - if (!start_enum_value_token) - { - start_enum_value_token = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPEnumValuesLinkedList); - enum_value_token = start_enum_value_token; + link->value = StringLiteral(token.str, token.len); + CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); + if (IsIdentifierToken(peek_token, STR_LITERAL("DQN_REFLECT_META"))) + { + link->metadata_array = ParseCPPReflectMeta(tokeniser); + } } - else - { - enum_value_token->next = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPEnumValuesLinkedList); - enum_value_token = enum_value_token->next; - } - - (*enum_value_token) = {}; - enum_value_token->metadata_array = metadata_array; - enum_value_token->value = StringLiteral(enum_value.str, enum_value.len); } } @@ -577,7 +613,7 @@ void ParseCPPEnum(CPPTokeniser *tokeniser) { CPPTokeniser_SprintfToFile(tokeniser, "char const *DqnReflect_%.*s_Strings[] = {", enum_name.len, enum_name.str); tokeniser->indent_level++; - for (CPPEnumValuesLinkedList *link = start_enum_value_token; link; link = link->next) + for (CPPDeclLinkedList *link = enum_members; link; link = link->next) { StringLiteral enum_value = link->value; CPPTokeniser_SprintfToFileNoIndenting(tokeniser, "\"%.*s\", ", enum_value.len, enum_value.str); @@ -611,7 +647,7 @@ void ParseCPPEnum(CPPTokeniser *tokeniser) { LinkedList *curr_src_code = nullptr; char const *fmt = (enum_is_struct_or_class) ? "if (val == %.*s::%.*s) " : "if (val == %.*s) "; - for (CPPEnumValuesLinkedList *link = start_enum_value_token; link; link = link->next) + for (CPPDeclLinkedList *link = enum_members; link; link = link->next) { if (!curr_src_code) curr_src_code = &src_code; else @@ -626,13 +662,13 @@ void ParseCPPEnum(CPPTokeniser *tokeniser) if (enum_is_struct_or_class) required_len = snprintf(nullptr, 0, fmt, enum_name.len, enum_name.str, enum_value.len, enum_value.str) + 1; else required_len = snprintf(nullptr, 0, fmt, enum_value.len, enum_value.str) + 1; - longest_decl_len = REFLECT_MAX(longest_decl_len, required_len); - curr_src_code->data.decl.str = MEM_ARENA_ALLOC_ARRAY(&global_main_arena, char, required_len); - curr_src_code->data.decl.len = required_len; - curr_src_code->data.enum_value = enum_value; + longest_decl_len = REFLECT_MAX(longest_decl_len, required_len); + curr_src_code->value.decl.str = MEM_ARENA_ALLOC_ARRAY(&global_main_arena, char, required_len); + curr_src_code->value.decl.len = required_len; + curr_src_code->value.enum_value = enum_value; - if (enum_is_struct_or_class) snprintf(curr_src_code->data.decl.str, curr_src_code->data.decl.len, fmt, enum_name.len, enum_name.str, enum_value.len, enum_value.str); - else snprintf(curr_src_code->data.decl.str, curr_src_code->data.decl.len, fmt, enum_value.len, enum_value.str); + if (enum_is_struct_or_class) snprintf(curr_src_code->value.decl.str, curr_src_code->value.decl.len, fmt, enum_name.len, enum_name.str, enum_value.len, enum_value.str); + else snprintf(curr_src_code->value.decl.str, curr_src_code->value.decl.len, fmt, enum_value.len, enum_value.str); } curr_src_code->next = nullptr; } @@ -642,9 +678,9 @@ void ParseCPPEnum(CPPTokeniser *tokeniser) src_code_ptr; src_code_ptr = src_code_ptr->next, ++enum_index) { - StringLiteral enum_value = src_code_ptr->data.enum_value; - int padding = longest_decl_len - src_code_ptr->data.decl.len; - CPPTokeniser_SprintfToFile(tokeniser, "%.*s%*s", src_code_ptr->data.decl.len, src_code_ptr->data.decl.str, padding, ""); + StringLiteral enum_value = src_code_ptr->value.enum_value; + int padding = longest_decl_len - src_code_ptr->value.decl.len; + CPPTokeniser_SprintfToFile(tokeniser, "%.*s%*s", src_code_ptr->value.decl.len, src_code_ptr->value.decl.str, padding, ""); CPPTokeniser_SprintfToFileNoIndenting(tokeniser, "return DqnReflect_%.*s_Strings[%d]; // \"%.*s\"\n", enum_name.len, enum_name.str, @@ -656,22 +692,9 @@ void ParseCPPEnum(CPPTokeniser *tokeniser) // // Write User Annotated Metadata Getter Functions // - if (has_metadata) { - struct CPPDeclToMetaValue - { - StringLiteral cpp_decl; - StringLiteral value; - }; - - struct MetadataEntry - { - StringLiteral key; - FixedArray cpp_decl_to_val; - }; - FixedArray metadata_entries = {}; - for (CPPEnumValuesLinkedList *link = start_enum_value_token; + for (CPPDeclLinkedList *link = enum_members; link; link = link->next) { @@ -739,14 +762,6 @@ void ParseCPPEnum(CPPTokeniser *tokeniser) } } -struct CPPVariableDecl -{ - StringLiteral type; - StringLiteral name; - b32 is_array; - int array_len; -}; - void ParseCPPStruct(CPPTokeniser *tokeniser) { CPPToken token = CPPTokeniser_NextToken(tokeniser); @@ -764,37 +779,46 @@ void ParseCPPStruct(CPPTokeniser *tokeniser) name = StringLiteral(token.str, token.len); } - FixedArray struct_members = {}; - for (token = CPPTokeniser_NextToken(tokeniser); - tokeniser->indent_level != original_indent_level && token.type != CPPTokenType::EndOfStream; - token = CPPTokeniser_NextToken(tokeniser)) + int struct_members_len = 0; + CPPDeclLinkedList *struct_members = nullptr; + MemArenaScopedRegion mem_region = MemArena_MakeScopedRegion(&global_main_arena); + { - if (token.type == CPPTokenType::Identifier) + CPPDeclLinkedList *link_iterator = nullptr; + for (token = CPPTokeniser_NextToken(tokeniser); + tokeniser->indent_level != original_indent_level && token.type != CPPTokenType::EndOfStream; + token = CPPTokeniser_NextToken(tokeniser)) { + if (token.type == CPPTokenType::Identifier) + { #if 0 - int asterisks_count = 0; - for (;; ++asterisks_count) - { - Token peek_token = CPPTokeniser_PeekToken(tokeniser); - if (peek_token == CPPTokenType::Asterisks) CPPTokeniser_NextToken(tokeniser); - else break; - } + int asterisks_count = 0; + for (;; ++asterisks_count) + { + Token peek_token = CPPTokeniser_PeekToken(tokeniser); + if (peek_token == CPPTokenType::Asterisks) CPPTokeniser_NextToken(tokeniser); + else break; + } #endif - CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - if (peek_token.type == CPPTokenType::Identifier) - { - CPPVariableDecl *decl = FixedArray_Make(&struct_members, 1); - decl->type = StringLiteral(token.str, token.len); - decl->name = StringLiteral(peek_token.str, peek_token.len); - - CPPTokeniser_NextToken(tokeniser); - peek_token = CPPTokeniser_PeekToken(tokeniser); - CPPReflectMetadataArray metadata_array = {}; - if (IsIdentifierToken(token, STR_LITERAL("DQN_REFLECT_META"))) + CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); + if (peek_token.type == CPPTokenType::Identifier) { - metadata_array = ParseCPPReflectMeta(tokeniser); + auto *link = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPDeclLinkedList); + *link = {}; + if (!link_iterator) struct_members = link; // Set struct_members to first linked list entry + else link_iterator->next = link; + link_iterator = link; + struct_members_len++; + + link->value.type = StringLiteral(token.str, token.len); + link->value.name = StringLiteral(peek_token.str, peek_token.len); + + CPPTokeniser_NextToken(tokeniser); + peek_token = CPPTokeniser_PeekToken(tokeniser); + if (IsIdentifierToken(peek_token, STR_LITERAL("DQN_REFLECT_META"))) + link->metadata_array = ParseCPPReflectMeta(tokeniser); } } } @@ -803,35 +827,60 @@ void ParseCPPStruct(CPPTokeniser *tokeniser) if (name.len == 0) return; - CPPTokeniser_SprintfToFile(tokeniser, "DqnReflect_Struct DqnReflect_Struct%.*s =\n{\n", name.len, name.str); - tokeniser->indent_level++; - - CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\", // name \n", name.len, name.str); - CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"), // name_len \n", name.len, name.str); - - CPPTokeniser_SprintfToFile(tokeniser, "{ // members \n"); - tokeniser->indent_level++; - for (CPPVariableDecl const &decl : struct_members) + // + // Write DqnReflect_Struct Definition + // { - CPPTokeniser_SprintfToFile(tokeniser, "{\n"); + CPPTokeniser_SprintfToFile(tokeniser, "DqnReflect_Struct DqnReflect_%.*s_Struct =\n{\n", name.len, name.str); tokeniser->indent_level++; - CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\",\n", decl.type.len, decl.type.str); - CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"),\n", decl.type.len, decl.type.str); - CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\",\n", decl.name.len, decl.name.str); - CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"),\n", decl.name.len, decl.name.str); + + CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\", // name \n", name.len, name.str); + CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"), // name_len \n", name.len, name.str); + + CPPTokeniser_SprintfToFile(tokeniser, "{ // members \n"); + tokeniser->indent_level++; + for (CPPDeclLinkedList const *link = struct_members; link; link = link->next) + { + CPPVariableDecl const *decl = &link->value; + CPPTokeniser_SprintfToFile(tokeniser, "{\n"); + tokeniser->indent_level++; + CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\",\n", decl->type.len, decl->type.str); + CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"),\n", decl->type.len, decl->type.str); + CPPTokeniser_SprintfToFile(tokeniser, "\"%.*s\",\n", decl->name.len, decl->name.str); + CPPTokeniser_SprintfToFile(tokeniser, "DQN_REFLECT_CHAR_COUNT(\"%.*s\"),\n", decl->name.len, decl->name.str); + tokeniser->indent_level--; + CPPTokeniser_SprintfToFile(tokeniser, "},\n"); + } tokeniser->indent_level--; CPPTokeniser_SprintfToFile(tokeniser, "},\n"); - } - tokeniser->indent_level--; - CPPTokeniser_SprintfToFile(tokeniser, "},\n"); - CPPTokeniser_SprintfToFile(tokeniser, "%d // members_len \n", (int)struct_members.len); + CPPTokeniser_SprintfToFile(tokeniser, "%d // members_len \n", struct_members_len); - tokeniser->indent_level--; - CPPTokeniser_SprintfToFile(tokeniser, "};\n"); + tokeniser->indent_level--; + CPPTokeniser_SprintfToFile(tokeniser, "};\n\n"); + assert(tokeniser->indent_level == 0); + } + + // + // Write DqnReflect_Struct getter + // + { + CPPTokeniser_SprintfToFile(tokeniser, "DqnReflect_Struct const *DqnReflect_GetStruct(%.*s const *val)\n", name.len, name.str); + CPPTokeniser_SprintfToFile(tokeniser, "{\n"); + tokeniser->indent_level++; + CPPTokeniser_SprintfToFile(tokeniser, "DqnReflect_Struct const *result = &DqnReflect_%.*s_Struct;\n", name.len, name.str); + CPPTokeniser_SprintfToFile(tokeniser, "return result;\n"); + tokeniser->indent_level--; + CPPTokeniser_SprintfToFile(tokeniser, "}\n\n"); + } + + // + // Write User Annotated Metadata Getter Functions + // + { + } int break_here = 5; (void)break_here; - assert(tokeniser->indent_level == 0); } int main(int argc, char *argv[]) diff --git a/Data/DqnReflect_TestData.h b/Data/DqnReflect_TestData.h index 012d7e3..1b8f8f0 100644 --- a/Data/DqnReflect_TestData.h +++ b/Data/DqnReflect_TestData.h @@ -1,8 +1,8 @@ -enum struct OpenGLShader +DQN_REFLECT enum struct OpenGLShader { Invalid, - Rect (VertexShaderFilePath = "Rect.vert", FragmentShaderFilePath = "Rect.frag"), - Text (VertexShaderFilePath = "Text.vert", FragmentShaderFilePath = "Text.frag"), + Rect DQN_REFLECT_META(VertexShaderFilePath = "Rect.vert", FragmentShaderFilePath = "Rect.frag"), + Text DQN_REFLECT_META(VertexShaderFilePath = "Text.vert", FragmentShaderFilePath = "Text.frag"), }; #if 0 @@ -19,7 +19,7 @@ DQN_REFLECT struct OpenGLState // #endif // u32 ebo, vbo, vao; // u32 shaders[(int)OpenGLShader::Count]; - V4 draw_color; + V4 draw_color DQN_REFLECT_META(FriendlyName = "HelloWorld"); V3 lighting_ambient_coeff; // u8 **bitmaps; // FixedArray lights;