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; return val.mVal;
} }
public implicit static operator Span<T> (ref Self val) public implicit static operator Span<T> (in Self val)
{ {
#unwarn #unwarn
return .(&val.mVal, CSize); return .(&val.mVal, CSize);

View file

@ -2069,7 +2069,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
} }
else else
{ {
if ((mAllowImplicitRef) && (wantType->IsRef()) && (!argTypedValue.mType->IsRef())) if ((wantType->IsRef()) && (!argTypedValue.mType->IsRef()) &&
((mAllowImplicitRef) || (wantType->IsIn())))
wantType = wantType->GetUnderlyingType(); wantType = wantType->GetUnderlyingType();
if (!mModule->CanCast(argTypedValue, wantType)) if (!mModule->CanCast(argTypedValue, wantType))
goto NoMatch; 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 else
{ {
@ -7011,8 +7012,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
if (refNode == NULL) if (refNode == NULL)
refNode = targetSrc; refNode = targetSrc;
if (((callFlags & BfCreateFallFlags_AllowImplicitRef) != 0) && if ((wantType->IsRef()) && (!argValue.mType->IsRef()) &&
(wantType->IsRef()) && (!argValue.mType->IsRef())) (((callFlags & BfCreateFallFlags_AllowImplicitRef) != 0) || (wantType->IsIn())))
argValue = mModule->ToRef(argValue, (BfRefType*)wantType); argValue = mModule->ToRef(argValue, (BfRefType*)wantType);
if (mModule->mCurMethodState != NULL) if (mModule->mCurMethodState != NULL)

View file

@ -11490,6 +11490,8 @@ BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue)
{ {
if ((typedValue.mType != NULL) && (typedValue.mType->IsRef())) if ((typedValue.mType != NULL) && (typedValue.mType->IsRef()))
{ {
auto refType = (BfRefType*)typedValue.mType;
auto elementType = typedValue.mType->GetUnderlyingType(); auto elementType = typedValue.mType->GetUnderlyingType();
if (typedValue.IsAddr()) if (typedValue.IsAddr())
{ {
@ -11508,6 +11510,12 @@ BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue)
{ {
BF_ASSERT(typedValue.mValue.IsFake()); BF_ASSERT(typedValue.mValue.IsFake());
} }
if (refType->mRefKind == BfRefType::RefKind_In)
{
if (typedValue.mKind == BfTypedValueKind_Addr)
typedValue.mKind = BfTypedValueKind_ReadOnlyAddr;
}
} }
return typedValue; return typedValue;
} }
@ -17275,6 +17283,10 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
{ {
auto refType = (BfRefType*)resolvedType; auto refType = (BfRefType*)resolvedType;
paramVar->mAssignedKind = (refType->mRefKind != BfRefType::RefKind_Out) ? BfLocalVarAssignKind_Unconditional : BfLocalVarAssignKind_None; paramVar->mAssignedKind = (refType->mRefKind != BfRefType::RefKind_Out) ? BfLocalVarAssignKind_Unconditional : BfLocalVarAssignKind_None;
if (refType->mRefKind == BfRefType::RefKind_In)
{
paramVar->mIsReadOnly = true;
}
} }
else else
{ {
@ -21736,7 +21748,11 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
if ((paramDef != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && if ((paramDef != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) &&
(paramDef->mParamKind != BfParamKind_AppendIdx)) (paramDef->mParamKind != BfParamKind_AppendIdx))
{
mCompiler->mResolvePassData->mAutoComplete->CheckTypeRef(paramDef->mTypeRef, false); 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)) 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; refType->mRefKind = BfRefType::RefKind_Ref;
if (refTypeRef->mRefToken == NULL) if (refTypeRef->mRefToken == NULL)
refType->mRefKind = BfRefType::RefKind_Ref; refType->mRefKind = BfRefType::RefKind_Ref;
else if (refTypeRef->mRefToken->GetToken() == BfToken_In)
refType->mRefKind = BfRefType::RefKind_In;
else if (refTypeRef->mRefToken->GetToken() == BfToken_Out) else if (refTypeRef->mRefToken->GetToken() == BfToken_Out)
refType->mRefKind = BfRefType::RefKind_Out; refType->mRefKind = BfRefType::RefKind_Out;
else if (refTypeRef->mRefToken->GetToken() == BfToken_Mut) 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); DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
return; return;
} }
else if (refType->mRefKind == BfRefType::RefKind_In)
{
str += "in ";
DoTypeToString(str, refType->mElementType, typeNameFlags, genericMethodNameOverrides);
return;
}
else if (refType->mRefKind == BfRefType::RefKind_Out) else if (refType->mRefKind == BfRefType::RefKind_Out)
{ {
str += "out "; str += "out ";

View file

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

View file

@ -178,7 +178,7 @@ public:
bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode); bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
BfAstNode* CreateAllocNode(BfTokenNode* newNode); 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); BfEnumCaseBindExpression* CreateEnumCaseBindExpression(BfTokenNode* bindToken);
BfExpression* CheckBinaryOperatorPrecedence(BfBinaryOperatorExpression* binOpExpression); BfExpression* CheckBinaryOperatorPrecedence(BfBinaryOperatorExpression* binOpExpression);
BfExpression* ApplyToFirstExpression(BfUnaryOperatorExpression* unaryOp, BfExpression* target); 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; auto refKind = BfRefType::RefKind_Ref;
if (refType->mRefToken == NULL) if (refType->mRefToken == NULL)
refKind = BfRefType::RefKind_Ref; refKind = BfRefType::RefKind_Ref;
else if (refType->mRefToken->GetToken() == BfToken_In)
refKind = BfRefType::RefKind_In;
else if (refType->mRefToken->GetToken() == BfToken_Out) else if (refType->mRefToken->GetToken() == BfToken_Out)
refKind = BfRefType::RefKind_Out; refKind = BfRefType::RefKind_Out;
else if (refType->mRefToken->GetToken() == BfToken_Mut) else if (refType->mRefToken->GetToken() == BfToken_Mut)
@ -4176,6 +4178,8 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfTypeReference* rhs, LookupContext*
auto refKind = BfRefType::RefKind_Ref; auto refKind = BfRefType::RefKind_Ref;
if (rhsRefTypeRef->mRefToken == NULL) if (rhsRefTypeRef->mRefToken == NULL)
refKind = BfRefType::RefKind_Ref; refKind = BfRefType::RefKind_Ref;
else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_In)
refKind = BfRefType::RefKind_In;
else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Out) else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Out)
refKind = BfRefType::RefKind_Out; refKind = BfRefType::RefKind_Out;
else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Mut) else if (rhsRefTypeRef->mRefToken->GetToken() == BfToken_Mut)
@ -4612,8 +4616,10 @@ String BfTypeUtils::TypeToString(BfAstNode* typeRefNode)
} }
if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef)) if (auto refTypeRef = BfNodeDynCast<BfRefTypeRef>(typeRef))
{ {
return ((refTypeRef->mRefToken->GetToken() == BfToken_Out) ? "out " : "ref ") + String str = BfTokenToString(refTypeRef->mRefToken->GetToken());
TypeToString(refTypeRef->mElementType); str += " ";
str += TypeToString(refTypeRef->mElementType);
return str;
} }
if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef)) if (auto directStrTypeName = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
return directStrTypeName->mTypeName; return directStrTypeName->mTypeName;

View file

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