Implement String#split (#301)

This commit is contained in:
Max Graey 2018-10-18 20:05:35 +03:00 committed by Daniel Wirtz
parent 086d96b299
commit 711f73b15d
13 changed files with 7436 additions and 3257 deletions

View File

@ -491,6 +491,7 @@ declare class String {
padStart(targetLength: i32, padString?: string): string; padStart(targetLength: i32, padString?: string): string;
padEnd(targetLength: i32, padString?: string): string; padEnd(targetLength: i32, padString?: string): string;
repeat(count?: i32): string; repeat(count?: i32): string;
split(separator?: string, limit?: i32): string[];
toString(): string; toString(): string;
static fromUTF8(ptr: usize, len: usize): string; static fromUTF8(ptr: usize, len: usize): string;
toUTF8(): usize; toUTF8(): usize;

View File

@ -10,6 +10,10 @@ import {
parse parse
} from "./internal/string"; } from "./internal/string";
import {
storeUnsafe as storeUnsafeArray
} from "./internal/arraybuffer";
@sealed @sealed
export class String { export class String {
@ -200,6 +204,7 @@ export class String {
return compareUnsafe(left, 0, right, 0, length) <= 0; return compareUnsafe(left, 0, right, 0, length) <= 0;
} }
@inline
includes(searchString: String, position: i32 = 0): bool { includes(searchString: String, position: i32 = 0): bool {
return this.indexOf(searchString, position) != -1; return this.indexOf(searchString, position) != -1;
} }
@ -400,14 +405,69 @@ export class String {
throw new RangeError("Invalid count value"); throw new RangeError("Invalid count value");
} }
if (count === 0 || !length) return changetype<String>(""); if (count == 0 || !length) return changetype<String>("");
if (count === 1) return this; if (count == 1) return this;
var result = allocateUnsafe(length * count); var result = allocateUnsafe(length * count);
repeatUnsafe(result, 0, this, count); repeatUnsafe(result, 0, this, count);
return result; return result;
} }
split(separator: String = null, limit: i32 = i32.MAX_VALUE): String[] {
assert(this !== null);
if (!limit) return new Array<String>();
if (separator === null) return <String[]>[this];
var length: isize = this.length;
var sepLen: isize = separator.length;
if (limit < 0) limit = i32.MAX_VALUE;
if (!sepLen) {
if (!length) return new Array<String>();
// split by chars
length = min<isize>(length, <isize>limit);
let result = new Array<String>(length);
let buffer = <ArrayBuffer>result.buffer_;
for (let i: isize = 0; i < length; ++i) {
let char = allocateUnsafe(1);
store<u16>(
changetype<usize>(char),
load<u16>(
changetype<usize>(this) + (<usize>i << 1),
HEADER_SIZE
),
HEADER_SIZE
);
storeUnsafeArray<String,String>(buffer, i, char);
}
return result;
} else if (!length) {
return <String[]>[changetype<String>("")];
}
var result = new Array<String>();
var end = 0, start = 0, i = 0;
while ((end = this.indexOf(separator, start)) != -1) {
let len = end - start;
if (len > 0) {
let out = allocateUnsafe(len);
copyUnsafe(out, 0, this, start, len);
result.push(out);
} else {
result.push(changetype<String>(""));
}
if (++i == limit) return result;
start = end + sepLen;
}
if (!start) return <String[]>[this];
var len = length - start;
if (len > 0) {
let out = allocateUnsafe(len);
copyUnsafe(out, 0, this, start, len);
result.push(out);
} else {
result.push(changetype<String>(""));
}
return result;
}
toString(): String { toString(): String {
return this; return this;
} }

View File

@ -310,6 +310,7 @@ declare class String {
padEnd(targetLength: i32, padString?: string): string; padEnd(targetLength: i32, padString?: string): string;
replace(search: string, replacement: string): string; replace(search: string, replacement: string): string;
repeat(count?: i32): string; repeat(count?: i32): string;
split(separator?: string, limit?: i32): string[];
toString(): string; toString(): string;
} }

View File

@ -132,7 +132,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 16) (i32.const 16)
(i32.const 239) (i32.const 244)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)

View File

@ -225,7 +225,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 16) (i32.const 16)
(i32.const 239) (i32.const 244)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)

View File

@ -7930,7 +7930,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 1616) (i32.const 1616)
(i32.const 106) (i32.const 110)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)
@ -8104,7 +8104,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 1616) (i32.const 1616)
(i32.const 264) (i32.const 269)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)

View File

@ -12670,7 +12670,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 1616) (i32.const 1616)
(i32.const 54) (i32.const 58)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)
@ -12764,7 +12764,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 1616) (i32.const 1616)
(i32.const 106) (i32.const 110)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)
@ -13051,7 +13051,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 1616) (i32.const 1616)
(i32.const 264) (i32.const 269)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)

View File

@ -13,6 +13,8 @@
(global $~lib/internal/allocator/AL_SIZE i32 (i32.const 8)) (global $~lib/internal/allocator/AL_SIZE i32 (i32.const 8))
(global $~lib/internal/allocator/AL_MASK i32 (i32.const 7)) (global $~lib/internal/allocator/AL_MASK i32 (i32.const 7))
(global $~lib/internal/allocator/MAX_SIZE_32 i32 (i32.const 1073741824)) (global $~lib/internal/allocator/MAX_SIZE_32 i32 (i32.const 1073741824))
(global $~lib/internal/arraybuffer/HEADER_SIZE i32 (i32.const 8))
(global $~lib/internal/arraybuffer/MAX_BLENGTH i32 (i32.const 1073741816))
(global $~lib/internal/string/HEADER_SIZE i32 (i32.const 4)) (global $~lib/internal/string/HEADER_SIZE i32 (i32.const 4))
(global $~lib/internal/string/MAX_LENGTH i32 (i32.const 536870910)) (global $~lib/internal/string/MAX_LENGTH i32 (i32.const 536870910))
(global $~lib/internal/hash/FNV_OFFSET i32 (i32.const -2128831035)) (global $~lib/internal/hash/FNV_OFFSET i32 (i32.const -2128831035))

View File

@ -2365,7 +2365,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 450) (i32.const 510)
(i32.const 8) (i32.const 8)
) )
(unreachable) (unreachable)
@ -2440,7 +2440,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 454) (i32.const 514)
(i32.const 8) (i32.const 8)
) )
(unreachable) (unreachable)
@ -2559,7 +2559,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 466) (i32.const 526)
(i32.const 8) (i32.const 8)
) )
(unreachable) (unreachable)
@ -2645,7 +2645,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 475) (i32.const 535)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)

View File

@ -2911,7 +2911,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 450) (i32.const 510)
(i32.const 8) (i32.const 8)
) )
(unreachable) (unreachable)
@ -2988,7 +2988,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 454) (i32.const 514)
(i32.const 8) (i32.const 8)
) )
(unreachable) (unreachable)
@ -3132,7 +3132,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 466) (i32.const 526)
(i32.const 8) (i32.const 8)
) )
(unreachable) (unreachable)
@ -3225,7 +3225,7 @@
(call $~lib/env/abort (call $~lib/env/abort
(i32.const 0) (i32.const 0)
(i32.const 72) (i32.const 72)
(i32.const 475) (i32.const 535)
(i32.const 4) (i32.const 4)
) )
(unreachable) (unreachable)

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,8 @@ assert("abc".padEnd(8, "abc") == "abcabcab");
assert("".indexOf("") == 0); assert("".indexOf("") == 0);
assert("".indexOf("hi") == -1); assert("".indexOf("hi") == -1);
assert("a".indexOf("a") == 0);
assert(str.indexOf(str) == 0);
assert(str.indexOf("") == 0); assert(str.indexOf("") == 0);
assert(str.indexOf(",") == 2); assert(str.indexOf(",") == 2);
assert(str.indexOf("x") == -1); assert(str.indexOf("x") == -1);
@ -131,6 +133,41 @@ assert("a".repeat(5) == "aaaaa");
assert("a".repeat(6) == "aaaaaa"); assert("a".repeat(6) == "aaaaaa");
assert("a".repeat(7) == "aaaaaaa"); assert("a".repeat(7) == "aaaaaaa");
var sa: string[];
sa = "".split();
assert(sa.length == 1 && sa[0] == "");
sa = "".split("");
assert(sa.length == 0);
sa = "".split(",");
assert(sa.length == 1 && sa[0] == "");
sa = "a,b,c".split(".");
assert(sa.length == 1 && sa[0] == "a,b,c");
sa = "a,b,c".split(",");
assert(sa.length == 3 && sa[0] == "a" && sa[1] == "b" && sa[2] == "c");
sa = "a, b, c".split(", ");
assert(sa.length == 3 && sa[0] == "a" && sa[1] == "b" && sa[2] == "c");
sa = "a,b,,c".split(",");
assert(sa.length == 4 && sa[0] == "a" && sa[1] == "b" && sa[2] == "" && sa[3] == "c");
sa = ",a,b,c".split(",");
assert(sa.length == 4 && sa[0] == "" && sa[1] == "a" && sa[2] == "b" && sa[3] == "c");
sa = "a,b,c,".split(",");
assert(sa.length == 4 && sa[0] == "a" && sa[1] == "b" && sa[2] == "c" && sa[3] == "");
sa = "abc".split("");
assert(sa.length == 3 && sa[0] == "a" && sa[1] == "b" && sa[2] == "c");
sa = "abc".split("", 0);
assert(sa.length == 0);
sa = "abc".split("", 1);
assert(sa.length == 1 && sa[0] == "a");
sa = "a,b,c".split(",", 1);
assert(sa.length == 1 && sa[0] == "a");
sa = "abc".split("", 4);
assert(sa.length == 3 && sa[0] == "a" && sa[1] == "b" && sa[2] == "c");
sa = "abc".split("", -1);
assert(sa.length == 3 && sa[0] == "a" && sa[1] == "b" && sa[2] == "c");
sa = "a,b,c".split(",", -1);
assert(sa.length == 3 && sa[0] == "a" && sa[1] == "b" && sa[2] == "c");
assert(itoa32(0) == "0"); assert(itoa32(0) == "0");
assert(itoa32(1) == "1"); assert(itoa32(1) == "1");
assert(itoa32(8) == "8"); assert(itoa32(8) == "8");

File diff suppressed because it is too large Load Diff