Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ node_modules/
*.lua
!dist/*.js
!dist/lualib/*.lua

# OSX
.DS_Store
7 changes: 7 additions & 0 deletions dist/Transpiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ var LuaTranspiler = /** @class */ (function () {
return this.transpileArrayLiteral(node);
case ts.SyntaxKind.ObjectLiteralExpression:
return this.transpileObjectLiteral(node);
case ts.SyntaxKind.DeleteExpression:
return this.transpileExpression(node.expression) + "=nil";
case ts.SyntaxKind.FunctionExpression:
case ts.SyntaxKind.ArrowFunction:
return this.transpileArrowFunction(node);
Expand Down Expand Up @@ -541,6 +543,9 @@ var LuaTranspiler = /** @class */ (function () {
var caller = this.transpileExpression(expression.expression);
switch (expression.name.escapedText) {
case "push":
if (node.arguments.length > 1) {
throw new TranspileError("Unsupported array function: " + expression.name.escapedText + " with more than one argument", node);
}
return "table.insert(" + caller + ", " + params + ")";
case "forEach":
return "TS_forEach(" + caller + ", " + params + ")";
Expand All @@ -554,6 +559,8 @@ var LuaTranspiler = /** @class */ (function () {
return "TS_every(" + caller + ", " + params + ")";
case "slice":
return "TS_slice(" + caller + ", " + params + ")";
case "splice":
return "TS_splice(" + caller + ", " + params + ")";
default:
throw new TranspileError("Unsupported array function: " + expression.name.escapedText, node);
}
Expand Down
26 changes: 26 additions & 0 deletions dist/lualib/typescript.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,32 @@ function TS_slice(list, startI, endI)
return out
end

function TS_splice(list, startI, deleteCount, ...)
if not deleteCount or deleteCount > #list - startI then
deleteCount = #list - startI
end
startI = startI + 1
local newElements = {...}
local out = {}
local outPtr = deleteCount
local newElementsCount = #newElements
for i = startI + deleteCount - 1, startI, -1 do
out[outPtr] = list[i]
outPtr = outPtr -1
if newElements[k] then
list[i] = newElements[k]
newElementsCount = newElementsCount - 1
else
table.remove(list, i)
end
end
while newElements[newElementsCount] do
table.insert(list, startI, newElements[newElementsCount])
newElementsCount = newElementsCount - 1
end
return out
end

function TS_some(list, func)
return #TS_filter(list, func) > 0
end
Expand Down
17 changes: 13 additions & 4 deletions src/Transpiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,8 @@ export class LuaTranspiler {
return this.transpileArrayLiteral(<ts.ArrayLiteralExpression>node);
case ts.SyntaxKind.ObjectLiteralExpression:
return this.transpileObjectLiteral(<ts.ObjectLiteralExpression>node);
case ts.SyntaxKind.DeleteExpression:
return this.transpileExpression((<ts.DeleteExpression>node).expression) + "=nil";
case ts.SyntaxKind.FunctionExpression:
case ts.SyntaxKind.ArrowFunction:
return this.transpileArrowFunction(<ts.ArrowFunction>node);
Expand All @@ -410,7 +412,7 @@ export class LuaTranspiler {
// Transpile operands
const lhs = this.transpileExpression(node.left, true);
const rhs = this.transpileExpression(node.right, true);

// Rewrite some non-existant binary operators
let result = "";
switch (node.operatorToken.kind) {
Expand Down Expand Up @@ -587,6 +589,9 @@ export class LuaTranspiler {
const caller = this.transpileExpression(expression.expression);
switch (expression.name.escapedText) {
case "push":
if (node.arguments.length > 1) {
throw new TranspileError("Unsupported array function: " + expression.name.escapedText + " with more than one argument", node);
}
return `table.insert(${caller}, ${params})`;
case "forEach":
return `TS_forEach(${caller}, ${params})`;
Expand All @@ -599,7 +604,11 @@ export class LuaTranspiler {
case "every":
return `TS_every(${caller}, ${params})`;
case "slice":
return `TS_slice(${caller}, ${params})`
return `TS_slice(${caller}, ${params})`;
case "splice":
return `TS_splice(${caller}, ${params})`;
case "join":
return `table.concat(${caller}, ${params})`;
default:
throw new TranspileError("Unsupported array function: " + expression.name.escapedText, node);
}
Expand All @@ -622,7 +631,7 @@ export class LuaTranspiler {

transpilePropertyAccessExpression(node: ts.PropertyAccessExpression): string {
const property = node.name.text;

// Check for primitive types to override
const type = this.checker.getTypeAtLocation(node.expression);
switch (type.flags) {
Expand Down Expand Up @@ -830,7 +839,7 @@ export class LuaTranspiler {
// Add static declarations
for (const field of staticFields) {
const fieldName = (<ts.Identifier>field.name).escapedText;
let value = this.transpileExpression(field.initializer);
let value = this.transpileExpression(field.initializer);
result += this.indent + `${className}.${fieldName} = ${value}\n`;
}

Expand Down
57 changes: 56 additions & 1 deletion test/integration/lua/lualib.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,59 @@ export class LuaTests {
// Assert
Expect(result).toBe(inp.slice(start, end).toString());
}
}

@TestCase([0,1,2,3], 1, 0, 9, 10, 11)
@TestCase([0,1,2,3], 2, 2, 9, 10, 11)
@TestCase([0,1,2,3], 4, 1, 8, 9)
@TestCase([0,1,2,3], 4, 0, 8, 9)
@TestCase([0,1,2,3,4,5], 5, 9, 10, 11)
@TestCase([0,1,2,3,4,5], 3, 2, 3, 4, 5)
@Test("array.splice[Insert]")
public spliceInsert<T>(inp: T[], start: number, deleteCount: number, ...newElements: any[]) {
// Make typechecker return array type
dummyType = dummyArrayType;
// Transpile
let lua = transpileString(
`let spliceTestTable = [${inp.toString()}]
spliceTestTable.splice(${start}, ${deleteCount}, ${newElements});
return ToString(spliceTestTable);`
);

// Add library
lua = toStringDef + lualib + lua;

// Execute
let result = executeLua(lua);

// Assert
inp.splice(start, deleteCount, ...newElements)
Expect(result).toBe(inp.toString());
}

@TestCase([0,1,2,3], 1, 1)
@TestCase([0,1,2,3], 10, 1)
@TestCase([0,1,2,3], 4)
@TestCase([0,1,2,3,4,5], 3)
@TestCase([0,1,2,3,4,5], 2, 2)
@TestCase([0,1,2,3,4,5,6,7,8], 5, 9, 10, 11)
@Test("array.splice[Remove]")
public spliceRemove<T>(inp: T[], start: number, deleteCount?: number, ...newElements: any[]) {
// Make typechecker return array type
dummyType = dummyArrayType;
// Transpile
let lua = transpileString(`return ToString([${inp.toString()}].splice(${start}, ${deleteCount}, ${newElements}))`);

// Add library
lua = toStringDef + lualib + lua;

// Execute
let result = executeLua(lua);

// Assert
if (deleteCount) {
Expect(result).toBe(inp.splice(start, deleteCount, ...newElements).toString());
} else {
Expect(result).toBe(inp.splice(start).toString());
}
}
}