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

Added 'in' parameter support

This commit is contained in:
Brian Fiete 2021-01-27 09:01:47 -08:00
parent bf97870ed4
commit 4d1672fbcf
8 changed files with 52 additions and 16 deletions

View file

@ -20,7 +20,7 @@ namespace System
return val.mVal;
}
public implicit static operator Span<T> (ref Self val)
public implicit static operator Span<T> (in Self val)
{
#unwarn
return .(&val.mVal, CSize);

View file

@ -2069,7 +2069,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
}
else
{
if ((mAllowImplicitRef) && (wantType->IsRef()) && (!argTypedValue.mType->IsRef()))
if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()) &&
((mAllowImplicitRef) || (wantType->IsIn())))
wantType = wantType->GetUnderlyingType();
if (!mModule->CanCast(argTypedValue, wantType))
goto NoMatch;
@ -3662,7 +3663,7 @@ BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef)
}
}
localResult = BfTypedValue(varDecl->mValue, innerType, BfTypedValueKind_Addr);
localResult = BfTypedValue(varDecl->mValue, innerType, varDecl->mIsReadOnly ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
}
else
{
@ -7011,8 +7012,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
if (refNode == NULL)
refNode = targetSrc;
if (((callFlags & BfCreateFallFlags_AllowImplicitRef) != 0) &&
(wantType->IsRef()) && (!argValue.mType->IsRef()))
if ((wantType->IsRef()) && (!argValue.mType->IsRef()) &&
(((callFlags & BfCreateFallFlags_AllowImplicitRef) != 0) || (wantType->IsIn())))
argValue = mModule->ToRef(argValue, (BfRefType*)wantType);
if (mModule->mCurMethodState != NULL)

View file

@ -11490,6 +11490,8 @@ BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue)
{
if ((typedValue.mType != NULL) && (typedValue.mType->IsRef()))
{
auto refType = (BfRefType*)typedValue.mType;
auto elementType = typedValue.mType->GetUnderlyingType();
if (typedValue.IsAddr())
{
@ -11508,6 +11510,12 @@ BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue)
{
BF_ASSERT(typedValue.mValue.IsFake());
}
if (refType->mRefKind == BfRefType::RefKind_In)
{
if (typedValue.mKind == BfTypedValueKind_Addr)
typedValue.mKind = BfTypedValueKind_ReadOnlyAddr;
}
}
return typedValue;
}
@ -17275,6 +17283,10 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
{
auto refType = (BfRefType*)resolvedType;
paramVar->mAssignedKind = (refType->mRefKind != BfRefType::RefKind_Out) ? BfLocalVarAssignKind_Unconditional : BfLocalVarAssignKind_None;
if (refType->mRefKind == BfRefType::RefKind_In)
{
paramVar->mIsReadOnly = true;
}
}
else
{
@ -21736,7 +21748,11 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
if ((paramDef != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) &&
(paramDef->mParamKind != BfParamKind_AppendIdx))
{
mCompiler->mResolvePassData->mAutoComplete->CheckTypeRef(paramDef->mTypeRef, false);
if (mCompiler->mResolvePassData->mAutoComplete->IsAutocompleteNode(paramDef->mTypeRef))
mCompiler->mResolvePassData->mAutoComplete->AddEntry(AutoCompleteEntry("token", "in"), paramDef->mTypeRef->ToString());
}
if ((paramDef != NULL) && (paramDef->mParamDeclaration != NULL) && (paramDef->mParamDeclaration->mAttributes != NULL))
{

View file

@ -9961,6 +9961,8 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
refType->mRefKind = BfRefType::RefKind_Ref;
if (refTypeRef->mRefToken == NULL)
refType->mRefKind = BfRefType::RefKind_Ref;
else if (refTypeRef->mRefToken->GetToken() == BfToken_In)
refType->mRefKind = BfRefType::RefKind_In;
else if (refTypeRef->mRefToken->GetToken() == BfToken_Out)
refType->mRefKind = BfRefType::RefKind_Out;
else if (refTypeRef->mRefToken->GetToken() == BfToken_Mut)
@ -13214,6 +13216,12 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
return;
}
else if (refType->mRefKind == BfRefType::RefKind_In)
{
str += "in ";
DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
return;
}
else if (refType->mRefKind == BfRefType::RefKind_Out)
{
str += "out ";

View file

@ -1303,12 +1303,12 @@ BfExpression* BfReducer::CheckBinaryOperatorPrecedence(BfBinaryOperatorExpressio
return resultExpr;
}
BfAstNode* BfReducer::ReplaceTokenStarter(BfAstNode* astNode, int idx)
BfAstNode* BfReducer::ReplaceTokenStarter(BfAstNode* astNode, int idx, bool allowIn)
{
if (auto tokenNode = BfNodeDynCast<BfTokenNode>(astNode))
{
if ((tokenNode->GetToken() == BfToken_As) ||
(tokenNode->GetToken() == BfToken_In))
((tokenNode->GetToken() == BfToken_In) && (!allowIn)))
{
if (idx == -1)
idx = mVisitorPos.mReadPos;
@ -5206,7 +5206,7 @@ BfTypeReference* BfReducer::CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRef
BfTypeReference* BfReducer::CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refTokenNode)
{
BfToken refToken = refTokenNode->GetToken();
BF_ASSERT((refToken == BfToken_Ref) || (refToken == BfToken_Mut) || (refToken == BfToken_Out));
BF_ASSERT((refToken == BfToken_Ref) || (refToken == BfToken_Mut) || (refToken == BfToken_In) || (refToken == BfToken_Out));
if (elementType->IsA<BfRefTypeRef>())
{
@ -8880,7 +8880,7 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
BfAttributeDirective* attributes = NULL;
for (int paramIdx = 0; true; paramIdx++)
{
auto nextNode = ReplaceTokenStarter(mVisitorPos.GetNext(), mVisitorPos.mReadPos + 1);
auto nextNode = ReplaceTokenStarter(mVisitorPos.GetNext(), mVisitorPos.mReadPos + 1, true);
auto tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
if (tokenNode != NULL)
@ -8910,7 +8910,7 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
return tokenNode;
if ((paramIdx == 0) && (
(token == BfToken_Out) || (token == BfToken_Ref) || (token == BfToken_Mut) ||
(token == BfToken_In) || (token == BfToken_Out) || (token == BfToken_Ref) || (token == BfToken_Mut) ||
(token == BfToken_Delegate) || (token == BfToken_Function) ||
(token == BfToken_Params) || (token == BfToken_LParen) ||
(token == BfToken_Var) || (token == BfToken_LBracket) ||
@ -8942,9 +8942,11 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
}
}
bool nextNextIsIdentifier = BfNodeIsA<BfIdentifierNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2));
attributes = NULL;
BfTokenNode* modTokenNode = NULL;
nextNode = ReplaceTokenStarter(mVisitorPos.GetNext(), mVisitorPos.mReadPos + 1);
nextNode = ReplaceTokenStarter(mVisitorPos.GetNext(), mVisitorPos.mReadPos + 1, nextNextIsIdentifier);
tokenNode = BfNodeDynCast<BfTokenNode>(nextNode);
BfTypeReference* typeRef = NULL;
if ((tokenNode != NULL) && (tokenNode->GetToken() == BfToken_LBracket))
@ -8973,7 +8975,7 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
}
else
{
if ((token != BfToken_Out) && (token != BfToken_Ref) && (token != BfToken_Mut) && (token != BfToken_Params) && (token != BfToken_ReadOnly))
if ((token != BfToken_In) && (token != BfToken_Out) && (token != BfToken_Ref) && (token != BfToken_Mut) && (token != BfToken_Params) && (token != BfToken_ReadOnly))
{
Fail("Invalid token", tokenNode);
return NULL;
@ -9009,7 +9011,7 @@ BfTokenNode* BfReducer::ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfPara
if (modTokenNode != NULL)
modToken = modTokenNode->GetToken();
if ((modTokenNode != NULL) && ((modToken == BfToken_Ref) || (modToken == BfToken_Mut) || (modToken == BfToken_Out)))
if ((modTokenNode != NULL) && ((modToken == BfToken_Ref) || (modToken == BfToken_Mut) || (modToken == BfToken_In) || (modToken == BfToken_Out)))
{
typeRef = CreateRefTypeRef(typeRef, modTokenNode);
modTokenNode = NULL;

View file

@ -178,7 +178,7 @@ public:
bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
BfAstNode* CreateAllocNode(BfTokenNode* newNode);
BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1);
BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1, bool allowIn = false);
BfEnumCaseBindExpression* CreateEnumCaseBindExpression(BfTokenNode* bindToken);
BfExpression* CheckBinaryOperatorPrecedence(BfBinaryOperatorExpression* binOpExpression);
BfExpression* ApplyToFirstExpression(BfUnaryOperatorExpression* unaryOp, BfExpression* target);

View file

@ -3297,6 +3297,8 @@ int BfResolvedTypeSet::Hash(BfTypeReference* typeRef, LookupContext* ctx, BfHash
auto refKind = BfRefType::RefKind_Ref;
if (refType->mRefToken == NULL)
refKind = BfRefType::RefKind_Ref;
else if (refType->mRefToken->GetToken() == BfToken_In)
refKind = BfRefType::RefKind_In;
else if (refType->mRefToken->GetToken() == BfToken_Out)
refKind = BfRefType::RefKind_Out;
else if (refType->mRefToken->GetToken() == BfToken_Mut)
@ -4176,6 +4178,8 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
auto refKind = BfRefType::RefKind_Ref;
if (rhsRefTypeRef->mRefToken == NULL)
refKind = BfRefType::RefKind_Ref;
else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_In)
refKind = BfRefType::RefKind_In;
else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Out)
refKind = BfRefType::RefKind_Out;
else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Mut)
@ -4612,8 +4616,10 @@ String BfTypeUtils::TypeToString(BfAstNode* typeRefNode)
}
if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
{
return ((refTypeRef->mRefToken->GetToken() == BfToken_Out) ? "out " : "ref ") +
TypeToString(refTypeRef->mElementType);
String str = BfTokenToString(refTypeRef->mRefToken->GetToken());
str += " ";
str += TypeToString(refTypeRef->mElementType);
return str;
}
if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
return directStrTypeName->mTypeName;

View file

@ -569,6 +569,7 @@ public:
virtual bool IsIntPtrable() { return false; }
virtual bool IsRef() { return false; }
virtual bool IsMut() { return false; }
virtual bool IsIn() { return false; }
virtual bool IsOut() { return false; }
virtual bool IsGenericParam() { return false; }
virtual bool IsClosure() { return false; }
@ -2263,6 +2264,7 @@ public:
enum RefKind
{
RefKind_Ref,
RefKind_In,
RefKind_Out,
RefKind_Mut
};
@ -2283,6 +2285,7 @@ public:
virtual bool IsRef() override { return true; }
virtual bool IsMut() override { return mRefKind == RefKind_Mut; }
virtual bool IsIn() override { return mRefKind == RefKind_In; }
virtual bool IsOut() override { return mRefKind == RefKind_Out; }
virtual bool IsDependentOnUnderlyingType() override { return true; }
virtual BfType* GetUnderlyingType() override { return mElementType; }