Skip to content

Commit 454e9e6

Browse files
MaxGraeydcodeIO
authored andcommitted
Add basic String#localeCompare (#1008)
1 parent b6d2771 commit 454e9e6

File tree

8 files changed

+2577
-2202
lines changed

8 files changed

+2577
-2202
lines changed

std/assembly/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,6 +1417,7 @@ declare class String {
14171417
endsWith(other: string): bool;
14181418
indexOf(other: string, fromIndex?: i32): i32;
14191419
lastIndexOf(other: string, fromIndex?: i32): i32;
1420+
localeCompare(other: string): i32;
14201421
includes(other: string): bool;
14211422
startsWith(other: string): bool;
14221423
substr(start: i32, length?: i32): string;

std/assembly/string.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,8 @@ import { idof } from "./builtins";
108108
@operator(">") private static __gt(left: String | null, right: String | null): bool {
109109
if (left === right || left === null || right === null) return false;
110110
var leftLength = left.length;
111+
if (!leftLength) return false;
111112
var rightLength = right.length;
112-
if (!leftLength) return false;
113113
if (!rightLength) return true;
114114
// @ts-ignore: string <-> String
115115
return compareImpl(left, 0, right, 0, min(leftLength, rightLength)) > 0;
@@ -121,10 +121,10 @@ import { idof } from "./builtins";
121121

122122
@operator("<") private static __lt(left: String, right: String): bool {
123123
if (left === right || left === null || right === null) return false;
124-
var leftLength = left.length;
125124
var rightLength = right.length;
126125
if (!rightLength) return false;
127-
if (!leftLength) return true;
126+
var leftLength = left.length;
127+
if (!leftLength) return true;
128128
// @ts-ignore: string <-> String
129129
return compareImpl(left, 0, right, 0, min(leftLength, rightLength)) < 0;
130130
}
@@ -163,6 +163,17 @@ import { idof } from "./builtins";
163163
return -1;
164164
}
165165

166+
// TODO: implement full locale comparison with locales and Collator options
167+
localeCompare(other: String): i32 {
168+
if (other === this) return 0; // compare pointers
169+
var len: isize = this.length;
170+
var otherLen: isize = other.length;
171+
if (otherLen != len) return select(1, -1, len > otherLen);
172+
if (!otherLen) return 0; // "" == ""
173+
// @ts-ignore: string <-> String
174+
return compareImpl(this, 0, other, 0, otherLen);
175+
}
176+
166177
startsWith(search: String, start: i32 = 0): bool {
167178
if (search === null) search = changetype<String>("null");
168179
var len = <isize>this.length;

std/assembly/util/string.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,13 @@ export function compareImpl(str1: string, index1: usize, str2: string, index2: u
101101
}
102102

103103
export function isSpace(c: i32): bool {
104-
if (c <= 0xFF) {
104+
if (c < 0x1680) { // < <LS> (1)
105105
// <SP>, <TAB>, <LF>, <VT>, <FF>, <CR> and <NBSP>
106-
return c == 0x20 || <u32>(c - 0x09) <= 0x0D - 0x09 || c == 0xA0;
106+
// (c == 0x20 || c == 0xA0) was optimized to (c | 0x80) == 0xA0
107+
// @ts-ignore: cast
108+
return ((c | 0x80) == 0xA0) | (u32(c - 0x09) <= 0x0D - 0x09);
107109
}
108-
if (<u32>(c - 0x2000) <= 0x200A - 0x2000) return true;
110+
if (u32(c - 0x2000) <= 0x200A - 0x2000) return true;
109111
switch (c) {
110112
case 0x1680: // <LS> (1)
111113
case 0x2028: // <LS> (2)

tests/compiler/std/string-encoding.optimized.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,7 +2722,7 @@
27222722
if
27232723
i32.const 0
27242724
i32.const 544
2725-
i32.const 684
2725+
i32.const 695
27262726
i32.const 8
27272727
call $~lib/builtins/abort
27282728
unreachable
@@ -2745,7 +2745,7 @@
27452745
if
27462746
i32.const 0
27472747
i32.const 544
2748-
i32.const 688
2748+
i32.const 699
27492749
i32.const 8
27502750
call $~lib/builtins/abort
27512751
unreachable
@@ -3062,7 +3062,7 @@
30623062
if
30633063
i32.const 0
30643064
i32.const 544
3065-
i32.const 702
3065+
i32.const 713
30663066
i32.const 6
30673067
call $~lib/builtins/abort
30683068
unreachable

tests/compiler/std/string-encoding.untouched.wat

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4453,7 +4453,7 @@
44534453
if
44544454
i32.const 0
44554455
i32.const 544
4456-
i32.const 684
4456+
i32.const 695
44574457
i32.const 8
44584458
call $~lib/builtins/abort
44594459
unreachable
@@ -4477,7 +4477,7 @@
44774477
if
44784478
i32.const 0
44794479
i32.const 544
4480-
i32.const 688
4480+
i32.const 699
44814481
i32.const 8
44824482
call $~lib/builtins/abort
44834483
unreachable
@@ -4833,7 +4833,7 @@
48334833
if
48344834
i32.const 0
48354835
i32.const 544
4836-
i32.const 702
4836+
i32.const 713
48374837
i32.const 6
48384838
call $~lib/builtins/abort
48394839
unreachable

tests/compiler/std/string.optimized.wat

Lines changed: 1223 additions & 1066 deletions
Large diffs are not rendered by default.

tests/compiler/std/string.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,17 @@ assert(str.lastIndexOf(", I", -1) == -1);
7878
assert(str.lastIndexOf("i", 0) == -1);
7979
assert(str.lastIndexOf("hi", 0) == 0);
8080

81+
assert("".localeCompare("") == 0);
82+
assert("a".localeCompare("") == 1);
83+
assert("".localeCompare("a") == -1);
84+
assert("null".localeCompare("null") == 0);
85+
assert("abc".localeCompare("abd") == -1);
86+
assert("abd".localeCompare("abc") == 1);
87+
assert("abcd".localeCompare("abc") == 1);
88+
assert("abc".localeCompare("abcd") == -1);
89+
assert("".localeCompare(" ") == -1);
90+
assert("\0".localeCompare("") == 1);
91+
8192
assert("".trimStart() == "");
8293
assert("ab c".trimStart() == "ab c");
8394
assert(" \n\t\rabc \t\r ".trimStart() == "abc \t\r ");

tests/compiler/std/string.untouched.wat

Lines changed: 1317 additions & 1124 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)