Skip to content

Commit 377fdb4

Browse files
committed
Implement EnumerateDF to visit all sub-statements
Improve Switch-Case
1 parent 77bbb22 commit 377fdb4

File tree

2 files changed

+114
-5
lines changed

2 files changed

+114
-5
lines changed

backend/Core/Stmt.cs

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ public bool IsAttrib( string key, string value )
2929
&& attribs.TryGetValue( key, out Strings values )
3030
&& values.Contains( value );
3131

32+
// Enumerate (depth first) through all contained Stmt and itself
33+
// Only overloaded in Stmt which contain more Stmt itself
34+
// Filter results with e.g. EnumerateDF.OfType<ReturnStmt>()
35+
[Pure]
36+
public virtual IEnumerable<Stmt> EnumerateDF {
37+
get { yield return this; }
38+
}
39+
3240
public virtual void AssignAttribs( Attribs inAttribs )
3341
{
3442
attribs = inAttribs;
@@ -189,6 +197,21 @@ public class IfStmt : Stmt
189197
public List<CondThen> ifThens;
190198
public Stmt? elseStmt;
191199

200+
[Pure]
201+
public override IEnumerable<Stmt> EnumerateDF {
202+
get {
203+
foreach( CondThen ifThen in ifThens )
204+
foreach( Stmt subStmt in ifThen.thenStmt.EnumerateDF )
205+
yield return subStmt;
206+
207+
if( elseStmt != null )
208+
foreach( Stmt subStmt in elseStmt.EnumerateDF )
209+
yield return subStmt;
210+
211+
yield return this;
212+
}
213+
}
214+
192215
public override Strings Gen( int level )
193216
{
194217
Strings ret = new();
@@ -211,10 +234,10 @@ public override Strings Gen( int level )
211234
}
212235
}
213236

214-
public class CaseStmt : Stmt
237+
public struct CaseStmt
215238
{
216-
public List<Expr> caseExprs;
217-
public List<Stmt> bodyStmts;
239+
public List<Expr> caseExprs; // can have multiple ORed conditions
240+
public MultiStmt bodyStmt;
218241
public bool autoBreak;
219242
}
220243

@@ -224,6 +247,22 @@ public class SwitchStmt : Stmt
224247
public List<CaseStmt> caseStmts;
225248
public List<Stmt>? elseStmts;
226249

250+
[Pure]
251+
public override IEnumerable<Stmt> EnumerateDF {
252+
get {
253+
foreach( CaseStmt caseStmt in caseStmts )
254+
foreach( Stmt subStmt in caseStmt.bodyStmt.EnumerateDF )
255+
yield return subStmt;
256+
257+
if( elseStmts != null )
258+
foreach( Stmt elseStmt in elseStmts )
259+
foreach( Stmt subStmt in elseStmt.EnumerateDF )
260+
yield return subStmt;
261+
262+
yield return this;
263+
}
264+
}
265+
227266
public override Strings Gen( int level )
228267
{
229268
throw new NotImplementedException();
@@ -235,6 +274,16 @@ public class LoopStmt : Stmt
235274
{
236275
public Stmt bodyStmt;
237276

277+
[Pure]
278+
public override IEnumerable<Stmt> EnumerateDF {
279+
get {
280+
foreach( Stmt subStmt in bodyStmt.EnumerateDF )
281+
yield return subStmt;
282+
283+
yield return this;
284+
}
285+
}
286+
238287
public override Strings Gen( int level )
239288
{
240289
Strings ret = new();
@@ -255,6 +304,21 @@ public class ForStmt : LoopStmt
255304
public Expr iterExpr;
256305
public Stmt? elseStmt;
257306

307+
[Pure]
308+
public override IEnumerable<Stmt> EnumerateDF {
309+
get {
310+
foreach( Stmt subStmt in initStmt.EnumerateDF )
311+
yield return subStmt;
312+
313+
if( elseStmt != null )
314+
foreach( Stmt subStmt in elseStmt.EnumerateDF )
315+
yield return subStmt;
316+
317+
foreach( Stmt baseStmt in base.EnumerateDF )
318+
yield return baseStmt;
319+
}
320+
}
321+
258322
public override Strings Gen( int level )
259323
{
260324
if( elseStmt != null )
@@ -280,6 +344,18 @@ public class WhileStmt : LoopStmt
280344
public Expr condExpr;
281345
public Stmt? elseStmt;
282346

347+
[Pure]
348+
public override IEnumerable<Stmt> EnumerateDF {
349+
get {
350+
if( elseStmt != null )
351+
foreach( Stmt subStmt in elseStmt.EnumerateDF )
352+
yield return subStmt;
353+
354+
foreach( Stmt baseStmt in base.EnumerateDF )
355+
yield return baseStmt;
356+
}
357+
}
358+
283359
public override Strings Gen( int level )
284360
{
285361
if( elseStmt != null )
@@ -347,6 +423,17 @@ public class MultiStmt : Stmt
347423
// TODO merge this with Block?
348424
// public bool IsBlock { get; init; }
349425

426+
[Pure]
427+
public override IEnumerable<Stmt> EnumerateDF {
428+
get {
429+
foreach( Stmt stmt in stmts )
430+
foreach( Stmt subStmt in stmt.EnumerateDF )
431+
yield return subStmt;
432+
433+
yield return this;
434+
}
435+
}
436+
350437
public override void AssignAttribs( Attribs inAttribs )
351438
{
352439
stmts.ForEach( v => v.AssignAttribs( inAttribs ) );
@@ -366,6 +453,17 @@ public class Block : Stmt
366453
{
367454
public List<Stmt> stmts;
368455

456+
[Pure]
457+
public override IEnumerable<Stmt> EnumerateDF {
458+
get {
459+
foreach( Stmt stmt in stmts )
460+
foreach( Stmt subStmt in stmt.EnumerateDF )
461+
yield return subStmt;
462+
463+
yield return this;
464+
}
465+
}
466+
369467
// only overriden here
370468
public override Strings GenWithoutCurly( int level )
371469
{

backend/Visitor/VStmt.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,21 @@ public override Stmt VisitIfStmt( IfStmtContext c )
166166

167167
public new CaseStmt VisitCaseStmt( CaseStmtContext c )
168168
{
169+
MultiStmt multiStmt = new() {
170+
srcPos = c.ToSrcPos(),
171+
stmts = c.levStmt().Select( Visit ).ToList(),
172+
};
173+
bool isFall = c.FALL() != null;
174+
if( !isFall )
175+
multiStmt.stmts.Append( new BreakStmt { depth = 1 } );
176+
// TODO: else C++ [[fallthrough]]
177+
//else
178+
// multiStmt.stmts.Append( new FallStmt() );
179+
// multiStmt.stmts.Append( new FreetextStmt( "[[fallthrough]]" ) );
180+
169181
CaseStmt ret = new() {
170-
srcPos = c.ToSrcPos(),
171182
caseExprs = c.expr().Select( q => q.Visit() ).ToList(),
172-
bodyStmts = c.levStmt().Select( Visit ).ToList(),
183+
bodyStmt = multiStmt,
173184
autoBreak = c.FALL() != null,
174185
};
175186
return ret;

0 commit comments

Comments
 (0)