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

Allow generic conversion operators

This commit is contained in:
Brian Fiete 2022-01-17 17:10:37 -05:00
parent c2461c8554
commit bf5c19269b
4 changed files with 45 additions and 21 deletions

View file

@ -12609,8 +12609,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
{ {
if (operatorDef->mOperatorDeclaration->mIsConvOperator) if (operatorDef->mOperatorDeclaration->mIsConvOperator)
{ {
if ((!explicitCast) && (operatorDef->mOperatorDeclaration->mExplicitToken != NULL) && if ((!explicitCast) && (operatorDef->IsExplicit()))
(operatorDef->mOperatorDeclaration->mExplicitToken->GetToken() == BfToken_Explicit))
continue; continue;
if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType)) if (!methodMatcher.IsMemberAccessible(checkType, operatorDef->mDeclaringType))

View file

@ -2505,7 +2505,8 @@ void BfPrinter::QueueMethodDeclaration(BfMethodDeclaration* methodDeclaration)
ExpectSpace(); ExpectSpace();
QueueVisitChild(operatorDecl->mExplicitToken); QueueVisitChild(operatorDecl->mExplicitToken);
ExpectSpace(); ExpectSpace();
QueueVisitChild(operatorDecl->mOperatorToken); QueueVisitChild(operatorDecl->mOperatorToken);
ExpectSpace();
QueueVisitChild(operatorDecl->mOpTypeToken); QueueVisitChild(operatorDecl->mOpTypeToken);
ExpectSpace(); ExpectSpace();
QueueVisitChild(methodDeclaration->mReturnType); QueueVisitChild(methodDeclaration->mReturnType);

View file

@ -5169,6 +5169,12 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
} }
else if (token == BfToken_LChevron) else if (token == BfToken_LChevron)
{ {
if (auto elementGeneric = BfNodeDynCastExact<BfGenericInstanceTypeRef>(typeRef))
{
// Already a generic
return typeRef;
}
auto genericInstance = mAlloc->Alloc<BfGenericInstanceTypeRef>(); auto genericInstance = mAlloc->Alloc<BfGenericInstanceTypeRef>();
BfDeferredSizedArray<BfTypeReference*> genericArguments(genericInstance->mGenericArguments, mAlloc); BfDeferredSizedArray<BfTypeReference*> genericArguments(genericInstance->mGenericArguments, mAlloc);
BfDeferredAstSizedArray<BfAstNode*> commas(genericInstance->mCommas, mAlloc); BfDeferredAstSizedArray<BfAstNode*> commas(genericInstance->mCommas, mAlloc);
@ -6846,38 +6852,47 @@ BfAstNode* BfReducer::ReadTypeMember(BfAstNode* node, bool declStarted, int dept
auto nextNode = mVisitorPos.GetNext(); auto nextNode = mVisitorPos.GetNext();
if (auto nextToken = BfNodeDynCast<BfTokenNode>(nextNode)) if (auto nextToken = BfNodeDynCast<BfTokenNode>(nextNode))
{ {
operatorDecl->mBinOp = BfTokenToBinaryOp(nextToken->GetToken()); if ((nextToken->mToken == BfToken_Implicit) || (nextToken->mToken == BfToken_Explicit))
if (operatorDecl->mBinOp != BfBinaryOp_None)
{ {
operatorDecl->mIsConvOperator = true;
MEMBER_SET(operatorDecl, mOpTypeToken, nextToken); MEMBER_SET(operatorDecl, mOpTypeToken, nextToken);
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
} }
else else
{ {
operatorDecl->mUnaryOp = BfTokenToUnaryOp(nextToken->GetToken()); operatorDecl->mBinOp = BfTokenToBinaryOp(nextToken->GetToken());
if (operatorDecl->mUnaryOp != BfUnaryOp_None) if (operatorDecl->mBinOp != BfBinaryOp_None)
{ {
MEMBER_SET(operatorDecl, mOpTypeToken, nextToken); MEMBER_SET(operatorDecl, mOpTypeToken, nextToken);
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
} }
else else
{ {
operatorDecl->mAssignOp = BfTokenToAssignmentOp(nextToken->GetToken()); operatorDecl->mUnaryOp = BfTokenToUnaryOp(nextToken->GetToken());
if (operatorDecl->mAssignOp == BfAssignmentOp_Assign) if (operatorDecl->mUnaryOp != BfUnaryOp_None)
{ {
Fail("The assignment operator '=' cannot be overridden", nextToken); MEMBER_SET(operatorDecl, mOpTypeToken, nextToken);
mVisitorPos.MoveNext();
} }
else
{
operatorDecl->mAssignOp = BfTokenToAssignmentOp(nextToken->GetToken());
if (operatorDecl->mAssignOp == BfAssignmentOp_Assign)
{
Fail("The assignment operator '=' cannot be overridden", nextToken);
}
if (operatorDecl->mAssignOp != BfAssignmentOp_None) if (operatorDecl->mAssignOp != BfAssignmentOp_None)
{ {
MEMBER_SET(operatorDecl, mOpTypeToken, nextToken); MEMBER_SET(operatorDecl, mOpTypeToken, nextToken);
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
} }
else if (nextToken->GetToken() != BfToken_LParen) else if (nextToken->GetToken() != BfToken_LParen)
{ {
Fail("Invalid operator type", nextToken); Fail("Invalid operator type", nextToken);
MEMBER_SET(operatorDecl, mOpTypeToken, nextToken); MEMBER_SET(operatorDecl, mOpTypeToken, nextToken);
mVisitorPos.MoveNext(); mVisitorPos.MoveNext();
}
} }
} }
} }

View file

@ -888,13 +888,22 @@ public:
class BfOperatorDef : public BfMethodDef class BfOperatorDef : public BfMethodDef
{ {
public: public:
BfOperatorDeclaration* mOperatorDeclaration; BfOperatorDeclaration* mOperatorDeclaration;
public: public:
BfOperatorDef() BfOperatorDef()
{ {
mOperatorDeclaration = NULL; mOperatorDeclaration = NULL;
} }
bool IsExplicit()
{
if (mOperatorDeclaration->mExplicitToken != NULL)
return mOperatorDeclaration->mExplicitToken->mToken == BfToken_Explicit;
if (mOperatorDeclaration->mOperatorToken != NULL)
return mOperatorDeclaration->mOperatorToken->mToken == BfToken_Explicit;
return false;
}
}; };
struct BfTypeDefLookupContext struct BfTypeDefLookupContext