Added all compound assignment operators to DECORATE

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

View file

@ -112,8 +112,68 @@ static FxExpression *ParseExpressionM (FScanner &sc, PClassActor *cls)
} }
else else
{ {
FxBinary *exp;
FxAssignSelf *left = new FxAssignSelf(sc);
sc.GetToken();
switch (sc.TokenType)
{
case TK_AddEq:
exp = new FxAddSub('+', left, nullptr);
break;
case TK_SubEq:
exp = new FxAddSub('-', left, nullptr);
break;
case TK_MulEq:
exp = new FxMulDiv('*', left, nullptr);
break;
case TK_DivEq:
exp = new FxMulDiv('/', left, nullptr);
break;
case TK_ModEq:
exp = new FxMulDiv('%', left, nullptr);
break;
case TK_LShiftEq:
exp = new FxBinaryInt(TK_LShift, left, nullptr);
break;
case TK_RShiftEq:
exp = new FxBinaryInt(TK_RShift, left, nullptr);
break;
case TK_URShiftEq:
exp = new FxBinaryInt(TK_URShift, left, nullptr);
break;
case TK_AndEq:
exp = new FxBinaryInt('&', left, nullptr);
break;
case TK_XorEq:
exp = new FxBinaryInt('^', left, nullptr);
break;
case TK_OrEq:
exp = new FxBinaryInt('|', left, nullptr);
break;
default:
sc.UnGet();
delete left;
return base; return base;
} }
exp->right = ParseExpressionM(sc, cls);
FxAssign *ret = new FxAssign(base, exp);
left->Assignment = ret;
return ret;
}
} }
static FxExpression *ParseExpressionL (FScanner &sc, PClassActor *cls) static FxExpression *ParseExpressionL (FScanner &sc, PClassActor *cls)

View file

@ -527,6 +527,24 @@ public:
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
bool RequestAddress(); bool RequestAddress();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
ExpEmit Address;
};
//==========================================================================
//
// FxAssignSelf
//
//==========================================================================
class FxAssignSelf : public FxExpression
{
public:
FxAssign *Assignment;
FxAssignSelf(const FScriptPosition &pos);
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
}; };
//========================================================================== //==========================================================================

View file

@ -1077,10 +1077,11 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
{ {
CHECKRESOLVED(); CHECKRESOLVED();
SAFE_RESOLVE(Base, ctx); SAFE_RESOLVE(Base, ctx);
SAFE_RESOLVE(Right, ctx);
ValueType = Base->ValueType; ValueType = Base->ValueType;
SAFE_RESOLVE(Right, ctx);
if (!Base->IsNumeric() || !Right->IsNumeric()) if (!Base->IsNumeric() || !Right->IsNumeric())
{ {
ScriptPosition.Message(MSG_ERROR, "Numeric type expected"); ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
@ -1120,6 +1121,8 @@ ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
assert(ValueType->GetRegType() == Right->ValueType->GetRegType()); assert(ValueType->GetRegType() == Right->ValueType->GetRegType());
ExpEmit pointer = Base->Emit(build); ExpEmit pointer = Base->Emit(build);
Address = pointer;
ExpEmit result = Right->Emit(build); ExpEmit result = Right->Emit(build);
if (result.Konst) if (result.Konst)
@ -1142,6 +1145,39 @@ ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
return result; return result;
} }
//==========================================================================
//
// FxAssignSelf
//
//==========================================================================
FxAssignSelf::FxAssignSelf(const FScriptPosition &pos)
: FxExpression(pos)
{
Assignment = nullptr;
}
FxExpression *FxAssignSelf::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
// This should never happen if FxAssignSelf is used correctly
assert(Assignment != nullptr);
ValueType = Assignment->ValueType;
return this;
}
ExpEmit FxAssignSelf::Emit(VMFunctionBuilder *build)
{
assert(ValueType = Assignment->ValueType);
ExpEmit pointer = Assignment->Address; // FxAssign should have already emitted it
ExpEmit out(build, ValueType->GetRegType());
build->Emit(ValueType->GetLoadOp(), out.RegNum, pointer.RegNum, build->GetConstantInt(0));
return out;
}
//========================================================================== //==========================================================================
// //
// //