- 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)
: ScriptPosition(pos)
{
isresolved = false;
ScriptPosition = pos;
ValueType = NULL;
}
public:
virtual ~FxExpression() {}
@ -215,12 +212,10 @@ public:
virtual ExpEmit Emit(VMFunctionBuilder *build);
TArray<FxJumpStatement *> 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<FxJumpStatement *> 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;

View File

@ -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<PClassActor *>(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<PClassActor *>(cls->ParentClass);
}
}
return false;
}