Skip to content

Commit 9eb5609

Browse files
committed
numeric for loops
1 parent 4aea8f1 commit 9eb5609

2 files changed

Lines changed: 86 additions & 13 deletions

File tree

Transpiler.ts

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,93 @@ export class LuaTranspiler {
5353
}
5454

5555
static transpileFor(node: ts.ForStatement, indent: string): string {
56-
const children = tsEx.getChildren(node);
5756

5857
// Get identifier
59-
const identifier = tsEx.getFirstChildOfType<ts.Identifier>(tsEx.getChildren(children[0])[0], ts.isIdentifier);
60-
61-
let min = 0;
62-
let max = 0;
63-
let step = 1;
58+
const identifier = tsEx.getFirstChildOfType<ts.Identifier>(tsEx.getChildren(node.initializer)[0], ts.isIdentifier);
59+
60+
let start = "0";
61+
let end = "0";
62+
let step = "1";
63+
64+
// Get initial value
65+
const varDec = tsEx.getFirstChildOfType<ts.VariableDeclaration>(node.initializer, ts.isVariableDeclaration);
66+
start = this.transpileExpression(tsEx.getChildren(varDec)[1]);
67+
68+
if (ts.isBinaryExpression(node.condition)) {
69+
if (ts.isIdentifier(node.condition.left)) {
70+
// Account for lua 1 indexing
71+
switch (node.condition.operatorToken.kind) {
72+
case ts.SyntaxKind.LessThanEqualsToken:
73+
case ts.SyntaxKind.GreaterThanEqualsToken:
74+
end = this.transpileExpression(node.condition.right);
75+
break;
76+
case ts.SyntaxKind.LessThanToken:
77+
end = this.transpileExpression(node.condition.right) + "-1";
78+
break;
79+
case ts.SyntaxKind.GreaterThanToken:
80+
end = this.transpileExpression(node.condition.right) + "+1";
81+
break;
82+
default:
83+
throw new TranspileError("Unsupported for-loop condition operator: " + tsEx.enumName(node.condition.operatorToken, ts.SyntaxKind), node);
84+
}
85+
} else {
86+
this.transpileExpression(node.condition.left);
87+
// Account for lua 1 indexing
88+
switch (node.condition.operatorToken.kind) {
89+
case ts.SyntaxKind.LessThanEqualsToken:
90+
case ts.SyntaxKind.GreaterThanEqualsToken:
91+
end = this.transpileExpression(node.condition.right);
92+
break;
93+
case ts.SyntaxKind.LessThanToken:
94+
end = this.transpileExpression(node.condition.right) + "+1";
95+
break;
96+
case ts.SyntaxKind.GreaterThanToken:
97+
end = this.transpileExpression(node.condition.right) + "-1";
98+
break;
99+
default:
100+
throw new TranspileError("Unsupported for-loop condition operator: " + tsEx.enumName(node.condition.operatorToken, ts.SyntaxKind), node);
101+
}
102+
}
103+
} else {
104+
throw new TranspileError("Unsupported for-loop condition type: " + tsEx.enumName(node.condition.kind, ts.SyntaxKind), node);
105+
}
64106

65107
// Get increment step
66-
const increment = children[2];
67-
switch (increment.kind) {
108+
switch (node.incrementor.kind) {
68109
case ts.SyntaxKind.PostfixUnaryExpression:
69-
//console.log(increment);
70-
break;
71110
case ts.SyntaxKind.PrefixUnaryExpression:
72-
//console.log(increment);
111+
switch ((<ts.PostfixUnaryExpression|ts.PrefixUnaryExpression>node.incrementor).operator) {
112+
case ts.SyntaxKind.PlusPlusToken:
113+
step = "1";
114+
break;
115+
case ts.SyntaxKind.MinusMinusToken:
116+
step = "-1";
117+
break;
118+
default:
119+
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(node.incrementor.kind, ts.SyntaxKind), node);
120+
}
73121
break;
122+
case ts.SyntaxKind.BinaryExpression:
123+
let value = ts.isIdentifier((<ts.BinaryExpression>node.incrementor).left) ?
124+
this.transpileExpression((<ts.BinaryExpression>node.incrementor).right) :
125+
this.transpileExpression((<ts.BinaryExpression>node.incrementor).left);
126+
switch((<ts.BinaryExpression>node.incrementor).operatorToken.kind) {
127+
case ts.SyntaxKind.PlusEqualsToken:
128+
step = value;
129+
break;
130+
case ts.SyntaxKind.MinusEqualsToken:
131+
step = "-" + value;
132+
break;
133+
default:
134+
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(node.incrementor.kind, ts.SyntaxKind), node);
135+
}
136+
break;
137+
default:
138+
throw new TranspileError("Unsupported for-loop increment step: " + tsEx.enumName(node.incrementor.kind, ts.SyntaxKind), node);
74139
}
75140

76141
// Add header
77-
let result = indent + `for ${identifier.escapedText}=${min},${max},${step} do\n`;
142+
let result = indent + `for ${identifier.escapedText}=${start},${end},${step} do\n`;
78143

79144
// Add body
80145
const block = tsEx.getFirstChildOfType<ts.Block>(node, ts.isBlock);
@@ -210,7 +275,7 @@ export class LuaTranspiler {
210275
let result = "";
211276

212277
let list = tsEx.getFirstChildOfType<ts.VariableDeclarationList>(node, ts.isVariableDeclarationList);
213-
list.forEachChild(declaration => {
278+
list.declarations.forEach(declaration => {
214279
result += this.transpileVariableDeclaration(<ts.VariableDeclaration>declaration);
215280
});
216281

test/test2.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ function Activate(a) {
4343
print(i);
4444
}
4545

46+
for (let i=40; i > 10; i--) {
47+
48+
}
49+
50+
for (let i=2; i <= 20;i += 2) {
51+
52+
}
53+
4654
let i = 0;
4755
i++;
4856
i--;

0 commit comments

Comments
 (0)