@grain/stdlib 0.5.3 β 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/array.gr +5 -0
- package/array.md +30 -0
- package/char.gr +2 -2
- package/immutablemap.gr +493 -0
- package/immutablemap.md +479 -0
- package/immutablepriorityqueue.gr +33 -5
- package/immutablepriorityqueue.md +44 -1
- package/immutableset.gr +498 -0
- package/immutableset.md +449 -0
- package/list.gr +2 -2
- package/marshal.gr +4 -4
- package/number.gr +648 -23
- package/number.md +284 -24
- package/package.json +1 -1
- package/priorityqueue.gr +25 -5
- package/priorityqueue.md +30 -0
- package/queue.gr +14 -1
- package/queue.md +16 -1
- package/regex.gr +85 -62
- package/runtime/bigint.gr +4 -4
- package/runtime/compare.gr +2 -1
- package/runtime/equal.gr +2 -1
- package/runtime/exception.gr +9 -5
- package/runtime/exception.md +8 -2
- package/runtime/gc.gr +2 -1
- package/runtime/malloc.gr +1 -3
- package/runtime/numberUtils.gr +11 -11
- package/runtime/numbers.gr +120 -36
- package/runtime/numbers.md +26 -0
- package/runtime/string.gr +4 -2
- package/set.gr +25 -25
- package/stack.gr +12 -0
- package/stack.md +15 -0
- package/string.gr +312 -38
- package/string.md +99 -0
- package/sys/file.gr +1 -1
package/string.gr
CHANGED
|
@@ -872,6 +872,239 @@ export let endsWith = (search: String, string: String) => {
|
|
|
872
872
|
}
|
|
873
873
|
}
|
|
874
874
|
|
|
875
|
+
/**
|
|
876
|
+
* Replaces the first appearance of the search pattern in the string with the replacement value.
|
|
877
|
+
*
|
|
878
|
+
* @param searchPattern: The string to replace
|
|
879
|
+
* @param replacement: The replacement
|
|
880
|
+
* @param string: The string to change
|
|
881
|
+
* @returns A new string with the first occurrence of the search pattern replaced
|
|
882
|
+
*
|
|
883
|
+
* @example String.replaceFirst("πΎ", "π", "Hello πΎπΎ") == "Hello ππΎ"
|
|
884
|
+
*
|
|
885
|
+
* @since v0.5.4
|
|
886
|
+
*/
|
|
887
|
+
@unsafe
|
|
888
|
+
export let replaceFirst =
|
|
889
|
+
(
|
|
890
|
+
searchPattern: String,
|
|
891
|
+
replacement: String,
|
|
892
|
+
string: String,
|
|
893
|
+
) => {
|
|
894
|
+
let (+) = WasmI32.add
|
|
895
|
+
let (-) = WasmI32.sub
|
|
896
|
+
let (>) = WasmI32.gtU
|
|
897
|
+
let (<) = WasmI32.ltU
|
|
898
|
+
let (==) = WasmI32.eq
|
|
899
|
+
|
|
900
|
+
let mut patternPtr = WasmI32.fromGrain(searchPattern)
|
|
901
|
+
let mut stringPtr = WasmI32.fromGrain(string)
|
|
902
|
+
let mut replacementPtr = WasmI32.fromGrain(replacement)
|
|
903
|
+
|
|
904
|
+
let patternLen = WasmI32.load(patternPtr, 4n)
|
|
905
|
+
let stringLen = WasmI32.load(stringPtr, 4n)
|
|
906
|
+
let replacementLen = WasmI32.load(replacementPtr, 4n)
|
|
907
|
+
// Bail if search str is longer than the string
|
|
908
|
+
if (stringLen < patternLen) {
|
|
909
|
+
string
|
|
910
|
+
} else {
|
|
911
|
+
patternPtr += 8n
|
|
912
|
+
stringPtr += 8n
|
|
913
|
+
replacementPtr += 8n
|
|
914
|
+
|
|
915
|
+
let mut found = false
|
|
916
|
+
// Search for an instance of the string
|
|
917
|
+
let mut foundIndex = -1n
|
|
918
|
+
let stringEndPtr = stringPtr + stringLen - patternLen + 1n
|
|
919
|
+
for (let mut i = stringPtr; i < stringEndPtr; i += 1n) {
|
|
920
|
+
// check for match
|
|
921
|
+
foundIndex += 1n
|
|
922
|
+
if (Memory.compare(i, patternPtr, patternLen) == 0n) {
|
|
923
|
+
found = true
|
|
924
|
+
break
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
if (found) {
|
|
928
|
+
// Create the new string
|
|
929
|
+
let str = allocateString(stringLen - patternLen + replacementLen)
|
|
930
|
+
let strPtr = str + 8n
|
|
931
|
+
Memory.copy(strPtr, stringPtr, foundIndex)
|
|
932
|
+
Memory.copy(strPtr + foundIndex, replacementPtr, replacementLen)
|
|
933
|
+
Memory.copy(
|
|
934
|
+
strPtr + foundIndex + replacementLen,
|
|
935
|
+
stringPtr + foundIndex + patternLen,
|
|
936
|
+
stringLen - foundIndex
|
|
937
|
+
)
|
|
938
|
+
// Copy over the str
|
|
939
|
+
WasmI32.toGrain(str): String
|
|
940
|
+
} else {
|
|
941
|
+
string
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* Replaces the last appearance of the search pattern in the string with the replacement value.
|
|
948
|
+
*
|
|
949
|
+
* @param searchPattern: The string to replace
|
|
950
|
+
* @param replacement: The replacement
|
|
951
|
+
* @param string: The string to change
|
|
952
|
+
* @returns A new string with the last occurrence of the search pattern replaced
|
|
953
|
+
*
|
|
954
|
+
* @example String.replaceLast("πΎ", "π", "Hello πΎπΎ") == "Hello πΎπ"
|
|
955
|
+
*
|
|
956
|
+
* @since v0.5.4
|
|
957
|
+
*/
|
|
958
|
+
@unsafe
|
|
959
|
+
export let replaceLast =
|
|
960
|
+
(
|
|
961
|
+
searchPattern: String,
|
|
962
|
+
replacement: String,
|
|
963
|
+
string: String,
|
|
964
|
+
) => {
|
|
965
|
+
let (+) = WasmI32.add
|
|
966
|
+
let (-) = WasmI32.sub
|
|
967
|
+
let (>) = WasmI32.gtU
|
|
968
|
+
let (<) = WasmI32.ltU
|
|
969
|
+
let (==) = WasmI32.eq
|
|
970
|
+
|
|
971
|
+
let mut patternPtr = WasmI32.fromGrain(searchPattern)
|
|
972
|
+
let mut stringPtr = WasmI32.fromGrain(string)
|
|
973
|
+
let mut replacementPtr = WasmI32.fromGrain(replacement)
|
|
974
|
+
|
|
975
|
+
let patternLen = WasmI32.load(patternPtr, 4n)
|
|
976
|
+
let stringLen = WasmI32.load(stringPtr, 4n)
|
|
977
|
+
let replacementLen = WasmI32.load(replacementPtr, 4n)
|
|
978
|
+
|
|
979
|
+
// Bail if search str is longer than the string
|
|
980
|
+
if (stringLen < patternLen) {
|
|
981
|
+
string
|
|
982
|
+
} else {
|
|
983
|
+
patternPtr += 8n
|
|
984
|
+
stringPtr += 8n
|
|
985
|
+
replacementPtr += 8n
|
|
986
|
+
|
|
987
|
+
let mut found = false
|
|
988
|
+
// Search for an instance of the string
|
|
989
|
+
let stringEndPtr = stringPtr + stringLen - patternLen
|
|
990
|
+
let mut foundIndex = stringLen - patternLen + 1n
|
|
991
|
+
for (let mut i = stringEndPtr; i > stringPtr - 1n; i -= 1n) {
|
|
992
|
+
// check for match
|
|
993
|
+
foundIndex -= 1n
|
|
994
|
+
if (Memory.compare(i, patternPtr, patternLen) == 0n) {
|
|
995
|
+
found = true
|
|
996
|
+
break
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
if (found) {
|
|
1000
|
+
// Create the new string
|
|
1001
|
+
let str = allocateString(stringLen - patternLen + replacementLen)
|
|
1002
|
+
let strPtr = str + 8n
|
|
1003
|
+
Memory.copy(strPtr, stringPtr, foundIndex)
|
|
1004
|
+
Memory.copy(strPtr + foundIndex, replacementPtr, replacementLen)
|
|
1005
|
+
Memory.copy(
|
|
1006
|
+
strPtr + foundIndex + replacementLen,
|
|
1007
|
+
stringPtr + foundIndex + patternLen,
|
|
1008
|
+
stringLen - foundIndex
|
|
1009
|
+
)
|
|
1010
|
+
// Copy over the str
|
|
1011
|
+
WasmI32.toGrain(str): String
|
|
1012
|
+
} else {
|
|
1013
|
+
string
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
/**
|
|
1019
|
+
* Replaces every appearance of the search pattern in the string with the replacement value.
|
|
1020
|
+
*
|
|
1021
|
+
* @param searchPattern: The string to replace
|
|
1022
|
+
* @param replacement: The replacement
|
|
1023
|
+
* @param string: The string to change
|
|
1024
|
+
* @returns A new string with each occurrence of the search pattern replaced
|
|
1025
|
+
*
|
|
1026
|
+
* @example String.replaceAll("πΎ", "π", "Hello πΎπΎ") == "Hello ππ"
|
|
1027
|
+
*
|
|
1028
|
+
* @since v0.5.4
|
|
1029
|
+
*/
|
|
1030
|
+
@unsafe
|
|
1031
|
+
export let replaceAll =
|
|
1032
|
+
(
|
|
1033
|
+
searchPattern: String,
|
|
1034
|
+
replacement: String,
|
|
1035
|
+
string: String,
|
|
1036
|
+
) => {
|
|
1037
|
+
let (*) = WasmI32.mul
|
|
1038
|
+
let (+) = WasmI32.add
|
|
1039
|
+
let (-) = WasmI32.sub
|
|
1040
|
+
let (>) = WasmI32.gtU
|
|
1041
|
+
let (<) = WasmI32.ltU
|
|
1042
|
+
let (==) = WasmI32.eq
|
|
1043
|
+
let (>>) = WasmI32.shrS
|
|
1044
|
+
|
|
1045
|
+
let mut patternPtr = WasmI32.fromGrain(searchPattern)
|
|
1046
|
+
let mut stringPtr = WasmI32.fromGrain(string)
|
|
1047
|
+
let mut replacementPtr = WasmI32.fromGrain(replacement)
|
|
1048
|
+
|
|
1049
|
+
let patternLen = WasmI32.load(patternPtr, 4n)
|
|
1050
|
+
let stringLen = WasmI32.load(stringPtr, 4n)
|
|
1051
|
+
let replacementLen = WasmI32.load(replacementPtr, 4n)
|
|
1052
|
+
|
|
1053
|
+
// Bail if search str is longer than the string
|
|
1054
|
+
if (stringLen < patternLen) {
|
|
1055
|
+
string
|
|
1056
|
+
} else {
|
|
1057
|
+
patternPtr += 8n
|
|
1058
|
+
stringPtr += 8n
|
|
1059
|
+
replacementPtr += 8n
|
|
1060
|
+
|
|
1061
|
+
let mut found = false
|
|
1062
|
+
// Search for an instance of the string
|
|
1063
|
+
let stringEndPtr = stringPtr + stringLen - patternLen
|
|
1064
|
+
let mut foundIndex = stringLen - patternLen + 1n
|
|
1065
|
+
let mut foundIndexes = []
|
|
1066
|
+
let mut foundCount = 0n
|
|
1067
|
+
for (let mut i = stringEndPtr; i > stringPtr - 1n; i -= 1n) {
|
|
1068
|
+
// check for match
|
|
1069
|
+
foundIndex -= 1n
|
|
1070
|
+
if (Memory.compare(i, patternPtr, patternLen) == 0n) {
|
|
1071
|
+
found = true
|
|
1072
|
+
foundCount += 1n
|
|
1073
|
+
foundIndexes = [tagSimpleNumber(foundIndex), ...foundIndexes]
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
if (found) {
|
|
1077
|
+
// Create the new string
|
|
1078
|
+
let str = allocateString(
|
|
1079
|
+
stringLen - (patternLen - replacementLen) * foundCount
|
|
1080
|
+
)
|
|
1081
|
+
let mut strPtr = str + 8n
|
|
1082
|
+
let mut lastIndex = 0n
|
|
1083
|
+
while (true) {
|
|
1084
|
+
match (foundIndexes) {
|
|
1085
|
+
[idx, ...rest] => {
|
|
1086
|
+
let index = untagSimpleNumber(idx)
|
|
1087
|
+
// Copy the part before
|
|
1088
|
+
Memory.copy(strPtr, stringPtr + lastIndex, index - lastIndex)
|
|
1089
|
+
strPtr += index - lastIndex
|
|
1090
|
+
// Copy the part after
|
|
1091
|
+
Memory.copy(strPtr, replacementPtr, replacementLen)
|
|
1092
|
+
strPtr += replacementLen
|
|
1093
|
+
lastIndex = index + patternLen
|
|
1094
|
+
foundIndexes = rest
|
|
1095
|
+
},
|
|
1096
|
+
[] => break,
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
// Copy remaining string
|
|
1100
|
+
Memory.copy(strPtr, stringPtr + lastIndex, stringLen - lastIndex)
|
|
1101
|
+
WasmI32.toGrain(str): String
|
|
1102
|
+
} else {
|
|
1103
|
+
string
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
875
1108
|
// String->Byte encoding and helper functions:
|
|
876
1109
|
|
|
877
1110
|
// these are globals to avoid memory leaks
|
|
@@ -1349,33 +1582,33 @@ let bytesHaveBom = (bytes: Bytes, encoding: Encoding, start: WasmI32) => {
|
|
|
1349
1582
|
match (encoding) {
|
|
1350
1583
|
UTF8 => {
|
|
1351
1584
|
bytesSize >= 3n &&
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1585
|
+
WasmI32.load8U(ptr, _BYTES_OFFSET) == 0xEFn &&
|
|
1586
|
+
WasmI32.load8U(ptr + 1n, _BYTES_OFFSET) == 0xBBn &&
|
|
1587
|
+
WasmI32.load8U(ptr + 2n, _BYTES_OFFSET) == 0xBFn
|
|
1355
1588
|
},
|
|
1356
1589
|
UTF16_BE => {
|
|
1357
1590
|
bytesSize >= 2n &&
|
|
1358
|
-
|
|
1359
|
-
|
|
1591
|
+
WasmI32.load8U(ptr, _BYTES_OFFSET) == 0xFEn &&
|
|
1592
|
+
WasmI32.load8U(ptr + 1n, _BYTES_OFFSET) == 0xFFn
|
|
1360
1593
|
},
|
|
1361
1594
|
UTF16_LE => {
|
|
1362
1595
|
bytesSize >= 2n &&
|
|
1363
|
-
|
|
1364
|
-
|
|
1596
|
+
WasmI32.load8U(ptr, _BYTES_OFFSET) == 0xFFn &&
|
|
1597
|
+
WasmI32.load8U(ptr + 1n, _BYTES_OFFSET) == 0xFEn
|
|
1365
1598
|
},
|
|
1366
1599
|
UTF32_BE => {
|
|
1367
1600
|
bytesSize >= 4n &&
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1601
|
+
WasmI32.load8U(ptr, _BYTES_OFFSET) == 0x00n &&
|
|
1602
|
+
WasmI32.load8U(ptr + 1n, _BYTES_OFFSET) == 0x00n &&
|
|
1603
|
+
WasmI32.load8U(ptr + 2n, _BYTES_OFFSET) == 0xFEn &&
|
|
1604
|
+
WasmI32.load8U(ptr + 3n, _BYTES_OFFSET) == 0xFFn
|
|
1372
1605
|
},
|
|
1373
1606
|
UTF32_LE => {
|
|
1374
1607
|
bytesSize >= 4n &&
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1608
|
+
WasmI32.load8U(ptr, _BYTES_OFFSET) == 0xFFn &&
|
|
1609
|
+
WasmI32.load8U(ptr + 1n, _BYTES_OFFSET) == 0xFEn &&
|
|
1610
|
+
WasmI32.load8U(ptr + 2n, _BYTES_OFFSET) == 0x00n &&
|
|
1611
|
+
WasmI32.load8U(ptr + 3n, _BYTES_OFFSET) == 0x00n
|
|
1379
1612
|
},
|
|
1380
1613
|
}
|
|
1381
1614
|
}
|
|
@@ -1612,7 +1845,7 @@ let decodeRangeHelp =
|
|
|
1612
1845
|
// high surrogate. next character is low srurrogate
|
|
1613
1846
|
let w1 = (w1 & 0x03FFn) << 10n
|
|
1614
1847
|
let w2 = (WasmI32.load8U(bytesPtr, 2n) << 8n |
|
|
1615
|
-
|
|
1848
|
+
WasmI32.load8U(bytesPtr, 3n)) &
|
|
1616
1849
|
0x03FFn
|
|
1617
1850
|
let codeWord = w1 + w2 + 0x10000n
|
|
1618
1851
|
// no problems, so go past both code words
|
|
@@ -1635,7 +1868,7 @@ let decodeRangeHelp =
|
|
|
1635
1868
|
// high surrogate. next character is low srurrogate
|
|
1636
1869
|
let w1 = (w1 & 0x03FFn) << 10n
|
|
1637
1870
|
let w2 = (WasmI32.load8U(bytesPtr, 3n) << 8n |
|
|
1638
|
-
|
|
1871
|
+
WasmI32.load8U(bytesPtr, 2n)) &
|
|
1639
1872
|
0x03FFn
|
|
1640
1873
|
//let uPrime = codePoint - 0x10000n
|
|
1641
1874
|
//let w1 = ((uPrime & 0b11111111110000000000n) >>> 10n) + 0xD800n // High surrogate
|
|
@@ -1867,30 +2100,71 @@ export let forEachCodePointi = (fn: (Number, Number) -> Void, str: String) => {
|
|
|
1867
2100
|
void
|
|
1868
2101
|
}
|
|
1869
2102
|
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
let
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
2103
|
+
@unsafe
|
|
2104
|
+
let trimString = (str: String, fromEnd: Bool) => {
|
|
2105
|
+
let (>>>) = WasmI32.shrU
|
|
2106
|
+
let (+) = WasmI32.add
|
|
2107
|
+
let (*) = WasmI32.mul
|
|
2108
|
+
let (-) = WasmI32.sub
|
|
2109
|
+
let (<) = WasmI32.ltU
|
|
2110
|
+
let (==) = WasmI32.eq
|
|
2111
|
+
let (!=) = WasmI32.ne
|
|
2112
|
+
|
|
2113
|
+
let mut stringPtr = WasmI32.fromGrain(str)
|
|
2114
|
+
let byteLength = WasmI32.load(stringPtr, 4n)
|
|
2115
|
+
stringPtr += 8n
|
|
2116
|
+
let mut i = 0n, offset = 1n
|
|
2117
|
+
if (fromEnd) {
|
|
2118
|
+
i = byteLength - 1n
|
|
2119
|
+
offset = -1n
|
|
1876
2120
|
}
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
//
|
|
2121
|
+
let mut count = 0n
|
|
2122
|
+
for (; i < byteLength; i += offset) {
|
|
2123
|
+
// Get the byte, not necessarily a full UTF-8 codepoint
|
|
2124
|
+
let byte = WasmI32.load8U(stringPtr, i)
|
|
2125
|
+
// TODO(#661): Use unicode whitespace property and unicode line terminator
|
|
2126
|
+
if (!fromEnd) {
|
|
2127
|
+
if (
|
|
2128
|
+
byte == 0xEFn && // Check for the first BOM byte
|
|
2129
|
+
// Check for the full BOM codepoint, 0xEFBBBF. Bytes are reversed because wasm is little-endian
|
|
2130
|
+
WasmI32.load(stringPtr, i - 1n) >>> 8n == 0xBFBBEFn
|
|
2131
|
+
) {
|
|
2132
|
+
i += 2n
|
|
2133
|
+
count += 3n
|
|
2134
|
+
continue
|
|
2135
|
+
}
|
|
2136
|
+
} else {
|
|
2137
|
+
if (
|
|
2138
|
+
byte == 0xBFn && // Check for the last BOM byte
|
|
2139
|
+
// Check for the full BOM codepoint, 0xEFBBBF. Bytes are reversed because wasm is little-endian
|
|
2140
|
+
WasmI32.load(stringPtr, i - 3n) >>> 8n == 0xBFBBEFn
|
|
2141
|
+
) {
|
|
2142
|
+
i -= 2n
|
|
2143
|
+
count += 3n
|
|
2144
|
+
continue
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
1880
2147
|
if (
|
|
1881
|
-
//
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
2148
|
+
byte != 0x20n && // Space
|
|
2149
|
+
byte != 0x0Dn && // LF
|
|
2150
|
+
byte != 0x0An && // CR
|
|
2151
|
+
byte != 0x09n && // Tab
|
|
2152
|
+
byte != 0x0Bn && // LINE TABULATION
|
|
2153
|
+
byte != 0x0Cn && // FORM FEED (FF)
|
|
2154
|
+
byte != 0xA0n // No Break Space
|
|
2155
|
+
) {
|
|
2156
|
+
break
|
|
2157
|
+
}
|
|
2158
|
+
count += 1n
|
|
1892
2159
|
}
|
|
1893
|
-
|
|
2160
|
+
let str = allocateString(byteLength - count)
|
|
2161
|
+
// Copy the string
|
|
2162
|
+
if (fromEnd) {
|
|
2163
|
+
Memory.copy(str + 8n, stringPtr, byteLength - count)
|
|
2164
|
+
} else {
|
|
2165
|
+
Memory.copy(str + 8n, stringPtr + count, byteLength - count)
|
|
2166
|
+
}
|
|
2167
|
+
WasmI32.toGrain(str): String
|
|
1894
2168
|
}
|
|
1895
2169
|
/**
|
|
1896
2170
|
* Trims the beginning of a stringβremoving any leading whitespace characters.
|
package/string.md
CHANGED
|
@@ -514,6 +514,105 @@ Examples:
|
|
|
514
514
|
String.endsWith("world", "Hello world") == true
|
|
515
515
|
```
|
|
516
516
|
|
|
517
|
+
### String.**replaceFirst**
|
|
518
|
+
|
|
519
|
+
<details disabled>
|
|
520
|
+
<summary tabindex="-1">Added in <code>0.5.4</code></summary>
|
|
521
|
+
No other changes yet.
|
|
522
|
+
</details>
|
|
523
|
+
|
|
524
|
+
```grain
|
|
525
|
+
replaceFirst : (String, String, String) -> String
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Replaces the first appearance of the search pattern in the string with the replacement value.
|
|
529
|
+
|
|
530
|
+
Parameters:
|
|
531
|
+
|
|
532
|
+
|param|type|description|
|
|
533
|
+
|-----|----|-----------|
|
|
534
|
+
|`searchPattern`|`String`|The string to replace|
|
|
535
|
+
|`replacement`|`String`|The replacement|
|
|
536
|
+
|`string`|`String`|The string to change|
|
|
537
|
+
|
|
538
|
+
Returns:
|
|
539
|
+
|
|
540
|
+
|type|description|
|
|
541
|
+
|----|-----------|
|
|
542
|
+
|`String`|A new string with the first occurrence of the search pattern replaced|
|
|
543
|
+
|
|
544
|
+
Examples:
|
|
545
|
+
|
|
546
|
+
```grain
|
|
547
|
+
String.replaceFirst("πΎ", "π", "Hello πΎπΎ") == "Hello ππΎ"
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### String.**replaceLast**
|
|
551
|
+
|
|
552
|
+
<details disabled>
|
|
553
|
+
<summary tabindex="-1">Added in <code>0.5.4</code></summary>
|
|
554
|
+
No other changes yet.
|
|
555
|
+
</details>
|
|
556
|
+
|
|
557
|
+
```grain
|
|
558
|
+
replaceLast : (String, String, String) -> String
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
Replaces the last appearance of the search pattern in the string with the replacement value.
|
|
562
|
+
|
|
563
|
+
Parameters:
|
|
564
|
+
|
|
565
|
+
|param|type|description|
|
|
566
|
+
|-----|----|-----------|
|
|
567
|
+
|`searchPattern`|`String`|The string to replace|
|
|
568
|
+
|`replacement`|`String`|The replacement|
|
|
569
|
+
|`string`|`String`|The string to change|
|
|
570
|
+
|
|
571
|
+
Returns:
|
|
572
|
+
|
|
573
|
+
|type|description|
|
|
574
|
+
|----|-----------|
|
|
575
|
+
|`String`|A new string with the last occurrence of the search pattern replaced|
|
|
576
|
+
|
|
577
|
+
Examples:
|
|
578
|
+
|
|
579
|
+
```grain
|
|
580
|
+
String.replaceLast("πΎ", "π", "Hello πΎπΎ") == "Hello πΎπ"
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### String.**replaceAll**
|
|
584
|
+
|
|
585
|
+
<details disabled>
|
|
586
|
+
<summary tabindex="-1">Added in <code>0.5.4</code></summary>
|
|
587
|
+
No other changes yet.
|
|
588
|
+
</details>
|
|
589
|
+
|
|
590
|
+
```grain
|
|
591
|
+
replaceAll : (String, String, String) -> String
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
Replaces every appearance of the search pattern in the string with the replacement value.
|
|
595
|
+
|
|
596
|
+
Parameters:
|
|
597
|
+
|
|
598
|
+
|param|type|description|
|
|
599
|
+
|-----|----|-----------|
|
|
600
|
+
|`searchPattern`|`String`|The string to replace|
|
|
601
|
+
|`replacement`|`String`|The replacement|
|
|
602
|
+
|`string`|`String`|The string to change|
|
|
603
|
+
|
|
604
|
+
Returns:
|
|
605
|
+
|
|
606
|
+
|type|description|
|
|
607
|
+
|----|-----------|
|
|
608
|
+
|`String`|A new string with each occurrence of the search pattern replaced|
|
|
609
|
+
|
|
610
|
+
Examples:
|
|
611
|
+
|
|
612
|
+
```grain
|
|
613
|
+
String.replaceAll("πΎ", "π", "Hello πΎπΎ") == "Hello ππ"
|
|
614
|
+
```
|
|
615
|
+
|
|
517
616
|
### String.**encodeAt**
|
|
518
617
|
|
|
519
618
|
<details disabled>
|
package/sys/file.gr
CHANGED
|
@@ -816,7 +816,7 @@ export let fdStats = (fd: FileDescriptor) => {
|
|
|
816
816
|
let rightsInheriting = WasmI64.load(structPtr, 16n)
|
|
817
817
|
(rightsInheriting &
|
|
818
818
|
1N << WasmI64.extendI32U(WasmI32.fromGrain(i) >> 1n)) >
|
|
819
|
-
|
|
819
|
+
0N
|
|
820
820
|
}
|
|
821
821
|
let rightsInheritingList = List.filteri(flagsToWasmVal, orderedRights)
|
|
822
822
|
|