- 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.

This commit is contained in:
Christoph Oelckers 2016-10-15 10:34:26 +02:00
parent 7bdd320f13
commit d8a8b59006
2 changed files with 65 additions and 41 deletions

View file

@ -198,9 +198,6 @@ protected:
FxExpression(const FScriptPosition &pos) FxExpression(const FScriptPosition &pos)
: ScriptPosition(pos) : ScriptPosition(pos)
{ {
isresolved = false;
ScriptPosition = pos;
ValueType = NULL;
} }
public: public:
virtual ~FxExpression() {} virtual ~FxExpression() {}
@ -215,12 +212,10 @@ public:
virtual ExpEmit Emit(VMFunctionBuilder *build); virtual ExpEmit Emit(VMFunctionBuilder *build);
TArray<FxJumpStatement *> JumpAddresses;
FScriptPosition ScriptPosition; FScriptPosition ScriptPosition;
PType *ValueType; PType *ValueType = nullptr;
bool isresolved; bool isresolved = false;
}; };
//========================================================================== //==========================================================================
@ -1003,13 +998,32 @@ public:
ExpEmit Emit(VMFunctionBuilder *build); 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<FxJumpStatement *> JumpAddresses;
};
//========================================================================== //==========================================================================
// //
// FxWhileLoop // FxWhileLoop
// //
//========================================================================== //==========================================================================
class FxWhileLoop : public FxExpression class FxWhileLoop : public FxLoopStatement
{ {
FxExpression *Condition; FxExpression *Condition;
FxExpression *Code; FxExpression *Code;
@ -1027,7 +1041,7 @@ public:
// //
//========================================================================== //==========================================================================
class FxDoWhileLoop : public FxExpression class FxDoWhileLoop : public FxLoopStatement
{ {
FxExpression *Condition; FxExpression *Condition;
FxExpression *Code; FxExpression *Code;
@ -1045,7 +1059,7 @@ public:
// //
//========================================================================== //==========================================================================
class FxForLoop : public FxExpression class FxForLoop : public FxLoopStatement
{ {
FxExpression *Init; FxExpression *Init;
FxExpression *Condition; FxExpression *Condition;

View file

@ -104,20 +104,6 @@ PSymbol *FCompileContext::FindGlobal(FName identifier)
return GlobalSymbols.FindSymbol(identifier, true); 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) void FCompileContext::CheckReturn(PPrototype *proto, FScriptPosition &pos)
{ {
assert(proto != nullptr); assert(proto != nullptr);
@ -4398,6 +4384,27 @@ ExpEmit FxIfStatement::Emit(VMFunctionBuilder *build)
return ExpEmit(); 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 // FxWhileLoop
@ -4405,7 +4412,7 @@ ExpEmit FxIfStatement::Emit(VMFunctionBuilder *build)
//========================================================================== //==========================================================================
FxWhileLoop::FxWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos) FxWhileLoop::FxWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos)
: FxExpression(pos), Condition(condition), Code(code) : FxLoopStatement(pos), Condition(condition), Code(code)
{ {
ValueType = TypeVoid; ValueType = TypeVoid;
} }
@ -4422,8 +4429,8 @@ FxExpression *FxWhileLoop::Resolve(FCompileContext &ctx)
SAFE_RESOLVE(Condition, ctx); SAFE_RESOLVE(Condition, ctx);
SAFE_RESOLVE_OPT(Code, ctx); SAFE_RESOLVE_OPT(Code, ctx);
ctx.HandleJumps(TK_Break, this); HandleJumps(TK_Break, ctx);
ctx.HandleJumps(TK_Continue, this); HandleJumps(TK_Continue, ctx);
if (Condition->ValueType != TypeBool) if (Condition->ValueType != TypeBool)
{ {
@ -4506,7 +4513,7 @@ ExpEmit FxWhileLoop::Emit(VMFunctionBuilder *build)
//========================================================================== //==========================================================================
FxDoWhileLoop::FxDoWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos) FxDoWhileLoop::FxDoWhileLoop(FxExpression *condition, FxExpression *code, const FScriptPosition &pos)
: FxExpression(pos), Condition(condition), Code(code) : FxLoopStatement(pos), Condition(condition), Code(code)
{ {
ValueType = TypeVoid; ValueType = TypeVoid;
} }
@ -4523,8 +4530,8 @@ FxExpression *FxDoWhileLoop::Resolve(FCompileContext &ctx)
SAFE_RESOLVE(Condition, ctx); SAFE_RESOLVE(Condition, ctx);
SAFE_RESOLVE_OPT(Code, ctx); SAFE_RESOLVE_OPT(Code, ctx);
ctx.HandleJumps(TK_Break, this); HandleJumps(TK_Break, ctx);
ctx.HandleJumps(TK_Continue, this); HandleJumps(TK_Continue, ctx);
if (Condition->ValueType != TypeBool) 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) 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; ValueType = TypeVoid;
} }
@ -4629,8 +4636,8 @@ FxExpression *FxForLoop::Resolve(FCompileContext &ctx)
SAFE_RESOLVE_OPT(Iteration, ctx); SAFE_RESOLVE_OPT(Iteration, ctx);
SAFE_RESOLVE_OPT(Code, ctx); SAFE_RESOLVE_OPT(Code, ctx);
ctx.HandleJumps(TK_Break, this); HandleJumps(TK_Break, ctx);
ctx.HandleJumps(TK_Continue, this); HandleJumps(TK_Continue, ctx);
if (Condition != nullptr) if (Condition != nullptr)
{ {
@ -5041,17 +5048,20 @@ static bool VerifyJumpTarget(AActor *stateowner, FStateParamInfo *stateinfo, int
{ {
PClassActor *cls = stateowner->GetClass(); 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. while (cls != RUNTIME_CLASS(AActor))
if (cls->OwnsState(stateinfo->mCallingState))
{ {
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 // We can safely assume the ParentClass is of type PClassActor
// since we stop when we see the Actor base class. // since we stop when we see the Actor base class.
cls = static_cast<PClassActor *>(cls->ParentClass); cls = static_cast<PClassActor *>(cls->ParentClass);
}
} }
return false; return false;
} }