diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 7c7160f67..1e0686e41 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2216,14 +2216,17 @@ export class LuaTransformer { } public transformDoStatement(statement: ts.DoStatement): StatementVisitResult { - return tstl.createRepeatStatement( - tstl.createBlock(this.transformLoopBody(statement)), - tstl.createUnaryExpression( - tstl.createParenthesizedExpression(this.transformExpression(statement.expression)), + const body = tstl.createDoStatement(this.transformLoopBody(statement)); + let condition = this.transformExpression(statement.expression); + if (tstl.isUnaryExpression(condition) && condition.operator === tstl.SyntaxKind.NotOperator) { + condition = condition.operand; + } else { + condition = tstl.createUnaryExpression( + tstl.createParenthesizedExpression(condition), tstl.SyntaxKind.NotOperator - ), - statement - ); + ); + } + return tstl.createRepeatStatement(tstl.createBlock([body]), condition, statement); } public transformForStatement(statement: ts.ForStatement): StatementVisitResult { diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index c77a614ca..7e5ae77f0 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -150,7 +150,9 @@ end" exports[`Transformation (do) 1`] = ` "local e = 10 repeat - e = e - 1 + do + e = e - 1 + end until not (e > 0)" `; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 38b16a7e0..57cd5cc11 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -981,3 +981,39 @@ test.each([ ).message ); }); + +test("do...while", () => { + const code = ` + let result = 0; + do { + ++result; + } while (result < 2); + return result; + `; + expect(util.transpileAndExecute(code)).toBe(2); +}); + +test("do...while scoping", () => { + const code = ` + let x = 0; + let result = 0; + do { + let x = 1; + ++result; + } while (x === 0 && result < 2); + return result; + `; + expect(util.transpileAndExecute(code)).toBe(2); +}); + +test("do...while double-negation", () => { + const code = ` + let result = 0; + do { + ++result; + } while (!(result >= 2)); + return result; + `; + expect(util.transpileString(code)).not.toMatch("not"); + expect(util.transpileAndExecute(code)).toBe(2); +});