Skip to content

Commit af1b806

Browse files
authored
Conditionals tests && Proposal new switch translation (#25)
* Added tests for conditionals && Proposal for new Switch statement * Added additional test for fallthroughs & Removed inline assigning
1 parent 3bd5d04 commit af1b806

File tree

8 files changed

+309
-36
lines changed

8 files changed

+309
-36
lines changed

dist/TSHelper.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ var TSHelper = /** @class */ (function () {
2828
}
2929
return "unknown";
3030
};
31+
TSHelper.containsStatement = function (statements, kind) {
32+
return statements.some(function (statement) { return statement.kind === kind; });
33+
};
3134
TSHelper.isFileModule = function (sourceFile) {
3235
if (sourceFile) {
3336
// Vanilla ts flags files as external module if they have an import or

dist/Transpiler.js

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ var LuaTranspiler = /** @class */ (function () {
221221
};
222222
LuaTranspiler.prototype.transpileBreak = function () {
223223
if (this.transpilingSwitch) {
224-
return this.indent + ("goto switchDone" + this.genVarCounter + "\n");
224+
return '';
225225
}
226226
else {
227227
return this.indent + "break\n";
@@ -312,33 +312,54 @@ var LuaTranspiler = /** @class */ (function () {
312312
var expression = this.transpileExpression(node.expression, true);
313313
var clauses = node.caseBlock.clauses;
314314
var result = this.indent + "-------Switch statement start-------\n";
315+
var jumpTableName = "____switch" + this.genVarCounter;
316+
this.genVarCounter++;
317+
result += this.indent + ("local " + jumpTableName + " = {\n");
318+
this.pushIndent();
315319
// If statement to go to right entry label
316320
clauses.forEach(function (clause, index) {
317321
if (ts.isCaseClause(clause)) {
318-
var keyword = index == 0 ? "if" : "elseif";
319-
var condition = _this.transpileExpression(clause.expression, true);
320-
result += _this.indent + (keyword + " " + expression + "==" + condition + " then\n");
322+
result += _this.indent + "-- case:\n";
323+
result += _this.indent + ("[" + _this.transpileExpression(clause.expression, true) + "] = function(self)\n");
321324
}
322-
else {
323-
// Default
324-
result += _this.indent + "else\n";
325+
if (ts.isDefaultClause(clause)) {
326+
result += _this.indent + "-- default:\n";
327+
result += _this.indent + ("[\"____default" + _this.genVarCounter + "\"] = function(self)\n");
325328
}
326329
_this.pushIndent();
327-
// Labels for fallthrough
328-
result += _this.indent + ("::switchCase" + (_this.genVarCounter + index) + "::\n");
329330
_this.transpilingSwitch = true;
330331
clause.statements.forEach(function (statement) {
331332
result += _this.transpileNode(statement);
332333
});
333334
_this.transpilingSwitch = false;
334-
// If this goto is reached, fall through to the next case
335-
if (index < clauses.length - 1) {
336-
result += _this.indent + ("goto switchCase" + (_this.genVarCounter + index + 1) + "\n");
335+
var i = index + 1;
336+
if (i < clauses.length && !TSHelper_1.TSHelper.containsStatement(clause.statements, ts.SyntaxKind.BreakStatement)) {
337+
var nextClause = clauses[i];
338+
while (i < clauses.length
339+
&& ts.isCaseClause(nextClause)
340+
&& nextClause.statements.length === 0) {
341+
i++;
342+
nextClause = clauses[i];
343+
}
344+
if (i !== index && nextClause) {
345+
if (ts.isCaseClause(nextClause)) {
346+
result += _this.indent + ("self[" + _this.transpileExpression(nextClause.expression, true) + "]()\n");
347+
}
348+
else {
349+
result += _this.indent + ("self[\"____default" + _this.genVarCounter + "\"]()\n");
350+
}
351+
}
352+
}
353+
else {
354+
result += _this.indent + "-- break;\n";
337355
}
338356
_this.popIndent();
357+
result += _this.indent + "end,\n";
339358
});
340-
result += this.indent + "end\n";
341-
result += this.indent + ("::switchDone" + this.genVarCounter + "::\n");
359+
this.popIndent();
360+
result += this.indent + "}\n";
361+
result += this.indent + ("if " + jumpTableName + "[" + expression + "] then " + jumpTableName + "[" + expression + "](" + jumpTableName + ")\n");
362+
result += this.indent + ("elseif " + jumpTableName + "[\"____default" + this.genVarCounter + "\"] then " + jumpTableName + "[\"____default" + this.genVarCounter + "\"](" + jumpTableName + ") end\n");
342363
result += this.indent + "--------Switch statement end--------\n";
343364
//Increment counter for next switch statement
344365
this.genVarCounter += clauses.length;

src/Compiler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function compile(fileNames: string[], options: ts.CompilerOptions, projectRoot:
3434
}
3535

3636
program.getSourceFiles().forEach(sourceFile => {
37-
if (!sourceFile.isDeclarationFile) {
37+
if (!sourceFile.isDeclarationFile) {
3838
// Print AST for debugging
3939
//printAST(sourceFile, 0);
4040

@@ -43,7 +43,7 @@ function compile(fileNames: string[], options: ts.CompilerOptions, projectRoot:
4343
const addHeader = options.noHeader === true ? false : true;
4444
let lua = LuaTranspiler.transpileSourceFile(sourceFile, checker, addHeader);
4545
let outPath = sourceFile.fileName.substring(0, sourceFile.fileName.lastIndexOf(".")) + ".lua";
46-
46+
4747
if (options.outDir) {
4848
var extension = options.outDir;
4949
if (extension[extension.length - 1] != "/") extension = extension + "/";
@@ -83,7 +83,7 @@ function printAST(node: ts.Node, indent: number) {
8383
const filename = process.argv[2].split("\\").join("/");
8484
const filepath = filename.substring(0, filename.lastIndexOf("/"));
8585
let configPath = ts.findConfigFile(filepath, ts.sys.fileExists);
86-
86+
8787
if (configPath) {
8888
configPath = configPath.split("\\").join("/");
8989
const projectRoot = configPath.substring(0, configPath.lastIndexOf("/"));

src/TSHelper.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ export class TSHelper {
2929
return "unknown";
3030
}
3131

32+
static containsStatement(statements: ts.NodeArray<ts.Statement>, kind: ts.SyntaxKind): boolean {
33+
return statements.some(statement => statement.kind === kind);
34+
}
35+
3236
static isFileModule(sourceFile: ts.SourceFile) {
3337
if (sourceFile) {
3438
// Vanilla ts flags files as external module if they have an import or

src/Transpiler.ts

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ export class LuaTranspiler {
232232

233233
transpileBreak(): string {
234234
if (this.transpilingSwitch) {
235-
return this.indent + `goto switchDone${this.genVarCounter}\n`;
235+
return '';
236236
} else {
237237
return this.indent + "break\n";
238238
}
@@ -347,37 +347,61 @@ export class LuaTranspiler {
347347

348348
let result = this.indent + "-------Switch statement start-------\n";
349349

350+
let jumpTableName = "____switch" + this.genVarCounter;
351+
this.genVarCounter++;
352+
353+
result += this.indent + `local ${jumpTableName} = {\n`;
354+
355+
this.pushIndent();
356+
350357
// If statement to go to right entry label
351358
clauses.forEach((clause, index) => {
352359
if (ts.isCaseClause(clause)) {
353-
let keyword = index == 0 ? "if" : "elseif";
354-
let condition = this.transpileExpression(clause.expression, true);
355-
result += this.indent + `${keyword} ${expression}==${condition} then\n`;
356-
} else {
357-
// Default
358-
result += this.indent + `else\n`;
360+
result += this.indent + `-- case:\n`;
361+
result += this.indent + `[${this.transpileExpression(clause.expression, true)}] = function(self)\n`;
362+
}
363+
if (ts.isDefaultClause(clause)) {
364+
result += this.indent + `-- default:\n`;
365+
result += this.indent + `["____default${this.genVarCounter}"] = function(self)\n`;
359366
}
360-
361367
this.pushIndent();
362368

363-
// Labels for fallthrough
364-
result += this.indent + `::switchCase${this.genVarCounter + index}::\n`;
365-
366369
this.transpilingSwitch = true;
367370
clause.statements.forEach(statement => {
368371
result += this.transpileNode(statement);
369372
});
370373
this.transpilingSwitch = false;
371374

372-
// If this goto is reached, fall through to the next case
373-
if (index < clauses.length - 1) {
374-
result += this.indent + `goto switchCase${this.genVarCounter + index + 1}\n`;
375+
let i = index + 1;
376+
if (i < clauses.length && !tsEx.containsStatement(clause.statements, ts.SyntaxKind.BreakStatement)) {
377+
let nextClause = clauses[i];
378+
while(i < clauses.length
379+
&& ts.isCaseClause(nextClause)
380+
&& nextClause.statements.length === 0
381+
) {
382+
i++;
383+
nextClause = clauses[i];
384+
}
385+
386+
if (i !== index && nextClause) {
387+
if (ts.isCaseClause(nextClause)) {
388+
result += this.indent + `self[${this.transpileExpression(nextClause.expression, true)}]()\n`;
389+
} else {
390+
result += this.indent + `self["____default${this.genVarCounter}"]()\n`;
391+
}
392+
}
393+
} else {
394+
result += this.indent + `-- break;\n`;
375395
}
376396

377397
this.popIndent();
398+
399+
result += this.indent + `end,\n`;
378400
});
379-
result += this.indent + "end\n";
380-
result += this.indent + `::switchDone${this.genVarCounter}::\n`;
401+
this.popIndent();
402+
result += this.indent + "}\n";
403+
result += this.indent + `if ${jumpTableName}[${expression}] then ${jumpTableName}[${expression}](${jumpTableName})\n`;
404+
result += this.indent + `elseif ${jumpTableName}["____default${this.genVarCounter}"] then ${jumpTableName}["____default${this.genVarCounter}"](${jumpTableName}) end\n`;
381405
result += this.indent + "--------Switch statement end--------\n";
382406

383407
//Increment counter for next switch statement

0 commit comments

Comments
 (0)