X Tutup
Skip to content

Commit 17bb60f

Browse files
DoctorGesterPerryvw
authored andcommitted
Switch case goto chain is now transpiled to an elseif chain (#791)
* Switch case goto chain is now transpiled to an elseif chain instead of multiple ifs * Switch case goto chain is now transpiled to an elseif chain instead of multiple ifs
1 parent 13817df commit 17bb60f

File tree

3 files changed

+79
-4
lines changed

3 files changed

+79
-4
lines changed

src/transformation/visitors/switch.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ export const transformSwitchStatement: FunctionVisitor<ts.SwitchStatement> = (st
1919
let statements: lua.Statement[] = [];
2020

2121
const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause);
22-
for (const [index, clause] of caseClauses.entries()) {
22+
23+
// Starting from the back, concatenating ifs into one big if/elseif statement
24+
const concatenatedIf = caseClauses.reduceRight((previousCondition, clause, index) => {
2325
// If the clause condition holds, go to the correct label
2426
const condition = lua.createBinaryExpression(
2527
switchVariable,
@@ -28,8 +30,11 @@ export const transformSwitchStatement: FunctionVisitor<ts.SwitchStatement> = (st
2830
);
2931

3032
const goto = lua.createGotoStatement(`${switchName}_case_${index}`);
31-
const conditionalGoto = lua.createIfStatement(condition, lua.createBlock([goto]));
32-
statements.push(conditionalGoto);
33+
return lua.createIfStatement(condition, lua.createBlock([goto]), previousCondition);
34+
}, undefined as lua.IfStatement | undefined);
35+
36+
if (concatenatedIf) {
37+
statements.push(concatenatedIf);
3338
}
3439

3540
const hasDefaultCase = statement.caseBlock.clauses.some(ts.isDefaultClause);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`array 1`] = `
4+
"local ____exports = {}
5+
function ____exports.__main(self)
6+
local result = -1
7+
local ____switch3 = 2
8+
if ____switch3 == 0 then
9+
goto ____switch3_case_0
10+
elseif ____switch3 == 1 then
11+
goto ____switch3_case_1
12+
elseif ____switch3 == 2 then
13+
goto ____switch3_case_2
14+
end
15+
goto ____switch3_end
16+
::____switch3_case_0::
17+
do
18+
do
19+
result = 200
20+
goto ____switch3_end
21+
end
22+
end
23+
::____switch3_case_1::
24+
do
25+
do
26+
result = 100
27+
goto ____switch3_end
28+
end
29+
end
30+
::____switch3_case_2::
31+
do
32+
do
33+
result = 1
34+
goto ____switch3_end
35+
end
36+
end
37+
::____switch3_end::
38+
return result
39+
end
40+
return ____exports"
41+
`;

test/unit/conditionals.spec.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ test("variable in nested scope does not interfere with case scope", () => {
184184
`.expectToMatchJsResult();
185185
});
186186

187-
test.only("switch using variable re-declared in cases", () => {
187+
test("switch using variable re-declared in cases", () => {
188188
util.testFunction`
189189
let foo: number = 0;
190190
switch (foo) {
@@ -311,6 +311,35 @@ test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => {
311311
`.expectToMatchJsResult();
312312
});
313313

314+
test("switch uses elseif", () => {
315+
test("array", () => {
316+
util.testFunction`
317+
let result: number = -1;
318+
319+
switch (2 as number) {
320+
case 0: {
321+
result = 200;
322+
break;
323+
}
324+
325+
case 1: {
326+
result = 100;
327+
break;
328+
}
329+
330+
case 2: {
331+
result = 1;
332+
break;
333+
}
334+
}
335+
336+
return result;
337+
`
338+
.expectLuaToMatchSnapshot()
339+
.expectToMatchJsResult();
340+
});
341+
});
342+
314343
test("switch not allowed in 5.1", () => {
315344
util.testFunction`
316345
switch ("abc") {}

0 commit comments

Comments
 (0)
X Tutup