From d8a8b590061c839f90774ca98018658d941b5b78 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Oct 2016 10:34:26 +0200 Subject: [PATCH] - cleaned up the loop statement nodes in the code generator, which put some handling in FCompileContext and some of their data into the base FxExpression class instead of having an intermediate base class for all loops which is responsible for the relevant data. All this is now encapsulated in a new FxLoopStatement class which serves as base for the actual loop statements. --- src/scripting/codegeneration/thingdef_exp.h | 34 ++++++--- .../codegeneration/thingdef_expression.cpp | 72 +++++++++++-------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/src/scripting/codegeneration/thingdef_exp.h b/src/scripting/codegeneration/thingdef_exp.h index 2e9af65b6d..3c52547c50 100644 --- a/src/scripting/codegeneration/thingdef_exp.h +++ b/src/scripting/codegeneration/thingdef_exp.h @@ -198,9 +198,6 @@ protected: FxExpression(const FScriptPosition &pos) : ScriptPosition(pos) { - isresolved = false; - ScriptPosition = pos; - ValueType = NULL; } public: virtual ~FxExpression() {} @@ -215,12 +212,10 @@ public: virtual ExpEmit Emit(VMFunctionBuilder *build); - TArray JumpAddresses; - FScriptPosition ScriptPosition; - PType *ValueType; + PType *ValueType = nullptr; - bool isresolved; + bool isresolved = false; }; //========================================================================== @@ -1003,13 +998,32 @@ public: ExpEmit Emit(VMFunctionBuilder *build); }; +//========================================================================== +// +// Base class for loops +// +//========================================================================== + +class FxLoopStatement : public FxExpression +{ +protected: + FxLoopStatement(const FScriptPosition &pos) + : FxExpression(pos) + { + } + + void HandleJumps(int token, FCompileContext &ctx); + + TArray JumpAddresses; +}; + //========================================================================== // // FxWhileLoop // //========================================================================== -class FxWhileLoop : public FxExpression +class FxWhileLoop : public FxLoopStatement { FxExpression *Condition; FxExpression *Code; @@ -1027,7 +1041,7 @@ public: // //========================================================================== -class FxDoWhileLoop : public FxExpression +class FxDoWhileLoop : public FxLoopStatement { FxExpression *Condition; FxExpression *Code; @@ -1045,7 +1059,7 @@ public: // //========================================================================== -class FxForLoop : public FxExpression +class FxForLoop : public FxLoopStatement { FxExpression *Init; FxExpression *Condition; diff --git a/src/scripting/codegeneration/thingdef_expression.cpp b/src/scripting/codegeneration/thingdef_expression.cpp index 323ca083ed..2a6cf51aa2 100644 --- a/src/scripting/codegeneration/thingdef_expression.cpp +++ b/src/scripting/codegeneration/thingdef_expression.cpp @@ -104,20 +104,6 @@ PSymbol *FCompileContext::FindGlobal(FName identifier) return GlobalSymbols.FindSymbol(identifier, true); } -void FCompileContext::HandleJumps(int token, FxExpression *handler) -{ - for (unsigned int i = 0; i < Jumps.Size(); i++) - { - if (Jumps[i]->Token == token) - { - Jumps[i]->AddressResolver = handler; - handler->JumpAddresses.Push(Jumps[i]); - Jumps.Delete(i); - i--; - } - } -} - void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos) { assert(proto != nullptr); @@ -4398,6 +4384,27 @@ ExpEmit FxIfStatement::Emit(VMFunctionBuilder *build) return ExpEmit(); } + +//========================================================================== +// +// FxLoopStatement +// +//========================================================================== + +void FxLoopStatement::HandleJumps(int token, FCompileContext &ctx) +{ + for (unsigned int i = 0; i < ctx.Jumps.Size(); i++) + { + if (ctx.Jumps[i]->Token == token) + { + ctx.Jumps[i]->AddressResolver = this; + JumpAddresses.Push(ctx.Jumps[i]); + ctx.Jumps.Delete(i); + i--; + } + } +} + //========================================================================== // // FxWhileLoop @@ -4405,7 +4412,7 @@ ExpEmit FxIfStatement::Emit(VMFunctionBuilder *build) //========================================================================== FxWhileLoop::FxWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos) -: FxExpression(pos), Condition(condition), Code(code) +: FxLoopStatement(pos), Condition(condition), Code(code) { ValueType = TypeVoid; } @@ -4422,8 +4429,8 @@ FxExpression *FxWhileLoop::Resolve(FCompileContext &ctx) SAFE_RESOLVE(Condition, ctx); SAFE_RESOLVE_OPT(Code, ctx); - ctx.HandleJumps(TK_Break, this); - ctx.HandleJumps(TK_Continue, this); + HandleJumps(TK_Break, ctx); + HandleJumps(TK_Continue, ctx); if (Condition->ValueType != TypeBool) { @@ -4506,7 +4513,7 @@ ExpEmit FxWhileLoop::Emit(VMFunctionBuilder *build) //========================================================================== FxDoWhileLoop::FxDoWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos) -: FxExpression(pos), Condition(condition), Code(code) +: FxLoopStatement(pos), Condition(condition), Code(code) { ValueType = TypeVoid; } @@ -4523,8 +4530,8 @@ FxExpression *FxDoWhileLoop::Resolve(FCompileContext &ctx) SAFE_RESOLVE(Condition, ctx); SAFE_RESOLVE_OPT(Code, ctx); - ctx.HandleJumps(TK_Break, this); - ctx.HandleJumps(TK_Continue, this); + HandleJumps(TK_Break, ctx); + HandleJumps(TK_Continue, ctx); if (Condition->ValueType != TypeBool) { @@ -4608,7 +4615,7 @@ ExpEmit FxDoWhileLoop::Emit(VMFunctionBuilder *build) //========================================================================== FxForLoop::FxForLoop(FxExpression *init, FxExpression *condition, FxExpression *iteration, FxExpression *code, const FScriptPosition &pos) -: FxExpression(pos), Init(init), Condition(condition), Iteration(iteration), Code(code) +: FxLoopStatement(pos), Init(init), Condition(condition), Iteration(iteration), Code(code) { ValueType = TypeVoid; } @@ -4629,8 +4636,8 @@ FxExpression *FxForLoop::Resolve(FCompileContext &ctx) SAFE_RESOLVE_OPT(Iteration, ctx); SAFE_RESOLVE_OPT(Code, ctx); - ctx.HandleJumps(TK_Break, this); - ctx.HandleJumps(TK_Continue, this); + HandleJumps(TK_Break, ctx); + HandleJumps(TK_Continue, ctx); if (Condition != nullptr) { @@ -5041,17 +5048,20 @@ static bool VerifyJumpTarget(AActor *stateowner, FStateParamInfo *stateinfo, int { PClassActor *cls = stateowner->GetClass(); - while (cls != RUNTIME_CLASS(AActor)) + if (stateinfo->mCallingState != nullptr) { - // both calling and target state need to belong to the same class. - if (cls->OwnsState(stateinfo->mCallingState)) + while (cls != RUNTIME_CLASS(AActor)) { - return cls->OwnsState(stateinfo->mCallingState + index); - } + // both calling and target state need to belong to the same class. + if (cls->OwnsState(stateinfo->mCallingState)) + { + return cls->OwnsState(stateinfo->mCallingState + index); + } - // We can safely assume the ParentClass is of type PClassActor - // since we stop when we see the Actor base class. - cls = static_cast(cls->ParentClass); + // We can safely assume the ParentClass is of type PClassActor + // since we stop when we see the Actor base class. + cls = static_cast(cls->ParentClass); + } } return false; }