@grain/stdlib 0.5.3 → 0.5.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 +61 -0
- package/array.gr +65 -57
- package/array.md +54 -6
- package/buffer.gr +71 -1
- package/buffer.md +142 -0
- package/bytes.gr +52 -3
- package/bytes.md +117 -0
- package/char.gr +23 -20
- package/char.md +18 -3
- package/immutablemap.gr +493 -0
- package/immutablemap.md +479 -0
- package/immutablepriorityqueue.gr +44 -16
- package/immutablepriorityqueue.md +44 -1
- package/immutableset.gr +498 -0
- package/immutableset.md +449 -0
- package/int32.gr +39 -37
- package/int32.md +6 -0
- package/int64.gr +39 -37
- package/int64.md +6 -0
- package/list.gr +33 -24
- package/list.md +39 -10
- package/map.gr +19 -28
- package/marshal.gr +4 -4
- package/number.gr +727 -26
- package/number.md +345 -23
- package/option.gr +30 -26
- package/option.md +12 -0
- package/package.json +1 -1
- package/path.gr +787 -0
- package/path.md +727 -0
- package/pervasives.gr +3 -4
- package/pervasives.md +6 -1
- package/priorityqueue.gr +25 -5
- package/priorityqueue.md +30 -0
- package/queue.gr +22 -7
- package/queue.md +18 -1
- package/regex.gr +161 -65
- package/regex.md +70 -0
- package/result.gr +24 -20
- package/result.md +12 -0
- package/runtime/atof/common.gr +198 -0
- package/runtime/atof/common.md +243 -0
- package/runtime/atof/decimal.gr +663 -0
- package/runtime/atof/decimal.md +59 -0
- package/runtime/atof/lemire.gr +264 -0
- package/runtime/atof/lemire.md +6 -0
- package/runtime/atof/parse.gr +615 -0
- package/runtime/atof/parse.md +12 -0
- package/runtime/atof/slow.gr +238 -0
- package/runtime/atof/slow.md +6 -0
- package/runtime/atof/table.gr +2016 -0
- package/runtime/atof/table.md +12 -0
- package/runtime/{stringUtils.gr → atoi/parse.gr} +1 -1
- package/runtime/{stringUtils.md → atoi/parse.md} +1 -1
- package/runtime/bigint.gr +7 -7
- package/runtime/compare.gr +2 -1
- package/runtime/equal.gr +3 -2
- 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 +13 -13
- package/runtime/numberUtils.md +6 -0
- package/runtime/numbers.gr +123 -39
- package/runtime/numbers.md +26 -0
- package/runtime/string.gr +4 -2
- package/runtime/unsafe/conv.gr +21 -41
- package/runtime/unsafe/conv.md +0 -3
- package/runtime/unsafe/printWasm.gr +4 -40
- package/runtime/utils/printing.gr +3 -3
- package/set.gr +25 -25
- package/stack.gr +14 -0
- package/stack.md +17 -0
- package/string.gr +313 -39
- package/string.md +99 -0
- package/sys/file.gr +1 -1
- package/sys/time.gr +4 -4
package/list.gr
CHANGED
|
@@ -230,10 +230,12 @@ export let rec flatMap = (fn, list) => {
|
|
|
230
230
|
*
|
|
231
231
|
* @since v0.1.0
|
|
232
232
|
*/
|
|
233
|
-
export let every = (fn, list) => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
export let rec every = (fn, list) => {
|
|
234
|
+
match (list) {
|
|
235
|
+
[] => true,
|
|
236
|
+
// The short-circuiting of `&&` makes this tail-recursive
|
|
237
|
+
[first, ...rest] => fn(first) && every(fn, rest),
|
|
238
|
+
}
|
|
237
239
|
}
|
|
238
240
|
|
|
239
241
|
/**
|
|
@@ -246,10 +248,12 @@ export let every = (fn, list) => {
|
|
|
246
248
|
*
|
|
247
249
|
* @since v0.1.0
|
|
248
250
|
*/
|
|
249
|
-
export let some = (fn, list) => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
export let rec some = (fn, list) => {
|
|
252
|
+
match (list) {
|
|
253
|
+
[] => false,
|
|
254
|
+
// The short-circuiting of `||` makes this tail-recursive
|
|
255
|
+
[first, ...rest] => fn(first) || some(fn, rest),
|
|
256
|
+
}
|
|
253
257
|
}
|
|
254
258
|
|
|
255
259
|
/**
|
|
@@ -433,13 +437,15 @@ export let rec flatten = list => {
|
|
|
433
437
|
|
|
434
438
|
/**
|
|
435
439
|
* Inserts a new value into a list at the specified index.
|
|
436
|
-
* Fails if the index is out-of-bounds.
|
|
437
440
|
*
|
|
438
441
|
* @param value: The value to insert
|
|
439
442
|
* @param index: The index to update
|
|
440
443
|
* @param list: The list to update
|
|
441
444
|
* @returns The new list
|
|
442
445
|
*
|
|
446
|
+
* @throws Failure(String): When `index` is negative
|
|
447
|
+
* @throws Failure(String): When `index` is more than 0 and greater than the list size
|
|
448
|
+
*
|
|
443
449
|
* @since v0.1.0
|
|
444
450
|
*/
|
|
445
451
|
export let rec insert = (value, index, list) => {
|
|
@@ -477,12 +483,14 @@ export let count = (fn, list) => {
|
|
|
477
483
|
|
|
478
484
|
/**
|
|
479
485
|
* Split a list into two, with the first list containing the required number of elements.
|
|
480
|
-
* Fails if the input list doesn't contain at least the required amount of elements.
|
|
481
486
|
*
|
|
482
487
|
* @param count: The number of elements required
|
|
483
488
|
* @param list: The list to split
|
|
484
489
|
* @returns Two lists where the first contains exactly the required amount of elements and the second contains any remaining elements
|
|
485
490
|
*
|
|
491
|
+
* @throws Failure(String): When `count` is negative
|
|
492
|
+
* @throws Failure(String): When the list doesn't contain at least the required amount of elements
|
|
493
|
+
*
|
|
486
494
|
* @since v0.1.0
|
|
487
495
|
*/
|
|
488
496
|
export let part = (count, list) => {
|
|
@@ -509,19 +517,19 @@ export let part = (count, list) => {
|
|
|
509
517
|
* If value is negative, list elements will be rotated by the
|
|
510
518
|
* specified amount to the right. See examples.
|
|
511
519
|
*
|
|
512
|
-
* Fails if the input list doesn't contain at least the required amount of elements.
|
|
513
|
-
*
|
|
514
520
|
* @param count: The number of elements to rotate by
|
|
515
521
|
* @param list: The list to be rotated
|
|
516
522
|
*
|
|
517
523
|
* @example List.rotate(2, [1, 2, 3, 4, 5]) // [3, 4, 5, 1, 2]
|
|
518
524
|
* @example List.rotate(-1, [1, 2, 3, 4, 5]) // [5, 1, 2, 3, 4]
|
|
519
525
|
*
|
|
526
|
+
* @throws Failure(String): When the list doesn't contain at least the required amount of elements
|
|
527
|
+
*
|
|
520
528
|
* @since v0.1.0
|
|
521
529
|
*/
|
|
522
530
|
export let rotate = (count, list) => {
|
|
523
|
-
let (beginning, end) =
|
|
524
|
-
else part(length(list) + count, list)
|
|
531
|
+
let (beginning, end) =
|
|
532
|
+
if (count >= 0) part(count, list) else part(length(list) + count, list)
|
|
525
533
|
append(end, beginning)
|
|
526
534
|
}
|
|
527
535
|
|
|
@@ -552,7 +560,7 @@ export let unique = list => {
|
|
|
552
560
|
* Produces a new list filled with tuples of elements from both given lists.
|
|
553
561
|
* The first tuple will contain the first item of each list, the second tuple
|
|
554
562
|
* will contain the second item of each list, and so on.
|
|
555
|
-
*
|
|
563
|
+
*
|
|
556
564
|
* Calling this function with lists of different sizes will cause the returned
|
|
557
565
|
* list to have the length of the smaller list.
|
|
558
566
|
*
|
|
@@ -562,7 +570,7 @@ export let unique = list => {
|
|
|
562
570
|
*
|
|
563
571
|
* @example List.zip([1, 2, 3], [4, 5, 6]) // [(1, 4), (2, 5), (3, 6)]
|
|
564
572
|
* @example List.zip([1, 2, 3], [4, 5]) // [(1, 4), (2, 5)]
|
|
565
|
-
*
|
|
573
|
+
*
|
|
566
574
|
* @since v0.5.3
|
|
567
575
|
*/
|
|
568
576
|
export let zip = (list1, list2) => {
|
|
@@ -582,7 +590,7 @@ export let zip = (list1, list2) => {
|
|
|
582
590
|
* applying the function to the first elements of each list, the second element
|
|
583
591
|
* will contain the result of applying the function to the second elements of
|
|
584
592
|
* each list, and so on.
|
|
585
|
-
*
|
|
593
|
+
*
|
|
586
594
|
* Calling this function with lists of different sizes will cause the returned
|
|
587
595
|
* list to have the length of the smaller list.
|
|
588
596
|
*
|
|
@@ -593,7 +601,7 @@ export let zip = (list1, list2) => {
|
|
|
593
601
|
*
|
|
594
602
|
* @example List.zipWith((a, b) => a + b, [1, 2, 3], [4, 5, 6]) // [5, 7, 9]
|
|
595
603
|
* @example List.zipWith((a, b) => a * b, [1, 2, 3], [4, 5]) // [4, 10]
|
|
596
|
-
*
|
|
604
|
+
*
|
|
597
605
|
* @since v0.5.3
|
|
598
606
|
*/
|
|
599
607
|
export let zipWith = (fn, list1, list2) => {
|
|
@@ -625,12 +633,12 @@ export let unzip = list => {
|
|
|
625
633
|
* Produces a new list with the specified number of elements removed from
|
|
626
634
|
* the beginning of the input list.
|
|
627
635
|
*
|
|
628
|
-
* Fails if the specified amount is a negative number.
|
|
629
|
-
*
|
|
630
636
|
* @param count: The amount of elements to remove
|
|
631
637
|
* @param list: The input list
|
|
632
638
|
* @returns The new list without the dropped elements
|
|
633
639
|
*
|
|
640
|
+
* @throws Failure(String): When `count` is negative
|
|
641
|
+
*
|
|
634
642
|
* @since v0.2.0
|
|
635
643
|
*/
|
|
636
644
|
export let rec drop = (count, list) => {
|
|
@@ -667,12 +675,12 @@ export let rec dropWhile = (fn, list) => {
|
|
|
667
675
|
* Produces a new list with–at most—the specified amount elements from
|
|
668
676
|
* the beginning of the input list.
|
|
669
677
|
*
|
|
670
|
-
* Fails if the specified amount is a negative number.
|
|
671
|
-
*
|
|
672
678
|
* @param count: The amount of elements to keep
|
|
673
679
|
* @param list: The input list
|
|
674
680
|
* @returns The new list containing the taken elements
|
|
675
681
|
*
|
|
682
|
+
* @throws Failure(String): When `count` is negative
|
|
683
|
+
*
|
|
676
684
|
* @since v0.2.0
|
|
677
685
|
*/
|
|
678
686
|
export let rec take = (count, list) => {
|
|
@@ -769,13 +777,14 @@ export let product = (list1, list2) => {
|
|
|
769
777
|
* Provides the subset of a list given zero-based start index and amount of elements
|
|
770
778
|
* to include.
|
|
771
779
|
*
|
|
772
|
-
* Fails if the start index or amount of elements are negative numbers.
|
|
773
|
-
*
|
|
774
780
|
* @param start: The index of the list where the subset will begin (inclusive)
|
|
775
781
|
* @param length: The amount of elements to be included in the subset
|
|
776
782
|
* @param list: The input list
|
|
777
783
|
* @returns The subset of the list
|
|
778
784
|
*
|
|
785
|
+
* @throws Failure(String): When `start` is negative
|
|
786
|
+
* @throws Failure(String): When `length` is negative
|
|
787
|
+
*
|
|
779
788
|
* @since v0.2.0
|
|
780
789
|
*/
|
|
781
790
|
export let sub = (start, length, list) => {
|
package/list.md
CHANGED
|
@@ -674,7 +674,6 @@ insert : (a, Number, List<a>) -> List<a>
|
|
|
674
674
|
```
|
|
675
675
|
|
|
676
676
|
Inserts a new value into a list at the specified index.
|
|
677
|
-
Fails if the index is out-of-bounds.
|
|
678
677
|
|
|
679
678
|
Parameters:
|
|
680
679
|
|
|
@@ -690,6 +689,13 @@ Returns:
|
|
|
690
689
|
|----|-----------|
|
|
691
690
|
|`List<a>`|The new list|
|
|
692
691
|
|
|
692
|
+
Throws:
|
|
693
|
+
|
|
694
|
+
`Failure(String)`
|
|
695
|
+
|
|
696
|
+
* When `index` is negative
|
|
697
|
+
* When `index` is more than 0 and greater than the list size
|
|
698
|
+
|
|
693
699
|
### List.**count**
|
|
694
700
|
|
|
695
701
|
<details>
|
|
@@ -735,7 +741,6 @@ part : (Number, List<a>) -> (List<a>, List<a>)
|
|
|
735
741
|
```
|
|
736
742
|
|
|
737
743
|
Split a list into two, with the first list containing the required number of elements.
|
|
738
|
-
Fails if the input list doesn't contain at least the required amount of elements.
|
|
739
744
|
|
|
740
745
|
Parameters:
|
|
741
746
|
|
|
@@ -750,6 +755,13 @@ Returns:
|
|
|
750
755
|
|----|-----------|
|
|
751
756
|
|`(List<a>, List<a>)`|Two lists where the first contains exactly the required amount of elements and the second contains any remaining elements|
|
|
752
757
|
|
|
758
|
+
Throws:
|
|
759
|
+
|
|
760
|
+
`Failure(String)`
|
|
761
|
+
|
|
762
|
+
* When `count` is negative
|
|
763
|
+
* When the list doesn't contain at least the required amount of elements
|
|
764
|
+
|
|
753
765
|
### List.**rotate**
|
|
754
766
|
|
|
755
767
|
<details disabled>
|
|
@@ -766,8 +778,6 @@ Rotates list elements by the specified amount to the left.
|
|
|
766
778
|
If value is negative, list elements will be rotated by the
|
|
767
779
|
specified amount to the right. See examples.
|
|
768
780
|
|
|
769
|
-
Fails if the input list doesn't contain at least the required amount of elements.
|
|
770
|
-
|
|
771
781
|
Parameters:
|
|
772
782
|
|
|
773
783
|
|param|type|description|
|
|
@@ -775,6 +785,12 @@ Parameters:
|
|
|
775
785
|
|`count`|`Number`|The number of elements to rotate by|
|
|
776
786
|
|`list`|`List<a>`|The list to be rotated|
|
|
777
787
|
|
|
788
|
+
Throws:
|
|
789
|
+
|
|
790
|
+
`Failure(String)`
|
|
791
|
+
|
|
792
|
+
* When the list doesn't contain at least the required amount of elements
|
|
793
|
+
|
|
778
794
|
Examples:
|
|
779
795
|
|
|
780
796
|
```grain
|
|
@@ -943,8 +959,6 @@ drop : (Number, List<a>) -> List<a>
|
|
|
943
959
|
Produces a new list with the specified number of elements removed from
|
|
944
960
|
the beginning of the input list.
|
|
945
961
|
|
|
946
|
-
Fails if the specified amount is a negative number.
|
|
947
|
-
|
|
948
962
|
Parameters:
|
|
949
963
|
|
|
950
964
|
|param|type|description|
|
|
@@ -958,6 +972,12 @@ Returns:
|
|
|
958
972
|
|----|-----------|
|
|
959
973
|
|`List<a>`|The new list without the dropped elements|
|
|
960
974
|
|
|
975
|
+
Throws:
|
|
976
|
+
|
|
977
|
+
`Failure(String)`
|
|
978
|
+
|
|
979
|
+
* When `count` is negative
|
|
980
|
+
|
|
961
981
|
### List.**dropWhile**
|
|
962
982
|
|
|
963
983
|
<details disabled>
|
|
@@ -1000,8 +1020,6 @@ take : (Number, List<a>) -> List<a>
|
|
|
1000
1020
|
Produces a new list with–at most—the specified amount elements from
|
|
1001
1021
|
the beginning of the input list.
|
|
1002
1022
|
|
|
1003
|
-
Fails if the specified amount is a negative number.
|
|
1004
|
-
|
|
1005
1023
|
Parameters:
|
|
1006
1024
|
|
|
1007
1025
|
|param|type|description|
|
|
@@ -1015,6 +1033,12 @@ Returns:
|
|
|
1015
1033
|
|----|-----------|
|
|
1016
1034
|
|`List<a>`|The new list containing the taken elements|
|
|
1017
1035
|
|
|
1036
|
+
Throws:
|
|
1037
|
+
|
|
1038
|
+
`Failure(String)`
|
|
1039
|
+
|
|
1040
|
+
* When `count` is negative
|
|
1041
|
+
|
|
1018
1042
|
### List.**takeWhile**
|
|
1019
1043
|
|
|
1020
1044
|
<details disabled>
|
|
@@ -1152,8 +1176,6 @@ sub : (Number, Number, List<a>) -> List<a>
|
|
|
1152
1176
|
Provides the subset of a list given zero-based start index and amount of elements
|
|
1153
1177
|
to include.
|
|
1154
1178
|
|
|
1155
|
-
Fails if the start index or amount of elements are negative numbers.
|
|
1156
|
-
|
|
1157
1179
|
Parameters:
|
|
1158
1180
|
|
|
1159
1181
|
|param|type|description|
|
|
@@ -1168,6 +1190,13 @@ Returns:
|
|
|
1168
1190
|
|----|-----------|
|
|
1169
1191
|
|`List<a>`|The subset of the list|
|
|
1170
1192
|
|
|
1193
|
+
Throws:
|
|
1194
|
+
|
|
1195
|
+
`Failure(String)`
|
|
1196
|
+
|
|
1197
|
+
* When `start` is negative
|
|
1198
|
+
* When `length` is negative
|
|
1199
|
+
|
|
1171
1200
|
### List.**join**
|
|
1172
1201
|
|
|
1173
1202
|
<details disabled>
|
package/map.gr
CHANGED
|
@@ -9,7 +9,7 @@ import Array from "array"
|
|
|
9
9
|
import { hash } from "hash"
|
|
10
10
|
import Memory from "runtime/unsafe/memory"
|
|
11
11
|
import WasmI32 from "runtime/unsafe/wasmi32"
|
|
12
|
-
import { allocateArray } from "runtime/dataStructures"
|
|
12
|
+
import { allocateArray, untagSimpleNumber } from "runtime/dataStructures"
|
|
13
13
|
|
|
14
14
|
// TODO: Consider implementing this as List<(Box<k>, Box<v>)>
|
|
15
15
|
record Bucket<k, v> {
|
|
@@ -418,19 +418,6 @@ export let fromList = list => {
|
|
|
418
418
|
map
|
|
419
419
|
}
|
|
420
420
|
|
|
421
|
-
let setInArray = array => {
|
|
422
|
-
@disableGC
|
|
423
|
-
let rec iter = (i, key, value) => {
|
|
424
|
-
array[i] = (key, value)
|
|
425
|
-
// no decRef on key and value, since they are stored in array
|
|
426
|
-
Memory.decRef(WasmI32.fromGrain(iter))
|
|
427
|
-
Memory.incRef(WasmI32.fromGrain((+)))
|
|
428
|
-
Memory.incRef(WasmI32.fromGrain(i))
|
|
429
|
-
i + 1
|
|
430
|
-
}
|
|
431
|
-
iter
|
|
432
|
-
}
|
|
433
|
-
|
|
434
421
|
/**
|
|
435
422
|
* Converts a map into an array of its key-value pairs.
|
|
436
423
|
*
|
|
@@ -439,20 +426,24 @@ let setInArray = array => {
|
|
|
439
426
|
*
|
|
440
427
|
* @since v0.2.0
|
|
441
428
|
*/
|
|
442
|
-
@
|
|
443
|
-
export let
|
|
444
|
-
let length =
|
|
445
|
-
let array = WasmI32.toGrain(allocateArray(length))
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
429
|
+
@unsafe
|
|
430
|
+
export let toArray: Map<a, b> -> Array<(a, b)> = map => {
|
|
431
|
+
let length = untagSimpleNumber(map.size)
|
|
432
|
+
let array = WasmI32.toGrain(allocateArray(length))
|
|
433
|
+
@unsafe
|
|
434
|
+
let reducer = (i, key, value) => {
|
|
435
|
+
// Assign the values into the array.
|
|
436
|
+
// We store them directly to prevent GC on uninitialized array data.
|
|
437
|
+
let array = WasmI32.fromGrain(array)
|
|
438
|
+
let item = (key, value)
|
|
439
|
+
WasmI32.store(
|
|
440
|
+
WasmI32.add(array, WasmI32.mul(untagSimpleNumber(i), 4n)),
|
|
441
|
+
Memory.incRef(WasmI32.fromGrain(item)),
|
|
442
|
+
8n
|
|
443
|
+
)
|
|
444
|
+
i + 1
|
|
445
|
+
}
|
|
446
|
+
reduce(reducer, 0, map)
|
|
456
447
|
array
|
|
457
448
|
}
|
|
458
449
|
|
package/marshal.gr
CHANGED
|
@@ -54,7 +54,7 @@ let roundTo8 = n => {
|
|
|
54
54
|
@unsafe
|
|
55
55
|
let isHeapPtr = value =>
|
|
56
56
|
(value & Tags._GRAIN_GENERIC_TAG_MASK) ==
|
|
57
|
-
|
|
57
|
+
Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
|
|
58
58
|
|
|
59
59
|
@unsafe
|
|
60
60
|
let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
@@ -157,9 +157,9 @@ let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
|
157
157
|
},
|
|
158
158
|
t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => {
|
|
159
159
|
acc +
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
16n +
|
|
161
|
+
size(load(value, 8n), 0n, valuesSeen, false) +
|
|
162
|
+
size(load(value, 12n), 0n, valuesSeen, false)
|
|
163
163
|
},
|
|
164
164
|
_ => {
|
|
165
165
|
fail "Unknown number type"
|