Skip to content

Commit 81fbd22

Browse files
committed
Fix(compiler): ForStatement - continue must jump to incrementor if it's exists or startBlock
1 parent 0f5886c commit 81fbd22

3 files changed

Lines changed: 36 additions & 15 deletions

File tree

src/backend/llvm/code-generation/for-statement.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,29 +45,36 @@ export class ForStatementGenerator implements NodeGenerateInterface<ts.ForStatem
4545
builder.setInsertionPoint(bodyBlock);
4646
}
4747

48-
ctx.scope.breakBlock = next;
49-
ctx.scope.continueBlock = startBlock;
50-
51-
builder.setInsertionPoint(bodyBlock);
52-
passStatement(node.statement, ctx, builder);
48+
/**
49+
* Continue block can be incrementer block: for (i = 0; i < 100; i++)
50+
* or next block: for (i = 0; i < 100; )
51+
*/
52+
let continueBlock: llvm.BasicBlock = startBlock;
5353

5454
if (node.incrementor) {
5555
const incrementer = llvm.BasicBlock.create(ctx.llvmContext, "for.inc");
5656
ctx.scope.enclosureFunction.llvmFunction.addBasicBlock(incrementer);
5757

58-
// jump from bodyBlock to incrementer
59-
builder.createBr(incrementer);
6058
builder.setInsertionPoint(incrementer);
61-
6259
passStatement(<any>node.incrementor, ctx, builder);
60+
61+
builder.createBr(startBlock);
62+
63+
continueBlock = incrementer;
6364
}
6465

66+
ctx.scope.breakBlock = next;
67+
ctx.scope.continueBlock = continueBlock;
68+
69+
builder.setInsertionPoint(bodyBlock);
70+
passStatement(node.statement, ctx, builder);
71+
6572
// next iteration of cycle
66-
builder.createBr(startBlock);
73+
builder.createBr(continueBlock);
6774

6875
ctx.scope.breakBlock = null;
6976
ctx.scope.continueBlock = null;
7077

7178
builder.setInsertionPoint(next);
7279
}
73-
}
80+
}

tests/snapshots/math/for.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
{
33
function calculateTotalFromRange(start: number, end: number): number {
4+
console_log("calculateTotalFromRange");
5+
46
let total: number = 0;
57

68
for (let i = start; i < end; i++) {
@@ -11,6 +13,8 @@
1113
}
1214

1315
function simpleBreak(): number {
16+
console_log("simpleBreak");
17+
1418
let total: number = 0;
1519

1620
for (let i = 0; ; i++) {
@@ -25,9 +29,11 @@
2529
}
2630

2731
function simpleContinue(): number {
32+
console_log("simpleContinue");
33+
2834
let total: number = 0;
2935

30-
for (let i = 0; i++; i++) {
36+
for (let i = 0; i < 100; i++) {
3137
if (i > 50) {
3238
continue;
3339
}
@@ -38,8 +44,8 @@
3844
return total;
3945
}
4046

41-
calculateTotalFromRange(1, 100);
42-
calculateTotalFromRange(50, 100);
43-
simpleBreak();
44-
simpleContinue();
47+
console_log(calculateTotalFromRange(1, 100));
48+
console_log(calculateTotalFromRange(50, 100));
49+
console_log(simpleBreak());
50+
console_log(simpleContinue());
4551
}

tests/snapshots/math/for.ts.stdout

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
calculateTotalFromRange
2+
4950.000000
3+
calculateTotalFromRange
4+
3725.000000
5+
simpleBreak
6+
5151.000000
7+
simpleContinue
8+
1275.000000

0 commit comments

Comments
 (0)