17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
if( p.isInParenExpr() || !p.cfg() )
{
dm.emitSyntaxErrorMessage( locationId, "the while statement is not allowed here.", 0 );
return false;
}
auto pPrecBB = p.currentBB();
auto np = p.makeNestedParser();
if( !np.parseExpression( precedence::IfStmt ) )
{
dm.emitSyntaxErrorMessage( locationId, "expected an expression following the while statement.", 0 );
return false;
}
|
|
>
>
>
>
>
>
>
|
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
if( p.isInParenExpr() || !p.cfg() )
{
dm.emitSyntaxErrorMessage( locationId, "the while statement is not allowed here.", 0 );
return false;
}
auto pPrecBB = p.cfg()->currentBB();
if( !pPrecBB || pPrecBB->terminator() )
{
DiagnosticsManager::GetInstance().emitSyntaxErrorMessage(
locationId, "unreachable code.", 0 );
p.cfg()->poison();
}
auto np = p.makeNestedParser();
if( !np.parseExpression( precedence::IfStmt ) )
{
dm.emitSyntaxErrorMessage( locationId, "expected an expression following the while statement.", 0 );
return false;
}
|
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
}
if( get< Value >( converted ).isPoison() )
p.cfg()->poison();
auto pHeaderBB = p.cfg()->createBB();
auto pBodyBB = ParseSubStatement( p, precedence::IfStmt );
if( !pBodyBB )
{
dm.emitSyntaxErrorMessage( p.resolver()->getCurrentLocation(), "expected a statement after the while condition.", 0 );
return false;
}
// Retrieve the final block of the loop body, if any
auto pBodySuccBB = p.currentBB();
ptr< llr::BasicBlock > pSuccBB = p.cfg()->createBB();
// Jump unconditionally from the pred block to the loop header.
pPrecBB->setTerminator( llr::Branch( pHeaderBB ) );
// Emit the conditional branch that will either run an iteration of the loop or exit to the succ bb.
pHeaderBB->setTerminator( llr::CondBranch(
get< Value >( converted ),
pBodyBB, pSuccBB ) );
// Jump from the end of the body BB back to the loop header
pBodySuccBB->setTerminator( llr::Branch( pHeaderBB ) );
p.setCurrentBB( pSuccBB );
return true;
};
Rule r( handleWhile );
auto ruleVal = ToValue( move( r ) );
auto ruleTerm = ValueToIRExpr( ruleVal );
e.storeValue( AppendToVectorTerm( RootIdentity(), TSID( while ) ), ANYTERM( _ ), ruleTerm );
}
}
|
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
|
|
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
}
if( get< Value >( converted ).isPoison() )
p.cfg()->poison();
auto pHeaderBB = p.cfg()->createBB();
Parser::BreakableScopeGuard bsg( p );
Parser::ContinuableScopeGuard csg( p );
auto pBodyBB = ParseSubStatement( p, precedence::IfStmt );
if( !pBodyBB )
{
dm.emitSyntaxErrorMessage( p.resolver()->getCurrentLocation(), "expected a statement after the while condition.", 0 );
return false;
}
if( !pPrecBB )
{
return true;
}
// Retrieve the final block of the loop body, if any
if( auto pBodySuccBB = p.cfg()->currentBB() )
{
// Jump from the end of the body BB back to the loop header
pBodySuccBB->setTerminator( llr::Branch( pHeaderBB ) );
}
ptr< llr::BasicBlock > pSuccBB = p.cfg()->createBB();
// Jump unconditionally from the pred block to the loop header.
pPrecBB->setTerminator( llr::Branch( pHeaderBB ) );
// Emit the conditional branch that will either run an iteration of the loop or exit to the succ bb.
pHeaderBB->setTerminator( llr::CondBranch(
get< Value >( converted ),
pBodyBB, pSuccBB ) );
auto breakLevel = p.breakableScopeLevels();
auto continueLevel = p.continuableScopeLevels();
// Go through all basic blocks, find all break and continue terminators
// for our scope level and replace them with branches respectively to
// the successor BB or to the loop header BB.
p.cfg()->ForEachBB( [&]( auto&& bb )
{
const auto& t = bb->terminator();
if( !t )
return;
if( const auto* pBreak = get_if< llr::Break >( &t->content() ) )
{
if( pBreak->level() == breakLevel )
bb->setTerminator( llr::Branch( pSuccBB ) );
return;
}
if( const auto* pCont = get_if< llr::Continue >( &t->content() ) )
{
if( pCont->level() == continueLevel )
bb->setTerminator( llr::Branch( pHeaderBB ) );
return;
}
} );
p.cfg()->setCurrentBB( pSuccBB );
return true;
};
Rule r( handleWhile );
auto ruleVal = ToValue( move( r ) );
auto ruleTerm = ValueToIRExpr( ruleVal );
e.storeValue( AppendToVectorTerm( RootIdentity(), TSID( while ) ), ANYTERM( _ ), ruleTerm );
}
}
|