X Tutup
Skip to content

Commit c4cd099

Browse files
authored
Cleaned up ForOf code (#260)
* Cleaned up forOf loop, made it use numeric loop instead of ipairs * Fixed bug in non-array loop header and fixed tests * Fixed up some PR comments
1 parent bab8df3 commit c4cd099

File tree

3 files changed

+46
-11
lines changed

3 files changed

+46
-11
lines changed

src/Transpiler.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -558,28 +558,41 @@ export abstract class LuaTranspiler {
558558
const variable = (node.initializer as ts.VariableDeclarationList).declarations[0];
559559

560560
// Transpile expression
561-
const expression = this.transpileExpression(node.expression);
561+
const iterable = this.transpileExpression(node.expression);
562562

563563
// Use ipairs for array types, pairs otherwise
564564
const isArray = tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker);
565-
const pairs = isArray ? "ipairs" : "pairs";
566565

567-
// Make header
568566
let result = "";
569-
if (ts.isIdentifier(variable.name)) {
570-
result = this.indent + `for _, ${this.transpileIdentifier(variable.name)} in ${pairs}(${expression}) do\n`;
571-
} else if (ts.isArrayBindingPattern(variable.name)) {
572-
const valueVar = "__forOfValue" + this.genVarCounter;
573-
result = this.indent + `for _, ${valueVar} in ${pairs}(${expression}) do\n`;
574-
const declaration = ts.createVariableDeclaration(variable.name, undefined, ts.createIdentifier(valueVar));
575-
result += this.indent + this.transpileVariableDeclaration(declaration);
567+
568+
if (!isArray && ts.isIdentifier(variable.name)) {
569+
result = this.indent + `for _, ${this.transpileIdentifier(variable.name)} in pairs(${iterable}) do\n`;
570+
} else {
571+
let itemVariable: ts.Identifier;
572+
if (isArray) {
573+
// Cache the expression result
574+
result += this.indent + `local __loopVariable${this.genVarCounter} = ${iterable};\n`;
575+
result += this.indent + `for i${this.genVarCounter}=1, #__loopVariable${this.genVarCounter} do\n`;
576+
itemVariable = ts.createIdentifier(`__loopVariable${this.genVarCounter}[i${this.genVarCounter}]`);
577+
} else {
578+
const variableName = `__forOfValue${this.genVarCounter}`;
579+
itemVariable = ts.createIdentifier(variableName);
580+
result += this.indent + `for _, ${variableName} in pairs(${iterable}) do\n`;
581+
}
582+
583+
const declaration = ts.createVariableDeclaration(variable.name, undefined, itemVariable);
584+
this.pushIndent();
585+
result += this.indent + this.transpileVariableDeclaration(declaration) + ";\n";
586+
this.popIndent();
576587
}
577588

578589
// For body
579590
this.pushIndent();
580591
result += this.transpileLoopBody(node);
581592
this.popIndent();
582593

594+
this.genVarCounter++;
595+
583596
return result + this.indent + "end\n";
584597
}
585598

test/translation/lua/forOf.lua

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
for _, i in ipairs({1,2,3,4,5,6,7,8,9,10}) do
1+
local __loopVariable0 = {1,2,3,4,5,6,7,8,9,10};
2+
for i0=1, #__loopVariable0 do
3+
local i = __loopVariable0[i0];
24
do
35
end
46
::__continue0::

test/unit/loops.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,26 @@ export class LuaLoopTests {
286286
Expect(result).toBe(JSON.stringify(expected));
287287
}
288288

289+
@TestCase([[1, 2], [2, 3], [3, 4]], [3, 5, 7])
290+
@Test("forof destructing")
291+
public forofDestructing(inp: number[][], expected: any): void {
292+
// Transpile
293+
const lua = util.transpileString(
294+
`let objTest = ${JSON.stringify(inp)};
295+
let arrResultTest = [];
296+
for (let [a,b] of objTest) {
297+
arrResultTest.push(a + b)
298+
}
299+
return JSONStringify(arrResultTest);`
300+
);
301+
302+
// Execute
303+
const result = util.executeLua(lua);
304+
305+
// Assert
306+
Expect(result).toBe(JSON.stringify(expected));
307+
}
308+
289309
@TestCase([0, 1, 2, 3, 4], [0, 0, 2, 0, 4])
290310
@Test("forof with continue")
291311
public forofWithContinue(inp: number[], expected: number[]): void {

0 commit comments

Comments
 (0)
X Tutup