mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
- 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:
parent
7bdd320f13
commit
d8a8b59006
2 changed files with 65 additions and 41 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue