Skip to content

Commit 61a3c52

Browse files
committed
Put numeric for loop functionality in separate helper class
1 parent ec4438d commit 61a3c52

2 files changed

Lines changed: 81 additions & 84 deletions

File tree

ForHelper.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as ts from "typescript";
2+
3+
import {TSHelper as tsEx} from "./TSHelper";
4+
import {LuaTranspiler, TranspileError} from "./Transpiler";
5+
6+
export class ForHelper {
7+
8+
// Get the ending value of a numeric for loop
9+
static GetForEnd(condition: ts.Expression, transpiler: LuaTranspiler): string {
10+
if (ts.isBinaryExpression(condition)) {
11+
if (ts.isIdentifier(condition.left)) {
12+
// Account for lua 1 indexing
13+
switch (condition.operatorToken.kind) {
14+
case ts.SyntaxKind.LessThanEqualsToken:
15+
case ts.SyntaxKind.GreaterThanEqualsToken:
16+
return transpiler.transpileExpression(condition.right);
17+
case ts.SyntaxKind.LessThanToken:
18+
return transpiler.transpileExpression(condition.right) + "-1";
19+
case ts.SyntaxKind.GreaterThanToken:
20+
return transpiler.transpileExpression(condition.right) + "+1";
21+
default:
22+
throw new TranspileError("Unsupported for-loop condition operator: " + tsEx.enumName(condition.operatorToken, ts.SyntaxKind), condition);
23+
}
24+
} else {
25+
// Account for lua 1 indexing
26+
switch (condition.operatorToken.kind) {
27+
case ts.SyntaxKind.LessThanEqualsToken:
28+
case ts.SyntaxKind.GreaterThanEqualsToken:
29+
return transpiler.transpileExpression(condition.right);
30+
case ts.SyntaxKind.LessThanToken:
31+
return transpiler.transpileExpression(condition.right) + "+1";
32+
case ts.SyntaxKind.GreaterThanToken:
33+
return transpiler.transpileExpression(condition.right) + "-1";
34+
default:
35+
throw new TranspileError("Unsupported for-loop condition operator: " + tsEx.enumName(condition.operatorToken, ts.SyntaxKind), condition);
36+
}
37+
}
38+
} else {
39+
throw new TranspileError("Unsupported for-loop condition type: " + tsEx.enumName(condition.kind, ts.SyntaxKind), condition);
40+
}
41+
}
42+
43+
// Get increment step for numeric for loop
44+
static GetForStep(incrementor: ts.Expression, transpiler: LuaTranspiler): string {
45+
switch (incrementor.kind) {
46+
case ts.SyntaxKind.PostfixUnaryExpression:
47+
case ts.SyntaxKind.PrefixUnaryExpression:
48+
switch ((<ts.PostfixUnaryExpression|ts.PrefixUnaryExpression>incrementor).operator) {
49+
case ts.SyntaxKind.PlusPlusToken:
50+
return "1";
51+
case ts.SyntaxKind.MinusMinusToken:
52+
return "-1";
53+
default:
54+
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(incrementor.kind, ts.SyntaxKind), incrementor);
55+
}
56+
case ts.SyntaxKind.BinaryExpression:
57+
let value = ts.isIdentifier((<ts.BinaryExpression>incrementor).left) ?
58+
transpiler.transpileExpression((<ts.BinaryExpression>incrementor).right) :
59+
transpiler.transpileExpression((<ts.BinaryExpression>incrementor).left);
60+
switch((<ts.BinaryExpression>incrementor).operatorToken.kind) {
61+
case ts.SyntaxKind.PlusEqualsToken:
62+
return value;
63+
case ts.SyntaxKind.MinusEqualsToken:
64+
return "-" + value;
65+
default:
66+
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(incrementor.kind, ts.SyntaxKind), incrementor);
67+
}
68+
default:
69+
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(incrementor.kind, ts.SyntaxKind), incrementor);
70+
}
71+
}
72+
}

Transpiler.ts

Lines changed: 9 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import * as ts from "typescript";
22

33
import {TSHelper as tsEx} from "./TSHelper";
4+
import {ForHelper} from "./ForHelper";
45

5-
class TranspileError extends Error {
6+
export class TranspileError extends Error {
67
node: ts.Node;
78
constructor(message: string, node: ts.Node) {
89
super(message);
@@ -109,91 +110,14 @@ export class LuaTranspiler {
109110
}
110111

111112
transpileFor(node: ts.ForStatement): string {
112-
// Goal: Populate three for components:
113-
let start = "0";
114-
let end = "0";
115-
let step = "1";
116-
117-
// Get variable
113+
// Get iterator variable
118114
const variable = (<ts.VariableDeclarationList>node.initializer).declarations[0];
119115
const identifier = <ts.Identifier>variable.name;
120116

121-
// Get initial value
122-
start = this.transpileExpression(variable.initializer);
123-
124-
// Get ending value
125-
if (ts.isBinaryExpression(node.condition)) {
126-
if (ts.isIdentifier(node.condition.left)) {
127-
// Account for lua 1 indexing
128-
switch (node.condition.operatorToken.kind) {
129-
case ts.SyntaxKind.LessThanEqualsToken:
130-
case ts.SyntaxKind.GreaterThanEqualsToken:
131-
end = this.transpileExpression(node.condition.right);
132-
break;
133-
case ts.SyntaxKind.LessThanToken:
134-
end = this.transpileExpression(node.condition.right) + "-1";
135-
break;
136-
case ts.SyntaxKind.GreaterThanToken:
137-
end = this.transpileExpression(node.condition.right) + "+1";
138-
break;
139-
default:
140-
throw new TranspileError("Unsupported for-loop condition operator: " + tsEx.enumName(node.condition.operatorToken, ts.SyntaxKind), node);
141-
}
142-
} else {
143-
this.transpileExpression(node.condition.left);
144-
// Account for lua 1 indexing
145-
switch (node.condition.operatorToken.kind) {
146-
case ts.SyntaxKind.LessThanEqualsToken:
147-
case ts.SyntaxKind.GreaterThanEqualsToken:
148-
end = this.transpileExpression(node.condition.right);
149-
break;
150-
case ts.SyntaxKind.LessThanToken:
151-
end = this.transpileExpression(node.condition.right) + "+1";
152-
break;
153-
case ts.SyntaxKind.GreaterThanToken:
154-
end = this.transpileExpression(node.condition.right) + "-1";
155-
break;
156-
default:
157-
throw new TranspileError("Unsupported for-loop condition operator: " + tsEx.enumName(node.condition.operatorToken, ts.SyntaxKind), node);
158-
}
159-
}
160-
} else {
161-
throw new TranspileError("Unsupported for-loop condition type: " + tsEx.enumName(node.condition.kind, ts.SyntaxKind), node);
162-
}
163-
164-
// Get increment step
165-
switch (node.incrementor.kind) {
166-
case ts.SyntaxKind.PostfixUnaryExpression:
167-
case ts.SyntaxKind.PrefixUnaryExpression:
168-
switch ((<ts.PostfixUnaryExpression|ts.PrefixUnaryExpression>node.incrementor).operator) {
169-
case ts.SyntaxKind.PlusPlusToken:
170-
step = "1";
171-
break;
172-
case ts.SyntaxKind.MinusMinusToken:
173-
step = "-1";
174-
break;
175-
default:
176-
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(node.incrementor.kind, ts.SyntaxKind), node);
177-
}
178-
break;
179-
case ts.SyntaxKind.BinaryExpression:
180-
let value = ts.isIdentifier((<ts.BinaryExpression>node.incrementor).left) ?
181-
this.transpileExpression((<ts.BinaryExpression>node.incrementor).right) :
182-
this.transpileExpression((<ts.BinaryExpression>node.incrementor).left);
183-
switch((<ts.BinaryExpression>node.incrementor).operatorToken.kind) {
184-
case ts.SyntaxKind.PlusEqualsToken:
185-
step = value;
186-
break;
187-
case ts.SyntaxKind.MinusEqualsToken:
188-
step = "-" + value;
189-
break;
190-
default:
191-
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(node.incrementor.kind, ts.SyntaxKind), node);
192-
}
193-
break;
194-
default:
195-
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(node.incrementor.kind, ts.SyntaxKind), node);
196-
}
117+
// Populate three components of lua numeric for loop:
118+
let start = this.transpileExpression(variable.initializer);
119+
let end = ForHelper.GetForEnd(node.condition, this);
120+
let step = ForHelper.GetForStep(node.incrementor, this);
197121

198122
// Add header
199123
let result = this.indent + `for ${identifier.escapedText}=${start},${end},${step} do\n`;
@@ -290,8 +214,8 @@ export class LuaTranspiler {
290214
// Transpile operands
291215
const lhs = this.transpileExpression(node.left, true);
292216
const rhs = this.transpileExpression(node.right, true);
217+
293218
// Rewrite some non-existant binary operators
294-
295219
let result = "";
296220
switch (node.operatorToken.kind) {
297221
case ts.SyntaxKind.PlusEqualsToken:
@@ -316,6 +240,7 @@ export class LuaTranspiler {
316240
result = lhs + this.transpileOperator(node.operatorToken) + rhs;
317241
}
318242

243+
// Optionally put brackets around result
319244
if (brackets) {
320245
return `(${result})`;
321246
} else {

0 commit comments

Comments
 (0)