Skip to content

Commit 365884f

Browse files
MaxGraeydcodeIO
authored andcommitted
Add String#lastIndexOf and improve tests (AssemblyScript#163)
1 parent c419967 commit 365884f

File tree

11 files changed

+1560
-620
lines changed

11 files changed

+1560
-620
lines changed

std/assembly/index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,8 @@ declare class String {
431431
charCodeAt(index: u32): u16;
432432
concat(other: string): string;
433433
endsWith(other: string): bool;
434-
indexOf(other: string): u32;
434+
indexOf(other: string, fromIndex?: i32): u32;
435+
lastIndexOf(other: string, fromIndex?: i32): i32;
435436
includes(other: string): bool;
436437
startsWith(other: string): bool;
437438
substr(start: u32, length?: u32): string;

std/assembly/internal/string.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export const MAX_LENGTH = (<i32>MAX_SIZE_32 - HEADER_SIZE) >>> 1;
1515
/** Singleton empty String. */
1616
export const EMPTY = changetype<String>(""); // TODO: is this a bad idea with '===' in place?
1717

18+
@inline
19+
export function clamp<T>(val: T, lo: T, hi: T): T {
20+
return max<T>(min<T>(val, hi), lo);
21+
}
22+
1823
/** Allocates a raw String with uninitialized contents. */
1924
export function allocate(length: i32): String {
2025
assert(length > 0 && length <= MAX_LENGTH);

std/assembly/string.ts

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
HEADER_SIZE,
33
MAX_LENGTH,
44
EMPTY,
5+
clamp,
56
allocate,
67
isWhiteSpaceOrLineTerminator,
78
CharCode,
@@ -97,7 +98,7 @@ export class String {
9798
endsWith(searchString: String, endPosition: i32 = MAX_LENGTH): bool {
9899
assert(this !== null);
99100
if (searchString === null) return false;
100-
var end: isize = <isize>min(max(endPosition, 0), this.length);
101+
var end = clamp<isize>(endPosition, 0, this.length);
101102
var searchLength: isize = searchString.length;
102103
var start: isize = end - searchLength;
103104
if (start < 0) return false;
@@ -206,21 +207,44 @@ export class String {
206207
return this.indexOf(searchString, position) != -1;
207208
}
208209

209-
indexOf(searchString: String, position: i32 = 0): i32 {
210+
indexOf(searchString: String, fromIndex: i32 = 0): i32 {
211+
assert(this !== null);
212+
if (searchString === null) searchString = changetype<String>("null");
213+
var searchLen: isize = searchString.length;
214+
if (!searchLen) return 0;
215+
var len: isize = this.length;
216+
if (!len) return -1;
217+
var start = clamp<isize>(fromIndex, 0, len);
218+
len -= searchLen;
219+
// TODO: multiple char codes
220+
for (let k: isize = start; k <= len; ++k) {
221+
if (!compare_memory(
222+
changetype<usize>(this) + HEADER_SIZE + (k << 1),
223+
changetype<usize>(searchString) + HEADER_SIZE,
224+
searchLen << 1
225+
)) {
226+
return <i32>k;
227+
}
228+
}
229+
return -1;
230+
}
231+
232+
lastIndexOf(searchString: String, fromIndex: i32 = 0): i32 {
210233
assert(this !== null);
211234
if (searchString === null) searchString = changetype<String>("null");
212-
var pos: isize = position;
213235
var len: isize = this.length;
214-
var start: isize = min<isize>(max<isize>(pos, 0), len);
215-
var searchLen: isize = <isize>searchString.length;
236+
var searchLen: isize = searchString.length;
237+
if (!searchLen) return len;
238+
if (!len) return -1;
239+
var start = clamp<isize>(fromIndex - searchLen, 0, len);
216240

217-
// TODO: two-way, multiple char codes
218-
for (let k: usize = start; <isize>k + searchLen <= len; ++k) {
241+
// TODO: multiple char codes
242+
for (let k: isize = len - 1; k >= start; --k) {
219243
if (!compare_memory(
220244
changetype<usize>(this) + HEADER_SIZE + (k << 1),
221245
changetype<usize>(searchString) + HEADER_SIZE,
222-
searchLen << 1)
223-
) {
246+
searchLen << 1
247+
)) {
224248
return <i32>k;
225249
}
226250
}
@@ -233,8 +257,8 @@ export class String {
233257

234258
var pos: isize = position;
235259
var len: isize = this.length;
236-
var start: isize = min<isize>(max<isize>(pos, 0), len);
237-
var searchLength: isize = <isize>searchString.length;
260+
var start = clamp<isize>(pos, 0, len);
261+
var searchLength: isize = searchString.length;
238262
if (searchLength + start > len) {
239263
return false;
240264
}
@@ -253,7 +277,7 @@ export class String {
253277
if (intStart < 0) {
254278
intStart = max<isize>(size + intStart, 0);
255279
}
256-
var resultLength: isize = min<isize>(max<isize>(end, 0), size - intStart);
280+
var resultLength = clamp<isize>(end, 0, size - intStart);
257281
if (resultLength <= 0) {
258282
return EMPTY;
259283
}
@@ -269,8 +293,8 @@ export class String {
269293
substring(start: i32, end: i32 = i32.MAX_VALUE): String {
270294
assert(this !== null);
271295
var len = this.length;
272-
var finalStart = min<i32>(max<i32>(start, 0), len);
273-
var finalEnd = min<i32>(max<i32>(end, 0), len);
296+
var finalStart = clamp<isize>(start, 0, len);
297+
var finalEnd = clamp<isize>(end, 0, len);
274298
var from = min<i32>(finalStart, finalEnd);
275299
var to = max<i32>(finalStart, finalEnd);
276300
len = to - from;

std/portable/index.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,14 @@ declare class String {
280280

281281
private constructor();
282282

283-
indexOf(subject: string, position?: i32): i32;
283+
indexOf(other: string, fromIndex?: i32): i32;
284+
lastIndexOf(other: string, fromIndex?: i32): i32;
284285
includes(other: string): bool;
285-
lastIndexOf(subject: string, position?: i32): i32;
286286
charAt(index: i32): string;
287287
charCodeAt(index: i32): i32;
288288
substring(from: i32, to?: i32): string;
289-
startsWith(subject: string): bool;
290-
endsWith(subject: string): bool;
289+
startsWith(other: string): bool;
290+
endsWith(other: string): bool;
291291
replace(search: string, replacement: string): string;
292292
repeat(count?: i32): string;
293293
toString(): string;

tests/compiler/std/array-access.optimized.wat

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@
132132
(call $~lib/env/abort
133133
(i32.const 0)
134134
(i32.const 12)
135-
(i32.const 231)
135+
(i32.const 255)
136136
(i32.const 4)
137137
)
138138
(unreachable)
@@ -154,31 +154,31 @@
154154
(get_local $1)
155155
)
156156
)
157-
(tee_local $3
157+
(tee_local $2
158158
(select
159-
(tee_local $3
159+
(tee_local $2
160160
(select
161161
(get_local $2)
162-
(i32.const 0)
163-
(i32.gt_s
162+
(tee_local $3
163+
(i32.load
164+
(get_local $0)
165+
)
166+
)
167+
(i32.lt_s
164168
(get_local $2)
165-
(i32.const 0)
169+
(get_local $3)
166170
)
167171
)
168172
)
169-
(tee_local $2
170-
(i32.load
171-
(get_local $0)
172-
)
173-
)
174-
(i32.lt_s
175-
(get_local $3)
173+
(i32.const 0)
174+
(i32.gt_s
176175
(get_local $2)
176+
(i32.const 0)
177177
)
178178
)
179179
)
180180
)
181-
(get_local $2)
181+
(get_local $3)
182182
)
183183
(return
184184
(i32.const 0)
@@ -192,7 +192,7 @@
192192
(i32.const 4)
193193
)
194194
(i32.shl
195-
(get_local $3)
195+
(get_local $2)
196196
(i32.const 1)
197197
)
198198
)

tests/compiler/std/array-access.untouched.wat

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
(local $6 i32)
202202
(local $7 i32)
203203
(local $8 i32)
204+
(local $9 i32)
204205
(if
205206
(i32.eqz
206207
(i32.ne
@@ -212,7 +213,7 @@
212213
(call $~lib/env/abort
213214
(i32.const 0)
214215
(i32.const 12)
215-
(i32.const 231)
216+
(i32.const 255)
216217
(i32.const 4)
217218
)
218219
(unreachable)
@@ -235,41 +236,46 @@
235236
(get_local $0)
236237
)
237238
)
238-
(set_local $7
239-
(select
240-
(tee_local $5
241-
(select
242-
(tee_local $5
243-
(get_local $3)
244-
)
245-
(tee_local $6
246-
(i32.const 0)
247-
)
248-
(i32.gt_s
249-
(get_local $5)
250-
(get_local $6)
239+
(set_local $8
240+
(block $~lib/internal/string/clamp<isize>|inlined.0 (result i32)
241+
(set_local $5
242+
(i32.const 0)
243+
)
244+
(select
245+
(tee_local $6
246+
(select
247+
(tee_local $6
248+
(get_local $3)
249+
)
250+
(tee_local $7
251+
(get_local $4)
252+
)
253+
(i32.lt_s
254+
(get_local $6)
255+
(get_local $7)
256+
)
251257
)
252258
)
253-
)
254-
(tee_local $6
255-
(get_local $4)
256-
)
257-
(i32.lt_s
258-
(get_local $5)
259-
(get_local $6)
259+
(tee_local $7
260+
(get_local $5)
261+
)
262+
(i32.gt_s
263+
(get_local $6)
264+
(get_local $7)
265+
)
260266
)
261267
)
262268
)
263-
(set_local $8
269+
(set_local $9
264270
(i32.load
265271
(get_local $1)
266272
)
267273
)
268274
(if
269275
(i32.gt_s
270276
(i32.add
277+
(get_local $9)
271278
(get_local $8)
272-
(get_local $7)
273279
)
274280
(get_local $4)
275281
)
@@ -285,7 +291,7 @@
285291
(i32.const 4)
286292
)
287293
(i32.shl
288-
(get_local $7)
294+
(get_local $8)
289295
(i32.const 1)
290296
)
291297
)
@@ -294,7 +300,7 @@
294300
(i32.const 4)
295301
)
296302
(i32.shl
297-
(get_local $8)
303+
(get_local $9)
298304
(i32.const 1)
299305
)
300306
)

tests/compiler/std/array.optimized.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5823,7 +5823,7 @@
58235823
(call $~lib/env/abort
58245824
(i32.const 0)
58255825
(i32.const 728)
5826-
(i32.const 20)
5826+
(i32.const 25)
58275827
(i32.const 2)
58285828
)
58295829
(unreachable)
@@ -5855,7 +5855,7 @@
58555855
(call $~lib/env/abort
58565856
(i32.const 0)
58575857
(i32.const 696)
5858-
(i32.const 18)
5858+
(i32.const 19)
58595859
(i32.const 4)
58605860
)
58615861
(unreachable)
@@ -5903,7 +5903,7 @@
59035903
(call $~lib/env/abort
59045904
(i32.const 0)
59055905
(i32.const 696)
5906-
(i32.const 74)
5906+
(i32.const 75)
59075907
(i32.const 4)
59085908
)
59095909
(unreachable)

tests/compiler/std/array.untouched.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8611,7 +8611,7 @@
86118611
(call $~lib/env/abort
86128612
(i32.const 0)
86138613
(i32.const 728)
8614-
(i32.const 20)
8614+
(i32.const 25)
86158615
(i32.const 2)
86168616
)
86178617
(unreachable)
@@ -8647,7 +8647,7 @@
86478647
(call $~lib/env/abort
86488648
(i32.const 0)
86498649
(i32.const 696)
8650-
(i32.const 18)
8650+
(i32.const 19)
86518651
(i32.const 4)
86528652
)
86538653
(unreachable)
@@ -8699,7 +8699,7 @@
86998699
(call $~lib/env/abort
87008700
(i32.const 0)
87018701
(i32.const 696)
8702-
(i32.const 74)
8702+
(i32.const 75)
87038703
(i32.const 4)
87048704
)
87058705
(unreachable)

0 commit comments

Comments
 (0)