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

Generic constructors

This commit is contained in:
Brian Fiete 2024-11-06 07:31:55 -05:00
parent 64d646e130
commit 04ea8a6634
13 changed files with 267 additions and 37 deletions

View file

@ -2051,17 +2051,30 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
return caseExpr;
}
else if (token == BfToken_Dot) // Abbreviated dot syntax ".EnumVal"
{
// Initializer ".{ x = 1, y = 2 }"
{
bool handled = false;
if (auto nextTokenNode = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
{
if (nextTokenNode->mToken == BfToken_This)
{
auto invocationExpr = CreateObjectCreateExpression(NULL, tokenNode);
if (invocationExpr == NULL)
return exprLeft;
exprLeft = invocationExpr;
handled = true;
}
}
if (auto blockNode = BfNodeDynCast<BfBlock>(mVisitorPos.GetNext()))
{
// Initializer ".{ x = 1, y = 2 }"
auto typeRef = CreateTypeRef(mVisitorPos.GetCurrent());
if (typeRef)
{
exprLeft = TryCreateInitializerExpression(typeRef);
}
}
else
else if (!handled)
{
auto memberReferenceExpr = mAlloc->Alloc<BfMemberReferenceExpression>();
ReplaceNode(tokenNode, memberReferenceExpr);
@ -2933,6 +2946,29 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
BF_ASSERT(tokenNode->GetToken() == token);
if (token == BfToken_Dot)
{
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2)))
{
if (nextToken->mToken == BfToken_This)
{
int outNodeIdx = -1;
bool isGenericType;
bool isTypeRef = ((IsTypeReference(exprLeft, BfToken_This, -1, &outNodeIdx, NULL, &isGenericType)) &&
(outNodeIdx != -1));
if (isTypeRef)
{
auto invocationExpr = CreateObjectCreateExpression(NULL, exprLeft);
if (invocationExpr == NULL)
return exprLeft;
exprLeft = invocationExpr;
continue;
}
}
}
}
// Not a binary op, it's a 'close'
if (token == BfToken_Bang)
{
@ -4875,6 +4911,11 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
}
firstNode = qualifiedTypeRef;
}
else if (auto typeRef = BfNodeDynCast<BfTypeReference>(firstNode))
{
// Already a typeRef
return typeRef;
}
else
{
bool isHandled = false;
@ -5169,6 +5210,15 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
BfToken token = tokenNode->GetToken();
if (token == BfToken_Dot)
{
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2)))
{
if (nextToken->mToken == BfToken_This)
{
// Don't encode '.this' in type ref
break;
}
}
BfQualifiedTypeReference* qualifiedTypeRef = mAlloc->Alloc<BfQualifiedTypeReference>();
ReplaceNode(typeRef, qualifiedTypeRef);
qualifiedTypeRef->mLeft = typeRef;
@ -5216,6 +5266,15 @@ BfTypeReference* BfReducer::DoCreateTypeRef(BfAstNode* firstNode, CreateTypeRefF
{
if (tokenNode->GetToken() == BfToken_Dot)
{
if (auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2)))
{
if (nextToken->mToken == BfToken_This)
{
// Don't encode '.this' in type ref
break;
}
}
BfQualifiedTypeReference* outerQualifiedTypeRef = mAlloc->Alloc<BfQualifiedTypeReference>();
ReplaceNode(qualifiedTypeRef, outerQualifiedTypeRef);
outerQualifiedTypeRef->mLeft = qualifiedTypeRef;
@ -5578,6 +5637,11 @@ BfIdentifierNode* BfReducer::CompactQualifiedName(BfAstNode* leftNode)
{
if (auto rightToken = BfNodeDynCast<BfTokenNode>(nextNextToken))
{
if (rightToken->mToken == BfToken_This)
{
return leftIdentifier;
}
if (BfTokenIsKeyword(rightToken->mToken))
{
rightIdentifier = mAlloc->Alloc<BfIdentifierNode>();
@ -8122,14 +8186,26 @@ BfAstNode* BfReducer::CreateAllocNode(BfTokenNode* allocToken)
return allocToken;
}
BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* allocNode)
BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* allocNode, BfAstNode* targetNode)
{
auto objectCreateExpr = mAlloc->Alloc<BfObjectCreateExpression>();
BfDeferredAstSizedArray<BfExpression*> arguments(objectCreateExpr->mArguments, mAlloc);
BfDeferredAstSizedArray<BfTokenNode*> commas(objectCreateExpr->mCommas, mAlloc);
ReplaceNode(allocNode, objectCreateExpr);
MEMBER_SET(objectCreateExpr, mNewNode, allocNode);
BfTypeReference* typeRef = NULL;
if (allocNode != NULL)
{
ReplaceNode(allocNode, objectCreateExpr);
MEMBER_SET(objectCreateExpr, mNewNode, allocNode);
}
else
{
ReplaceNode(targetNode, objectCreateExpr);
typeRef = CreateTypeRef(targetNode);
if (typeRef == NULL)
return NULL;
}
auto nextNode = mVisitorPos.GetNext();
@ -8145,7 +8221,8 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
// }
// }
auto typeRef = CreateTypeRefAfter(objectCreateExpr);
if (typeRef == NULL)
typeRef = CreateTypeRefAfter(objectCreateExpr);
if (typeRef == NULL)
return objectCreateExpr;
@ -8206,6 +8283,42 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
}
else
{
auto nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
auto nextNextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.Get(mVisitorPos.mReadPos + 2));
if ((nextToken != NULL) && (nextToken->mToken == BfToken_Dot) &&
(nextNextToken != NULL) && (nextNextToken->mToken == BfToken_This))
{
auto ctorExplicitNode = mAlloc->Alloc<BfCtorExplicitNode>();
ReplaceNode(nextToken, ctorExplicitNode);
ctorExplicitNode->mDotToken = nextToken;
MEMBER_SET(ctorExplicitNode, mThisToken, nextNextToken);
mVisitorPos.MoveNext();
mVisitorPos.MoveNext();
MEMBER_SET(objectCreateExpr, mCtorExplicit, ctorExplicitNode);
}
else if ((nextToken != NULL) && (nextToken->mToken == BfToken_This))
{
auto ctorExplicitNode = mAlloc->Alloc<BfCtorExplicitNode>();
ReplaceNode(nextToken, ctorExplicitNode);
ctorExplicitNode->mThisToken = nextToken;
mVisitorPos.MoveNext();
MEMBER_SET(objectCreateExpr, mCtorExplicit, ctorExplicitNode);
}
if (objectCreateExpr->mCtorExplicit != NULL)
{
nextToken = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext());
if ((nextToken->mToken != NULL) && (nextToken->mToken == BfToken_LChevron))
{
mVisitorPos.MoveNext();
auto genericParamsDecl = CreateGenericArguments(nextToken, true);
if (genericParamsDecl == NULL)
return objectCreateExpr;
MEMBER_SET(objectCreateExpr->mCtorExplicit, mGenericArgs, genericParamsDecl);
objectCreateExpr->mSrcEnd = objectCreateExpr->mCtorExplicit->mSrcEnd;
}
}
// Note- if there WERE an LBracket here then we'd have an 'isArray' case. We pass this in here for
// error display purposes
tokenNode = ExpectTokenAfter(objectCreateExpr, BfToken_LParen, BfToken_LBracket);
@ -8308,6 +8421,12 @@ BfMemberReferenceExpression* BfReducer::CreateMemberReferenceExpression(BfAstNod
MEMBER_SET(memberReferenceExpr, mMemberName, attrIdentifier);
}
}
if (tokenNode->GetToken() == BfToken_This)
{
mVisitorPos.MoveNext();
MEMBER_SET(memberReferenceExpr, mMemberName, tokenNode);
}
}
if (memberReferenceExpr->mMemberName == NULL)