Skip to content

Commit 0c32b79

Browse files
authored
Merge pull request #14 from lolleko/array-table-features
Added splice array call & delete expression
2 parents fff847b + dccc1a1 commit 0c32b79

File tree

5 files changed

+105
-5
lines changed

5 files changed

+105
-5
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ node_modules/
33
*.lua
44
!dist/*.js
55
!dist/lualib/*.lua
6+
7+
# OSX
8+
.DS_Store

dist/Transpiler.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,8 @@ var LuaTranspiler = /** @class */ (function () {
350350
return this.transpileArrayLiteral(node);
351351
case ts.SyntaxKind.ObjectLiteralExpression:
352352
return this.transpileObjectLiteral(node);
353+
case ts.SyntaxKind.DeleteExpression:
354+
return this.transpileExpression(node.expression) + "=nil";
353355
case ts.SyntaxKind.FunctionExpression:
354356
case ts.SyntaxKind.ArrowFunction:
355357
return this.transpileArrowFunction(node);
@@ -541,6 +543,9 @@ var LuaTranspiler = /** @class */ (function () {
541543
var caller = this.transpileExpression(expression.expression);
542544
switch (expression.name.escapedText) {
543545
case "push":
546+
if (node.arguments.length > 1) {
547+
throw new TranspileError("Unsupported array function: " + expression.name.escapedText + " with more than one argument", node);
548+
}
544549
return "table.insert(" + caller + ", " + params + ")";
545550
case "forEach":
546551
return "TS_forEach(" + caller + ", " + params + ")";
@@ -554,6 +559,8 @@ var LuaTranspiler = /** @class */ (function () {
554559
return "TS_every(" + caller + ", " + params + ")";
555560
case "slice":
556561
return "TS_slice(" + caller + ", " + params + ")";
562+
case "splice":
563+
return "TS_splice(" + caller + ", " + params + ")";
557564
default:
558565
throw new TranspileError("Unsupported array function: " + expression.name.escapedText, node);
559566
}

dist/lualib/typescript.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,32 @@ function TS_slice(list, startI, endI)
4242
return out
4343
end
4444

45+
function TS_splice(list, startI, deleteCount, ...)
46+
if not deleteCount or deleteCount > #list - startI then
47+
deleteCount = #list - startI
48+
end
49+
startI = startI + 1
50+
local newElements = {...}
51+
local out = {}
52+
local outPtr = deleteCount
53+
local newElementsCount = #newElements
54+
for i = startI + deleteCount - 1, startI, -1 do
55+
out[outPtr] = list[i]
56+
outPtr = outPtr -1
57+
if newElements[k] then
58+
list[i] = newElements[k]
59+
newElementsCount = newElementsCount - 1
60+
else
61+
table.remove(list, i)
62+
end
63+
end
64+
while newElements[newElementsCount] do
65+
table.insert(list, startI, newElements[newElementsCount])
66+
newElementsCount = newElementsCount - 1
67+
end
68+
return out
69+
end
70+
4571
function TS_some(list, func)
4672
return #TS_filter(list, func) > 0
4773
end

src/Transpiler.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,8 @@ export class LuaTranspiler {
384384
return this.transpileArrayLiteral(<ts.ArrayLiteralExpression>node);
385385
case ts.SyntaxKind.ObjectLiteralExpression:
386386
return this.transpileObjectLiteral(<ts.ObjectLiteralExpression>node);
387+
case ts.SyntaxKind.DeleteExpression:
388+
return this.transpileExpression((<ts.DeleteExpression>node).expression) + "=nil";
387389
case ts.SyntaxKind.FunctionExpression:
388390
case ts.SyntaxKind.ArrowFunction:
389391
return this.transpileArrowFunction(<ts.ArrowFunction>node);
@@ -410,7 +412,7 @@ export class LuaTranspiler {
410412
// Transpile operands
411413
const lhs = this.transpileExpression(node.left, true);
412414
const rhs = this.transpileExpression(node.right, true);
413-
415+
414416
// Rewrite some non-existant binary operators
415417
let result = "";
416418
switch (node.operatorToken.kind) {
@@ -587,6 +589,9 @@ export class LuaTranspiler {
587589
const caller = this.transpileExpression(expression.expression);
588590
switch (expression.name.escapedText) {
589591
case "push":
592+
if (node.arguments.length > 1) {
593+
throw new TranspileError("Unsupported array function: " + expression.name.escapedText + " with more than one argument", node);
594+
}
590595
return `table.insert(${caller}, ${params})`;
591596
case "forEach":
592597
return `TS_forEach(${caller}, ${params})`;
@@ -599,7 +604,11 @@ export class LuaTranspiler {
599604
case "every":
600605
return `TS_every(${caller}, ${params})`;
601606
case "slice":
602-
return `TS_slice(${caller}, ${params})`
607+
return `TS_slice(${caller}, ${params})`;
608+
case "splice":
609+
return `TS_splice(${caller}, ${params})`;
610+
case "join":
611+
return `table.concat(${caller}, ${params})`;
603612
default:
604613
throw new TranspileError("Unsupported array function: " + expression.name.escapedText, node);
605614
}
@@ -622,7 +631,7 @@ export class LuaTranspiler {
622631

623632
transpilePropertyAccessExpression(node: ts.PropertyAccessExpression): string {
624633
const property = node.name.text;
625-
634+
626635
// Check for primitive types to override
627636
const type = this.checker.getTypeAtLocation(node.expression);
628637
switch (type.flags) {
@@ -830,7 +839,7 @@ export class LuaTranspiler {
830839
// Add static declarations
831840
for (const field of staticFields) {
832841
const fieldName = (<ts.Identifier>field.name).escapedText;
833-
let value = this.transpileExpression(field.initializer);
842+
let value = this.transpileExpression(field.initializer);
834843
result += this.indent + `${className}.${fieldName} = ${value}\n`;
835844
}
836845

test/integration/lua/lualib.spec.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,59 @@ export class LuaTests {
5151
// Assert
5252
Expect(result).toBe(inp.slice(start, end).toString());
5353
}
54-
}
54+
55+
@TestCase([0,1,2,3], 1, 0, 9, 10, 11)
56+
@TestCase([0,1,2,3], 2, 2, 9, 10, 11)
57+
@TestCase([0,1,2,3], 4, 1, 8, 9)
58+
@TestCase([0,1,2,3], 4, 0, 8, 9)
59+
@TestCase([0,1,2,3,4,5], 5, 9, 10, 11)
60+
@TestCase([0,1,2,3,4,5], 3, 2, 3, 4, 5)
61+
@Test("array.splice[Insert]")
62+
public spliceInsert<T>(inp: T[], start: number, deleteCount: number, ...newElements: any[]) {
63+
// Make typechecker return array type
64+
dummyType = dummyArrayType;
65+
// Transpile
66+
let lua = transpileString(
67+
`let spliceTestTable = [${inp.toString()}]
68+
spliceTestTable.splice(${start}, ${deleteCount}, ${newElements});
69+
return ToString(spliceTestTable);`
70+
);
71+
72+
// Add library
73+
lua = toStringDef + lualib + lua;
74+
75+
// Execute
76+
let result = executeLua(lua);
77+
78+
// Assert
79+
inp.splice(start, deleteCount, ...newElements)
80+
Expect(result).toBe(inp.toString());
81+
}
82+
83+
@TestCase([0,1,2,3], 1, 1)
84+
@TestCase([0,1,2,3], 10, 1)
85+
@TestCase([0,1,2,3], 4)
86+
@TestCase([0,1,2,3,4,5], 3)
87+
@TestCase([0,1,2,3,4,5], 2, 2)
88+
@TestCase([0,1,2,3,4,5,6,7,8], 5, 9, 10, 11)
89+
@Test("array.splice[Remove]")
90+
public spliceRemove<T>(inp: T[], start: number, deleteCount?: number, ...newElements: any[]) {
91+
// Make typechecker return array type
92+
dummyType = dummyArrayType;
93+
// Transpile
94+
let lua = transpileString(`return ToString([${inp.toString()}].splice(${start}, ${deleteCount}, ${newElements}))`);
95+
96+
// Add library
97+
lua = toStringDef + lualib + lua;
98+
99+
// Execute
100+
let result = executeLua(lua);
101+
102+
// Assert
103+
if (deleteCount) {
104+
Expect(result).toBe(inp.splice(start, deleteCount, ...newElements).toString());
105+
} else {
106+
Expect(result).toBe(inp.splice(start).toString());
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)