@grain/stdlib 0.6.3 → 0.6.5
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 +21 -0
- package/LICENSE +1 -1
- package/array.gr +2 -0
- package/bytes.gr +38 -7
- package/float32.gr +68 -0
- package/float32.md +164 -0
- package/float64.gr +87 -16
- package/float64.md +164 -0
- package/hash.gr +2 -0
- package/int16.gr +85 -0
- package/int16.md +168 -0
- package/int32.gr +107 -0
- package/int32.md +235 -0
- package/int64.gr +107 -0
- package/int64.md +235 -0
- package/int8.gr +1 -1
- package/int8.md +1 -1
- package/map.gr +3 -2
- package/package.json +1 -1
- package/pervasives.md +10 -3
- package/runtime/malloc.gr +269 -135
- package/runtime/malloc.md +3 -10
- package/runtime/numbers.gr +181 -100
- package/runtime/string.gr +1 -0
- package/runtime/string.md +10 -3
- package/set.gr +0 -5
- package/string.gr +291 -72
- package/string.md +108 -0
- package/wasi/file.gr +5 -0
- package/wasi/process.gr +2 -1
package/string.gr
CHANGED
|
@@ -64,11 +64,11 @@ provide let concat = (++)
|
|
|
64
64
|
@unsafe
|
|
65
65
|
provide let length = (string: String) => {
|
|
66
66
|
use WasmI32.{ (+), (&), (!=) }
|
|
67
|
-
let
|
|
68
|
-
let size = WasmI32.load(
|
|
67
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
68
|
+
let size = WasmI32.load(stringPtr, 4n)
|
|
69
69
|
|
|
70
70
|
let mut len = 0n
|
|
71
|
-
let mut ptr =
|
|
71
|
+
let mut ptr = stringPtr + 8n
|
|
72
72
|
let end = ptr + size
|
|
73
73
|
|
|
74
74
|
while (WasmI32.ltU(ptr, end)) {
|
|
@@ -79,6 +79,8 @@ provide let length = (string: String) => {
|
|
|
79
79
|
ptr += 1n
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
ignore(string)
|
|
83
|
+
|
|
82
84
|
Conv.wasmI32ToNumber(len)
|
|
83
85
|
}
|
|
84
86
|
|
|
@@ -94,8 +96,10 @@ provide let length = (string: String) => {
|
|
|
94
96
|
*/
|
|
95
97
|
@unsafe
|
|
96
98
|
provide let byteLength = (string: String) => {
|
|
97
|
-
let
|
|
98
|
-
Conv.wasmI32ToNumber(WasmI32.load(
|
|
99
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
100
|
+
let result = Conv.wasmI32ToNumber(WasmI32.load(stringPtr, 4n))
|
|
101
|
+
ignore(string)
|
|
102
|
+
result
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
/**
|
|
@@ -110,7 +114,9 @@ provide let byteLength = (string: String) => {
|
|
|
110
114
|
provide let isEmpty = (string: String) => {
|
|
111
115
|
use WasmI32.{ (==) }
|
|
112
116
|
let strPtr = WasmI32.fromGrain(string)
|
|
113
|
-
WasmI32.load(strPtr, 4n) == 0n
|
|
117
|
+
let result = WasmI32.load(strPtr, 4n) == 0n
|
|
118
|
+
ignore(string)
|
|
119
|
+
result
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
/**
|
|
@@ -126,19 +132,19 @@ provide let isEmpty = (string: String) => {
|
|
|
126
132
|
*/
|
|
127
133
|
@unsafe
|
|
128
134
|
provide let indexOf = (search: String, string: String) => {
|
|
129
|
-
let
|
|
130
|
-
let
|
|
135
|
+
let searchPtr = WasmI32.fromGrain(search)
|
|
136
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
131
137
|
|
|
132
|
-
let size = WasmI32.load(
|
|
133
|
-
let psize = WasmI32.load(
|
|
138
|
+
let size = WasmI32.load(stringPtr, 4n)
|
|
139
|
+
let psize = WasmI32.load(searchPtr, 4n)
|
|
134
140
|
use WasmI32.{ (+), (-), (&), ltU as (<), gtU as (>), (==) }
|
|
135
141
|
|
|
136
142
|
if (psize > size) {
|
|
137
143
|
return None
|
|
138
144
|
}
|
|
139
145
|
let mut idx = 0n
|
|
140
|
-
let mut ptr =
|
|
141
|
-
let pptr =
|
|
146
|
+
let mut ptr = stringPtr + 8n
|
|
147
|
+
let pptr = searchPtr + 8n
|
|
142
148
|
let end = ptr + size - psize + 1n
|
|
143
149
|
|
|
144
150
|
while (ptr < end) {
|
|
@@ -158,6 +164,9 @@ provide let indexOf = (search: String, string: String) => {
|
|
|
158
164
|
}
|
|
159
165
|
}
|
|
160
166
|
|
|
167
|
+
ignore(search)
|
|
168
|
+
ignore(string)
|
|
169
|
+
|
|
161
170
|
return None
|
|
162
171
|
}
|
|
163
172
|
|
|
@@ -179,16 +188,16 @@ provide let lastIndexOf = (search: String, string: String) => {
|
|
|
179
188
|
|
|
180
189
|
use WasmI32.{ (+), (-), (&), gtU as (>), geU as (>=), (==), (!=) }
|
|
181
190
|
|
|
182
|
-
let
|
|
183
|
-
let
|
|
184
|
-
let searchSize = WasmI32.load(
|
|
185
|
-
let stringSize = WasmI32.load(
|
|
191
|
+
let searchPtr = WasmI32.fromGrain(search)
|
|
192
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
193
|
+
let searchSize = WasmI32.load(searchPtr, 4n)
|
|
194
|
+
let stringSize = WasmI32.load(stringPtr, 4n)
|
|
186
195
|
if (searchSize > stringSize) {
|
|
187
196
|
return None
|
|
188
197
|
}
|
|
189
198
|
let mut stringIndex = untagSimpleNumber(lastIndex)
|
|
190
|
-
let searchPtr =
|
|
191
|
-
let stringStartPtr =
|
|
199
|
+
let searchPtr = searchPtr + 8n
|
|
200
|
+
let stringStartPtr = stringPtr + 8n
|
|
192
201
|
for (
|
|
193
202
|
let mut stringPtr = stringStartPtr + stringSize - searchSize;
|
|
194
203
|
stringPtr >= stringStartPtr;
|
|
@@ -205,6 +214,9 @@ provide let lastIndexOf = (search: String, string: String) => {
|
|
|
205
214
|
stringIndex -= 1n
|
|
206
215
|
}
|
|
207
216
|
|
|
217
|
+
ignore(search)
|
|
218
|
+
ignore(string)
|
|
219
|
+
|
|
208
220
|
return None
|
|
209
221
|
}
|
|
210
222
|
|
|
@@ -268,8 +280,8 @@ let charAtHelp = (position, string: String) => {
|
|
|
268
280
|
use WasmI32.{ (+), (&), (>>>), ltU as (<), (==) }
|
|
269
281
|
let size = WasmI32.fromGrain(byteLength(string)) >>> 1n
|
|
270
282
|
let position = WasmI32.fromGrain(position) >>> 1n
|
|
271
|
-
let
|
|
272
|
-
let mut ptr =
|
|
283
|
+
let stringPre = WasmI32.fromGrain(string)
|
|
284
|
+
let mut ptr = stringPre + 8n
|
|
273
285
|
let end = ptr + size
|
|
274
286
|
let mut counter = 0n
|
|
275
287
|
while (ptr < end) {
|
|
@@ -290,6 +302,8 @@ let charAtHelp = (position, string: String) => {
|
|
|
290
302
|
ptr += n
|
|
291
303
|
}
|
|
292
304
|
|
|
305
|
+
ignore(string)
|
|
306
|
+
|
|
293
307
|
fail "charAt: should be impossible (please report)"
|
|
294
308
|
}
|
|
295
309
|
|
|
@@ -338,9 +352,9 @@ let explodeHelp = (s: String, chars) => {
|
|
|
338
352
|
let size = WasmI32.fromGrain(byteLength(s)) >>> 1n
|
|
339
353
|
let len = WasmI32.fromGrain(length(s)) >>> 1n
|
|
340
354
|
|
|
341
|
-
let
|
|
355
|
+
let sPtr = WasmI32.fromGrain(s)
|
|
342
356
|
|
|
343
|
-
let mut ptr =
|
|
357
|
+
let mut ptr = sPtr + 8n
|
|
344
358
|
let end = ptr + size
|
|
345
359
|
|
|
346
360
|
let arr = allocateArray(len)
|
|
@@ -361,9 +375,9 @@ let explodeHelp = (s: String, chars) => {
|
|
|
361
375
|
let c = if (chars) {
|
|
362
376
|
WasmI32.fromGrain(tagChar(getCodePoint(ptr)))
|
|
363
377
|
} else {
|
|
364
|
-
let
|
|
365
|
-
Memory.copy(
|
|
366
|
-
|
|
378
|
+
let sPtr = allocateString(n)
|
|
379
|
+
Memory.copy(sPtr + 8n, ptr, n)
|
|
380
|
+
sPtr
|
|
367
381
|
}
|
|
368
382
|
|
|
369
383
|
WasmI32.store(arr + arrIdx, c, 8n)
|
|
@@ -371,6 +385,8 @@ let explodeHelp = (s: String, chars) => {
|
|
|
371
385
|
ptr += n
|
|
372
386
|
}
|
|
373
387
|
|
|
388
|
+
ignore(s)
|
|
389
|
+
|
|
374
390
|
arr
|
|
375
391
|
}
|
|
376
392
|
|
|
@@ -523,11 +539,11 @@ provide let split = (separator: String, string: String) => {
|
|
|
523
539
|
} else if (psize > size) {
|
|
524
540
|
[> string]
|
|
525
541
|
} else {
|
|
526
|
-
let
|
|
527
|
-
let
|
|
542
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
543
|
+
let separatorPtr = WasmI32.fromGrain(separator)
|
|
528
544
|
|
|
529
|
-
let mut ptr =
|
|
530
|
-
let mut pptr =
|
|
545
|
+
let mut ptr = stringPtr + 8n
|
|
546
|
+
let mut pptr = separatorPtr + 8n
|
|
531
547
|
let end = ptr + size - psize + 1n
|
|
532
548
|
|
|
533
549
|
let mut numStrings = 1n
|
|
@@ -548,7 +564,7 @@ provide let split = (separator: String, string: String) => {
|
|
|
548
564
|
}
|
|
549
565
|
}
|
|
550
566
|
|
|
551
|
-
ptr =
|
|
567
|
+
ptr = stringPtr + 8n
|
|
552
568
|
let mut last = ptr
|
|
553
569
|
let arr = allocateArray(numStrings)
|
|
554
570
|
let mut arrIdx = 0n
|
|
@@ -577,11 +593,14 @@ provide let split = (separator: String, string: String) => {
|
|
|
577
593
|
}
|
|
578
594
|
|
|
579
595
|
// Grab last string
|
|
580
|
-
let strSize =
|
|
596
|
+
let strSize = stringPtr + 8n + size - last
|
|
581
597
|
let lastStr = allocateString(strSize)
|
|
582
598
|
Memory.copy(lastStr + 8n, last, strSize)
|
|
583
599
|
WasmI32.store(arr + arrIdx, lastStr, 8n)
|
|
584
600
|
|
|
601
|
+
ignore(separator)
|
|
602
|
+
ignore(string)
|
|
603
|
+
|
|
585
604
|
WasmI32.toGrain(arr): Array<String>
|
|
586
605
|
}
|
|
587
606
|
}
|
|
@@ -613,7 +632,7 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
613
632
|
let len = WasmI32.fromGrain(length(string)) >> 1n
|
|
614
633
|
let size = WasmI32.fromGrain(byteLength(string)) >> 1n
|
|
615
634
|
|
|
616
|
-
let
|
|
635
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
617
636
|
|
|
618
637
|
let mut start = WasmI32.fromGrain(start)
|
|
619
638
|
if ((start & 1n) != 1n) {
|
|
@@ -642,7 +661,7 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
642
661
|
throw InvalidArgument("Start index exceeds end index")
|
|
643
662
|
}
|
|
644
663
|
|
|
645
|
-
let mut ptr =
|
|
664
|
+
let mut ptr = stringPtr + 8n
|
|
646
665
|
let mut begin = ptr
|
|
647
666
|
let mut end = ptr
|
|
648
667
|
let stop = ptr + size
|
|
@@ -663,7 +682,7 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
663
682
|
ptr += 1n
|
|
664
683
|
}
|
|
665
684
|
if (to == len) {
|
|
666
|
-
end =
|
|
685
|
+
end = stringPtr + 8n + size
|
|
667
686
|
}
|
|
668
687
|
if (start == to) {
|
|
669
688
|
begin = end
|
|
@@ -674,6 +693,8 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
674
693
|
|
|
675
694
|
Memory.copy(newString + 8n, begin, newSize)
|
|
676
695
|
|
|
696
|
+
ignore(string)
|
|
697
|
+
|
|
677
698
|
WasmI32.toGrain(newString): String
|
|
678
699
|
}
|
|
679
700
|
|
|
@@ -710,11 +731,11 @@ provide let contains = (search: String, string: String) => {
|
|
|
710
731
|
let n = WasmI32.fromGrain(byteLength(string)) >> 1n
|
|
711
732
|
let m = WasmI32.fromGrain(byteLength(search)) >> 1n
|
|
712
733
|
|
|
713
|
-
let mut
|
|
714
|
-
let mut
|
|
734
|
+
let mut stringPtr = WasmI32.fromGrain(string)
|
|
735
|
+
let mut searchPtr = WasmI32.fromGrain(search)
|
|
715
736
|
|
|
716
|
-
|
|
717
|
-
|
|
737
|
+
stringPtr += 8n
|
|
738
|
+
searchPtr += 8n
|
|
718
739
|
|
|
719
740
|
let mut j = 0n
|
|
720
741
|
and k = 0n
|
|
@@ -731,9 +752,9 @@ provide let contains = (search: String, string: String) => {
|
|
|
731
752
|
return true
|
|
732
753
|
}
|
|
733
754
|
|
|
734
|
-
let pat = WasmI32.load8U(
|
|
755
|
+
let pat = WasmI32.load8U(searchPtr, 0n)
|
|
735
756
|
while (j < n) {
|
|
736
|
-
if (pat == WasmI32.load8U(
|
|
757
|
+
if (pat == WasmI32.load8U(stringPtr + j, 0n)) {
|
|
737
758
|
return true
|
|
738
759
|
} else {
|
|
739
760
|
j += 1n
|
|
@@ -744,7 +765,7 @@ provide let contains = (search: String, string: String) => {
|
|
|
744
765
|
}
|
|
745
766
|
|
|
746
767
|
// NSM preprocessing
|
|
747
|
-
if (WasmI32.load8U(
|
|
768
|
+
if (WasmI32.load8U(searchPtr, 0n) == WasmI32.load8U(searchPtr, 1n)) {
|
|
748
769
|
k = 2n
|
|
749
770
|
ell = 1n
|
|
750
771
|
} else {
|
|
@@ -754,12 +775,12 @@ provide let contains = (search: String, string: String) => {
|
|
|
754
775
|
|
|
755
776
|
// NSM searching
|
|
756
777
|
while (j <= n - m) {
|
|
757
|
-
if (WasmI32.load8U(
|
|
778
|
+
if (WasmI32.load8U(searchPtr, 1n) != WasmI32.load8U(stringPtr + j, 1n)) {
|
|
758
779
|
j += k
|
|
759
780
|
} else {
|
|
760
781
|
if (
|
|
761
|
-
Memory.compare(
|
|
762
|
-
WasmI32.load8U(
|
|
782
|
+
Memory.compare(searchPtr + 2n, stringPtr + j + 2n, m - 2n) == 0n &&
|
|
783
|
+
WasmI32.load8U(searchPtr, 0n) == WasmI32.load8U(stringPtr + j, 0n)
|
|
763
784
|
) {
|
|
764
785
|
return true
|
|
765
786
|
}
|
|
@@ -767,6 +788,9 @@ provide let contains = (search: String, string: String) => {
|
|
|
767
788
|
}
|
|
768
789
|
}
|
|
769
790
|
|
|
791
|
+
ignore(search)
|
|
792
|
+
ignore(string)
|
|
793
|
+
|
|
770
794
|
return false
|
|
771
795
|
}
|
|
772
796
|
|
|
@@ -787,21 +811,26 @@ provide let startsWith = (search: String, string: String) => {
|
|
|
787
811
|
let pOrig = search
|
|
788
812
|
let sOrig = string
|
|
789
813
|
|
|
790
|
-
let mut
|
|
791
|
-
let mut
|
|
814
|
+
let mut searchPtr = WasmI32.fromGrain(search)
|
|
815
|
+
let mut stringPtr = WasmI32.fromGrain(string)
|
|
792
816
|
|
|
793
|
-
let n = WasmI32.load(
|
|
794
|
-
let m = WasmI32.load(
|
|
817
|
+
let n = WasmI32.load(stringPtr, 4n)
|
|
818
|
+
let m = WasmI32.load(searchPtr, 4n)
|
|
795
819
|
|
|
796
|
-
|
|
797
|
-
|
|
820
|
+
stringPtr += 8n
|
|
821
|
+
searchPtr += 8n
|
|
798
822
|
|
|
799
823
|
// Bail if pattern length is longer than input length
|
|
800
|
-
if (m > n) {
|
|
824
|
+
let result = if (m > n) {
|
|
801
825
|
false
|
|
802
826
|
} else {
|
|
803
|
-
Memory.compare(
|
|
827
|
+
Memory.compare(searchPtr, stringPtr, m) == 0n
|
|
804
828
|
}
|
|
829
|
+
|
|
830
|
+
ignore(search)
|
|
831
|
+
ignore(string)
|
|
832
|
+
|
|
833
|
+
result
|
|
805
834
|
}
|
|
806
835
|
|
|
807
836
|
/**
|
|
@@ -821,21 +850,26 @@ provide let endsWith = (search: String, string: String) => {
|
|
|
821
850
|
let pOrig = search
|
|
822
851
|
let sOrig = string
|
|
823
852
|
|
|
824
|
-
let mut
|
|
825
|
-
let mut
|
|
853
|
+
let mut searchPtr = WasmI32.fromGrain(search)
|
|
854
|
+
let mut stringPtr = WasmI32.fromGrain(string)
|
|
826
855
|
|
|
827
|
-
let n = WasmI32.load(
|
|
828
|
-
let m = WasmI32.load(
|
|
856
|
+
let n = WasmI32.load(stringPtr, 4n)
|
|
857
|
+
let m = WasmI32.load(searchPtr, 4n)
|
|
829
858
|
|
|
830
|
-
|
|
831
|
-
|
|
859
|
+
stringPtr += 8n
|
|
860
|
+
searchPtr += 8n
|
|
832
861
|
|
|
833
862
|
// Bail if pattern length is longer than input length
|
|
834
|
-
if (m > n) {
|
|
863
|
+
let result = if (m > n) {
|
|
835
864
|
false
|
|
836
865
|
} else {
|
|
837
|
-
Memory.compare(
|
|
866
|
+
Memory.compare(searchPtr, stringPtr + n - m, m) == 0n
|
|
838
867
|
}
|
|
868
|
+
|
|
869
|
+
ignore(search)
|
|
870
|
+
ignore(string)
|
|
871
|
+
|
|
872
|
+
result
|
|
839
873
|
}
|
|
840
874
|
|
|
841
875
|
/**
|
|
@@ -895,6 +929,10 @@ provide let replaceFirst = (
|
|
|
895
929
|
}
|
|
896
930
|
}
|
|
897
931
|
|
|
932
|
+
ignore(searchPattern)
|
|
933
|
+
ignore(string)
|
|
934
|
+
ignore(replacement)
|
|
935
|
+
|
|
898
936
|
return string
|
|
899
937
|
}
|
|
900
938
|
|
|
@@ -957,6 +995,10 @@ provide let replaceLast = (
|
|
|
957
995
|
}
|
|
958
996
|
}
|
|
959
997
|
|
|
998
|
+
ignore(searchPattern)
|
|
999
|
+
ignore(string)
|
|
1000
|
+
ignore(replacement)
|
|
1001
|
+
|
|
960
1002
|
return string
|
|
961
1003
|
}
|
|
962
1004
|
|
|
@@ -989,7 +1031,7 @@ provide let replaceAll = (
|
|
|
989
1031
|
let replacementLen = WasmI32.load(replacementPtr, 4n)
|
|
990
1032
|
|
|
991
1033
|
// Bail if search str is longer than the string
|
|
992
|
-
if (stringLen < patternLen) {
|
|
1034
|
+
let result = if (stringLen < patternLen) {
|
|
993
1035
|
string
|
|
994
1036
|
} else {
|
|
995
1037
|
patternPtr += 8n
|
|
@@ -1043,6 +1085,12 @@ provide let replaceAll = (
|
|
|
1043
1085
|
string
|
|
1044
1086
|
}
|
|
1045
1087
|
}
|
|
1088
|
+
|
|
1089
|
+
ignore(searchPattern)
|
|
1090
|
+
ignore(string)
|
|
1091
|
+
ignore(replacement)
|
|
1092
|
+
|
|
1093
|
+
result
|
|
1046
1094
|
}
|
|
1047
1095
|
|
|
1048
1096
|
// String->Byte encoding and helper functions:
|
|
@@ -1075,9 +1123,9 @@ let utf16Length = (s: String) => {
|
|
|
1075
1123
|
let size = WasmI32.fromGrain(byteLength(s)) >>> 1n
|
|
1076
1124
|
let len = WasmI32.fromGrain(length(s)) >>> 1n
|
|
1077
1125
|
|
|
1078
|
-
let
|
|
1126
|
+
let sPtr = WasmI32.fromGrain(s)
|
|
1079
1127
|
|
|
1080
|
-
let mut ptr =
|
|
1128
|
+
let mut ptr = sPtr + 8n
|
|
1081
1129
|
let end = ptr + size
|
|
1082
1130
|
let mut size = 0n // <- number of UTF-16 code words
|
|
1083
1131
|
|
|
@@ -1099,11 +1147,13 @@ let utf16Length = (s: String) => {
|
|
|
1099
1147
|
}
|
|
1100
1148
|
ptr += n
|
|
1101
1149
|
}
|
|
1150
|
+
|
|
1151
|
+
ignore(s)
|
|
1152
|
+
|
|
1102
1153
|
// multiply by two to get number of bytes
|
|
1103
1154
|
tagSimpleNumber(size << 1n)
|
|
1104
1155
|
}
|
|
1105
1156
|
|
|
1106
|
-
@unsafe
|
|
1107
1157
|
let encodedLength = (s: String, encoding) => {
|
|
1108
1158
|
match (encoding) {
|
|
1109
1159
|
UTF32_BE => length(s) * 4,
|
|
@@ -1131,9 +1181,9 @@ let encodeAtHelp = (
|
|
|
1131
1181
|
let byteSize = WasmI32.fromGrain(byteLength(string)) >>> 1n
|
|
1132
1182
|
let len = WasmI32.fromGrain(length(string)) >>> 1n
|
|
1133
1183
|
|
|
1134
|
-
let
|
|
1184
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
1135
1185
|
|
|
1136
|
-
let mut ptr =
|
|
1186
|
+
let mut ptr = stringPtr + 8n
|
|
1137
1187
|
let end = ptr + byteSize
|
|
1138
1188
|
|
|
1139
1189
|
let bytes = WasmI32.fromGrain(dest)
|
|
@@ -1358,6 +1408,8 @@ let encodeAtHelp = (
|
|
|
1358
1408
|
},
|
|
1359
1409
|
}
|
|
1360
1410
|
|
|
1411
|
+
ignore(string)
|
|
1412
|
+
|
|
1361
1413
|
dest
|
|
1362
1414
|
}
|
|
1363
1415
|
|
|
@@ -1472,7 +1524,7 @@ let bytesHaveBom = (bytes: Bytes, encoding: Encoding, start: WasmI32) => {
|
|
|
1472
1524
|
let ptr = WasmI32.fromGrain(bytes)
|
|
1473
1525
|
let bytesSize = WasmI32.load(ptr, 4n)
|
|
1474
1526
|
let ptr = ptr + start
|
|
1475
|
-
match (encoding) {
|
|
1527
|
+
let result = match (encoding) {
|
|
1476
1528
|
UTF8 => {
|
|
1477
1529
|
bytesSize >= 3n &&
|
|
1478
1530
|
WasmI32.load8U(ptr, _BYTES_OFFSET) == 0xEFn &&
|
|
@@ -1504,6 +1556,10 @@ let bytesHaveBom = (bytes: Bytes, encoding: Encoding, start: WasmI32) => {
|
|
|
1504
1556
|
WasmI32.load8U(ptr + 3n, _BYTES_OFFSET) == 0x00n
|
|
1505
1557
|
},
|
|
1506
1558
|
}
|
|
1559
|
+
|
|
1560
|
+
ignore(bytes)
|
|
1561
|
+
|
|
1562
|
+
result
|
|
1507
1563
|
}
|
|
1508
1564
|
|
|
1509
1565
|
@unsafe
|
|
@@ -1537,7 +1593,7 @@ let decodedLength = (
|
|
|
1537
1593
|
}
|
|
1538
1594
|
}
|
|
1539
1595
|
let start = ptr + _BYTES_OFFSET + start
|
|
1540
|
-
match (encoding) {
|
|
1596
|
+
let result = match (encoding) {
|
|
1541
1597
|
UTF8 => bytesSize,
|
|
1542
1598
|
UTF16_BE => {
|
|
1543
1599
|
let end = start + bytesSize
|
|
@@ -1674,6 +1730,10 @@ let decodedLength = (
|
|
|
1674
1730
|
count
|
|
1675
1731
|
},
|
|
1676
1732
|
}
|
|
1733
|
+
|
|
1734
|
+
ignore(bytes)
|
|
1735
|
+
|
|
1736
|
+
result
|
|
1677
1737
|
}
|
|
1678
1738
|
|
|
1679
1739
|
@unsafe
|
|
@@ -1723,7 +1783,7 @@ let decodeRangeHelp = (
|
|
|
1723
1783
|
UTF32_BE => 4n,
|
|
1724
1784
|
}
|
|
1725
1785
|
}
|
|
1726
|
-
if (stringSize == 0n) {
|
|
1786
|
+
let result = if (stringSize == 0n) {
|
|
1727
1787
|
WasmI32.toGrain(str): String
|
|
1728
1788
|
} else {
|
|
1729
1789
|
match (encoding) {
|
|
@@ -1808,6 +1868,10 @@ let decodeRangeHelp = (
|
|
|
1808
1868
|
}
|
|
1809
1869
|
WasmI32.toGrain(str): String
|
|
1810
1870
|
}
|
|
1871
|
+
|
|
1872
|
+
ignore(bytes)
|
|
1873
|
+
|
|
1874
|
+
result
|
|
1811
1875
|
}
|
|
1812
1876
|
|
|
1813
1877
|
/**
|
|
@@ -1842,7 +1906,15 @@ provide let decodeRange = (
|
|
|
1842
1906
|
let decodeHelp = (bytes: Bytes, encoding: Encoding, skipBom: Bool) => {
|
|
1843
1907
|
let bytesPtr = WasmI32.fromGrain(bytes)
|
|
1844
1908
|
let bytesSize = WasmI32.load(bytesPtr, 4n)
|
|
1845
|
-
|
|
1909
|
+
let result = decodeRangeHelp(
|
|
1910
|
+
bytes,
|
|
1911
|
+
encoding,
|
|
1912
|
+
skipBom,
|
|
1913
|
+
0,
|
|
1914
|
+
tagSimpleNumber(bytesSize)
|
|
1915
|
+
)
|
|
1916
|
+
ignore(bytes)
|
|
1917
|
+
result
|
|
1846
1918
|
}
|
|
1847
1919
|
|
|
1848
1920
|
/**
|
|
@@ -1881,7 +1953,6 @@ provide let forEachCodePoint = (fn: Number => Void, str: String) => {
|
|
|
1881
1953
|
let mut ptr = strPtr + 8n
|
|
1882
1954
|
let end = ptr + byteSize
|
|
1883
1955
|
|
|
1884
|
-
let mut idx = 0n
|
|
1885
1956
|
while (ptr < end) {
|
|
1886
1957
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
1887
1958
|
let codePointByteCount = if ((byte & 0x80n) == 0x00n) {
|
|
@@ -1905,8 +1976,10 @@ provide let forEachCodePoint = (fn: Number => Void, str: String) => {
|
|
|
1905
1976
|
fn(tagSimpleNumber(codePoint))
|
|
1906
1977
|
|
|
1907
1978
|
ptr += codePointByteCount
|
|
1908
|
-
idx += 1n
|
|
1909
1979
|
}
|
|
1980
|
+
|
|
1981
|
+
ignore(str)
|
|
1982
|
+
|
|
1910
1983
|
void
|
|
1911
1984
|
}
|
|
1912
1985
|
|
|
@@ -1959,9 +2032,152 @@ provide let forEachCodePointi = (fn: (Number, Number) => Void, str: String) => {
|
|
|
1959
2032
|
ptr += codePointByteCount
|
|
1960
2033
|
idx += 1n
|
|
1961
2034
|
}
|
|
2035
|
+
|
|
2036
|
+
ignore(str)
|
|
2037
|
+
|
|
1962
2038
|
void
|
|
1963
2039
|
}
|
|
1964
2040
|
|
|
2041
|
+
/**
|
|
2042
|
+
* Iterates over Unicode characters in a string.
|
|
2043
|
+
*
|
|
2044
|
+
* @param fn: The iterator function
|
|
2045
|
+
* @param str: The string to iterate
|
|
2046
|
+
*
|
|
2047
|
+
* @example String.forEachChar(print, "Hello world")
|
|
2048
|
+
*
|
|
2049
|
+
* @since v0.6.5
|
|
2050
|
+
*/
|
|
2051
|
+
@unsafe
|
|
2052
|
+
provide let forEachChar = (fn: Char => Void, str: String) => {
|
|
2053
|
+
use WasmI32.{ (+), (-), (&), (>>>), ltU as (<), leU as (<=), (==) }
|
|
2054
|
+
|
|
2055
|
+
let strPtr = WasmI32.fromGrain(str)
|
|
2056
|
+
|
|
2057
|
+
let byteSize = WasmI32.load(strPtr, 4n)
|
|
2058
|
+
|
|
2059
|
+
let mut ptr = strPtr + 8n
|
|
2060
|
+
let end = ptr + byteSize
|
|
2061
|
+
|
|
2062
|
+
while (ptr < end) {
|
|
2063
|
+
let byte = WasmI32.load8U(ptr, 0n)
|
|
2064
|
+
let codePointByteCount = if ((byte & 0x80n) == 0x00n) {
|
|
2065
|
+
1n
|
|
2066
|
+
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
2067
|
+
4n
|
|
2068
|
+
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
2069
|
+
3n
|
|
2070
|
+
} else {
|
|
2071
|
+
2n
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
// Note that even if up to 4 bytes are needed to represent Unicode
|
|
2075
|
+
// codepoints, this doesn't mean 32 bits. The highest allowed code point is
|
|
2076
|
+
// 0x10FFFF and it should not change in future versions of Unicode. This
|
|
2077
|
+
// means no more than 21 bits are necessary to represent a code point and
|
|
2078
|
+
// thus we can use Grain's "simple" numbers that hold up to 31 bits and
|
|
2079
|
+
// avoid heap allocations. `getCodePoint` will throw
|
|
2080
|
+
// MalformedUnicode exception for values exceeding this limit.
|
|
2081
|
+
let codePoint = getCodePoint(ptr)
|
|
2082
|
+
fn(tagChar(codePoint))
|
|
2083
|
+
|
|
2084
|
+
ptr += codePointByteCount
|
|
2085
|
+
}
|
|
2086
|
+
void
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
/**
|
|
2090
|
+
* Iterates over Unicode characters in a string. This is the same as
|
|
2091
|
+
* `forEachChar`, but provides the characters's index in the string
|
|
2092
|
+
* as the second argument to the iterator function.
|
|
2093
|
+
*
|
|
2094
|
+
* @param fn: The iterator function
|
|
2095
|
+
* @param str: The string to iterate
|
|
2096
|
+
*
|
|
2097
|
+
* @example String.forEachChari((char, index) => print((char, index)), "Hello world")
|
|
2098
|
+
*
|
|
2099
|
+
* @since v0.6.5
|
|
2100
|
+
*/
|
|
2101
|
+
@unsafe
|
|
2102
|
+
provide let forEachChari = (fn: (Char, Number) => Void, str: String) => {
|
|
2103
|
+
use WasmI32.{ (+), (-), (&), (>>>), ltU as (<), leU as (<=), (==) }
|
|
2104
|
+
|
|
2105
|
+
let strPtr = WasmI32.fromGrain(str)
|
|
2106
|
+
|
|
2107
|
+
let byteSize = WasmI32.load(strPtr, 4n)
|
|
2108
|
+
|
|
2109
|
+
let mut ptr = strPtr + 8n
|
|
2110
|
+
let end = ptr + byteSize
|
|
2111
|
+
|
|
2112
|
+
let mut idx = 0n
|
|
2113
|
+
while (ptr < end) {
|
|
2114
|
+
let byte = WasmI32.load8U(ptr, 0n)
|
|
2115
|
+
let codePointByteCount = if ((byte & 0x80n) == 0x00n) {
|
|
2116
|
+
1n
|
|
2117
|
+
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
2118
|
+
4n
|
|
2119
|
+
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
2120
|
+
3n
|
|
2121
|
+
} else {
|
|
2122
|
+
2n
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
// Note that even if up to 4 bytes are needed to represent Unicode
|
|
2126
|
+
// codepoints, this doesn't mean 32 bits. The highest allowed code point is
|
|
2127
|
+
// 0x10FFFF and it should not change in future versions of Unicode. This
|
|
2128
|
+
// means no more than 21 bits are necessary to represent a code point and
|
|
2129
|
+
// thus we can use Grain's "simple" numbers that hold up to 31 bits and
|
|
2130
|
+
// avoid heap allocations. `getCodePoint` will throw
|
|
2131
|
+
// MalformedUnicode exception for values exceeding this limit.
|
|
2132
|
+
let codePoint = getCodePoint(ptr)
|
|
2133
|
+
fn(tagChar(codePoint), tagSimpleNumber(idx))
|
|
2134
|
+
|
|
2135
|
+
ptr += codePointByteCount
|
|
2136
|
+
idx += 1n
|
|
2137
|
+
}
|
|
2138
|
+
void
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
/**
|
|
2142
|
+
* Builds a new string by mapping Unicode characters.
|
|
2143
|
+
*
|
|
2144
|
+
* @param fn: The mapping function
|
|
2145
|
+
* @param str: The string to map
|
|
2146
|
+
*
|
|
2147
|
+
* @example assert String.map((c) => 'a', "Hello world") == "aaaaaaaaaaa"
|
|
2148
|
+
*
|
|
2149
|
+
* @since v0.6.5
|
|
2150
|
+
*/
|
|
2151
|
+
provide let map = (fn: Char => Char, str: String) => {
|
|
2152
|
+
let chars = explode(str)
|
|
2153
|
+
let arrLen = arrayLength(chars)
|
|
2154
|
+
for (let mut i = 0; i < arrLen; i += 1) {
|
|
2155
|
+
chars[i] = fn(chars[i])
|
|
2156
|
+
}
|
|
2157
|
+
implode(chars)
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
/**
|
|
2161
|
+
* Builds a new string by mapping Unicode characters. This is the same as
|
|
2162
|
+
* `mapChar`, but provides the characters's index in the string
|
|
2163
|
+
* as the second argument to the mapping function.
|
|
2164
|
+
*
|
|
2165
|
+
* @param fn: The mapping function
|
|
2166
|
+
* @param str: The string to map
|
|
2167
|
+
*
|
|
2168
|
+
* @example assert String.mapi((char, index) => String.charAt(0, toString(index)), "Hello world") == "01234567891"
|
|
2169
|
+
*
|
|
2170
|
+
* @since v0.6.5
|
|
2171
|
+
*/
|
|
2172
|
+
provide let mapi = (fn: (Char, Number) => Char, str: String) => {
|
|
2173
|
+
let chars = explode(str)
|
|
2174
|
+
let arrLen = arrayLength(chars)
|
|
2175
|
+
for (let mut i = 0; i < arrLen; i += 1) {
|
|
2176
|
+
chars[i] = fn(chars[i], i)
|
|
2177
|
+
}
|
|
2178
|
+
implode(chars)
|
|
2179
|
+
}
|
|
2180
|
+
|
|
1965
2181
|
@unsafe
|
|
1966
2182
|
let trimString = (stringPtr: WasmI32, byteLength: WasmI32, fromEnd: Bool) => {
|
|
1967
2183
|
use WasmI32.{ (+), (-), (*), (>>>), ltU as (<), (==), (!=) }
|
|
@@ -2031,6 +2247,7 @@ provide let trimStart = (string: String) => {
|
|
|
2031
2247
|
let count = trimString(stringPtr, byteLength, false)
|
|
2032
2248
|
let str = allocateString(byteLength - count)
|
|
2033
2249
|
Memory.copy(str + 8n, stringPtr + count, byteLength - count)
|
|
2250
|
+
ignore(string)
|
|
2034
2251
|
WasmI32.toGrain(str): String
|
|
2035
2252
|
}
|
|
2036
2253
|
/**
|
|
@@ -2052,6 +2269,7 @@ provide let trimEnd = (string: String) => {
|
|
|
2052
2269
|
let count = trimString(stringPtr, byteLength, true)
|
|
2053
2270
|
let str = allocateString(byteLength - count)
|
|
2054
2271
|
Memory.copy(str + 8n, stringPtr, byteLength - count)
|
|
2272
|
+
ignore(string)
|
|
2055
2273
|
WasmI32.toGrain(str): String
|
|
2056
2274
|
}
|
|
2057
2275
|
/**
|
|
@@ -2079,6 +2297,7 @@ provide let trim = (string: String) => {
|
|
|
2079
2297
|
stringPtr + startCount,
|
|
2080
2298
|
byteLength - startCount - endCount
|
|
2081
2299
|
)
|
|
2300
|
+
ignore(string)
|
|
2082
2301
|
return WasmI32.toGrain(str): String
|
|
2083
2302
|
}
|
|
2084
2303
|
|