1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-04 15:26:00 +02:00

Added label support to 'fallthrough'

This commit is contained in:
Brian Fiete 2023-12-16 07:38:27 -05:00
parent 3f7fc178e5
commit 85273962be
5 changed files with 49 additions and 5 deletions

View file

@ -3311,6 +3311,7 @@ public:
BF_AST_TYPE(BfFallthroughStatement, BfStatement);
BfTokenNode* mFallthroughToken;
BfAstNode* mLabel;
}; BF_AST_DECL(BfFallthroughStatement, BfStatement);
class BfForEachStatement : public BfLabelableStatement

View file

@ -902,6 +902,7 @@ void BfElementVisitor::Visit(BfFallthroughStatement* fallthroughStmt)
Visit(fallthroughStmt->ToBase());
VisitChild(fallthroughStmt->mFallthroughToken);
VisitChild(fallthroughStmt->mLabel);
}
void BfElementVisitor::Visit(BfForStatement* forStmt)

View file

@ -2275,7 +2275,11 @@ void BfPrinter::Visit(BfFallthroughStatement* fallthroughStmt)
Visit(fallthroughStmt->ToBase());
VisitChild(fallthroughStmt->mFallthroughToken);
if (fallthroughStmt->mLabel != NULL)
{
ExpectSpace();
VisitChild(fallthroughStmt->mLabel);
}
VisitChild(fallthroughStmt->mTrailingSemicolon);
}

View file

@ -3838,6 +3838,19 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
auto fallthroughStmt = mAlloc->Alloc<BfFallthroughStatement>();
ReplaceNode(tokenNode, fallthroughStmt);
fallthroughStmt->mFallthroughToken = tokenNode;
if (auto label = BfNodeDynCast<BfIdentifierNode>(mVisitorPos.GetNext()))
{
MEMBER_SET(fallthroughStmt, mLabel, label);
mVisitorPos.MoveNext();
}
else if (auto tokenNode = BfNodeDynCast<BfTokenNode>(mVisitorPos.GetNext()))
{
if (tokenNode->GetToken() == BfToken_Mixin)
{
MEMBER_SET(fallthroughStmt, mLabel, tokenNode);
mVisitorPos.MoveNext();
}
}
return fallthroughStmt;
}
else if (token == BfToken_For)

View file

@ -5637,11 +5637,27 @@ void BfModule::Visit(BfFallthroughStatement* fallthroughStmt)
{
UpdateSrcPos(fallthroughStmt);
BfBreakData* breakData = mCurMethodState->mBreakData;
while (breakData != NULL)
if (fallthroughStmt->mLabel != NULL)
{
if (breakData->mIRFallthroughBlock)
break;
breakData = breakData->mPrevBreakData;
breakData = FindBreakData(fallthroughStmt->mLabel);
}
else
{
while (breakData != NULL)
{
if (breakData->mIRFallthroughBlock)
break;
breakData = breakData->mPrevBreakData;
}
}
if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL))
{
BfScopeData* scope = NULL;
if (breakData != NULL)
scope = breakData->mScope;
if (auto identifer = BfNodeDynCast<BfIdentifierNode>(fallthroughStmt->mLabel))
mCompiler->mResolvePassData->mAutoComplete->CheckLabel(identifer, fallthroughStmt->mFallthroughToken, scope);
}
if (mCurMethodState->mInDeferredBlock)
@ -5669,6 +5685,15 @@ void BfModule::Visit(BfFallthroughStatement* fallthroughStmt)
mCurMethodState->mLeftBlockUncond = true; // Not really a return, but handled the same way
if (mCurMethodState->mDeferredLocalAssignData != NULL)
mCurMethodState->mDeferredLocalAssignData->mHadFallthrough = true;
auto checkBreakData = mCurMethodState->mBreakData;
while (true)
{
if (checkBreakData == breakData)
break;
checkBreakData->mHadBreak = true;
checkBreakData = checkBreakData->mPrevBreakData;
}
}
void BfModule::Visit(BfUsingStatement* usingStmt)