Added the direct assignment operator to DECORATE

This commit is contained in:
Leonard2 2016-08-01 00:32:02 +02:00 committed by Christoph Oelckers
parent 8437313e7c
commit 90cc79a902
3 changed files with 123 additions and 3 deletions

View file

@ -96,18 +96,23 @@ FxExpression *ParseExpression (FScanner &sc, PClassActor *cls, bool mustresolve)
static FxExpression *ParseExpressionM (FScanner &sc, PClassActor *cls)
{
FxExpression *condition = ParseExpressionL (sc, cls);
FxExpression *base = ParseExpressionL (sc, cls);
if (sc.CheckToken('?'))
{
FxExpression *truex = ParseExpressionM (sc, cls);
sc.MustGetToken(':');
FxExpression *falsex = ParseExpressionM (sc, cls);
return new FxConditional(condition, truex, falsex);
return new FxConditional(base, truex, falsex);
}
else if (sc.CheckToken('='))
{
FxExpression *right = ParseExpressionM(sc, cls);
return new FxAssign(base, right);
}
else
{
return condition;
return base;
}
}

View file

@ -508,6 +508,27 @@ public:
ExpEmit Emit(VMFunctionBuilder *build);
};
//==========================================================================
//
// FxAssign
//
//==========================================================================
class FxAssign : public FxExpression
{
FxExpression *Base;
FxExpression *Right;
bool AddressRequested;
bool AddressWritable;
public:
FxAssign(FxExpression *base, FxExpression *right);
~FxAssign();
FxExpression *Resolve(FCompileContext&);
bool RequestAddress();
ExpEmit Emit(VMFunctionBuilder *build);
};
//==========================================================================
//
// FxBinary

View file

@ -1048,6 +1048,100 @@ ExpEmit FxPostIncrDecr::Emit(VMFunctionBuilder *build)
return out;
}
//==========================================================================
//
// FxAssign
//
//==========================================================================
FxAssign::FxAssign(FxExpression *base, FxExpression *right)
: FxExpression(base->ScriptPosition), Base(base), Right(right)
{
AddressRequested = false;
AddressWritable = false;
}
FxAssign::~FxAssign()
{
SAFE_DELETE(Base);
SAFE_DELETE(Right);
}
bool FxAssign::RequestAddress()
{
AddressRequested = true;
return AddressWritable;
}
FxExpression *FxAssign::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
SAFE_RESOLVE(Base, ctx);
SAFE_RESOLVE(Right, ctx);
ValueType = Base->ValueType;
if (!Base->IsNumeric() || !Right->IsNumeric())
{
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
delete this;
return nullptr;
}
if (!(AddressWritable = Base->RequestAddress()))
{
ScriptPosition.Message(MSG_ERROR, "Expression must be a modifiable value");
delete this;
return nullptr;
}
if (Right->ValueType != ValueType)
{
if (ValueType == TypeBool)
{
Right = new FxBoolCast(Right);
}
else if (ValueType->GetRegType() == REGT_INT)
{
Right = new FxIntCast(Right);
}
else
{
Right = new FxFloatCast(Right);
}
SAFE_RESOLVE(Right, ctx);
}
return this;
}
ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
{
assert(ValueType == Base->ValueType && IsNumeric());
assert(ValueType->GetRegType() == Right->ValueType->GetRegType());
ExpEmit pointer = Base->Emit(build);
ExpEmit result = Right->Emit(build);
if (result.Konst)
{
ExpEmit temp(build, result.RegType);
build->Emit(result.RegType == REGT_FLOAT ? OP_LKF : OP_LK, temp.RegNum, result.RegNum);
result.Free(build);
result = temp;
}
build->Emit(ValueType->GetStoreOp(), pointer.RegNum, result.RegNum, build->GetConstantInt(0));
if (AddressRequested)
{
result.Free(build);
return pointer;
}
pointer.Free(build);
return result;
}
//==========================================================================
//
//