Skip to content

Commit 0e98485

Browse files
committed
fix(transpiler): support continue in nested for loops.
1 parent a61804a commit 0e98485

5 files changed

Lines changed: 504 additions & 10 deletions

File tree

packages/transpiler/src/kotlin/KotlinAstPrinter.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,15 +1601,42 @@ export default class KotlinAstPrinter extends AstPrinterBase {
16011601
this.writeExpression(s.expression);
16021602
this.writeLine(')');
16031603

1604-
if (cs.isBlock(s.statement)) {
1605-
this.writeStatement(s.statement);
1606-
} else {
1607-
this._indent++;
1608-
this.writeStatement(s.statement);
1609-
this._indent--;
1604+
this._forLoopIncrementors.push(undefined);
1605+
try {
1606+
if (cs.isBlock(s.statement)) {
1607+
this.writeStatement(s.statement);
1608+
} else {
1609+
this._indent++;
1610+
this.writeStatement(s.statement);
1611+
this._indent--;
1612+
}
1613+
} finally {
1614+
this._forLoopIncrementors.pop();
1615+
}
1616+
}
1617+
1618+
protected override writeWhileStatement(s: cs.WhileStatement) {
1619+
this._forLoopIncrementors.push(undefined);
1620+
try {
1621+
super.writeWhileStatement(s);
1622+
} finally {
1623+
this._forLoopIncrementors.pop();
1624+
}
1625+
}
1626+
1627+
protected override writeDoStatement(s: cs.DoStatement) {
1628+
this._forLoopIncrementors.push(undefined);
1629+
try {
1630+
super.writeDoStatement(s);
1631+
} finally {
1632+
this._forLoopIncrementors.pop();
16101633
}
16111634
}
16121635

1636+
// Stack of pending step-expressions for enclosing C-style `for` loops
1637+
// lowered to `while`. Non-loop scopes never push; nested `for-of`, `for-in`,
1638+
// `while`, and `do-while` push `undefined` so a `continue` inside them
1639+
// targets the inner loop and skips the outer's step injection.
16131640
private _forLoopIncrementors: (cs.Expression | undefined)[] = [];
16141641

16151642
protected writeForStatement(s: cs.ForStatement) {

packages/transpiler/src/transforms/Statements.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ export function visitStatement(state: AstTransformer, parent: cs.Node, s: ts.Sta
3434
case ts.SyntaxKind.ForInStatement:
3535
return visitForInStatement(state, s as ts.ForInStatement);
3636
case ts.SyntaxKind.BreakStatement:
37-
return visitBreakStatement(parent, s as ts.BreakStatement);
37+
return visitBreakStatement(state, parent, s as ts.BreakStatement);
3838
case ts.SyntaxKind.ContinueStatement:
39-
return visitContinueStatement(parent, s as ts.ContinueStatement);
39+
return visitContinueStatement(state, parent, s as ts.ContinueStatement);
4040
case ts.SyntaxKind.ReturnStatement:
4141
return visitReturnStatement(state, parent, s as ts.ReturnStatement);
4242
case ts.SyntaxKind.WithStatement:
@@ -373,11 +373,17 @@ function visitForInStatement(state: AstTransformer, s: ts.ForInStatement): null
373373
return null;
374374
}
375375

376-
function visitBreakStatement(parent: cs.Node, s: ts.BreakStatement): cs.BreakStatement {
376+
function visitBreakStatement(state: AstTransformer, parent: cs.Node, s: ts.BreakStatement): cs.BreakStatement {
377+
if (s.label) {
378+
state.context.addTsNodeDiagnostics(s, 'Labeled break is not supported', ts.DiagnosticCategory.Error);
379+
}
377380
return { nodeType: cs.SyntaxKind.BreakStatement, parent, tsNode: s };
378381
}
379382

380-
function visitContinueStatement(parent: cs.Node, s: ts.ContinueStatement): cs.ContinueStatement {
383+
function visitContinueStatement(state: AstTransformer, parent: cs.Node, s: ts.ContinueStatement): cs.ContinueStatement {
384+
if (s.label) {
385+
state.context.addTsNodeDiagnostics(s, 'Labeled continue is not supported', ts.DiagnosticCategory.Error);
386+
}
381387
return { nodeType: cs.SyntaxKind.ContinueStatement, parent, tsNode: s };
382388
}
383389

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// <auto-generated>
2+
// This code was auto-generated.
3+
// Changes to this file may cause incorrect behavior and will be lost if
4+
// the code is regenerated.
5+
// </auto-generated>
6+
#nullable enable annotations
7+
8+
using System;
9+
using AlphaTab.Core;
10+
11+
namespace AlphaTab
12+
{
13+
public class ForNestedContinue
14+
{
15+
public double Baseline(System.Collections.Generic.IList<double> items)
16+
{
17+
double sum = 0;
18+
for (double i = 0;i < items.Count;i++)
19+
{
20+
if (items[(int)(i)] < 0)
21+
{
22+
continue;
23+
}
24+
sum += items[(int)(i)];
25+
}
26+
return sum;
27+
}
28+
29+
30+
public double NestedForOf(System.Collections.Generic.IList<double> outer, System.Collections.Generic.IList<double> inner)
31+
{
32+
double sum = 0;
33+
for (double i = 0;i < outer.Count;i++)
34+
{
35+
foreach (double v in inner)
36+
{
37+
if (v < 0)
38+
{
39+
continue;
40+
}
41+
sum += outer[(int)(i)] + v;
42+
}
43+
}
44+
return sum;
45+
}
46+
47+
48+
public double NestedWhile(System.Collections.Generic.IList<double> outer, double target)
49+
{
50+
double sum = 0;
51+
for (double i = 0;i < outer.Count;i++)
52+
{
53+
double j = 0;
54+
while (j < outer.Count)
55+
{
56+
j++;
57+
if (outer[(int)(j - (double)(1))] == target)
58+
{
59+
continue;
60+
}
61+
sum += outer[(int)(j - (double)(1))];
62+
}
63+
}
64+
return sum;
65+
}
66+
67+
68+
public double NestedDoWhile(System.Collections.Generic.IList<double> outer)
69+
{
70+
double sum = 0;
71+
for (double i = 0;i < outer.Count;i++)
72+
{
73+
double j = 0;
74+
do
75+
{
76+
j++;
77+
if (outer[(int)(j - (double)(1))] < 0)
78+
{
79+
continue;
80+
}
81+
sum += outer[(int)(j - (double)(1))];
82+
}
83+
while (j < outer.Count);
84+
}
85+
return sum;
86+
}
87+
88+
89+
public double NestedCStyle(System.Collections.Generic.IList<double> outer, System.Collections.Generic.IList<double> inner)
90+
{
91+
double sum = 0;
92+
for (double i = 0;i < outer.Count;i++)
93+
{
94+
for (double j = 0;j < inner.Count;j++)
95+
{
96+
if (inner[(int)(j)] < 0)
97+
{
98+
continue;
99+
}
100+
sum += outer[(int)(i)] + inner[(int)(j)];
101+
}
102+
}
103+
return sum;
104+
}
105+
106+
107+
public double ContinueInSwitch(System.Collections.Generic.IList<double> items)
108+
{
109+
double sum = 0;
110+
for (double i = 0;i < items.Count;i++)
111+
{
112+
switch (items[(int)(i)])
113+
{
114+
case 0:
115+
continue;
116+
default:
117+
sum += items[(int)(i)];
118+
break;
119+
}
120+
}
121+
return sum;
122+
}
123+
124+
125+
public double BreakInNested(System.Collections.Generic.IList<double> outer, double target)
126+
{
127+
for (double i = 0;i < outer.Count;i++)
128+
{
129+
foreach (double v in outer)
130+
{
131+
if (v == target)
132+
{
133+
break;
134+
}
135+
}
136+
}
137+
return -1;
138+
}
139+
140+
141+
}
142+
143+
}

0 commit comments

Comments
 (0)