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:
parent
3f7fc178e5
commit
85273962be
5 changed files with 49 additions and 5 deletions
|
@ -3311,6 +3311,7 @@ public:
|
||||||
BF_AST_TYPE(BfFallthroughStatement, BfStatement);
|
BF_AST_TYPE(BfFallthroughStatement, BfStatement);
|
||||||
|
|
||||||
BfTokenNode* mFallthroughToken;
|
BfTokenNode* mFallthroughToken;
|
||||||
|
BfAstNode* mLabel;
|
||||||
}; BF_AST_DECL(BfFallthroughStatement, BfStatement);
|
}; BF_AST_DECL(BfFallthroughStatement, BfStatement);
|
||||||
|
|
||||||
class BfForEachStatement : public BfLabelableStatement
|
class BfForEachStatement : public BfLabelableStatement
|
||||||
|
|
|
@ -902,6 +902,7 @@ void BfElementVisitor::Visit(BfFallthroughStatement* fallthroughStmt)
|
||||||
Visit(fallthroughStmt->ToBase());
|
Visit(fallthroughStmt->ToBase());
|
||||||
|
|
||||||
VisitChild(fallthroughStmt->mFallthroughToken);
|
VisitChild(fallthroughStmt->mFallthroughToken);
|
||||||
|
VisitChild(fallthroughStmt->mLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfElementVisitor::Visit(BfForStatement* forStmt)
|
void BfElementVisitor::Visit(BfForStatement* forStmt)
|
||||||
|
|
|
@ -2275,7 +2275,11 @@ void BfPrinter::Visit(BfFallthroughStatement* fallthroughStmt)
|
||||||
Visit(fallthroughStmt->ToBase());
|
Visit(fallthroughStmt->ToBase());
|
||||||
|
|
||||||
VisitChild(fallthroughStmt->mFallthroughToken);
|
VisitChild(fallthroughStmt->mFallthroughToken);
|
||||||
|
if (fallthroughStmt->mLabel != NULL)
|
||||||
|
{
|
||||||
|
ExpectSpace();
|
||||||
|
VisitChild(fallthroughStmt->mLabel);
|
||||||
|
}
|
||||||
VisitChild(fallthroughStmt->mTrailingSemicolon);
|
VisitChild(fallthroughStmt->mTrailingSemicolon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3838,6 +3838,19 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
|
||||||
auto fallthroughStmt = mAlloc->Alloc<BfFallthroughStatement>();
|
auto fallthroughStmt = mAlloc->Alloc<BfFallthroughStatement>();
|
||||||
ReplaceNode(tokenNode, fallthroughStmt);
|
ReplaceNode(tokenNode, fallthroughStmt);
|
||||||
fallthroughStmt->mFallthroughToken = tokenNode;
|
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;
|
return fallthroughStmt;
|
||||||
}
|
}
|
||||||
else if (token == BfToken_For)
|
else if (token == BfToken_For)
|
||||||
|
|
|
@ -5637,12 +5637,28 @@ void BfModule::Visit(BfFallthroughStatement* fallthroughStmt)
|
||||||
{
|
{
|
||||||
UpdateSrcPos(fallthroughStmt);
|
UpdateSrcPos(fallthroughStmt);
|
||||||
BfBreakData* breakData = mCurMethodState->mBreakData;
|
BfBreakData* breakData = mCurMethodState->mBreakData;
|
||||||
|
if (fallthroughStmt->mLabel != NULL)
|
||||||
|
{
|
||||||
|
breakData = FindBreakData(fallthroughStmt->mLabel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while (breakData != NULL)
|
while (breakData != NULL)
|
||||||
{
|
{
|
||||||
if (breakData->mIRFallthroughBlock)
|
if (breakData->mIRFallthroughBlock)
|
||||||
break;
|
break;
|
||||||
breakData = breakData->mPrevBreakData;
|
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)
|
if (mCurMethodState->mInDeferredBlock)
|
||||||
{
|
{
|
||||||
|
@ -5669,6 +5685,15 @@ void BfModule::Visit(BfFallthroughStatement* fallthroughStmt)
|
||||||
mCurMethodState->mLeftBlockUncond = true; // Not really a return, but handled the same way
|
mCurMethodState->mLeftBlockUncond = true; // Not really a return, but handled the same way
|
||||||
if (mCurMethodState->mDeferredLocalAssignData != NULL)
|
if (mCurMethodState->mDeferredLocalAssignData != NULL)
|
||||||
mCurMethodState->mDeferredLocalAssignData->mHadFallthrough = true;
|
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)
|
void BfModule::Visit(BfUsingStatement* usingStmt)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue