Skip to content

Commit 33b2084

Browse files
committed
Switch statement and ternary operator
1 parent 7ae1e79 commit 33b2084

2 files changed

Lines changed: 96 additions & 3 deletions

File tree

Transpiler.ts

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@ export class LuaTranspiler {
2020

2121
indent: string;
2222
checker: ts.TypeChecker;
23+
switchCounter: number;
24+
transpilingSwitch: boolean;
2325

2426
constructor(checker: ts.TypeChecker) {
2527
this.indent = "";
2628
this.checker = checker;
29+
this.switchCounter = 0;
30+
this.transpilingSwitch = false;
2731
}
2832

2933
pushIndent(): void {
@@ -71,8 +75,10 @@ export class LuaTranspiler {
7175
return this.transpileForOf(<ts.ForOfStatement>node);
7276
case ts.SyntaxKind.ForInStatement:
7377
return this.transpileForIn(<ts.ForInStatement>node);
78+
case ts.SyntaxKind.SwitchStatement:
79+
return this.transpileSwitch(<ts.SwitchStatement>node);
7480
case ts.SyntaxKind.BreakStatement:
75-
return this.indent + "break\n";
81+
return this.transpileBreak();
7682
case ts.SyntaxKind.ContinueKeyword:
7783
// Disallow continue
7884
throw new TranspileError("Continue is not supported in Lua", node);
@@ -83,6 +89,14 @@ export class LuaTranspiler {
8389
}
8490
}
8591

92+
transpileBreak(): string {
93+
if (this.transpilingSwitch) {
94+
return this.indent + `goto switchDone${this.switchCounter}\n`;
95+
} else {
96+
return this.indent + "break\n";
97+
}
98+
}
99+
86100
transpileIf(node: ts.IfStatement): string {
87101
const condition = this.transpileExpression(node.expression);
88102

@@ -178,6 +192,50 @@ export class LuaTranspiler {
178192
return result + this.indent + "end\n";
179193
}
180194

195+
transpileSwitch(node: ts.SwitchStatement): string {
196+
const expression = this.transpileExpression(node.expression, true);
197+
const clauses = node.caseBlock.clauses;
198+
199+
let result = this.indent + "-------Switch statement start-------\n";
200+
201+
// If statement to go to right entry label
202+
clauses.forEach((clause, index) => {
203+
if (ts.isCaseClause(clause)) {
204+
let keyword = index == 0 ? "if" : "elseif";
205+
let condition = this.transpileExpression(clause.expression, true);
206+
result += this.indent + `${keyword} ${expression}==${condition} then\n`;
207+
} else {
208+
// Default
209+
result += this.indent + `else\n`;
210+
}
211+
212+
this.pushIndent();
213+
214+
// Labels for fallthrough
215+
result += this.indent + `::switchCase${this.switchCounter+index}::\n`;
216+
217+
this.transpilingSwitch = true;
218+
clause.statements.forEach(statement => {
219+
result += this.transpileNode(statement);
220+
});
221+
this.transpilingSwitch = false;
222+
223+
// If this goto is reached, fall through to the next case
224+
if (index < clauses.length - 1) {
225+
result += this.indent + `goto switchCase${this.switchCounter + index + 1}\n`;
226+
}
227+
228+
this.popIndent();
229+
});
230+
result += this.indent + "end\n";
231+
result += this.indent + `::switchDone${this.switchCounter}::\n`;
232+
result += this.indent + "--------Switch statement end--------\n";
233+
234+
//Increment counter for next switch statement
235+
this.switchCounter += clauses.length;
236+
return result;
237+
}
238+
181239
transpileReturn(node: ts.ReturnStatement): string {
182240
return "return " + this.transpileExpression(node.expression);
183241
}
@@ -187,6 +245,9 @@ export class LuaTranspiler {
187245
case ts.SyntaxKind.BinaryExpression:
188246
// Add brackets to preserve ordering
189247
return this.transpileBinaryExpression(<ts.BinaryExpression>node, brackets);
248+
case ts.SyntaxKind.ConditionalExpression:
249+
// Add brackets to preserve ordering
250+
return this.transpileConditionalExpression(<ts.ConditionalExpression>node, brackets);
190251
case ts.SyntaxKind.CallExpression:
191252
return this.transpileCallExpression(<ts.CallExpression>node);
192253
case ts.SyntaxKind.PropertyAccessExpression:
@@ -258,6 +319,14 @@ export class LuaTranspiler {
258319
}
259320
}
260321

322+
transpileConditionalExpression(node: ts.ConditionalExpression, brackets?: boolean): string {
323+
let condition = this.transpileExpression(node.condition);
324+
let val1 = this.transpileExpression(node.whenTrue);
325+
let val2 = this.transpileExpression(node.whenFalse);
326+
327+
return `ITE(${condition},function() return ${val1} end, function() return ${val2} end)`;
328+
}
329+
261330
// Replace some missmatching operators
262331
transpileOperator<T extends ts.SyntaxKind>(operator: ts.Token<T>): string {
263332
switch (operator.kind) {

test/test2.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function Activate() {
5151

5252
}
5353

54-
let i = 0;
54+
let i = false == false ? 0 : 4;
5555
i++;
5656
i--;
5757
!true;
@@ -88,5 +88,29 @@ function Activate() {
8888
while (true) {
8989
break;
9090
}
91-
}
91+
}
92+
93+
switch (a) {
94+
case 1:
95+
2+2
96+
case 3:
97+
return 5;
98+
case 4:
99+
1+1
100+
break;
101+
default:
102+
let b = 3
103+
}
104+
105+
switch (a) {
106+
case 1:
107+
2+2
108+
case 3:
109+
return 5;
110+
case 4:
111+
1+1
112+
break;
113+
default:
114+
let b = 3
115+
}
92116
}

0 commit comments

Comments
 (0)