mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 15:21:51 +00:00
- split up FxCompoundStatement into the old FxSequence and a new subclass. FxSequence is just a sequence of expressions, while FxCompoundStatement is the one that actually implements handling of local variables. The split was done so that ZCCCompiler::ConvertNode can return multiple statements as one object and for that FxCompoundStatement is not suitable.
- added conversion of local variable declarations. This is still untested
This commit is contained in:
parent
2d85efce2a
commit
ffc38d422e
3 changed files with 112 additions and 38 deletions
|
@ -5014,6 +5014,58 @@ ExpEmit FxFlopFunctionCall::Emit(VMFunctionBuilder *build)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FxSequence :: Resolve
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FxExpression *FxSequence::Resolve(FCompileContext &ctx)
|
||||||
|
{
|
||||||
|
CHECKRESOLVED();
|
||||||
|
for (unsigned i = 0; i < Expressions.Size(); ++i)
|
||||||
|
{
|
||||||
|
if (NULL == (Expressions[i] = Expressions[i]->Resolve(ctx)))
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FxSequence :: Emit
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
ExpEmit FxSequence::Emit(VMFunctionBuilder *build)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < Expressions.Size(); ++i)
|
||||||
|
{
|
||||||
|
ExpEmit v = Expressions[i]->Emit(build);
|
||||||
|
// Throw away any result. We don't care about it.
|
||||||
|
v.Free(build);
|
||||||
|
}
|
||||||
|
return ExpEmit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FxSequence :: GetDirectFunction
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
VMFunction *FxSequence::GetDirectFunction()
|
||||||
|
{
|
||||||
|
if (Expressions.Size() == 1)
|
||||||
|
{
|
||||||
|
return Expressions[0]->GetDirectFunction();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FxCompoundStatement :: Resolve
|
// FxCompoundStatement :: Resolve
|
||||||
|
@ -5023,18 +5075,11 @@ ExpEmit FxFlopFunctionCall::Emit(VMFunctionBuilder *build)
|
||||||
FxExpression *FxCompoundStatement::Resolve(FCompileContext &ctx)
|
FxExpression *FxCompoundStatement::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
CHECKRESOLVED();
|
CHECKRESOLVED();
|
||||||
|
auto outer = ctx.Block;
|
||||||
Outer = ctx.Block;
|
Outer = ctx.Block;
|
||||||
ctx.Block = this;
|
ctx.Block = this;
|
||||||
for (unsigned i = 0; i < Expressions.Size(); ++i)
|
auto x = FxSequence::Resolve(ctx);
|
||||||
{
|
ctx.Block = outer;
|
||||||
if (NULL == (Expressions[i] = Expressions[i]->Resolve(ctx)))
|
|
||||||
{
|
|
||||||
ctx.Block = Outer;
|
|
||||||
delete this;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.Block = Outer;
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5046,33 +5091,13 @@ FxExpression *FxCompoundStatement::Resolve(FCompileContext &ctx)
|
||||||
|
|
||||||
ExpEmit FxCompoundStatement::Emit(VMFunctionBuilder *build)
|
ExpEmit FxCompoundStatement::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < Expressions.Size(); ++i)
|
auto e = FxSequence::Emit(build);
|
||||||
{
|
|
||||||
ExpEmit v = Expressions[i]->Emit(build);
|
|
||||||
// Throw away any result. We don't care about it.
|
|
||||||
v.Free(build);
|
|
||||||
}
|
|
||||||
// Release all local variables in this block.
|
// Release all local variables in this block.
|
||||||
for (auto l : LocalVars)
|
for (auto l : LocalVars)
|
||||||
{
|
{
|
||||||
l->Release(build);
|
l->Release(build);
|
||||||
}
|
}
|
||||||
return ExpEmit();
|
return e;
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// FxCompoundStatement :: GetDirectFunction
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
VMFunction *FxCompoundStatement::GetDirectFunction()
|
|
||||||
{
|
|
||||||
if (Expressions.Size() == 1)
|
|
||||||
{
|
|
||||||
return Expressions[0]->GetDirectFunction();
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -1087,25 +1087,41 @@ public:
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FxCompoundStatement
|
// FxSequence (a list of statements with no semantics attached - used to return multiple nodes as one)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
class FxLocalVariableDeclaration;
|
class FxLocalVariableDeclaration;
|
||||||
|
|
||||||
class FxCompoundStatement : public FxExpression
|
class FxSequence : public FxExpression
|
||||||
|
{
|
||||||
|
TDeletingArray<FxExpression *> Expressions;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FxSequence(const FScriptPosition &pos) : FxExpression(pos) {}
|
||||||
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
|
void Add(FxExpression *expr) { if (expr != NULL) Expressions.Push(expr); }
|
||||||
|
VMFunction *GetDirectFunction();
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FxCompoundStatement (like a list but implements maintenance of local variables)
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
class FxLocalVariableDeclaration;
|
||||||
|
|
||||||
|
class FxCompoundStatement : public FxSequence
|
||||||
{
|
{
|
||||||
TArray<FxLocalVariableDeclaration *> LocalVars;
|
TArray<FxLocalVariableDeclaration *> LocalVars;
|
||||||
TDeletingArray<FxExpression *> Expressions;
|
|
||||||
FxCompoundStatement *Outer = nullptr;
|
FxCompoundStatement *Outer = nullptr;
|
||||||
|
|
||||||
friend class FxLocalVariableDeclaration;
|
friend class FxLocalVariableDeclaration;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FxCompoundStatement(const FScriptPosition &pos) : FxExpression(pos) {}
|
FxCompoundStatement(const FScriptPosition &pos) : FxSequence(pos) {}
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
void Add(FxExpression *expr) { if (expr != NULL) Expressions.Push(expr); }
|
|
||||||
VMFunction *GetDirectFunction();
|
|
||||||
FxLocalVariableDeclaration *FindLocalVariable(FName name);
|
FxLocalVariableDeclaration *FindLocalVariable(FName name);
|
||||||
bool CheckLocalVariable(FName name);
|
bool CheckLocalVariable(FName name);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2534,6 +2534,39 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
||||||
return new FxConditional(condition, left, right);
|
return new FxConditional(condition, left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case AST_LocalVarStmt:
|
||||||
|
{
|
||||||
|
auto loc = static_cast<ZCC_LocalVarStmt *>(ast);
|
||||||
|
auto node = loc->Vars;
|
||||||
|
FxSequence *list = new FxSequence(*ast);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Type determination must be done for each field to properly handle array definitions.
|
||||||
|
PType *type = DetermineType(ConvertClass, node, node->Name, loc->Type, true, false);
|
||||||
|
if (type->IsKindOf(RUNTIME_CLASS(PArray)))
|
||||||
|
{
|
||||||
|
Error(loc, "Local array variables not implemented yet.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FxExpression *val;
|
||||||
|
if (node->InitIsArray)
|
||||||
|
{
|
||||||
|
Error(node, "Tried to initialize %s with an array", FName(node->Name).GetChars());
|
||||||
|
val = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
val = node->Init ? ConvertNode(node->Init) : nullptr;
|
||||||
|
}
|
||||||
|
list->Add(new FxLocalVariableDeclaration(type, node->Name, val, *node));
|
||||||
|
}
|
||||||
|
|
||||||
|
node = static_cast<decltype(node)>(node->SiblingNext);
|
||||||
|
} while (node != loc->Vars);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
case AST_ExpressionStmt:
|
case AST_ExpressionStmt:
|
||||||
return ConvertNode(static_cast<ZCC_ExpressionStmt *>(ast)->Expression);
|
return ConvertNode(static_cast<ZCC_ExpressionStmt *>(ast)->Expression);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue