Skip to content

Commit 3c96b40

Browse files
tomblindPerryvw
authored andcommitted
Recursion fix (#220)
* Separated variable assignment from declaration when assigning to function expression or arrow function to allow recursion. fixes #187 * Added tests for recursive functions.
1 parent 989b365 commit 3c96b40

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

src/Transpiler.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1462,7 +1462,12 @@ export abstract class LuaTranspiler {
14621462
const identifierName = this.transpileIdentifier(node.name);
14631463
if (node.initializer) {
14641464
const value = this.transpileExpression(node.initializer);
1465-
return `local ${identifierName} = ${value}`;
1465+
if (ts.isFunctionExpression(node.initializer) || ts.isArrowFunction(node.initializer)) {
1466+
// Separate declaration and assignment for functions to allow recursion
1467+
return `local ${identifierName}; ${identifierName} = ${value}`;
1468+
} else {
1469+
return `local ${identifierName} = ${value}`;
1470+
}
14661471
} else {
14671472
return `local ${identifierName} = nil`;
14681473
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
local f = function(x) return ({x = x}) end;
1+
local f; f = function(x) return ({x = x}) end;

test/unit/functions.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,28 @@ export class FunctionTests {
245245

246246
Expect(result).toBe(3);
247247
}
248+
249+
@Test("Recursive function definition")
250+
public recursiveFunctionDefinition(): void {
251+
const result = util.transpileAndExecute(
252+
`function f() { return typeof f; } return f();`);
253+
254+
Expect(result).toBe("function");
255+
}
256+
257+
@Test("Recursive function expression")
258+
public recursiveFunctionExpression(): void {
259+
const result = util.transpileAndExecute(
260+
`let f = function() { return typeof f; } return f();`);
261+
262+
Expect(result).toBe("function");
263+
}
264+
265+
@Test("Recursive arrow function")
266+
public recursiveArrowFunction(): void {
267+
const result = util.transpileAndExecute(
268+
`let f = () => typeof f; return f();`);
269+
270+
Expect(result).toBe("function");
271+
}
248272
}

0 commit comments

Comments
 (0)