From a603af805c8aebfa637aa2847e7e0e3aaa6b8bc6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 12 Nov 2016 15:21:59 +0100 Subject: [PATCH] - fixed identifier resolution in FxIdentifier for action functions with a different invoker than self. - fixed creation of direct function invocations on a state line. In order to receive the implicit arguments this needs to be wrapped into a compound statement so that the local variable getter works. --- src/dobjtype.cpp | 4 ++++ src/scripting/codegeneration/codegen.cpp | 30 ++++++++++++++++-------- src/scripting/zscript/zcc_compile.cpp | 4 +++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index a6408c307..c2b1008df 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -2495,6 +2495,10 @@ unsigned PFunction::AddVariant(PPrototype *proto, TArray &argflags, TArra variant.SelfClass = dyn_cast(selftypeptr->PointedType); assert(variant.SelfClass != nullptr); } + else + { + variant.SelfClass = nullptr; + } return Variants.Push(variant); } diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 2759e41ba..dac88aa76 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -5096,14 +5096,11 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) // Ugh, the horror. Constants need to be taken from the owning class, but members from the self class to catch invalid accesses here... // see if the current class (if valid) defines something with this name. PSymbolTable *symtbl; - if ((sym = ctx.FindInClass(Identifier, symtbl)) != nullptr) + + // first check fields in self + if ((sym = ctx.FindInSelfClass(Identifier, symtbl)) != nullptr) { - if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) - { - ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as class constant\n", Identifier.GetChars()); - newex = FxConstant::MakeConstant(sym, ScriptPosition); - } - else if (sym->IsKindOf(RUNTIME_CLASS(PField))) + if (sym->IsKindOf(RUNTIME_CLASS(PField))) { if (!ctx.Function) { @@ -5161,6 +5158,18 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as member variable, index %d\n", Identifier.GetChars(), vsym->Offset); newex = new FxClassMember((new FxSelf(ScriptPosition))->Resolve(ctx), vsym, ScriptPosition); } + } + + // now constants in the owning class. + if (newex == nullptr && (sym = ctx.FindInClass(Identifier, symtbl)) != nullptr) + { + if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) + { + ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as class constant\n", Identifier.GetChars()); + newex = FxConstant::MakeConstant(sym, ScriptPosition); + delete this; + return newex->Resolve(ctx); + } else { if (sym->IsKindOf(RUNTIME_CLASS(PFunction))) @@ -5177,7 +5186,7 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) } // now check the global identifiers. - else if ((sym = ctx.FindGlobal(Identifier)) != nullptr) + if (newex == nullptr && (sym = ctx.FindGlobal(Identifier)) != nullptr) { if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) { @@ -5197,12 +5206,13 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx) } // and line specials - else if ((num = P_FindLineSpecial(Identifier, nullptr, nullptr))) + if (newex == nullptr && (num = P_FindLineSpecial(Identifier, nullptr, nullptr))) { ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as line special %d\n", Identifier.GetChars(), num); newex = new FxConstant(num, ScriptPosition); } - else + + if (newex == nullptr) { ScriptPosition.Message(MSG_ERROR, "Unknown identifier '%s'", Identifier.GetChars()); delete this; diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index c42ef299a..c5ac21783 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2577,7 +2577,9 @@ FxExpression *ZCCCompiler::ConvertAST(PClass *cls, ZCC_TreeNode *ast) // there are two possibilities here: either a single function call or a compound statement. For a compound statement we also need to check if the last thing added was a return. if (ast->NodeType == AST_ExprFuncCall) { - return new FxReturnStatement(ConvertNode(ast), *ast); + auto cp = new FxCompoundStatement(*ast); + cp->Add(new FxReturnStatement(ConvertNode(ast), *ast)); + return cp; } else {