mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 20:12:21 +02:00
Fixed compond assignment operator overloads
This commit is contained in:
parent
0c7597fe60
commit
ca64ea1f28
3 changed files with 66 additions and 14 deletions
|
@ -522,12 +522,22 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
|
||||||
declError = "'public'";
|
declError = "'public'";
|
||||||
methodDef->mProtection = BfProtection_Public; // Fix it
|
methodDef->mProtection = BfProtection_Public; // Fix it
|
||||||
}
|
}
|
||||||
if (!methodDef->mIsStatic)
|
if (operatorDecl->mAssignOp != BfAssignmentOp_None)
|
||||||
{
|
{
|
||||||
if (!declError.empty())
|
if (methodDef->mIsStatic)
|
||||||
declError += " and ";
|
{
|
||||||
declError += "'static'";
|
Fail("Assignment operator must not be declared 'static'", operatorDecl->mStaticSpecifier);
|
||||||
methodDef->mIsStatic = true; // Fix it
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!methodDef->mIsStatic)
|
||||||
|
{
|
||||||
|
if (!declError.empty())
|
||||||
|
declError += " and ";
|
||||||
|
declError += "'static'";
|
||||||
|
methodDef->mIsStatic = true; // Fix it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!declError.empty())
|
if (!declError.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -14856,26 +14856,68 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
|
||||||
BfTypedValue convVal;
|
BfTypedValue convVal;
|
||||||
if (binaryOp != BfBinaryOp_None)
|
if (binaryOp != BfBinaryOp_None)
|
||||||
{
|
{
|
||||||
|
CheckResultForReading(ptr);
|
||||||
|
BfTypedValue leftValue = ptr;
|
||||||
|
leftValue = mModule->LoadValue(leftValue);
|
||||||
|
|
||||||
auto expectedType = ptr.mType;
|
auto expectedType = ptr.mType;
|
||||||
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
if ((binaryOp == BfBinaryOp_LeftShift) || (binaryOp == BfBinaryOp_RightShift))
|
||||||
expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
expectedType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||||
|
|
||||||
if ((!rightValue) && (assignExpr->mRight != NULL))
|
if ((!rightValue) && (assignExpr->mRight != NULL))
|
||||||
{
|
{
|
||||||
rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
|
rightValue = mModule->CreateValueFromExpression(assignExpr->mRight, expectedType, (BfEvalExprFlags)(BfEvalExprFlags_AllowSplat | BfEvalExprFlags_NoCast));
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckResultForReading(ptr);
|
bool handled = false;
|
||||||
BfTypedValue leftValue = ptr;
|
|
||||||
leftValue = mModule->LoadValue(leftValue);
|
|
||||||
|
|
||||||
if (rightValue)
|
if (rightValue)
|
||||||
PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue, rightValue);
|
{
|
||||||
|
auto checkTypeInst = leftValue.mType->ToTypeInstance();
|
||||||
|
while (checkTypeInst != NULL)
|
||||||
|
{
|
||||||
|
for (auto operatorDef : checkTypeInst->mTypeDef->mOperators)
|
||||||
|
{
|
||||||
|
if (operatorDef->mOperatorDeclaration->mAssignOp != assignExpr->mOp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto methodInst = mModule->GetRawMethodInstanceAtIdx(checkTypeInst, operatorDef->mIdx);
|
||||||
|
if (methodInst->GetParamCount() != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto paramType = methodInst->GetParamType(0);
|
||||||
|
if (!mModule->CanCast(rightValue, paramType))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, BfTypeVector());
|
||||||
|
|
||||||
|
BfExprEvaluator exprEvaluator(mModule);
|
||||||
|
SizedArray<BfIRValue, 1> args;
|
||||||
|
exprEvaluator.PushThis(assignExpr->mLeft, leftValue, moduleMethodInstance.mMethodInstance, args);
|
||||||
|
exprEvaluator.PushArg(rightValue, args);
|
||||||
|
exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, args);
|
||||||
|
convVal = leftValue;
|
||||||
|
handled = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled)
|
||||||
|
break;
|
||||||
|
checkTypeInst = mModule->GetBaseType(checkTypeInst);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handled)
|
||||||
|
PerformBinaryOperation(assignExpr->mLeft, assignExpr->mRight, binaryOp, assignExpr->mOpToken, BfBinOpFlag_ForceLeftType, leftValue, rightValue);
|
||||||
|
}
|
||||||
|
|
||||||
convVal = mResult;
|
if (!handled)
|
||||||
mResult = BfTypedValue();
|
{
|
||||||
|
convVal = mResult;
|
||||||
|
mResult = BfTypedValue();
|
||||||
|
}
|
||||||
|
|
||||||
if (!convVal)
|
if (!convVal)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -16101,7 +16101,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
Fail("Assignment operators must declare one parameter", paramErrorRefNode);
|
Fail("Assignment operators must declare one parameter", paramErrorRefNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mCurMethodInstance->mReturnType->IsVoid())
|
if (!mCurMethodInstance->mReturnType->IsVoid())
|
||||||
{
|
{
|
||||||
Fail("The return type for assignment operator must be 'void'", operatorDef->mOperatorDeclaration->mReturnType);
|
Fail("The return type for assignment operator must be 'void'", operatorDef->mOperatorDeclaration->mReturnType);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue