1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Support for non-static ++ and -- operator overloads

This commit is contained in:
Brian Fiete 2020-08-31 16:11:20 -07:00
parent 5924d4819b
commit 66d5f67528
3 changed files with 58 additions and 19 deletions

View file

@ -521,10 +521,13 @@ BfMethodDef* BfDefBuilder::CreateMethodDef(BfMethodDeclaration* methodDeclaratio
{ {
if (!methodDef->mIsStatic) if (!methodDef->mIsStatic)
{ {
if (!declError.empty()) if ((operatorDecl->mUnaryOp != BfUnaryOp_Increment) && (operatorDecl->mUnaryOp != BfUnaryOp_Decrement))
declError += " and "; {
declError += "'static'"; if (!declError.empty())
methodDef->mIsStatic = true; // Fix it declError += " and ";
declError += "'static'";
methodDef->mIsStatic = true; // Fix it
}
} }
} }
if (!declError.empty()) if (!declError.empty())

View file

@ -17721,8 +17721,16 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal
{ {
if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType)) if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))
continue; continue;
int prevArgSize = (int)args.mSize;
if (!operatorDef->mIsStatic)
{
// Try without arg
args.mSize = 0;
}
if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false)) if (methodMatcher.CheckMethod(NULL, checkType, operatorDef, false))
methodMatcher.mSelfType = entry.mSrcType; methodMatcher.mSelfType = entry.mSrcType;
args.mSize = prevArgSize;
} }
} }
} }
@ -17786,13 +17794,26 @@ BfTypedValue BfExprEvaluator::PerformUnaryOperation_TryOperator(const BfTypedVal
SizedArray<BfExpression*, 2> argSrcs; SizedArray<BfExpression*, 2> argSrcs;
argSrcs.push_back(unaryOpExpr); argSrcs.push_back(unaryOpExpr);
BfTypedValue targetVal = args[0].mTypedValue;
BfTypedValue postOpVal; BfTypedValue postOpVal;
if (isPostOp) if (isPostOp)
postOpVal = mModule->LoadValue(args[0].mTypedValue); postOpVal = mModule->LoadValue(targetVal);
BfTypedValue callTarget;
if (!methodMatcher.mBestMethodDef->mIsStatic)
{
callTarget = targetVal;
args.Clear();
}
auto result = CreateCall(&methodMatcher, BfTypedValue()); auto result = CreateCall(&methodMatcher, callTarget);
if ((result.mType != NULL) && (methodMatcher.mSelfType != NULL) && (result.mType->IsSelf())) if (!methodMatcher.mBestMethodDef->mIsStatic)
{
if (!isPostOp)
result = mModule->LoadValue(targetVal);
}
else if ((result.mType != NULL) && (methodMatcher.mSelfType != NULL) && (result.mType->IsSelf()))
{ {
BF_ASSERT(mModule->IsInGeneric()); BF_ASSERT(mModule->IsInGeneric());
result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType); result = mModule->GetDefaultTypedValue(methodMatcher.mSelfType);

View file

@ -17002,20 +17002,35 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
} }
else if (operatorDef->mOperatorDeclaration->mUnaryOp != BfUnaryOp_None) else if (operatorDef->mOperatorDeclaration->mUnaryOp != BfUnaryOp_None)
{ {
if (methodDef->mParams.size() != 1) if (methodDef->mIsStatic)
{ {
Fail("Unary operators must declare one parameter", paramErrorRefNode); if (methodDef->mParams.size() != 1)
} {
else if ((mCurMethodInstance->GetParamType(0) != mCurTypeInstance) && (!mCurMethodInstance->GetParamType(0)->IsSelf())) Fail("Unary operators must declare one parameter", paramErrorRefNode);
{ }
Fail("The parameter of a unary operator must be the containing type", paramErrorRefNode); else if ((mCurMethodInstance->GetParamType(0) != mCurTypeInstance) && (!mCurMethodInstance->GetParamType(0)->IsSelf()))
} {
Fail("The parameter of a unary operator must be the containing type", paramErrorRefNode);
}
if (((operatorDef->mOperatorDeclaration->mUnaryOp == BfUnaryOp_Increment) || if (((operatorDef->mOperatorDeclaration->mUnaryOp == BfUnaryOp_Increment) ||
(operatorDef->mOperatorDeclaration->mUnaryOp == BfUnaryOp_Decrement)) && (operatorDef->mOperatorDeclaration->mUnaryOp == BfUnaryOp_Decrement)) &&
(!TypeIsSubTypeOf(mCurMethodInstance->mReturnType->ToTypeInstance(), mCurTypeInstance))) (!TypeIsSubTypeOf(mCurMethodInstance->mReturnType->ToTypeInstance(), mCurTypeInstance)))
{
Fail("The return type for the '++' or '--' operator must match the parameter type or be derived from the parameter type", operatorDef->mOperatorDeclaration->mReturnType);
}
}
else
{ {
Fail("The return type for the '++' or '--' operator must match the parameter type or be derived from the parameter type", operatorDef->mOperatorDeclaration->mReturnType); if (methodDef->mParams.size() != 0)
{
Fail("Non-static unary operators not declare any parameters", paramErrorRefNode);
}
if (!mCurMethodInstance->mReturnType->IsVoid())
{
Fail("The return type for non-static operator must be 'void'", operatorDef->mOperatorDeclaration->mReturnType);
}
} }
} }
else if (operatorDef->mOperatorDeclaration->mAssignOp != BfAssignmentOp_None) else if (operatorDef->mOperatorDeclaration->mAssignOp != BfAssignmentOp_None)