Skip to content

Commit 0003996

Browse files
authored
Splice fix (#140)
* WIP update runtime lib (array.splice) * Changed pairs to ipairs * Added link to ECMA specs
1 parent 0887fd4 commit 0003996

File tree

2 files changed

+127
-28
lines changed

2 files changed

+127
-28
lines changed

dist/lualib/typescript.lua

Lines changed: 109 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,39 +32,123 @@ function TS_filter(list, func)
3232
end
3333

3434
function TS_slice(list, startI, endI)
35-
endI = endI or #list
36-
if startI < 0 then startI = #list + startI end
37-
if endI < 0 then endI = #list + endI end
35+
if not endI or endI > #list then endI = #list end
36+
if startI < 0 then startI = math.max(#list + startI, 1) end
37+
if endI < 0 then endI = math.max(#list + endI, 1) end
3838
local out = {}
3939
for i = startI + 1, endI do
4040
table.insert(out, list[i])
4141
end
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
45+
-- https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
46+
function TS_splice(list, start, deleteCount, ...)
47+
-- 1. 2.
48+
local len = #list
49+
50+
local actualStart
51+
52+
-- 4.
53+
if start < 0 then
54+
actualStart = math.max(len + start, 0)
55+
else
56+
actualStart = math.min(start, len)
57+
end
58+
59+
-- 13.
60+
local items = {...}
61+
-- 14.
62+
local itemCount = #items
63+
64+
-- 5. - 7.
65+
local actualDeleteCount
66+
67+
if not start then
68+
actualDeleteCount = 0
69+
elseif not deleteCount then
70+
actualDeleteCount = len - actualStart
71+
else
72+
actualDeleteCount = math.min(math.max(deleteCount, 0), len - actualStart)
4873
end
49-
startI = startI + 1
50-
local newElements = {...}
74+
75+
-- 8. ignored
76+
77+
-- 9.
5178
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)
79+
80+
-- 10.
81+
local k
82+
83+
k = 0
84+
85+
-- 11.
86+
while k < actualDeleteCount do
87+
local from = actualStart + k
88+
89+
if list[from + 1] then
90+
out[k + 1] = list[from + 1]
6291
end
92+
93+
k = k + 1
6394
end
64-
while newElements[newElementsCount] do
65-
table.insert(list, startI, newElements[newElementsCount])
66-
newElementsCount = newElementsCount - 1
95+
96+
-- 15.
97+
if itemCount < actualDeleteCount then
98+
-- a. b.
99+
k = actualStart
100+
while k < len - actualDeleteCount do
101+
local from = k + actualDeleteCount
102+
local to = k + itemCount
103+
104+
if list[from + 1] then
105+
list[to + 1] = list[from + 1]
106+
else
107+
list[to + 1] = nil
108+
end
109+
110+
k = k + 1
111+
end
112+
-- c. d.
113+
k = len
114+
while k > len - actualDeleteCount + itemCount do
115+
list[k] = nil
116+
k = k - 1
117+
end
118+
-- 16.
119+
elseif itemCount > actualDeleteCount then
120+
k = len - actualDeleteCount
121+
while k > actualStart do
122+
local from = k + actualDeleteCount
123+
local to = k + itemCount
124+
125+
if list[from] then
126+
list[to] = list[from]
127+
else
128+
list[to] = nil
129+
end
130+
131+
k = k - 1
132+
end
133+
end
134+
135+
-- 17.
136+
k = actualStart
137+
138+
-- 18.
139+
for _, e in ipairs(items) do
140+
list[k + 1] = e
141+
k = k + 1
67142
end
143+
144+
-- 19.
145+
k = #list
146+
while k > len - actualDeleteCount + itemCount do
147+
list[k] = nil
148+
k = k - 1
149+
end
150+
151+
-- 20.
68152
return out
69153
end
70154

@@ -154,8 +238,8 @@ function Set.constructor(self, other)
154238
end
155239
end
156240
end
157-
function Set.add(self, item)
158-
self._items[item] = true
241+
function Set.add(self, item)
242+
self._items[item] = true
159243
self.size = self.size + 1
160244
end
161245
function Set.clear(self)
@@ -210,7 +294,7 @@ function Map.constructor(self, other)
210294
end
211295
end
212296
end
213-
function Map.clear(self)
297+
function Map.clear(self)
214298
self._items = {}
215299
self.size = 0
216300
end
@@ -241,7 +325,7 @@ function Map.keys(self)
241325
end
242326
return out
243327
end
244-
function Map.set(self, key, value)
328+
function Map.set(self, key, value)
245329
self._items[key] = value
246330
self.size = self.size + 1
247331
return self

test/unit/lualib.spec.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,31 @@ export class LuaLibArrayTests {
144144
@Test("array.splice[Remove]")
145145
public spliceRemove<T>(inp: T[], start: number, deleteCount?: number, ...newElements: any[]) {
146146
// Transpile
147-
const lua = util.transpileString(`return JSONStringify([${inp.toString()}].splice(${start}, ${deleteCount}, ${newElements}))`);
147+
let lua;
148+
if (deleteCount) {
149+
lua = util.transpileString(
150+
`let spliceTestTable = [${inp.toString()}];
151+
spliceTestTable.splice(${start}, ${deleteCount}, ${newElements});
152+
return JSONStringify(spliceTestTable);`
153+
);
154+
} else {
155+
lua = util.transpileString(
156+
`let spliceTestTable = [${inp.toString()}];
157+
spliceTestTable.splice(${start});
158+
return JSONStringify(spliceTestTable);`
159+
);
160+
}
148161

149162
// Execute
150163
const result = util.executeLua(lua);
151164

152165
// Assert
153166
if (deleteCount) {
154-
Expect(result).toBe(JSON.stringify(inp.splice(start, deleteCount, ...newElements)));
167+
inp.splice(start, deleteCount, ...newElements);
168+
Expect(result).toBe(JSON.stringify(inp));
155169
} else {
156-
Expect(result).toBe(JSON.stringify(inp.splice(start)));
170+
inp.splice(start);
171+
Expect(result).toBe(JSON.stringify(inp));
157172
}
158173
}
159174

0 commit comments

Comments
 (0)