diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 94070209e..a21aa483e 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -26,6 +26,10 @@ export enum LuaLibFeature { ArrayIndexOf = "ArrayIndexOf", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", + ArrayReverse = "ArrayReverse", + ArrayShift = "ArrayShift", + ArrayUnshift = "ArrayUnshift", + ArraySort = "ArraySort", ArraySlice = "ArraySlice", ArraySome = "ArraySome", ArraySplice = "ArraySplice", @@ -305,6 +309,9 @@ export abstract class LuaTranspiler { public transpileLuaLibFunction(func: LuaLibFeature, ...params: string[]): string { this.importLuaLibFeature(func); + params = params.filter(element => { + return element.toString() !== ""; + }); return `__TS__${func}(${params.join(", ")})`; } @@ -1239,6 +1246,14 @@ export abstract class LuaTranspiler { return this.transpileLuaLibFunction(LuaLibFeature.ArrayConcat, caller, params); case "push": return this.transpileLuaLibFunction(LuaLibFeature.ArrayPush, caller, params); + case "reverse": + return this.transpileLuaLibFunction(LuaLibFeature.ArrayReverse, caller); + case "shift": + return this.transpileLuaLibFunction(LuaLibFeature.ArrayShift, caller); + case "unshift": + return this.transpileLuaLibFunction(LuaLibFeature.ArrayUnshift, caller, params); + case "sort": + return this.transpileLuaLibFunction(LuaLibFeature.ArraySort, caller); case "pop": return `table.remove(${caller})`; case "forEach": diff --git a/src/lualib/ArrayReverse.ts b/src/lualib/ArrayReverse.ts new file mode 100644 index 000000000..3c4839417 --- /dev/null +++ b/src/lualib/ArrayReverse.ts @@ -0,0 +1,12 @@ +function __TS__ArrayReverse(arr: any[]): any[] { + let i = 0; + let j = arr.length - 1; + while (i < j) { + const temp = arr[j]; + arr[j] = arr[i]; + arr[i] = temp; + i = i + 1; + j = j - 1; + } + return arr; +} diff --git a/src/lualib/ArrayShift.ts b/src/lualib/ArrayShift.ts new file mode 100644 index 000000000..a95df1a49 --- /dev/null +++ b/src/lualib/ArrayShift.ts @@ -0,0 +1,6 @@ +declare namespace table { + function remove(arr: T[], idx: number): T; +} +function __TS__ArrayShift(arr: T[]): T { + return table.remove(arr, 1); +} diff --git a/src/lualib/ArraySort.ts b/src/lualib/ArraySort.ts new file mode 100644 index 000000000..18745695c --- /dev/null +++ b/src/lualib/ArraySort.ts @@ -0,0 +1,7 @@ +declare namespace table { + function sort(arr: T[], compareFn?: (a: T, b: T) => number): void; +} +function __TS__ArraySort(arr: T[], compareFn?: (a: T, b: T) => number): T[] { + table.sort(arr, compareFn); + return arr; +} diff --git a/src/lualib/ArrayUnshift.ts b/src/lualib/ArrayUnshift.ts new file mode 100644 index 000000000..cb0031100 --- /dev/null +++ b/src/lualib/ArrayUnshift.ts @@ -0,0 +1,9 @@ +declare namespace table { + function insert(arr: T[], idx: number, val: T): void; +} +function __TS__ArrayUnshift(arr: T[], ...items: T[]): number { + for (let i = items.length - 1; i >= 0; --i) { + table.insert(arr, 1, items[i]); + } + return arr.length; +} diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index 328e346ee..b81f83c90 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -320,7 +320,98 @@ export class LuaLibArrayTests { Expect(result).toBe(expected[1]); } } + @TestCase("[1, 2, 3]", [3, 2, 1]) + @TestCase("[1, 2, 3, null]", [3, 2, 1]) + @TestCase("[1, 2, 3, 4]", [4, 3, 2, 1]) + @TestCase("[1]", [1]) + @TestCase("[]", []) + @Test("array.reverse") + public arrayReverse(array: string, expected): void { + { + // Transpile + const lua = util.transpileString( + `let testArray = ${array}; + let val = testArray.reverse(); + return JSONStringify(testArray)`); + + // Execute + const result = util.executeLua(lua); + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + } + @TestCase("[1, 2, 3]", [2, 3], 1) + @TestCase("[1]", [], 1) + @TestCase("[]", [], null) + @Test("array.shift") + public arrayShift(array: string, expectedArray: number[], expectedValue: number): void { + { + // test array mutation + { + // Transpile + const lua = util.transpileString( + `let testArray = ${array}; + let val = testArray.shift(); + return JSONStringify(testArray)`); + + // Execute + const result = util.executeLua(lua); + // Assert + Expect(result).toBe(JSON.stringify(expectedArray)); + } + // test return value + { + // Transpile + const lua = util.transpileString( + `let testArray = ${array}; + let val = testArray.shift(); + return val`); + + // Execute + const result = util.executeLua(lua); + // Assert + Expect(result).toBe(expectedValue); + } + } + } + @TestCase("[3, 4, 5]", [1, 2], [1, 2, 3, 4, 5]) + @TestCase("[]", [], []) + @TestCase("[1]", [], [1]) + @TestCase("[]", [1], [1]) + @Test("array.unshift") + public arrayUnshift(array: string, toUnshift, expected): void { + { + // Transpile + const lua = util.transpileString( + `let testArray = ${array}; + testArray.unshift(${toUnshift}); + return JSONStringify(testArray)`); + // Execute + const result = util.executeLua(lua); + + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + } + @TestCase("[4, 5, 3, 2, 1]", [1, 2, 3, 4, 5]) + @TestCase("[1]", [1]) + @TestCase("[1, null]", [1]) + @TestCase("[]", []) + @Test("array.sort") + public arraySort(array: string, expected): void { + { + // Transpile + const lua = util.transpileString( + `let testArray = ${array}; + testArray.sort(); + return JSONStringify(testArray)`); + // Execute + const result = util.executeLua(lua); + // Assert + Expect(result).toBe(JSON.stringify(expected)); + } + } @TestCase("true", "4", "5", 4) @TestCase("false", "4", "5", 5) @TestCase("3", "4", "5", 4)