From 9a228d22ba1439b43be2e7155b6c32b377bb6a83 Mon Sep 17 00:00:00 2001 From: Peter Slattery Date: Sun, 19 Jan 2020 00:14:14 -0800 Subject: [PATCH] Handled struct members which are pointers to data with the type of the containing struct. ie struct foo { foo* Next; } --- meta/foldhaus_meta.cpp | 40 ++++++++----- meta/foldhaus_meta_type_table.h | 102 ++++++++++++++++++-------------- 2 files changed, 84 insertions(+), 58 deletions(-) diff --git a/meta/foldhaus_meta.cpp b/meta/foldhaus_meta.cpp index d689f00..1ac6013 100644 --- a/meta/foldhaus_meta.cpp +++ b/meta/foldhaus_meta.cpp @@ -1,3 +1,15 @@ +// +// Usage +// +// GSMetaTag() to give commands to the meta layer +// +// Tag Values +// +// breakpoint +// will cause the meta layer to break in the debugger when it reaches +// that point in processing the file +// TODO: specify which stage you want it to break at + #include #include @@ -354,7 +366,15 @@ ParseMetaTag(token_iter* Iter, gs_bucket* TagList) if (Iter->TokenAt->Type == Token_Identifier) { TagList->PushElementOnBucket(Iter->TokenAt); + if (StringsEqual(Iter->TokenAt->Text, MakeStringLiteral("breakpoint"))) + { + // NOTE(Peter): This is not a temporary breakpoint. It is + // used to be able to break the meta program at specific points + // throughout execution + __debugbreak(); + } NextToken(Iter); + if (TokenAtEquals(Iter, ")") && TokenAtEquals(Iter, ";")) { @@ -790,7 +810,7 @@ ParseStruct(token_iter* Iter, s32* StructTypeIndexOut, gs_bucket* TagLis if (TokenAtEquals(Iter, ";")) { Result = true; - *StructTypeIndexOut = TypeTable->Types.PushElementOnBucket(StructDecl); + *StructTypeIndexOut = PushTypeDefOnTypeTable(StructDecl, TypeTable); } } } @@ -872,7 +892,7 @@ ParseFunctionDeclaration (token_iter* Iter, token* Identifier, gs_bucket if (TokenAtEquals(Iter, ";")) { Result = true; - TypeTable->Types.PushElementOnBucket(FunctionPtr); + PushTypeDefOnTypeTable(FunctionPtr, TypeTable); } } } @@ -934,17 +954,7 @@ ParseTypedef(token_iter* Iter, gs_bucket* TagList, type_table* TypeTable NextToken(Iter); Result = true; - - s32 ExistingUndeclaredTypeIndex = GetIndexOfType(NewType.Identifier, *TypeTable); - if (ExistingUndeclaredTypeIndex < 0) - { - TypeTable->Types.PushElementOnBucket(NewType); - } - else - { - type_definition* ExistingTypeDef = TypeTable->Types.GetElementAtIndex(ExistingUndeclaredTypeIndex); - *ExistingTypeDef = NewType; - } + PushTypeDefOnTypeTable(NewType, TypeTable); } } else @@ -1190,11 +1200,11 @@ int main(int ArgCount, char** ArgV) type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i); if (TypeDef->Type == TypeDef_Struct) { - FixUpStructSize(TypeDef, TypeTable); + FixUpStructSize(i, TypeTable); } else if (TypeDef->Type == TypeDef_Union) { - FixUpUnionSize(TypeDef, TypeTable); + FixUpUnionSize(i, TypeTable); } } diff --git a/meta/foldhaus_meta_type_table.h b/meta/foldhaus_meta_type_table.h index 60a8aac..a4dbb92 100644 --- a/meta/foldhaus_meta_type_table.h +++ b/meta/foldhaus_meta_type_table.h @@ -78,6 +78,19 @@ struct type_table gs_bucket Types; }; +internal void +MetaTagBreakpoint(gs_bucket Tags) +{ + for (u32 i = 0; i < Tags.Used; i++) + { + meta_tag* Tag = Tags.GetElementAtIndex(i); + if (StringsEqual(Tag->Identifier, MakeStringLiteral("breakpoint"))) + { + __debugbreak(); + } + } +} + internal void CopyMetaTagsAndClear(gs_bucket* Source, gs_bucket* Dest) { @@ -91,35 +104,6 @@ CopyMetaTagsAndClear(gs_bucket* Source, gs_bucket* Dest) Source->Used = 0; } -internal type_definition* -PushStructOnTypeTable(string Identifier, type_definition_type DeclType, gs_bucket* TagList, type_table* TypeTable) -{ - Assert(DeclType == TypeDef_Struct || DeclType == TypeDef_Union); - - type_definition* Result = TypeTable->Types.TakeElement(); - *Result = {0}; - - Result->Type = DeclType; - Result->Identifier = Identifier; - CopyMetaTagsAndClear(TagList, &Result->MetaTags); - return Result; -} - -internal s32 -PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable) -{ - s32 Index = -1; - if (TypeDef.Type != TypeDef_BasicType) - { - printf("Invalid TypeDef: %.*s\n", StringExpand(TypeDef.Identifier)); - } - else - { - Index = TypeTable->Types.PushElementOnBucket(TypeDef); - } - return Index; -} - internal s32 PushUndeclaredType (string Identifier, type_table* TypeTable) { @@ -146,6 +130,26 @@ GetIndexOfType (string Identifier, type_table TypeTable) return Result; } +internal s32 +PushTypeDefOnTypeTable(type_definition TypeDef, type_table* TypeTable) +{ + s32 Index = -1; + + s32 ExistingUndeclaredTypeIndex = GetIndexOfType(TypeDef.Identifier, *TypeTable); + if (ExistingUndeclaredTypeIndex < 0) + { + Index = TypeTable->Types.PushElementOnBucket(TypeDef); + } + else + { + Index = ExistingUndeclaredTypeIndex; + type_definition* ExistingTypeDef = TypeTable->Types.GetElementAtIndex(ExistingUndeclaredTypeIndex); + *ExistingTypeDef = TypeDef; + } + + return Index; +} + internal s32 GetSizeOfType (s32 TypeIndex, type_table TypeTable) { @@ -241,8 +245,8 @@ FindIndexOfMatchingType (type_definition Match, type_table TypeTable) return Result; } -internal void FixUpStructSize (type_definition* Struct, type_table TypeTable); -internal void FixUpUnionSize (type_definition* Union, type_table TypeTable); +internal void FixUpStructSize (s32 StructIndex, type_table TypeTable); +internal void FixUpUnionSize (s32 UnionIndex, type_table TypeTable); internal void FixupMemberType (variable_decl* Member, type_table TypeTable) @@ -275,10 +279,13 @@ CalculateStructMemberSize (variable_decl Member, type_definition MemberType) } internal void -FixUpStructSize (type_definition* Struct, type_table TypeTable) +FixUpStructSize (s32 StructIndex, type_table TypeTable) { + type_definition* Struct = TypeTable.Types.GetElementAtIndex(StructIndex); Assert(Struct->Type == TypeDef_Struct); + MetaTagBreakpoint(Struct->MetaTags); + s32 SizeAcc = 0; for (u32 j = 0; j < Struct->Struct.MemberDecls.Used; j++) { @@ -288,15 +295,23 @@ FixUpStructSize (type_definition* Struct, type_table TypeTable) if (Member->TypeIndex >= 0) { type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member->TypeIndex); - if (MemberTypeDef->Size == 0) + + // NOTE(Peter): This signals a nested pointer to an address of the + // same type as the one we are parsing now. In that case, the size + // also hasn't been determined yet, but we know the size of the member + // is just a pointer (32 or 64 bits). + // For example, this would go into an infinite recursion without the case + // of StructIndex != Member->TypeIndex: + // struct foo { foo* Next; } + if (MemberTypeDef->Size == 0 && StructIndex != Member->TypeIndex) { if (MemberTypeDef->Type == TypeDef_Struct) { - FixUpStructSize(MemberTypeDef, TypeTable); + FixUpStructSize(Member->TypeIndex, TypeTable); } - else if(MemberTypeDef->Type == TypeDef_Union) + else if (MemberTypeDef->Type == TypeDef_Union) { - FixUpUnionSize(MemberTypeDef, TypeTable); + FixUpUnionSize(Member->TypeIndex, TypeTable); } else { @@ -305,7 +320,7 @@ FixUpStructSize (type_definition* Struct, type_table TypeTable) #if 0 InvalidCodePath; #else - printf("Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier)); + printf("Struct Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier)); #endif } } @@ -327,14 +342,15 @@ FixUpStructSize (type_definition* Struct, type_table TypeTable) #else if (Struct->Size == 0) { - printf("Error: Struct Size = 0. %.*s\n", StringExpand(Struct->Identifier)); + printf("Struct Error: Struct Size = 0. %.*s\n", StringExpand(Struct->Identifier)); } #endif } internal void -FixUpUnionSize (type_definition* Union, type_table TypeTable) +FixUpUnionSize (s32 UnionIndex, type_table TypeTable) { + type_definition* Union = TypeTable.Types.GetElementAtIndex(UnionIndex); Assert(Union->Type == TypeDef_Union); s32 BiggestMemberSize = 0; @@ -350,11 +366,11 @@ FixUpUnionSize (type_definition* Union, type_table TypeTable) { if (MemberTypeDef->Type == TypeDef_Struct) { - FixUpStructSize(MemberTypeDef, TypeTable); + FixUpStructSize(Member->TypeIndex, TypeTable); } else if(MemberTypeDef->Type == TypeDef_Union) { - FixUpUnionSize(MemberTypeDef, TypeTable); + FixUpUnionSize(Member->TypeIndex, TypeTable); } else { @@ -363,7 +379,7 @@ FixUpUnionSize (type_definition* Union, type_table TypeTable) #if 0 InvalidCodePath; #else - printf("Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier)); + printf("Union Error: TypeDef Size = 0. %.*s\n", StringExpand(MemberTypeDef->Identifier)); #endif } } @@ -385,7 +401,7 @@ FixUpUnionSize (type_definition* Union, type_table TypeTable) #else if (Union->Size == 0) { - printf("Error: Struct Size = 0. %.*s\n", StringExpand(Union->Identifier)); + printf("Union Error: Struct Size = 0. %.*s\n", StringExpand(Union->Identifier)); } #endif }