From bad7b96189d340cf8f91d9321c853e5664baab6f Mon Sep 17 00:00:00 2001 From: InfiniteRain Date: Mon, 4 Jun 2018 16:38:56 +0300 Subject: [PATCH 1/5] add support for continue statement --- src/Transpiler.ts | 43 +++++++++++++++++++++++++++++++++++++++-- test/unit/loops.spec.ts | 30 ++++++++++++++++++++-------- test/unit/while.spec.ts | 13 +++++++++++-- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 3cda3f54e..1d04511b7 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -194,8 +194,7 @@ export class LuaTranspiler { case ts.SyntaxKind.ThrowStatement: return this.transpileThrow(node as ts.ThrowStatement); case ts.SyntaxKind.ContinueStatement: - // Disallow continue - throw new TranspileError("Continue is not supported in Lua", node); + return this.transpileContinue(); case ts.SyntaxKind.TypeAliasDeclaration: case ts.SyntaxKind.InterfaceDeclaration: case ts.SyntaxKind.EndOfFileToken: @@ -317,6 +316,11 @@ export class LuaTranspiler { } } + public transpileContinue(): string { + const result = this.indent + "____continue = true\n"; + return result + this.indent + "break\n"; + } + public transpileIf(node: ts.IfStatement): string { const condition = this.transpileExpression(node.expression); @@ -340,7 +344,14 @@ export class LuaTranspiler { let result = this.indent + `while ${condition} do\n`; this.pushIndent(); + result += this.indent + "local ____continue = false\n"; + result += this.indent + "repeat\n"; + this.pushIndent(); result += this.transpileStatement(node.statement); + result += this.indent + "____continue = true\n"; + this.popIndent(); + result += this.indent + "until true\n"; + result += this.indent + "if not ____continue then break end\n"; this.popIndent(); return result + this.indent + "end\n"; } @@ -348,8 +359,15 @@ export class LuaTranspiler { public transpileDoStatement(node: ts.DoStatement): string { let result = this.indent + `repeat\n`; + this.pushIndent(); + result += this.indent + "local ____continue = false\n"; + result += this.indent + "repeat\n"; this.pushIndent(); result += this.transpileStatement(node.statement); + result += this.indent + "____continue = true\n"; + this.popIndent(); + result += this.indent + "until true\n"; + result += this.indent + "if not ____continue then break end\n"; this.popIndent(); // Negate the expression because we translate from do-while to repeat-until (repeat-while-not) @@ -368,8 +386,15 @@ export class LuaTranspiler { // Add body this.pushIndent(); + result += this.indent + "local ____continue = false\n"; + result += this.indent + "repeat\n"; + this.pushIndent(); result += this.transpileStatement(node.statement); + result += this.indent + "____continue = true\n"; + this.popIndent(); + result += this.indent + "until true\n"; result += this.indent + this.transpileExpression(node.incrementor) + "\n"; + result += this.indent + "if not ____continue then break end\n"; this.popIndent(); result += this.indent + "end\n"; @@ -394,7 +419,14 @@ export class LuaTranspiler { // For body this.pushIndent(); + result += this.indent + "local ____continue = false\n"; + result += this.indent + "repeat\n"; + this.pushIndent(); result += this.transpileStatement(node.statement); + result += this.indent + "____continue = true\n"; + this.popIndent(); + result += this.indent + "until true\n"; + result += this.indent + "if not ____continue then break end\n"; this.popIndent(); return result + this.indent + "end\n"; @@ -417,7 +449,14 @@ export class LuaTranspiler { // For body this.pushIndent(); + result += this.indent + "local ____continue = false\n"; + result += this.indent + "repeat\n"; + this.pushIndent(); result += this.transpileStatement(node.statement); + result += this.indent + "____continue = true\n"; + this.popIndent(); + result += this.indent + "until true\n"; + result += this.indent + "if not ____continue then break end\n"; this.popIndent(); return result + this.indent + "end\n"; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index f3db44381..e6d00fb46 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -7,14 +7,28 @@ export class LuaLoopTests { @Test("continue") public continue(inp: number[], expected: number[]) { - // Transpile & Assert - Expect(() => { - let lua = util.transpileString( - `while (i < arrTest.length) { - continue; - }` - ); - }).toThrowError(Error, "Continue is not supported in Lua") + const input = `const i = 2; + const arrTest = [1, 2, 3, 4, 5, 6]; + while (i < arrTest.length) { + continue; + }`; + + const exp = `local i = 2 + + local arrTest = {1,2,3,4,5,6} + + while i<#arrTest do + local ____continue = false + repeat + ____continue = true + break + ____continue = true + until true + if not ____continue then break end + end`; + + util.expectCodeEqual(util.transpileString(input), exp); + } diff --git a/test/unit/while.spec.ts b/test/unit/while.spec.ts index 29f9e3295..40bd9d40c 100644 --- a/test/unit/while.spec.ts +++ b/test/unit/while.spec.ts @@ -11,7 +11,12 @@ export class WhileTests { }`; const expected = `while a<10 do - a=a+1 + local ____continue = false + repeat + a=a+1 + ____continue = true + until true + if not ____continue then break end end`; util.expectCodeEqual(util.transpileString(input), expected); @@ -25,7 +30,11 @@ export class WhileTests { } while (a < 10);`; const expected = `repeat - a=a+1 + local ____continue = false + repeat + a=a+1 + ____continue = true + until true if not ____continue then break end until not (a<10)`; util.expectCodeEqual(util.transpileString(input), expected); From 37f844cc55481057a4e1e77bb7ce3b75ee7f7d0a Mon Sep 17 00:00:00 2001 From: InfiniteRain Date: Wed, 6 Jun 2018 16:06:40 +0300 Subject: [PATCH 2/5] make us of lua goto; decrease code reusage; add tests --- src/Transpiler.ts | 222 ++++++++++----------- test/translation/lua/do.lua | 5 + test/translation/lua/doWithContinue.lua | 11 + test/translation/lua/for.lua | 5 + test/translation/lua/forIn.lua | 2 + test/translation/lua/forInWithContinue.lua | 8 + test/translation/lua/forOf.lua | 2 + test/translation/lua/forOfWithContinue.lua | 8 + test/translation/lua/forWithContinue.lua | 11 + test/translation/lua/while.lua | 5 + test/translation/lua/whileWithContinue.lua | 11 + test/translation/ts/do.ts | 4 + test/translation/ts/doWithContinue.ts | 7 + test/translation/ts/for.ts | 2 + test/translation/ts/forIn.ts | 7 + test/translation/ts/forInWithContinue.ts | 10 + test/translation/ts/forOf.ts | 2 + test/translation/ts/forOfWithContinue.ts | 5 + test/translation/ts/forWithContinue.ts | 5 + test/translation/ts/while.ts | 4 + test/translation/ts/whileWithContinue.ts | 7 + test/unit/loops.spec.ts | 179 ++++++++++++++--- test/unit/while.spec.ts | 42 ---- 23 files changed, 381 insertions(+), 183 deletions(-) create mode 100644 test/translation/lua/do.lua create mode 100644 test/translation/lua/doWithContinue.lua create mode 100644 test/translation/lua/for.lua create mode 100644 test/translation/lua/forIn.lua create mode 100644 test/translation/lua/forInWithContinue.lua create mode 100644 test/translation/lua/forOf.lua create mode 100644 test/translation/lua/forOfWithContinue.lua create mode 100644 test/translation/lua/forWithContinue.lua create mode 100644 test/translation/lua/while.lua create mode 100644 test/translation/lua/whileWithContinue.lua create mode 100644 test/translation/ts/do.ts create mode 100644 test/translation/ts/doWithContinue.ts create mode 100644 test/translation/ts/for.ts create mode 100644 test/translation/ts/forIn.ts create mode 100644 test/translation/ts/forInWithContinue.ts create mode 100644 test/translation/ts/forOf.ts create mode 100644 test/translation/ts/forOfWithContinue.ts create mode 100644 test/translation/ts/forWithContinue.ts create mode 100644 test/translation/ts/while.ts create mode 100644 test/translation/ts/whileWithContinue.ts delete mode 100644 test/unit/while.spec.ts diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 1d04511b7..6c80dd8ea 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -128,6 +128,35 @@ export class LuaTranspiler { return `"${relativePath.replace(new RegExp("\\\\|\/", "g"), ".")}"`; } + // Recursively check if the node has a continue statement which belongs + // to this node + public hasContinue(node: ts.Node): boolean { + let found = false; + for (const child of node.getChildren()) { + switch (child.kind) { + case ts.SyntaxKind.ContinueStatement: + found = true; + break; + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForInStatement: + // Do no recursively check the loops, as continues inside + // of these loops would no longer belong to the parent loop + break; + default: + // Recursively check for continue in all the other nodes + if (this.hasContinue(child)) { + found = true; + } + break; + } + } + + return found; + } + // Transpile a block public transpileBlock(node: ts.Node): string { let result = ""; @@ -176,15 +205,15 @@ export class LuaTranspiler { case ts.SyntaxKind.IfStatement: return this.transpileIf(node as ts.IfStatement); case ts.SyntaxKind.WhileStatement: - return this.transpileWhile(node as ts.WhileStatement); + return this.transpileLoop(node as ts.WhileStatement); case ts.SyntaxKind.DoStatement: - return this.transpileDoStatement(node as ts.DoStatement); + return this.transpileLoop(node as ts.DoStatement); case ts.SyntaxKind.ForStatement: - return this.transpileFor(node as ts.ForStatement); + return this.transpileLoop(node as ts.ForStatement); case ts.SyntaxKind.ForOfStatement: - return this.transpileForOf(node as ts.ForOfStatement); + return this.transpileLoop(node as ts.ForOfStatement); case ts.SyntaxKind.ForInStatement: - return this.transpileForIn(node as ts.ForInStatement); + return this.transpileLoop(node as ts.ForInStatement); case ts.SyntaxKind.SwitchStatement: return this.transpileSwitch(node as ts.SwitchStatement); case ts.SyntaxKind.BreakStatement: @@ -317,8 +346,7 @@ export class LuaTranspiler { } public transpileContinue(): string { - const result = this.indent + "____continue = true\n"; - return result + this.indent + "break\n"; + return this.indent + "goto __continue\n"; } public transpileIf(node: ts.IfStatement): string { @@ -339,127 +367,93 @@ export class LuaTranspiler { return result + this.indent + "end\n"; } - public transpileWhile(node: ts.WhileStatement): string { - const condition = this.transpileExpression(node.expression); + public transpileLoop( + node: ts.WhileStatement + | ts.DoStatement + | ts.ForStatement + | ts.ForOfStatement + | ts.ForInStatement + ): string { + const hasContinue = this.hasContinue(node); + let result = ""; - let result = this.indent + `while ${condition} do\n`; - this.pushIndent(); - result += this.indent + "local ____continue = false\n"; - result += this.indent + "repeat\n"; - this.pushIndent(); - result += this.transpileStatement(node.statement); - result += this.indent + "____continue = true\n"; - this.popIndent(); - result += this.indent + "until true\n"; - result += this.indent + "if not ____continue then break end\n"; - this.popIndent(); - return result + this.indent + "end\n"; - } + // Loop header + switch (node.kind) { + case ts.SyntaxKind.WhileStatement: + const whileCond = this.transpileExpression(node.expression); + result += this.indent + `while (${whileCond}) do\n`; + break; + case ts.SyntaxKind.DoStatement: + result += this.indent + "repeat\n"; + break; + case ts.SyntaxKind.ForStatement: + for (const variableDeclaration of (node.initializer as ts.VariableDeclarationList).declarations) { + result += this.indent + this.transpileVariableDeclaration(variableDeclaration) + "\n"; + } + result += this.indent + `while (${this.transpileExpression(node.condition)}) do\n`; + break; + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForInStatement: + // Get variable identifier + const forVar = (node.initializer as ts.VariableDeclarationList).declarations[0]; + const forId = forVar.name as ts.Identifier; - public transpileDoStatement(node: ts.DoStatement): string { - let result = this.indent + `repeat\n`; + // Transpile expression + const forExp = this.transpileExpression(node.expression); - this.pushIndent(); - result += this.indent + "local ____continue = false\n"; - result += this.indent + "repeat\n"; - this.pushIndent(); - result += this.transpileStatement(node.statement); - result += this.indent + "____continue = true\n"; - this.popIndent(); - result += this.indent + "until true\n"; - result += this.indent + "if not ____continue then break end\n"; - this.popIndent(); + if (node.kind === ts.SyntaxKind.ForOfStatement) { + // Use ipairs for array types, pairs otherwise + const isArray = tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker); + const pairs = isArray ? "ipairs" : "pairs"; - // Negate the expression because we translate from do-while to repeat-until (repeat-while-not) - result += this.indent + `until not ${this.transpileExpression(node.expression, true)}\n`; + // Create the header + result += this.indent + `for _, ${forId.escapedText} in ${pairs}(${forExp}) do\n`; + } else { + // For in array check + if (tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker)) { + throw new TranspileError("Iterating over arrays with 'for in' is not allowed.", node); + } - return result; - } + // Make header + result = this.indent + `for ${forId.escapedText}, _ in pairs(${forExp}) do\n`; + } - public transpileFor(node: ts.ForStatement): string { - // Add header - let result = ""; - for (const variableDeclaration of (node.initializer as ts.VariableDeclarationList).declarations) { - result += this.indent + this.transpileVariableDeclaration(variableDeclaration); + break; } - result += this.indent + `while(${this.transpileExpression(node.condition)}) do\n`; - - // Add body - this.pushIndent(); - result += this.indent + "local ____continue = false\n"; - result += this.indent + "repeat\n"; this.pushIndent(); - result += this.transpileStatement(node.statement); - result += this.indent + "____continue = true\n"; - this.popIndent(); - result += this.indent + "until true\n"; - result += this.indent + this.transpileExpression(node.incrementor) + "\n"; - result += this.indent + "if not ____continue then break end\n"; - this.popIndent(); - - result += this.indent + "end\n"; - - return result; - } - - public transpileForOf(node: ts.ForOfStatement): string { - // Get variable identifier - const variable = (node.initializer as ts.VariableDeclarationList).declarations[0]; - const identifier = variable.name as ts.Identifier; - - // Transpile expression - const expression = this.transpileExpression(node.expression); - - // Use ipairs for array types, pairs otherwise - const isArray = tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker); - const pairs = isArray ? "ipairs" : "pairs"; - // Make header - let result = this.indent + `for _, ${identifier.escapedText} in ${pairs}(${expression}) do\n`; - - // For body - this.pushIndent(); - result += this.indent + "local ____continue = false\n"; - result += this.indent + "repeat\n"; - this.pushIndent(); + // Loop body + if (hasContinue) { + result += this.indent + "do\n"; + this.pushIndent(); + } result += this.transpileStatement(node.statement); - result += this.indent + "____continue = true\n"; - this.popIndent(); - result += this.indent + "until true\n"; - result += this.indent + "if not ____continue then break end\n"; - this.popIndent(); - - return result + this.indent + "end\n"; - } - - public transpileForIn(node: ts.ForInStatement): string { - // Get variable identifier - const variable = (node.initializer as ts.VariableDeclarationList).declarations[0] as ts.VariableDeclaration; - const identifier = variable.name as ts.Identifier; - - // Transpile expression - const expression = this.transpileExpression(node.expression); - - if (tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker)) { - throw new TranspileError("Iterating over arrays with 'for in' is not allowed.", node); + if (hasContinue) { + this.popIndent(); + result += this.indent + "end\n"; + result += this.indent + "::__continue::\n"; + } + if (node.kind === ts.SyntaxKind.ForStatement) { + const forInc = this.transpileExpression(node.incrementor); + result += this.indent + `${forInc}\n`; } - // Make header - let result = this.indent + `for ${identifier.escapedText}, _ in pairs(${expression}) do\n`; - - // For body - this.pushIndent(); - result += this.indent + "local ____continue = false\n"; - result += this.indent + "repeat\n"; - this.pushIndent(); - result += this.transpileStatement(node.statement); - result += this.indent + "____continue = true\n"; - this.popIndent(); - result += this.indent + "until true\n"; - result += this.indent + "if not ____continue then break end\n"; + // Loop footer this.popIndent(); + switch (node.kind) { + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.ForStatement: + case ts.SyntaxKind.ForOfStatement: + case ts.SyntaxKind.ForInStatement: + result += this.indent + "end\n"; + break; + case ts.SyntaxKind.DoStatement: + const doCond = this.transpileExpression(node.expression, true); + result += this.indent + `until not ${doCond}\n`; + break; + } - return result + this.indent + "end\n"; + return result; } public transpileStatement(node: ts.Statement): string { diff --git a/test/translation/lua/do.lua b/test/translation/lua/do.lua new file mode 100644 index 000000000..0362d2e48 --- /dev/null +++ b/test/translation/lua/do.lua @@ -0,0 +1,5 @@ +local e = 10 + +repeat + e=e-1 +until not (e>0) diff --git a/test/translation/lua/doWithContinue.lua b/test/translation/lua/doWithContinue.lua new file mode 100644 index 000000000..420554c94 --- /dev/null +++ b/test/translation/lua/doWithContinue.lua @@ -0,0 +1,11 @@ +local e = 10 + +repeat + do + e=e-1 + if e>5 then + goto __continue + end + end + ::__continue:: +until not (e>0) diff --git a/test/translation/lua/for.lua b/test/translation/lua/for.lua new file mode 100644 index 000000000..1056a3a11 --- /dev/null +++ b/test/translation/lua/for.lua @@ -0,0 +1,5 @@ +local i = 1 + +while (i<=100) do + i=i+1 +end diff --git a/test/translation/lua/forIn.lua b/test/translation/lua/forIn.lua new file mode 100644 index 000000000..0a2c5e2fe --- /dev/null +++ b/test/translation/lua/forIn.lua @@ -0,0 +1,2 @@ +for i, _ in pairs({a = 1,b = 2,c = 3,d = 4}) do +end diff --git a/test/translation/lua/forInWithContinue.lua b/test/translation/lua/forInWithContinue.lua new file mode 100644 index 000000000..514681a31 --- /dev/null +++ b/test/translation/lua/forInWithContinue.lua @@ -0,0 +1,8 @@ +for i, _ in pairs({a = 1,b = 2,c = 3,d = 4}) do + do + if i=="a" then + goto __continue + end + end + ::__continue:: +end diff --git a/test/translation/lua/forOf.lua b/test/translation/lua/forOf.lua new file mode 100644 index 000000000..2ccd4915d --- /dev/null +++ b/test/translation/lua/forOf.lua @@ -0,0 +1,2 @@ +for _, i in ipairs({1,2,3,4,5,6,7,8,9,10}) do +end diff --git a/test/translation/lua/forOfWithContinue.lua b/test/translation/lua/forOfWithContinue.lua new file mode 100644 index 000000000..7a1c8caad --- /dev/null +++ b/test/translation/lua/forOfWithContinue.lua @@ -0,0 +1,8 @@ +for _, i in ipairs({1,2,3,4,5,6,7,8,9,10}) do + do + if i<3 then + goto __continue + end + end + ::__continue:: +end diff --git a/test/translation/lua/forWithContinue.lua b/test/translation/lua/forWithContinue.lua new file mode 100644 index 000000000..4345f5f1e --- /dev/null +++ b/test/translation/lua/forWithContinue.lua @@ -0,0 +1,11 @@ +local i = 1 + +while (i<=100) do + do + if i<25 then + goto __continue + end + end + ::__continue:: + i=i+1 +end diff --git a/test/translation/lua/while.lua b/test/translation/lua/while.lua new file mode 100644 index 000000000..426b33b1d --- /dev/null +++ b/test/translation/lua/while.lua @@ -0,0 +1,5 @@ +local d = 10 + +while (d>0) do + d=d-1 +end diff --git a/test/translation/lua/whileWithContinue.lua b/test/translation/lua/whileWithContinue.lua new file mode 100644 index 000000000..b61a1ac1d --- /dev/null +++ b/test/translation/lua/whileWithContinue.lua @@ -0,0 +1,11 @@ +local d = 10 + +while (d>0) do + do + d=d-1 + if d>5 then + goto __continue + end + end + ::__continue:: +end diff --git a/test/translation/ts/do.ts b/test/translation/ts/do.ts new file mode 100644 index 000000000..62b1c0a65 --- /dev/null +++ b/test/translation/ts/do.ts @@ -0,0 +1,4 @@ +let e = 10 +do { + e--; +} while (e > 0) diff --git a/test/translation/ts/doWithContinue.ts b/test/translation/ts/doWithContinue.ts new file mode 100644 index 000000000..ee4a286a5 --- /dev/null +++ b/test/translation/ts/doWithContinue.ts @@ -0,0 +1,7 @@ +let e = 10 +do { + e--; + if (e > 5) { + continue; + } +} while (e > 0) diff --git a/test/translation/ts/for.ts b/test/translation/ts/for.ts new file mode 100644 index 000000000..02d8156e2 --- /dev/null +++ b/test/translation/ts/for.ts @@ -0,0 +1,2 @@ +for (let i = 1; i <= 100; i++) { +} diff --git a/test/translation/ts/forIn.ts b/test/translation/ts/forIn.ts new file mode 100644 index 000000000..55e50cce7 --- /dev/null +++ b/test/translation/ts/forIn.ts @@ -0,0 +1,7 @@ +for (let i in { + a: 1, + b: 2, + c: 3, + d: 4 +}) { +} diff --git a/test/translation/ts/forInWithContinue.ts b/test/translation/ts/forInWithContinue.ts new file mode 100644 index 000000000..2ede18d32 --- /dev/null +++ b/test/translation/ts/forInWithContinue.ts @@ -0,0 +1,10 @@ +for (let i in { + a: 1, + b: 2, + c: 3, + d: 4 +}) { + if (i == 'a') { + continue; + } +} diff --git a/test/translation/ts/forOf.ts b/test/translation/ts/forOf.ts new file mode 100644 index 000000000..c017d5c0c --- /dev/null +++ b/test/translation/ts/forOf.ts @@ -0,0 +1,2 @@ +for (let i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) { +} diff --git a/test/translation/ts/forOfWithContinue.ts b/test/translation/ts/forOfWithContinue.ts new file mode 100644 index 000000000..6715deec3 --- /dev/null +++ b/test/translation/ts/forOfWithContinue.ts @@ -0,0 +1,5 @@ +for (let i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) { + if (i < 3) { + continue; + } +} diff --git a/test/translation/ts/forWithContinue.ts b/test/translation/ts/forWithContinue.ts new file mode 100644 index 000000000..2da165095 --- /dev/null +++ b/test/translation/ts/forWithContinue.ts @@ -0,0 +1,5 @@ +for (let i = 1; i <= 100; i++) { + if (i < 25) { + continue; + } +} diff --git a/test/translation/ts/while.ts b/test/translation/ts/while.ts new file mode 100644 index 000000000..6101bd4f2 --- /dev/null +++ b/test/translation/ts/while.ts @@ -0,0 +1,4 @@ +let d = 10; +while (d > 0) { + d--; +} diff --git a/test/translation/ts/whileWithContinue.ts b/test/translation/ts/whileWithContinue.ts new file mode 100644 index 000000000..f007e8ee6 --- /dev/null +++ b/test/translation/ts/whileWithContinue.ts @@ -0,0 +1,7 @@ +let d = 10; +while (d > 0) { + d--; + if (d > 5) { + continue; + } +} diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index e6d00fb46..30aaa9941 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -5,33 +5,6 @@ const deepEqual = require('deep-equal') export class LuaLoopTests { - @Test("continue") - public continue(inp: number[], expected: number[]) { - const input = `const i = 2; - const arrTest = [1, 2, 3, 4, 5, 6]; - while (i < arrTest.length) { - continue; - }`; - - const exp = `local i = 2 - - local arrTest = {1,2,3,4,5,6} - - while i<#arrTest do - local ____continue = false - repeat - ____continue = true - break - ____continue = true - until true - if not ____continue then break end - end`; - - util.expectCodeEqual(util.transpileString(input), exp); - - } - - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) @Test("while") public while(inp: number[], expected: number[]) { @@ -53,6 +26,74 @@ export class LuaLoopTests { Expect(result).toBe(JSON.stringify(expected)); } + @TestCase([0, 1, 2, 3, 4], [0, 1, 2, 1, 4]) + @Test("while with continue") + public whileWithContinue(inp: number[], expected: number[]) { + // Transpile + let lua = util.transpileString( + `let arrTest = ${JSON.stringify(inp)}; + let i = 0; + while (i < arrTest.length) { + if (i % 2 == 0) { + i++; + continue; + } + let j = 2; + while (j > 0) { + if (j == 2) { + j-- + continue; + } + arrTest[i] = j; + j--; + } + + i++; + } + return JSONStringify(arrTest);` + ); + + // Executre + let result = util.executeLua(lua); + + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + + @TestCase([0, 1, 2, 3, 4], [0, 1, 2, 1, 4]) + @Test("dowhile with continue") + public dowhileWithContinue(inp: number[], expected: number[]) { + // Transpile + let lua = util.transpileString( + `let arrTest = ${JSON.stringify(inp)}; + let i = 0; + do { + if (i % 2 == 0) { + i++; + continue; + } + let j = 2; + do { + if (j == 2) { + j-- + continue; + } + arrTest[i] = j; + j--; + } while (j > 0) + + i++; + } while (i < arrTest.length) + return JSONStringify(arrTest);` + ); + + // Executre + let result = util.executeLua(lua); + + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) @Test("for") public for(inp: number[], expected: number[]) { @@ -72,6 +113,35 @@ export class LuaLoopTests { Expect(result).toBe(JSON.stringify(expected)); } + @TestCase([0, 1, 2, 3, 4], [0, 0, 2, 0, 4]) + @Test("for with continue") + public forWithContinue(inp: number[], expected: number[]) { + // Transpile + let lua = util.transpileString( + `let arrTest = ${JSON.stringify(inp)}; + for (let i = 0; i < arrTest.length; i++) { + if (i % 2 == 0) { + continue; + } + + for (let j = 0; j < 2; j++) { + if (j == 1) { + continue; + } + arrTest[i] = j; + } + } + return JSONStringify(arrTest); + ` + ); + + // Execute + let result = util.executeLua(lua); + + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) @Test("forMirror") public forMirror(inp: number[], expected: number[]) { @@ -170,6 +240,30 @@ export class LuaLoopTests { }).toThrowError(Error, "Iterating over arrays with 'for in' is not allowed."); } + @TestCase({a: 0, b: 1, c: 2, d: 3, e: 4}, {a: 0, b: 0, c: 2, d: 0, e: 4}) + @Test("forin with continue") + public forinWithContinue(inp: number[], expected: number[]) { + // Transpile + let lua = util.transpileString( + `let obj = ${JSON.stringify(inp)}; + for (let i in obj) { + if (obj[i] % 2 == 0) { + continue; + } + + obj[i] = 0; + } + return JSONStringify(obj); + ` + ); + + // Execute + let result = util.executeLua(lua); + + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + @TestCase([0, 1, 2], [1, 2, 3]) @Test("forof") public forof(inp: any, expected: any) { @@ -190,4 +284,35 @@ export class LuaLoopTests { Expect(result).toBe(JSON.stringify(expected)); } + @TestCase([0, 1, 2, 3, 4], [0, 0, 2, 0, 4]) + @Test("forof with continue") + public forofWithContinue(inp: number[], expected: number[]) { + // Transpile + let lua = util.transpileString( + `let testArr = ${JSON.stringify(inp)}; + let a = 0; + for (let i of testArr) { + if (i % 2 == 0) { + a++; + continue; + } + + for (let j of [0, 1]) { + if (j == 1) { + continue; + } + testArr[a] = j; + } + a++; + } + return JSONStringify(testArr);` + ); + + // Execute + let result = util.executeLua(lua); + + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + } diff --git a/test/unit/while.spec.ts b/test/unit/while.spec.ts deleted file mode 100644 index 40bd9d40c..000000000 --- a/test/unit/while.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Expect, Test, TestCase, FocusTest } from "alsatian"; -import * as util from "../src/util"; - -export class WhileTests { - - @Test("While loop") - public defaultWhile() { - const input = `declare var a: number; - while (a < 10) { - a++; - }`; - - const expected = `while a<10 do - local ____continue = false - repeat - a=a+1 - ____continue = true - until true - if not ____continue then break end - end`; - - util.expectCodeEqual(util.transpileString(input), expected); - } - - @Test("Do While") - public doWhile() { - const input = `declare var a: number; - do { - a++; - } while (a < 10);`; - - const expected = `repeat - local ____continue = false - repeat - a=a+1 - ____continue = true - until true if not ____continue then break end - until not (a<10)`; - - util.expectCodeEqual(util.transpileString(input), expected); - } -} From 66cacc421ab088a3ff8a8ff237bbdcc56cca15f1 Mon Sep 17 00:00:00 2001 From: InfiniteRain Date: Wed, 6 Jun 2018 23:35:29 +0300 Subject: [PATCH 3/5] implement requested changes --- src/Transpiler.ts | 197 ++++++++++----------- test/translation/lua/do.lua | 5 +- test/translation/lua/doWithContinue.lua | 11 -- test/translation/lua/for.lua | 6 +- test/translation/lua/forIn.lua | 3 + test/translation/lua/forInWithContinue.lua | 8 - test/translation/lua/forOf.lua | 3 + test/translation/lua/forOfWithContinue.lua | 8 - test/translation/lua/forWithContinue.lua | 11 -- test/translation/lua/while.lua | 7 +- test/translation/lua/whileWithContinue.lua | 11 -- test/translation/ts/doWithContinue.ts | 7 - test/translation/ts/forInWithContinue.ts | 10 -- test/translation/ts/forOfWithContinue.ts | 5 - test/translation/ts/forWithContinue.ts | 5 - test/translation/ts/whileWithContinue.ts | 7 - 16 files changed, 113 insertions(+), 191 deletions(-) delete mode 100644 test/translation/lua/doWithContinue.lua delete mode 100644 test/translation/lua/forInWithContinue.lua delete mode 100644 test/translation/lua/forOfWithContinue.lua delete mode 100644 test/translation/lua/forWithContinue.lua delete mode 100644 test/translation/lua/whileWithContinue.lua delete mode 100644 test/translation/ts/doWithContinue.ts delete mode 100644 test/translation/ts/forInWithContinue.ts delete mode 100644 test/translation/ts/forOfWithContinue.ts delete mode 100644 test/translation/ts/forWithContinue.ts delete mode 100644 test/translation/ts/whileWithContinue.ts diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 6c80dd8ea..90d09f22e 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -61,6 +61,7 @@ export class LuaTranspiler { public importCount: number; public isModule: boolean; public sourceFile: ts.SourceFile; + public loopStack: number[]; constructor(checker: ts.TypeChecker, options: ts.CompilerOptions, sourceFile: ts.SourceFile) { this.indent = ""; @@ -72,6 +73,7 @@ export class LuaTranspiler { this.importCount = 0; this.sourceFile = sourceFile; this.isModule = tsHelper.isFileModule(sourceFile); + this.loopStack = []; } public pushIndent(): void { @@ -128,35 +130,6 @@ export class LuaTranspiler { return `"${relativePath.replace(new RegExp("\\\\|\/", "g"), ".")}"`; } - // Recursively check if the node has a continue statement which belongs - // to this node - public hasContinue(node: ts.Node): boolean { - let found = false; - for (const child of node.getChildren()) { - switch (child.kind) { - case ts.SyntaxKind.ContinueStatement: - found = true; - break; - case ts.SyntaxKind.WhileStatement: - case ts.SyntaxKind.DoStatement: - case ts.SyntaxKind.ForStatement: - case ts.SyntaxKind.ForOfStatement: - case ts.SyntaxKind.ForInStatement: - // Do no recursively check the loops, as continues inside - // of these loops would no longer belong to the parent loop - break; - default: - // Recursively check for continue in all the other nodes - if (this.hasContinue(child)) { - found = true; - } - break; - } - } - - return found; - } - // Transpile a block public transpileBlock(node: ts.Node): string { let result = ""; @@ -205,15 +178,15 @@ export class LuaTranspiler { case ts.SyntaxKind.IfStatement: return this.transpileIf(node as ts.IfStatement); case ts.SyntaxKind.WhileStatement: - return this.transpileLoop(node as ts.WhileStatement); + return this.transpileWhile(node as ts.WhileStatement); case ts.SyntaxKind.DoStatement: - return this.transpileLoop(node as ts.DoStatement); + return this.transpileDoStatement(node as ts.DoStatement); case ts.SyntaxKind.ForStatement: - return this.transpileLoop(node as ts.ForStatement); + return this.transpileFor(node as ts.ForStatement); case ts.SyntaxKind.ForOfStatement: - return this.transpileLoop(node as ts.ForOfStatement); + return this.transpileForOf(node as ts.ForOfStatement); case ts.SyntaxKind.ForInStatement: - return this.transpileLoop(node as ts.ForInStatement); + return this.transpileForIn(node as ts.ForInStatement); case ts.SyntaxKind.SwitchStatement: return this.transpileSwitch(node as ts.SwitchStatement); case ts.SyntaxKind.BreakStatement: @@ -346,7 +319,7 @@ export class LuaTranspiler { } public transpileContinue(): string { - return this.indent + "goto __continue\n"; + return this.indent + `goto __continue${this.loopStack[this.loopStack.length - 1]}\n`; } public transpileIf(node: ts.IfStatement): string { @@ -367,93 +340,111 @@ export class LuaTranspiler { return result + this.indent + "end\n"; } - public transpileLoop( + public transpileLoopBody( node: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInStatement ): string { - const hasContinue = this.hasContinue(node); - let result = ""; + this.genVarCounter++; + this.loopStack.push(this.genVarCounter); + let result = this.indent + "do\n"; + this.pushIndent(); + result += this.transpileStatement(node.statement); + this.popIndent(); + result += this.indent + "end\n"; + result += this.indent + `::__continue${this.loopStack[this.loopStack.length - 1]}::\n`; + this.loopStack.pop(); + return result; + } - // Loop header - switch (node.kind) { - case ts.SyntaxKind.WhileStatement: - const whileCond = this.transpileExpression(node.expression); - result += this.indent + `while (${whileCond}) do\n`; - break; - case ts.SyntaxKind.DoStatement: - result += this.indent + "repeat\n"; - break; - case ts.SyntaxKind.ForStatement: - for (const variableDeclaration of (node.initializer as ts.VariableDeclarationList).declarations) { - result += this.indent + this.transpileVariableDeclaration(variableDeclaration) + "\n"; - } - result += this.indent + `while (${this.transpileExpression(node.condition)}) do\n`; - break; - case ts.SyntaxKind.ForOfStatement: - case ts.SyntaxKind.ForInStatement: - // Get variable identifier - const forVar = (node.initializer as ts.VariableDeclarationList).declarations[0]; - const forId = forVar.name as ts.Identifier; + public transpileWhile(node: ts.WhileStatement): string { + const condition = this.transpileExpression(node.expression); - // Transpile expression - const forExp = this.transpileExpression(node.expression); + let result = this.indent + `while ${condition} do\n`; + this.pushIndent(); + result += this.transpileLoopBody(node); + this.popIndent(); + return result + this.indent + "end\n"; + } - if (node.kind === ts.SyntaxKind.ForOfStatement) { - // Use ipairs for array types, pairs otherwise - const isArray = tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker); - const pairs = isArray ? "ipairs" : "pairs"; + public transpileDoStatement(node: ts.DoStatement): string { + let result = this.indent + `repeat\n`; - // Create the header - result += this.indent + `for _, ${forId.escapedText} in ${pairs}(${forExp}) do\n`; - } else { - // For in array check - if (tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker)) { - throw new TranspileError("Iterating over arrays with 'for in' is not allowed.", node); - } + this.pushIndent(); + result += this.transpileLoopBody(node); + this.popIndent(); - // Make header - result = this.indent + `for ${forId.escapedText}, _ in pairs(${forExp}) do\n`; - } + // Negate the expression because we translate from do-while to repeat-until (repeat-while-not) + result += this.indent + `until not ${this.transpileExpression(node.expression, true)}\n`; + + return result; + } - break; + public transpileFor(node: ts.ForStatement): string { + // Add header + let result = ""; + for (const variableDeclaration of (node.initializer as ts.VariableDeclarationList).declarations) { + result += this.indent + this.transpileVariableDeclaration(variableDeclaration); } + result += this.indent + `while(${this.transpileExpression(node.condition)}) do\n`; + + // Add body this.pushIndent(); + result += this.transpileLoopBody(node); + result += this.indent + this.transpileExpression(node.incrementor) + "\n"; + this.popIndent(); - // Loop body - if (hasContinue) { - result += this.indent + "do\n"; - this.pushIndent(); - } - result += this.transpileStatement(node.statement); - if (hasContinue) { - this.popIndent(); - result += this.indent + "end\n"; - result += this.indent + "::__continue::\n"; - } - if (node.kind === ts.SyntaxKind.ForStatement) { - const forInc = this.transpileExpression(node.incrementor); - result += this.indent + `${forInc}\n`; - } + result += this.indent + "end\n"; - // Loop footer + return result; + } + + public transpileForOf(node: ts.ForOfStatement): string { + // Get variable identifier + const variable = (node.initializer as ts.VariableDeclarationList).declarations[0]; + const identifier = variable.name as ts.Identifier; + + // Transpile expression + const expression = this.transpileExpression(node.expression); + + // Use ipairs for array types, pairs otherwise + const isArray = tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker); + const pairs = isArray ? "ipairs" : "pairs"; + + // Make header + let result = this.indent + `for _, ${identifier.escapedText} in ${pairs}(${expression}) do\n`; + + // For body + this.pushIndent(); + result += this.transpileLoopBody(node); this.popIndent(); - switch (node.kind) { - case ts.SyntaxKind.WhileStatement: - case ts.SyntaxKind.ForStatement: - case ts.SyntaxKind.ForOfStatement: - case ts.SyntaxKind.ForInStatement: - result += this.indent + "end\n"; - break; - case ts.SyntaxKind.DoStatement: - const doCond = this.transpileExpression(node.expression, true); - result += this.indent + `until not ${doCond}\n`; - break; + + return result + this.indent + "end\n"; + } + + public transpileForIn(node: ts.ForInStatement): string { + // Get variable identifier + const variable = (node.initializer as ts.VariableDeclarationList).declarations[0] as ts.VariableDeclaration; + const identifier = variable.name as ts.Identifier; + + // Transpile expression + const expression = this.transpileExpression(node.expression); + + if (tsHelper.isArrayType(this.checker.getTypeAtLocation(node.expression), this.checker)) { + throw new TranspileError("Iterating over arrays with 'for in' is not allowed.", node); } - return result; + // Make header + let result = this.indent + `for ${identifier.escapedText}, _ in pairs(${expression}) do\n`; + + // For body + this.pushIndent(); + result += this.transpileLoopBody(node); + this.popIndent(); + + return result + this.indent + "end\n"; } public transpileStatement(node: ts.Statement): string { diff --git a/test/translation/lua/do.lua b/test/translation/lua/do.lua index 0362d2e48..dcb807b60 100644 --- a/test/translation/lua/do.lua +++ b/test/translation/lua/do.lua @@ -1,5 +1,8 @@ local e = 10 repeat - e=e-1 + do + e=e-1 + end + ::__continue1:: until not (e>0) diff --git a/test/translation/lua/doWithContinue.lua b/test/translation/lua/doWithContinue.lua deleted file mode 100644 index 420554c94..000000000 --- a/test/translation/lua/doWithContinue.lua +++ /dev/null @@ -1,11 +0,0 @@ -local e = 10 - -repeat - do - e=e-1 - if e>5 then - goto __continue - end - end - ::__continue:: -until not (e>0) diff --git a/test/translation/lua/for.lua b/test/translation/lua/for.lua index 1056a3a11..ede1f123a 100644 --- a/test/translation/lua/for.lua +++ b/test/translation/lua/for.lua @@ -1,5 +1,7 @@ local i = 1 - -while (i<=100) do +while(i<=100) do + do + end + ::__continue1:: i=i+1 end diff --git a/test/translation/lua/forIn.lua b/test/translation/lua/forIn.lua index 0a2c5e2fe..a1e1a0b76 100644 --- a/test/translation/lua/forIn.lua +++ b/test/translation/lua/forIn.lua @@ -1,2 +1,5 @@ for i, _ in pairs({a = 1,b = 2,c = 3,d = 4}) do + do + end + ::__continue1:: end diff --git a/test/translation/lua/forInWithContinue.lua b/test/translation/lua/forInWithContinue.lua deleted file mode 100644 index 514681a31..000000000 --- a/test/translation/lua/forInWithContinue.lua +++ /dev/null @@ -1,8 +0,0 @@ -for i, _ in pairs({a = 1,b = 2,c = 3,d = 4}) do - do - if i=="a" then - goto __continue - end - end - ::__continue:: -end diff --git a/test/translation/lua/forOf.lua b/test/translation/lua/forOf.lua index 2ccd4915d..8f3f65880 100644 --- a/test/translation/lua/forOf.lua +++ b/test/translation/lua/forOf.lua @@ -1,2 +1,5 @@ for _, i in ipairs({1,2,3,4,5,6,7,8,9,10}) do + do + end + ::__continue1:: end diff --git a/test/translation/lua/forOfWithContinue.lua b/test/translation/lua/forOfWithContinue.lua deleted file mode 100644 index 7a1c8caad..000000000 --- a/test/translation/lua/forOfWithContinue.lua +++ /dev/null @@ -1,8 +0,0 @@ -for _, i in ipairs({1,2,3,4,5,6,7,8,9,10}) do - do - if i<3 then - goto __continue - end - end - ::__continue:: -end diff --git a/test/translation/lua/forWithContinue.lua b/test/translation/lua/forWithContinue.lua deleted file mode 100644 index 4345f5f1e..000000000 --- a/test/translation/lua/forWithContinue.lua +++ /dev/null @@ -1,11 +0,0 @@ -local i = 1 - -while (i<=100) do - do - if i<25 then - goto __continue - end - end - ::__continue:: - i=i+1 -end diff --git a/test/translation/lua/while.lua b/test/translation/lua/while.lua index 426b33b1d..ce87e37de 100644 --- a/test/translation/lua/while.lua +++ b/test/translation/lua/while.lua @@ -1,5 +1,8 @@ local d = 10 -while (d>0) do - d=d-1 +while d>0 do + do + d=d-1 + end + ::__continue1:: end diff --git a/test/translation/lua/whileWithContinue.lua b/test/translation/lua/whileWithContinue.lua deleted file mode 100644 index b61a1ac1d..000000000 --- a/test/translation/lua/whileWithContinue.lua +++ /dev/null @@ -1,11 +0,0 @@ -local d = 10 - -while (d>0) do - do - d=d-1 - if d>5 then - goto __continue - end - end - ::__continue:: -end diff --git a/test/translation/ts/doWithContinue.ts b/test/translation/ts/doWithContinue.ts deleted file mode 100644 index ee4a286a5..000000000 --- a/test/translation/ts/doWithContinue.ts +++ /dev/null @@ -1,7 +0,0 @@ -let e = 10 -do { - e--; - if (e > 5) { - continue; - } -} while (e > 0) diff --git a/test/translation/ts/forInWithContinue.ts b/test/translation/ts/forInWithContinue.ts deleted file mode 100644 index 2ede18d32..000000000 --- a/test/translation/ts/forInWithContinue.ts +++ /dev/null @@ -1,10 +0,0 @@ -for (let i in { - a: 1, - b: 2, - c: 3, - d: 4 -}) { - if (i == 'a') { - continue; - } -} diff --git a/test/translation/ts/forOfWithContinue.ts b/test/translation/ts/forOfWithContinue.ts deleted file mode 100644 index 6715deec3..000000000 --- a/test/translation/ts/forOfWithContinue.ts +++ /dev/null @@ -1,5 +0,0 @@ -for (let i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) { - if (i < 3) { - continue; - } -} diff --git a/test/translation/ts/forWithContinue.ts b/test/translation/ts/forWithContinue.ts deleted file mode 100644 index 2da165095..000000000 --- a/test/translation/ts/forWithContinue.ts +++ /dev/null @@ -1,5 +0,0 @@ -for (let i = 1; i <= 100; i++) { - if (i < 25) { - continue; - } -} diff --git a/test/translation/ts/whileWithContinue.ts b/test/translation/ts/whileWithContinue.ts deleted file mode 100644 index f007e8ee6..000000000 --- a/test/translation/ts/whileWithContinue.ts +++ /dev/null @@ -1,7 +0,0 @@ -let d = 10; -while (d > 0) { - d--; - if (d > 5) { - continue; - } -} From 08216d662ef09c4752485c1c3214d30a2fe42b52 Mon Sep 17 00:00:00 2001 From: InfiniteRain Date: Thu, 7 Jun 2018 12:25:00 +0300 Subject: [PATCH 4/5] add continue translation tests; minor requested changes --- src/Transpiler.ts | 5 ++-- test/translation/lua/continue.lua | 10 ++++++++ test/translation/lua/continueConcurrent.lua | 13 +++++++++++ test/translation/lua/continueNested.lua | 20 ++++++++++++++++ .../lua/continueNestedConcurrent.lua | 23 +++++++++++++++++++ test/translation/lua/do.lua | 2 +- test/translation/lua/for.lua | 2 +- test/translation/lua/forIn.lua | 2 +- test/translation/lua/forOf.lua | 2 +- test/translation/lua/while.lua | 2 +- test/translation/ts/continue.ts | 5 ++++ test/translation/ts/continueConcurrent.ts | 9 ++++++++ test/translation/ts/continueNested.ts | 11 +++++++++ .../ts/continueNestedConcurrent.ts | 15 ++++++++++++ 14 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 test/translation/lua/continue.lua create mode 100644 test/translation/lua/continueConcurrent.lua create mode 100644 test/translation/lua/continueNested.lua create mode 100644 test/translation/lua/continueNestedConcurrent.lua create mode 100644 test/translation/ts/continue.ts create mode 100644 test/translation/ts/continueConcurrent.ts create mode 100644 test/translation/ts/continueNested.ts create mode 100644 test/translation/ts/continueNestedConcurrent.ts diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 90d09f22e..0458bbe7e 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -347,15 +347,14 @@ export class LuaTranspiler { | ts.ForOfStatement | ts.ForInStatement ): string { - this.genVarCounter++; this.loopStack.push(this.genVarCounter); + this.genVarCounter++; let result = this.indent + "do\n"; this.pushIndent(); result += this.transpileStatement(node.statement); this.popIndent(); result += this.indent + "end\n"; - result += this.indent + `::__continue${this.loopStack[this.loopStack.length - 1]}::\n`; - this.loopStack.pop(); + result += this.indent + `::__continue${this.loopStack.pop()}::\n`; return result; } diff --git a/test/translation/lua/continue.lua b/test/translation/lua/continue.lua new file mode 100644 index 000000000..0c0f62812 --- /dev/null +++ b/test/translation/lua/continue.lua @@ -0,0 +1,10 @@ +local i = 0 +while(i<10) do + do + if i<5 then + goto __continue0 + end + end + ::__continue0:: + i=i+1 +end diff --git a/test/translation/lua/continueConcurrent.lua b/test/translation/lua/continueConcurrent.lua new file mode 100644 index 000000000..a41b64ada --- /dev/null +++ b/test/translation/lua/continueConcurrent.lua @@ -0,0 +1,13 @@ +local i = 0 +while(i<10) do + do + if i<5 then + goto __continue0 + end + if i==7 then + goto __continue0 + end + end + ::__continue0:: + i=i+1 +end diff --git a/test/translation/lua/continueNested.lua b/test/translation/lua/continueNested.lua new file mode 100644 index 000000000..fb9d08c89 --- /dev/null +++ b/test/translation/lua/continueNested.lua @@ -0,0 +1,20 @@ +local i = 0 +while(i<5) do + do + if (i%2)==0 then + goto __continue0 + end + local j = 0 + while(j<2) do + do + if j==1 then + goto __continue1 + end + end + ::__continue1:: + j=j+1 + end + end + ::__continue0:: + i=i+1 +end diff --git a/test/translation/lua/continueNestedConcurrent.lua b/test/translation/lua/continueNestedConcurrent.lua new file mode 100644 index 000000000..65c146739 --- /dev/null +++ b/test/translation/lua/continueNestedConcurrent.lua @@ -0,0 +1,23 @@ +local i = 0 +while(i<5) do + do + if (i%2)==0 then + goto __continue0 + end + local j = 0 + while(j<2) do + do + if j==1 then + goto __continue1 + end + end + ::__continue1:: + j=j+1 + end + if i==4 then + goto __continue0 + end + end + ::__continue0:: + i=i+1 +end diff --git a/test/translation/lua/do.lua b/test/translation/lua/do.lua index dcb807b60..87b49f201 100644 --- a/test/translation/lua/do.lua +++ b/test/translation/lua/do.lua @@ -4,5 +4,5 @@ repeat do e=e-1 end - ::__continue1:: + ::__continue0:: until not (e>0) diff --git a/test/translation/lua/for.lua b/test/translation/lua/for.lua index ede1f123a..0d9b20db4 100644 --- a/test/translation/lua/for.lua +++ b/test/translation/lua/for.lua @@ -2,6 +2,6 @@ local i = 1 while(i<=100) do do end - ::__continue1:: + ::__continue0:: i=i+1 end diff --git a/test/translation/lua/forIn.lua b/test/translation/lua/forIn.lua index a1e1a0b76..9d1bd7bad 100644 --- a/test/translation/lua/forIn.lua +++ b/test/translation/lua/forIn.lua @@ -1,5 +1,5 @@ for i, _ in pairs({a = 1,b = 2,c = 3,d = 4}) do do end - ::__continue1:: + ::__continue0:: end diff --git a/test/translation/lua/forOf.lua b/test/translation/lua/forOf.lua index 8f3f65880..79c0a9fed 100644 --- a/test/translation/lua/forOf.lua +++ b/test/translation/lua/forOf.lua @@ -1,5 +1,5 @@ for _, i in ipairs({1,2,3,4,5,6,7,8,9,10}) do do end - ::__continue1:: + ::__continue0:: end diff --git a/test/translation/lua/while.lua b/test/translation/lua/while.lua index ce87e37de..c9fb9ba85 100644 --- a/test/translation/lua/while.lua +++ b/test/translation/lua/while.lua @@ -4,5 +4,5 @@ while d>0 do do d=d-1 end - ::__continue1:: + ::__continue0:: end diff --git a/test/translation/ts/continue.ts b/test/translation/ts/continue.ts new file mode 100644 index 000000000..64830718d --- /dev/null +++ b/test/translation/ts/continue.ts @@ -0,0 +1,5 @@ +for (let i = 0; i < 10; i++) { + if (i < 5) { + continue; + } +} diff --git a/test/translation/ts/continueConcurrent.ts b/test/translation/ts/continueConcurrent.ts new file mode 100644 index 000000000..ef1b20c68 --- /dev/null +++ b/test/translation/ts/continueConcurrent.ts @@ -0,0 +1,9 @@ +for (let i = 0; i < 10; i++) { + if (i < 5) { + continue; + } + + if (i === 7) { + continue; + } +} diff --git a/test/translation/ts/continueNested.ts b/test/translation/ts/continueNested.ts new file mode 100644 index 000000000..563b7d0f1 --- /dev/null +++ b/test/translation/ts/continueNested.ts @@ -0,0 +1,11 @@ +for (let i = 0; i < 5; i++) { + if (i % 2 === 0) { + continue; + } + + for (let j = 0; j < 2; j++) { + if (j === 1) { + continue; + } + } +} diff --git a/test/translation/ts/continueNestedConcurrent.ts b/test/translation/ts/continueNestedConcurrent.ts new file mode 100644 index 000000000..fe0bd0966 --- /dev/null +++ b/test/translation/ts/continueNestedConcurrent.ts @@ -0,0 +1,15 @@ +for (let i = 0; i < 5; i++) { + if (i % 2 === 0) { + continue; + } + + for (let j = 0; j < 2; j++) { + if (j === 1) { + continue; + } + } + + if (i === 4) { + continue; + } +} From 61675aefeecbf6a56dec6f2a2bb6cf6b89915ab2 Mon Sep 17 00:00:00 2001 From: InfiniteRain Date: Thu, 7 Jun 2018 12:42:23 +0300 Subject: [PATCH 5/5] fix tupleArrayUses translation test --- test/translation/lua/tupleArrayUses.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/translation/lua/tupleArrayUses.lua b/test/translation/lua/tupleArrayUses.lua index 396b53995..eb5076124 100644 --- a/test/translation/lua/tupleArrayUses.lua +++ b/test/translation/lua/tupleArrayUses.lua @@ -1,4 +1,7 @@ for _, value in ipairs(tuple) do + do + end + ::__continue0:: end TS_forEach(tuple, function(v) end