From 9d0e4149d960b39d57e114976c5ff246f56f6cda Mon Sep 17 00:00:00 2001 From: Peter Slattery Date: Sat, 18 Jan 2020 22:51:15 -0800 Subject: [PATCH] Began parsing function pointer typedefs in the meta layer. Some of them are working now, but not all. --- meta/foldhaus_meta.cpp | 145 +++++++++++++++++++++++--------- meta/foldhaus_meta_type_table.h | 32 ++++--- src/foldhaus_app.cpp | 2 - 3 files changed, 127 insertions(+), 52 deletions(-) diff --git a/meta/foldhaus_meta.cpp b/meta/foldhaus_meta.cpp index 9d164e6..d689f00 100644 --- a/meta/foldhaus_meta.cpp +++ b/meta/foldhaus_meta.cpp @@ -167,7 +167,6 @@ FileAlreadyInSource(string Path, gs_bucket SourceFiles) if (StringsEqual(File->Path, Path)) { Result = true; - printf("-- File already in source: %.*s\n", StringExpand(Path)); break; } } @@ -648,9 +647,10 @@ ParsePointer (token_iter* Iter) } internal b32 -ParseStructMember(token_iter* Iter, gs_bucket* TagList, struct_member_decl* MemberDecl, type_table* TypeTable) +ParseVariableDecl(token_iter* Iter, gs_bucket* TagList, variable_decl* VarDecl, type_table* TypeTable) { b32 Result = false; + *VarDecl = {0}; PushSnapshot(Iter); s32 TypeIndex = -1; @@ -663,13 +663,13 @@ ParseStructMember(token_iter* Iter, gs_bucket* TagList, struct_member_de NextToken(Iter); } - MemberDecl->Pointer = ParsePointer(Iter); + VarDecl->Pointer = ParsePointer(Iter); if (Iter->TokenAt->Type == Token_Identifier) { - MemberDecl->TypeIndex = TypeIndex; - MemberDecl->Identifier = Iter->TokenAt->Text; - CopyMetaTagsAndClear(TagList, &MemberDecl->MetaTags); + VarDecl->TypeIndex = TypeIndex; + VarDecl->Identifier = Iter->TokenAt->Text; + CopyMetaTagsAndClear(TagList, &VarDecl->MetaTags); NextToken(Iter); @@ -686,7 +686,7 @@ ParseStructMember(token_iter* Iter, gs_bucket* TagList, struct_member_de if (Iter->TokenAt->Type == Token_Number) { parse_result ArrayCount = ParseUnsignedInt(StringExpand(Iter->TokenAt->Text)); - MemberDecl->ArrayCount = ArrayCount.UnsignedIntValue; + VarDecl->ArrayCount = ArrayCount.UnsignedIntValue; NextToken(Iter); if (TokenAtEquals(Iter, "]")) @@ -698,7 +698,8 @@ ParseStructMember(token_iter* Iter, gs_bucket* TagList, struct_member_de // TODO(Peter): Handle comma separated members // ie. r32 x, y, z; - if (TokenAtEquals(Iter, ";") && ArrayParseSuccess) + + if (ArrayParseSuccess) { Result = true; } @@ -755,14 +756,17 @@ ParseStruct(token_iter* Iter, s32* StructTypeIndexOut, gs_bucket* TagLis while (!TokenAtEquals(Iter, "}")) { s32 MemberStructTypeIndex = {}; - struct_member_decl MemberDecl = {}; + variable_decl MemberDecl = {}; if (ParseMetaTag(Iter, TagList)) { } - else if (ParseStructMember(Iter, TagList, &MemberDecl, TypeTable)) + else if (ParseVariableDecl(Iter, TagList, &MemberDecl, TypeTable)) { - StructDecl.Struct.MemberDecls.PushElementOnBucket(MemberDecl); + if (TokenAtEquals(Iter, ";")) + { + StructDecl.Struct.MemberDecls.PushElementOnBucket(MemberDecl); + } } else if (ParseStruct(Iter, &MemberStructTypeIndex, TagList, TypeTable)) { @@ -795,34 +799,80 @@ ParseStruct(token_iter* Iter, s32* StructTypeIndexOut, gs_bucket* TagLis return Result; } +// ( type *? identifier, ... ) +internal b32 +ParseFunctionParameterList (token_iter* Iter, type_definition* FunctionPtrDecl, gs_bucket* TagList, type_table* TypeTable) +{ + b32 Result = false; + PushSnapshot(Iter); + + if (TokenAtEquals(Iter, "(")) + { + Result = true; + + while(!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(")"))) + { + variable_decl ParameterDecl = {}; + if (ParseVariableDecl(Iter, TagList, &ParameterDecl, TypeTable)) + { + FunctionPtrDecl->FunctionPtr.Parameters.PushElementOnBucket(ParameterDecl); + if (Iter->TokenAt->Type == Token_Comma) + { + NextToken(Iter); + } + else if (!StringsEqual(Iter->TokenAt->Text, MakeStringLiteral(")"))) + { + Result = false; + break; + } + } + } + + if (TokenAtEquals(Iter, ")")) + { + Result = true; + } + } + + ApplySnapshotIfNotParsedAndPop(Result, Iter); + return Result; +} + internal b32 ParseFunctionDeclaration (token_iter* Iter, token* Identifier, gs_bucket* TagList, type_table* TypeTable) { b32 Result = false; PushSnapshot(Iter); - s32 TypeIndex = -1; - if (ParseType(Iter, TypeTable, &TypeIndex)) + s32 ReturnTypeIndex = -1; + if (ParseType(Iter, TypeTable, &ReturnTypeIndex)) { - if (TypeIndex < 0) { NextToken(Iter); } + if (ReturnTypeIndex < 0) + { + ReturnTypeIndex = PushUndeclaredType(Iter->TokenAt->Text, TypeTable); + NextToken(Iter); + } b32 IsPointer = ParsePointer(Iter); if (Iter->TokenAt->Type == Token_Identifier) { + type_definition FunctionPtr = {}; + FunctionPtr.Identifier = Iter->TokenAt->Text; + FunctionPtr.Size = sizeof(void*); + CopyMetaTagsAndClear(TagList, &FunctionPtr.MetaTags); + FunctionPtr.Type = TypeDef_FunctionPointer; + FunctionPtr.Pointer = true; + FunctionPtr.FunctionPtr.ReturnTypeIndex = ReturnTypeIndex; + *Identifier = *Iter->TokenAt; NextToken(Iter); - if (TokenAtEquals(Iter, "(")) + if (ParseFunctionParameterList(Iter, &FunctionPtr, TagList, TypeTable)) { - while(!TokenAtEquals(Iter, ")")) - { - // TODO(Peter): parse function params - NextToken(Iter); - } - if (TokenAtEquals(Iter, ";")) { Result = true; + TypeTable->Types.PushElementOnBucket(FunctionPtr); } } } @@ -854,8 +904,6 @@ ParseTypedef(token_iter* Iter, gs_bucket* TagList, type_table* TypeTable else if (ParseFunctionDeclaration(Iter, &TypeToken, TagList, TypeTable)) { Result = true; - - printf("New Function Type: %.*s\n", StringExpand(TypeToken.Text)); } else if (ParseType(Iter, TypeTable, &TypeIndex)) { @@ -885,8 +933,6 @@ ParseTypedef(token_iter* Iter, gs_bucket* TagList, type_table* TypeTable NewType.Identifier = Iter->TokenAt->Text; NextToken(Iter); - printf("New Type: %.*s\n", StringExpand(NewType.Identifier)); - Result = true; s32 ExistingUndeclaredTypeIndex = GetIndexOfType(NewType.Identifier, *TypeTable); @@ -930,7 +976,7 @@ PrintIndent (u32 Indent) internal void PrintStructDecl (type_definition* StructDecl, type_table TypeTable, u32 Indent); internal void -PrintStructMember (struct_member_decl Member, type_table TypeTable, u32 Indent = 0) +PrintVariableDecl (variable_decl Member, type_table TypeTable, u32 Indent = 0) { type_definition* MemberTypeDef = TypeTable.Types.GetElementAtIndex(Member.TypeIndex); if ((MemberTypeDef->Type == TypeDef_Struct || MemberTypeDef->Type == TypeDef_Union) @@ -959,8 +1005,6 @@ PrintStructMember (struct_member_decl Member, type_table TypeTable, u32 Indent = { printf("[%d]", Member.ArrayCount); } - - printf(";"); } internal void @@ -988,14 +1032,36 @@ PrintStructDecl (type_definition* StructDecl, type_table TypeTable, u32 Indent = for (u32 MemberIndex = 0; MemberIndex < StructDecl->Struct.MemberDecls.Used; MemberIndex++) { - struct_member_decl* Member = StructDecl->Struct.MemberDecls.GetElementAtIndex(MemberIndex); - PrintStructMember(*Member, TypeTable, Indent + 1); - printf("\n"); + variable_decl* Member = StructDecl->Struct.MemberDecls.GetElementAtIndex(MemberIndex); + PrintVariableDecl(*Member, TypeTable, Indent + 1); + printf(";\n"); } PrintIndent(Indent); printf("} ( size = %d ) ", StructDecl->Size); } +internal void +PrintFunctionPtrDecl (type_definition* FnPtrDecl, type_table TypeTable) +{ + type_definition* ReturnType = TypeTable.Types.GetElementAtIndex(FnPtrDecl->FunctionPtr.ReturnTypeIndex); + printf("%.*s ", StringExpand(ReturnType->Identifier)); + + if (FnPtrDecl->Identifier.Length > 0) + { + printf("%.*s ", StringExpand(FnPtrDecl->Identifier)); + } + printf("("); + + for (u32 MemberIndex = 0; MemberIndex < FnPtrDecl->FunctionPtr.Parameters.Used; MemberIndex++) + { + variable_decl* Param = FnPtrDecl->FunctionPtr.Parameters.GetElementAtIndex(MemberIndex); + PrintVariableDecl(*Param, TypeTable, 0); + printf(", "); + } + + printf(");"); +} + // Step 1: Get All Tokens, for every file // Step 2: Identify all preprocessor directives // Step 3: Apply Preprocessor Directives && Generate Code @@ -1049,12 +1115,6 @@ int main(int ArgCount, char** ArgV) type_table TypeTable = {0}; PopulateTableWithDefaultCPPTypes(&TypeTable); - for (u32 i = 0; i < TypeTable.Types.Used; i++) - { - type_definition* TypeDefinition = TypeTable.Types.GetElementAtIndex(i); - printf("%.*s\n", StringExpand(TypeDefinition->Identifier)); - } - s32 NodeProcCount = 0; for (u32 SourceFileIdx = 0; SourceFileIdx < SourceFiles.Used; SourceFileIdx++) { @@ -1138,17 +1198,26 @@ int main(int ArgCount, char** ArgV) } } - + // Print All Structs for (u32 i = 0; i < TypeTable.Types.Used; i++) { type_definition* TypeDef = TypeTable.Types.GetElementAtIndex(i); +#if 0 if ((TypeDef->Type == TypeDef_Struct || TypeDef->Type == TypeDef_Union) && TypeDef->Identifier.Length > 0) { PrintStructDecl(TypeDef, TypeTable); printf("\n\n"); } +#endif + + if (TypeDef->Type == TypeDef_FunctionPointer) + { + PrintFunctionPtrDecl(TypeDef, TypeTable); + printf("\n\n"); + } } + s64 Cycles_Preprocess = GetWallClock(); MakeStringBuffer(Buffer, 256); diff --git a/meta/foldhaus_meta_type_table.h b/meta/foldhaus_meta_type_table.h index 43a574b..60a8aac 100644 --- a/meta/foldhaus_meta_type_table.h +++ b/meta/foldhaus_meta_type_table.h @@ -9,7 +9,8 @@ enum type_definition_type { TypeDef_Invalid, - TypeDef_Unknown, // NOTE(Peter): these require fixup later + // NOTE(Peter): tokens with this type require fixup later + TypeDef_Unknown, TypeDef_Struct, TypeDef_Union, TypeDef_BasicType, @@ -23,7 +24,7 @@ struct meta_tag string Identifier; }; -struct struct_member_decl +struct variable_decl { // NOTE(Peter): Because of the way the tokenizer works, we don't lex and parse // at the same time. This means that not all types will be able to be matched @@ -41,13 +42,19 @@ struct struct_member_decl gs_bucket MetaTags; }; -// TODO(Peter): This is just a struct_decl struct struct_decl { // TODO(Peter): Lots of tiny arrays everywhere! Pull these into a central allocation // buffer somewhere // :SmallAllocationsAllOver - gs_bucket MemberDecls; + gs_bucket MemberDecls; +}; + +struct function_pointer_decl +{ + s32 ReturnTypeIndex; + // :SmallAllocationsAllOver + gs_bucket Parameters; }; struct type_definition @@ -61,6 +68,7 @@ struct type_definition union { struct_decl Struct; + function_pointer_decl FunctionPtr; }; b32 Pointer; }; @@ -165,7 +173,7 @@ GetSizeOfType (string Identifier, type_table TypeTable) } internal b32 -StructMembersEqual (struct_member_decl A, struct_member_decl B) +VariableDeclsEqual (variable_decl A, variable_decl B) { b32 Result = false; if (A.TypeIndex == B.TypeIndex && @@ -192,10 +200,10 @@ StructOrUnionsEqual (type_definition A, type_definition B) Result = true; for (u32 i = 0; i < A.Struct.MemberDecls.Used; i++) { - struct_member_decl* AMember = A.Struct.MemberDecls.GetElementAtIndex(i); - struct_member_decl* BMember = A.Struct.MemberDecls.GetElementAtIndex(i); + variable_decl* AMember = A.Struct.MemberDecls.GetElementAtIndex(i); + variable_decl* BMember = A.Struct.MemberDecls.GetElementAtIndex(i); - if (!StructMembersEqual(*AMember, *BMember)) + if (!VariableDeclsEqual(*AMember, *BMember)) { Result = false; break; @@ -237,7 +245,7 @@ internal void FixUpStructSize (type_definition* Struct, type_table TypeTable); internal void FixUpUnionSize (type_definition* Union, type_table TypeTable); internal void -FixupMemberType (struct_member_decl* Member, type_table TypeTable) +FixupMemberType (variable_decl* Member, type_table TypeTable) { if (Member->TypeIndex == -1) { @@ -247,7 +255,7 @@ FixupMemberType (struct_member_decl* Member, type_table TypeTable) } internal s32 -CalculateStructMemberSize (struct_member_decl Member, type_definition MemberType) +CalculateStructMemberSize (variable_decl Member, type_definition MemberType) { Assert(Member.TypeIndex >= 0); // TODO(Peter): Assert(MemberType.Size != 0); @@ -274,7 +282,7 @@ FixUpStructSize (type_definition* Struct, type_table TypeTable) s32 SizeAcc = 0; for (u32 j = 0; j < Struct->Struct.MemberDecls.Used; j++) { - struct_member_decl* Member = Struct->Struct.MemberDecls.GetElementAtIndex(j); + variable_decl* Member = Struct->Struct.MemberDecls.GetElementAtIndex(j); FixupMemberType(Member, TypeTable); if (Member->TypeIndex >= 0) @@ -332,7 +340,7 @@ FixUpUnionSize (type_definition* Union, type_table TypeTable) s32 BiggestMemberSize = 0; for (u32 j = 0; j < Union->Struct.MemberDecls.Used; j++) { - struct_member_decl* Member = Union->Struct.MemberDecls.GetElementAtIndex(j); + variable_decl* Member = Union->Struct.MemberDecls.GetElementAtIndex(j); FixupMemberType(Member, TypeTable); if (Member->TypeIndex >= 0) diff --git a/src/foldhaus_app.cpp b/src/foldhaus_app.cpp index 2ba23c4..a7b995b 100644 --- a/src/foldhaus_app.cpp +++ b/src/foldhaus_app.cpp @@ -1,5 +1,3 @@ -typedef INITIALIZE_APPLICATION(initialize_application); - // // File: foldhaus_app.cpp // Author: Peter Slattery