mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 23:32:04 +00:00
Added all compound assignment operators to DECORATE
This commit is contained in:
parent
90cc79a902
commit
e79c0225ed
3 changed files with 117 additions and 3 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue