From 66460bfeb83d06cdb6eb5f7d0948d02fcbac2721 Mon Sep 17 00:00:00 2001 From: Marisa Heit Date: Wed, 3 Aug 2022 23:28:41 -0500 Subject: [PATCH] Add support for nested user types The grammar already understood these constructs. Now the compiler does too. --- src/common/scripting/frontend/zcc_compile.cpp | 37 +++++++++++++++---- src/common/scripting/frontend/zcc_compile.h | 2 +- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/common/scripting/frontend/zcc_compile.cpp b/src/common/scripting/frontend/zcc_compile.cpp index 16940339a..7acb56f54 100644 --- a/src/common/scripting/frontend/zcc_compile.cpp +++ b/src/common/scripting/frontend/zcc_compile.cpp @@ -1813,7 +1813,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n { Error(field, "%s: @ not allowed for user scripts", name.GetChars()); } - retval = ResolveUserType(btype, outertype? &outertype->Symbols : nullptr, true); + retval = ResolveUserType(btype, btype->UserType, outertype? &outertype->Symbols : nullptr, true); break; case ZCC_UserType: @@ -1837,7 +1837,7 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n break; default: - retval = ResolveUserType(btype, outertype ? &outertype->Symbols : nullptr, false); + retval = ResolveUserType(btype, btype->UserType, outertype ? &outertype->Symbols : nullptr, false); break; } break; @@ -1936,18 +1936,25 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n // // ZCCCompiler :: ResolveUserType // -// resolves a user type and returns a matching PType -// //========================================================================== -PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, PSymbolTable *symt, bool nativetype) +/** +* Resolves a user type and returns a matching PType. +* +* @param type The tree node with the identifiers to look for. +* @param type The current identifier being looked for. This must be in type's UserType list. +* @param symt The symbol table to search in. If id is the first identifier and not found in symt, then OutNamespace will also be searched. +* @param nativetype Distinguishes between searching for a native type or a user type. +* @returns the PType found for this user type +*/ +PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *symt, bool nativetype) { // Check the symbol table for the identifier. PSymbol *sym = nullptr; // We first look in the current class and its parents, and then in the current namespace and its parents. - if (symt != nullptr) sym = symt->FindSymbol(type->UserType->Id, true); - if (sym == nullptr) sym = OutNamespace->Symbols.FindSymbol(type->UserType->Id, true); + if (symt != nullptr) sym = symt->FindSymbol(id->Id, true); + if (sym == nullptr && type->UserType == id) sym = OutNamespace->Symbols.FindSymbol(id->Id, true); if (sym != nullptr && sym->IsKindOf(RUNTIME_CLASS(PSymbolType))) { auto ptype = static_cast(sym)->Type; @@ -1957,6 +1964,21 @@ PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, PSymbolTable *symt, boo return TypeError; } + if (id->SiblingNext != type->UserType) + { + assert(id->SiblingNext->NodeType == AST_Identifier); + ptype = ResolveUserType( + type, + static_cast(id->SiblingNext), + &ptype->Symbols, + nativetype + ); + if (ptype == TypeError) + { + return ptype; + } + } + if (ptype->isEnum()) { if (!nativetype) return TypeSInt32; // hack this to an integer until we can resolve the enum mess. @@ -1976,7 +1998,6 @@ PType *ZCCCompiler::ResolveUserType(ZCC_BasicType *type, PSymbolTable *symt, boo return TypeError; } - //========================================================================== // // ZCCCompiler :: ResolveArraySize diff --git a/src/common/scripting/frontend/zcc_compile.h b/src/common/scripting/frontend/zcc_compile.h index adfadaff1..1a94bd820 100644 --- a/src/common/scripting/frontend/zcc_compile.h +++ b/src/common/scripting/frontend/zcc_compile.h @@ -134,7 +134,7 @@ protected: FString FlagsToString(uint32_t flags); PType *DetermineType(PType *outertype, ZCC_TreeNode *field, FName name, ZCC_Type *ztype, bool allowarraytypes, bool formember); PType *ResolveArraySize(PType *baseType, ZCC_Expression *arraysize, PContainerType *cls, bool *nosize); - PType *ResolveUserType(ZCC_BasicType *type, PSymbolTable *sym, bool nativetype); + PType *ResolveUserType(ZCC_BasicType *type, ZCC_Identifier *id, PSymbolTable *sym, bool nativetype); TArray OrderStructs(); void AddStruct(TArray &new_order, ZCC_StructWork *struct_def); ZCC_StructWork *StructTypeToWork(const PStruct *type) const;