@grain/stdlib 0.5.4 → 0.5.6
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 +30 -0
- package/array.gr +60 -57
- package/array.md +24 -6
- package/buffer.gr +71 -1
- package/buffer.md +142 -0
- package/bytes.gr +52 -3
- package/bytes.md +117 -0
- package/char.gr +21 -18
- package/char.md +18 -3
- package/immutablepriorityqueue.gr +13 -13
- package/int32.gr +39 -37
- package/int32.md +6 -0
- package/int64.gr +39 -37
- package/int64.md +6 -0
- package/list.gr +31 -22
- package/list.md +39 -10
- package/map.gr +19 -28
- package/number.gr +81 -5
- package/number.md +64 -2
- 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/queue.gr +11 -9
- package/queue.md +2 -0
- package/regex.gr +76 -3
- 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 +3 -3
- package/runtime/equal.gr +1 -1
- package/runtime/numberUtils.gr +2 -2
- package/runtime/numberUtils.md +6 -0
- package/runtime/numbers.gr +4 -4
- 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/stack.gr +4 -2
- package/stack.md +2 -0
- package/string.gr +1 -1
- package/sys/time.gr +4 -4
package/pervasives.gr
CHANGED
|
@@ -473,10 +473,11 @@ export primitive ignore: a -> Void = "@ignore"
|
|
|
473
473
|
|
|
474
474
|
/**
|
|
475
475
|
* Assert that the given Boolean condition is `true`.
|
|
476
|
-
* Throws an `AssertionError` if the condition is `false`.
|
|
477
476
|
*
|
|
478
477
|
* @param condition: The condition to assert
|
|
479
478
|
*
|
|
479
|
+
* @throws AssertionError: When the `condition` is false
|
|
480
|
+
*
|
|
480
481
|
* @example assert 3 > 2
|
|
481
482
|
* @example assert true
|
|
482
483
|
*
|
|
@@ -578,7 +579,7 @@ export let cons = (a, b) =>
|
|
|
578
579
|
export let empty = [] // <- for parity with `cons`, but should be deleted as well
|
|
579
580
|
|
|
580
581
|
// Setup exception printing
|
|
581
|
-
@
|
|
582
|
+
@unsafe
|
|
582
583
|
let rec setupExceptions = () => {
|
|
583
584
|
Exception.dangerouslyRegisterPrinter(e => {
|
|
584
585
|
match (e) {
|
|
@@ -589,8 +590,6 @@ let rec setupExceptions = () => {
|
|
|
589
590
|
})
|
|
590
591
|
|
|
591
592
|
Exception.dangerouslyRegisterBasePrinter(e => Some(toString(e)))
|
|
592
|
-
Memory.decRef(WasmI32.fromGrain(setupExceptions))
|
|
593
|
-
void
|
|
594
593
|
}
|
|
595
594
|
|
|
596
595
|
setupExceptions()
|
package/pervasives.md
CHANGED
|
@@ -942,7 +942,6 @@ assert : Bool -> Void
|
|
|
942
942
|
```
|
|
943
943
|
|
|
944
944
|
Assert that the given Boolean condition is `true`.
|
|
945
|
-
Throws an `AssertionError` if the condition is `false`.
|
|
946
945
|
|
|
947
946
|
Parameters:
|
|
948
947
|
|
|
@@ -950,6 +949,12 @@ Parameters:
|
|
|
950
949
|
|-----|----|-----------|
|
|
951
950
|
|`condition`|`Bool`|The condition to assert|
|
|
952
951
|
|
|
952
|
+
Throws:
|
|
953
|
+
|
|
954
|
+
`AssertionError`
|
|
955
|
+
|
|
956
|
+
* When the `condition` is false
|
|
957
|
+
|
|
953
958
|
Examples:
|
|
954
959
|
|
|
955
960
|
```grain
|
package/queue.gr
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* @module Queue: An immutable queue implementation. A queue is a FIFO (first-in-first-out) data structure where new values are added to the end and retrieved or removed from the beginning.
|
|
3
3
|
* @example import Queue from "queue"
|
|
4
4
|
* @since v0.2.0
|
|
5
|
+
*
|
|
6
|
+
* @deprecated This module will be renamed to ImmutableQueue in the v0.6.0 release of Grain.
|
|
5
7
|
*/
|
|
6
8
|
import List from "list"
|
|
7
9
|
|
|
@@ -20,7 +22,7 @@ record Queue<a> {
|
|
|
20
22
|
|
|
21
23
|
/**
|
|
22
24
|
* An empty queue.
|
|
23
|
-
*
|
|
25
|
+
*
|
|
24
26
|
* @since v0.5.4
|
|
25
27
|
*/
|
|
26
28
|
export let empty = {
|
|
@@ -30,11 +32,11 @@ export let empty = {
|
|
|
30
32
|
|
|
31
33
|
/**
|
|
32
34
|
* Creates an empty queue.
|
|
33
|
-
*
|
|
35
|
+
*
|
|
34
36
|
* @returns An empty queue
|
|
35
|
-
*
|
|
37
|
+
*
|
|
36
38
|
* @deprecated This will be removed in the v0.6.0 release of Grain.
|
|
37
|
-
*
|
|
39
|
+
*
|
|
38
40
|
* @since v0.2.0
|
|
39
41
|
*/
|
|
40
42
|
export let make = () => {
|
|
@@ -43,7 +45,7 @@ export let make = () => {
|
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* Checks if the given queue contains any values.
|
|
46
|
-
*
|
|
48
|
+
*
|
|
47
49
|
* @param queue: The queue to check
|
|
48
50
|
* @returns `true` if the given queue is empty or `false` otherwise
|
|
49
51
|
*
|
|
@@ -58,7 +60,7 @@ export let isEmpty = queue => {
|
|
|
58
60
|
|
|
59
61
|
/**
|
|
60
62
|
* Returns the value at the beginning of the queue. It is not removed from the queue.
|
|
61
|
-
*
|
|
63
|
+
*
|
|
62
64
|
* @param queue: The queue to inspect
|
|
63
65
|
* @returns `Some(value)` containing the value at the beginning of the queue, or `None` if the queue is empty
|
|
64
66
|
*
|
|
@@ -76,7 +78,7 @@ export let peek = queue => {
|
|
|
76
78
|
|
|
77
79
|
/**
|
|
78
80
|
* Adds a value to the end of the queue.
|
|
79
|
-
*
|
|
81
|
+
*
|
|
80
82
|
* @param value: The value to append
|
|
81
83
|
* @param queue: The queue to update
|
|
82
84
|
* @returns An updated queue
|
|
@@ -95,7 +97,7 @@ export let push = (value, queue) => {
|
|
|
95
97
|
|
|
96
98
|
/**
|
|
97
99
|
* Dequeues the next value in the queue.
|
|
98
|
-
*
|
|
100
|
+
*
|
|
99
101
|
* @param queue: The queue to change
|
|
100
102
|
* @returns An updated queue
|
|
101
103
|
*
|
|
@@ -119,7 +121,7 @@ export let pop = queue => {
|
|
|
119
121
|
|
|
120
122
|
/**
|
|
121
123
|
* Get the number of values in a queue.
|
|
122
|
-
*
|
|
124
|
+
*
|
|
123
125
|
* @param queue: The queue to inspect
|
|
124
126
|
* @returns The number of values in the queue
|
|
125
127
|
*
|
package/queue.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
title: Queue
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
+
> **Deprecated:** This module will be renamed to ImmutableQueue in the v0.6.0 release of Grain.
|
|
6
|
+
|
|
5
7
|
An immutable queue implementation. A queue is a FIFO (first-in-first-out) data structure where new values are added to the end and retrieved or removed from the beginning.
|
|
6
8
|
|
|
7
9
|
<details disabled>
|
package/regex.gr
CHANGED
|
@@ -458,7 +458,10 @@ enum ParsedRegularExpression {
|
|
|
458
458
|
), // regex, n-start, num-n, needs-backtrack
|
|
459
459
|
REReference(Number, Bool), // n, case-sensitive
|
|
460
460
|
RERange(RERange),
|
|
461
|
-
REUnicodeCategories(
|
|
461
|
+
REUnicodeCategories(
|
|
462
|
+
List<UnicodeCategory>,
|
|
463
|
+
Bool
|
|
464
|
+
), // symlist, true=match/false=does-not-match
|
|
462
465
|
}
|
|
463
466
|
|
|
464
467
|
let needsBacktrack = (rx: ParsedRegularExpression) => {
|
|
@@ -3626,7 +3629,7 @@ export record MatchResult {
|
|
|
3626
3629
|
/**
|
|
3627
3630
|
* Returns the contents of the given group
|
|
3628
3631
|
*/
|
|
3629
|
-
|
|
3632
|
+
group: Number -> Option<String>,
|
|
3630
3633
|
/**
|
|
3631
3634
|
* Returns the position of the given group
|
|
3632
3635
|
*/
|
|
@@ -3973,7 +3976,6 @@ let regexReplaceHelp =
|
|
|
3973
3976
|
all: Bool,
|
|
3974
3977
|
) => {
|
|
3975
3978
|
let buf = makeMatchBuffer(toSearch)
|
|
3976
|
-
let mut out = []
|
|
3977
3979
|
let rec loop = searchPos => {
|
|
3978
3980
|
let state = Array.make(rx.reNumGroups, None)
|
|
3979
3981
|
let inStart = max(0, searchPos - rx.reMaxLookbehind)
|
|
@@ -4067,3 +4069,74 @@ export let replaceAll =
|
|
|
4067
4069
|
) => {
|
|
4068
4070
|
regexReplaceHelp(rx, toSearch, replacement, true)
|
|
4069
4071
|
}
|
|
4072
|
+
|
|
4073
|
+
let regexSplitHelp = (rx: RegularExpression, str: String, all: Bool) => {
|
|
4074
|
+
// Get list of matches
|
|
4075
|
+
let regexMatches = if (all) {
|
|
4076
|
+
findAll(rx, str)
|
|
4077
|
+
} else {
|
|
4078
|
+
match (find(rx, str)) {
|
|
4079
|
+
None => [],
|
|
4080
|
+
Some(m) => [m],
|
|
4081
|
+
}
|
|
4082
|
+
}
|
|
4083
|
+
// Perform replacements
|
|
4084
|
+
let mut out = []
|
|
4085
|
+
let mut currentLocation = 0
|
|
4086
|
+
List.forEach(regexMatch => {
|
|
4087
|
+
let locations = regexMatch.allGroupPositions()
|
|
4088
|
+
Array.forEachi((pos, i) => {
|
|
4089
|
+
match (pos) {
|
|
4090
|
+
Some((start, end)) => {
|
|
4091
|
+
if (i == 0) {
|
|
4092
|
+
// Add the string between this match and the last match
|
|
4093
|
+
out = [String.slice(currentLocation, start, str), ...out]
|
|
4094
|
+
} else {
|
|
4095
|
+
// This adds the groups back in
|
|
4096
|
+
out = [String.slice(start, end, str), ...out]
|
|
4097
|
+
}
|
|
4098
|
+
if (end > currentLocation) currentLocation = end
|
|
4099
|
+
},
|
|
4100
|
+
None => void,
|
|
4101
|
+
}
|
|
4102
|
+
}, locations)
|
|
4103
|
+
}, regexMatches)
|
|
4104
|
+
out = [String.slice(currentLocation, String.length(str), str), ...out]
|
|
4105
|
+
List.reverse(out)
|
|
4106
|
+
}
|
|
4107
|
+
|
|
4108
|
+
/**
|
|
4109
|
+
* Splits the given string at the first match for the given regular expression.
|
|
4110
|
+
*
|
|
4111
|
+
* If the regex pattern contains capture groups, the content of the groups
|
|
4112
|
+
* will be included in the output list.
|
|
4113
|
+
*
|
|
4114
|
+
* @param rx: The regular expression to match
|
|
4115
|
+
* @param str: The string to split
|
|
4116
|
+
* @returns A list of the split segments
|
|
4117
|
+
*
|
|
4118
|
+
* @example assert Regex.split(Result.unwrap(Regex.make(",")), "a,b,c") == [ "a", "b,c" ]
|
|
4119
|
+
*
|
|
4120
|
+
* @since v0.5.5
|
|
4121
|
+
*/
|
|
4122
|
+
export let split = (rx: RegularExpression, str: String) => {
|
|
4123
|
+
regexSplitHelp(rx, str, false)
|
|
4124
|
+
}
|
|
4125
|
+
|
|
4126
|
+
/**
|
|
4127
|
+
* Splits the given string at every match for the given regular expression.
|
|
4128
|
+
*
|
|
4129
|
+
* If the regex pattern contains capture groups, the content of the groups
|
|
4130
|
+
* will be included in the output list.
|
|
4131
|
+
*
|
|
4132
|
+
* @param rx: The regular expression to match
|
|
4133
|
+
* @param str: The string to split
|
|
4134
|
+
* @returns A list of the split segments
|
|
4135
|
+
*
|
|
4136
|
+
* @example assert Regex.splitAll(Result.unwrap(Regex.make(",")), "a,b,c") == [ "a", "b", "c" ]
|
|
4137
|
+
*
|
|
4138
|
+
* @since v0.5.5
|
|
4139
|
+
*/
|
|
4140
|
+
export let splitAll = (rx: RegularExpression, str: String) => {
|
|
4141
|
+
regexSplitHelp(rx, str, true)
|
|
4142
|
+
}
|
package/regex.md
CHANGED
|
@@ -447,3 +447,73 @@ Examples:
|
|
|
447
447
|
assert Regex.replaceAll(Result.unwrap(Regex.make("o")), "skoot", "r") == "skrrt"
|
|
448
448
|
```
|
|
449
449
|
|
|
450
|
+
### Regex.**split**
|
|
451
|
+
|
|
452
|
+
<details disabled>
|
|
453
|
+
<summary tabindex="-1">Added in <code>0.5.5</code></summary>
|
|
454
|
+
No other changes yet.
|
|
455
|
+
</details>
|
|
456
|
+
|
|
457
|
+
```grain
|
|
458
|
+
split : (RegularExpression, String) -> List<String>
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
Splits the given string at the first match for the given regular expression.
|
|
462
|
+
|
|
463
|
+
If the regex pattern contains capture groups, the content of the groups
|
|
464
|
+
will be included in the output list.
|
|
465
|
+
|
|
466
|
+
Parameters:
|
|
467
|
+
|
|
468
|
+
|param|type|description|
|
|
469
|
+
|-----|----|-----------|
|
|
470
|
+
|`rx`|`RegularExpression`|The regular expression to match|
|
|
471
|
+
|`str`|`String`|The string to split|
|
|
472
|
+
|
|
473
|
+
Returns:
|
|
474
|
+
|
|
475
|
+
|type|description|
|
|
476
|
+
|----|-----------|
|
|
477
|
+
|`List<String>`|A list of the split segments|
|
|
478
|
+
|
|
479
|
+
Examples:
|
|
480
|
+
|
|
481
|
+
```grain
|
|
482
|
+
assert Regex.split(Result.unwrap(Regex.make(",")), "a,b,c") == [ "a", "b,c" ]
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### Regex.**splitAll**
|
|
486
|
+
|
|
487
|
+
<details disabled>
|
|
488
|
+
<summary tabindex="-1">Added in <code>0.5.5</code></summary>
|
|
489
|
+
No other changes yet.
|
|
490
|
+
</details>
|
|
491
|
+
|
|
492
|
+
```grain
|
|
493
|
+
splitAll : (RegularExpression, String) -> List<String>
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
Splits the given string at every match for the given regular expression.
|
|
497
|
+
|
|
498
|
+
If the regex pattern contains capture groups, the content of the groups
|
|
499
|
+
will be included in the output list.
|
|
500
|
+
|
|
501
|
+
Parameters:
|
|
502
|
+
|
|
503
|
+
|param|type|description|
|
|
504
|
+
|-----|----|-----------|
|
|
505
|
+
|`rx`|`RegularExpression`|The regular expression to match|
|
|
506
|
+
|`str`|`String`|The string to split|
|
|
507
|
+
|
|
508
|
+
Returns:
|
|
509
|
+
|
|
510
|
+
|type|description|
|
|
511
|
+
|----|-----------|
|
|
512
|
+
|`List<String>`|A list of the split segments|
|
|
513
|
+
|
|
514
|
+
Examples:
|
|
515
|
+
|
|
516
|
+
```grain
|
|
517
|
+
assert Regex.splitAll(Result.unwrap(Regex.make(",")), "a,b,c") == [ "a", "b", "c" ]
|
|
518
|
+
```
|
|
519
|
+
|
package/result.gr
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @module Result: Utilities for working with the Result data type.
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* The Result type is an enum that represents the possibility of a success case (with the `Ok` variant),
|
|
5
5
|
* or an error case (with the `Err` variant). Use a Result as the return type of a function that may return an error.
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* @example import Result from "result"
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
*
|
|
9
|
+
*
|
|
10
10
|
* @example let success = Ok((x) => 1 + x) // Creates a successful Result containing (x) => 1 + x
|
|
11
11
|
* @example let failure = Err("Something bad happened") // Creates an unsuccessful Result containing "Something bad happened"
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
13
|
* @since v0.2.0
|
|
14
14
|
*/
|
|
15
15
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*
|
|
23
23
|
* @param result: The result to check
|
|
24
24
|
* @returns `true` if the Result is the `Ok` variant or `false` otherwise
|
|
25
|
-
*
|
|
25
|
+
*
|
|
26
26
|
* @since v0.2.0
|
|
27
27
|
*/
|
|
28
28
|
export let isOk = result => {
|
|
@@ -37,7 +37,7 @@ export let isOk = result => {
|
|
|
37
37
|
*
|
|
38
38
|
* @param result: The result to check
|
|
39
39
|
* @returns `true` if the Result is the `Err` variant or `false` otherwise
|
|
40
|
-
*
|
|
40
|
+
*
|
|
41
41
|
* @since v0.2.0
|
|
42
42
|
*/
|
|
43
43
|
export let isErr = result => !isOk(result)
|
|
@@ -47,7 +47,7 @@ export let isErr = result => !isOk(result)
|
|
|
47
47
|
*
|
|
48
48
|
* @param result: The result to convert
|
|
49
49
|
* @returns `Some(value)` if the Result is `Ok(value)` or `None` if the Result is an `Err`
|
|
50
|
-
*
|
|
50
|
+
*
|
|
51
51
|
* @since v0.2.0
|
|
52
52
|
*/
|
|
53
53
|
export let toOption = result => {
|
|
@@ -63,7 +63,7 @@ export let toOption = result => {
|
|
|
63
63
|
* @param fn: The function to call on the value of an `Ok` variant
|
|
64
64
|
* @param result: The result to map
|
|
65
65
|
* @returns A new Result produced by the mapping function if the variant was `Ok` or the unmodified `Err` otherwise
|
|
66
|
-
*
|
|
66
|
+
*
|
|
67
67
|
* @since v0.2.0
|
|
68
68
|
*/
|
|
69
69
|
export let flatMap = (fn, result) => {
|
|
@@ -79,7 +79,7 @@ export let flatMap = (fn, result) => {
|
|
|
79
79
|
* @param fn: The function to call on the value of an `Err` variant
|
|
80
80
|
* @param result: The result to map
|
|
81
81
|
* @returns A new Result produced by the mapping function if the variant was `Err` or the unmodified `Ok` otherwise
|
|
82
|
-
*
|
|
82
|
+
*
|
|
83
83
|
* @since v0.2.0
|
|
84
84
|
*/
|
|
85
85
|
export let flatMapErr = (fn, result) => {
|
|
@@ -95,7 +95,7 @@ export let flatMapErr = (fn, result) => {
|
|
|
95
95
|
* @param fn: The function to call on the value of an `Ok` variant
|
|
96
96
|
* @param result: The result to map
|
|
97
97
|
* @returns A new `Ok` variant produced by the mapping function if the variant was `Ok` or the unmodified `Err` otherwise
|
|
98
|
-
*
|
|
98
|
+
*
|
|
99
99
|
* @since v0.2.0
|
|
100
100
|
*/
|
|
101
101
|
export let map = (fn, result) => {
|
|
@@ -111,7 +111,7 @@ export let map = (fn, result) => {
|
|
|
111
111
|
* @param fn: The function to call on the value of an `Err` variant
|
|
112
112
|
* @param result: The result to map
|
|
113
113
|
* @returns A new `Err` variant produced by the mapping function if the variant was `Err` or the unmodified `Ok` otherwise
|
|
114
|
-
*
|
|
114
|
+
*
|
|
115
115
|
* @since v0.2.0
|
|
116
116
|
*/
|
|
117
117
|
export let mapErr = (fn, result) => {
|
|
@@ -129,8 +129,8 @@ export let mapErr = (fn, result) => {
|
|
|
129
129
|
* @param def: A fallback value for an `Err` variant
|
|
130
130
|
* @param result: The result to map
|
|
131
131
|
* @returns The value produced by the mapping function if the result is of the `Ok` variant or the default value otherwise
|
|
132
|
-
*
|
|
133
|
-
* @since v0.2.0
|
|
132
|
+
*
|
|
133
|
+
* @since v0.2.0
|
|
134
134
|
*/
|
|
135
135
|
export let mapWithDefault = (fn, def, result) => {
|
|
136
136
|
match (result) {
|
|
@@ -148,7 +148,7 @@ export let mapWithDefault = (fn, def, result) => {
|
|
|
148
148
|
* @param fnErr: The function to call on the value of an `Err` variant
|
|
149
149
|
* @param result: The result to map
|
|
150
150
|
* @returns The value produced by one of the mapping functions
|
|
151
|
-
*
|
|
151
|
+
*
|
|
152
152
|
* @since v0.2.0
|
|
153
153
|
*/
|
|
154
154
|
export let mapWithDefaultFn = (fnOk, fnErr, result) => {
|
|
@@ -164,7 +164,7 @@ export let mapWithDefaultFn = (fnOk, fnErr, result) => {
|
|
|
164
164
|
* @param result1: The first result
|
|
165
165
|
* @param result2: The second result
|
|
166
166
|
* @returns The first Result if it is the `Ok` variant or the second Result otherwise
|
|
167
|
-
*
|
|
167
|
+
*
|
|
168
168
|
* @since v0.2.0
|
|
169
169
|
*/
|
|
170
170
|
export let or = (result1, result2) => {
|
|
@@ -180,7 +180,7 @@ export let or = (result1, result2) => {
|
|
|
180
180
|
* @param result1: The first result
|
|
181
181
|
* @param result2: The second result
|
|
182
182
|
* @returns The second Result if both are the `Ok` variant or the first Result otherwise
|
|
183
|
-
*
|
|
183
|
+
*
|
|
184
184
|
* @since v0.2.0
|
|
185
185
|
*/
|
|
186
186
|
export let and = (result1, result2) => {
|
|
@@ -198,7 +198,7 @@ export let and = (result1, result2) => {
|
|
|
198
198
|
* @param fnOk: The function to call on the value of an `Ok` variant
|
|
199
199
|
* @param fnErr: The function to call on the value of an `Err` variant
|
|
200
200
|
* @param result: The result to inspect
|
|
201
|
-
*
|
|
201
|
+
*
|
|
202
202
|
* @since v0.2.0
|
|
203
203
|
*/
|
|
204
204
|
export let peek = (fnOk, fnErr, result) => {
|
|
@@ -213,7 +213,7 @@ export let peek = (fnOk, fnErr, result) => {
|
|
|
213
213
|
*
|
|
214
214
|
* @param fn: The function to call on the value of an `Ok` variant
|
|
215
215
|
* @param result: The result to inspect
|
|
216
|
-
*
|
|
216
|
+
*
|
|
217
217
|
* @since v0.2.0
|
|
218
218
|
*/
|
|
219
219
|
export let peekOk = (fn, result) => {
|
|
@@ -225,7 +225,7 @@ export let peekOk = (fn, result) => {
|
|
|
225
225
|
*
|
|
226
226
|
* @param fn: The function to call on the value of an `Err` variant
|
|
227
227
|
* @param result: The result to inspect
|
|
228
|
-
*
|
|
228
|
+
*
|
|
229
229
|
* @since v0.2.0
|
|
230
230
|
*/
|
|
231
231
|
export let peekErr = (fn, result) => {
|
|
@@ -240,6 +240,8 @@ export let peekErr = (fn, result) => {
|
|
|
240
240
|
* @param result: The result to extract a value from
|
|
241
241
|
* @returns The unwrapped value if the Result is the `Ok` variant
|
|
242
242
|
*
|
|
243
|
+
* @throws Failure(String): When the `result` is `Err`
|
|
244
|
+
*
|
|
243
245
|
* @example Result.expect("Unexpected error", Ok(1234)) + 42
|
|
244
246
|
*
|
|
245
247
|
* @since v0.4.0
|
|
@@ -258,6 +260,8 @@ export let expect = (msg, result) => {
|
|
|
258
260
|
* @param result: The result to extract a value from
|
|
259
261
|
* @returns The unwrapped value if the result is the `Ok` variant
|
|
260
262
|
*
|
|
263
|
+
* @throws Failure(String): When the `result` is `Err`
|
|
264
|
+
*
|
|
261
265
|
* @example Result.unwrap(Err("This will throw"))
|
|
262
266
|
*
|
|
263
267
|
* @since v0.4.0
|
package/result.md
CHANGED
|
@@ -406,6 +406,12 @@ Returns:
|
|
|
406
406
|
|----|-----------|
|
|
407
407
|
|`a`|The unwrapped value if the Result is the `Ok` variant|
|
|
408
408
|
|
|
409
|
+
Throws:
|
|
410
|
+
|
|
411
|
+
`Failure(String)`
|
|
412
|
+
|
|
413
|
+
* When the `result` is `Err`
|
|
414
|
+
|
|
409
415
|
Examples:
|
|
410
416
|
|
|
411
417
|
```grain
|
|
@@ -438,6 +444,12 @@ Returns:
|
|
|
438
444
|
|----|-----------|
|
|
439
445
|
|`a`|The unwrapped value if the result is the `Ok` variant|
|
|
440
446
|
|
|
447
|
+
Throws:
|
|
448
|
+
|
|
449
|
+
`Failure(String)`
|
|
450
|
+
|
|
451
|
+
* When the `result` is `Err`
|
|
452
|
+
|
|
441
453
|
Examples:
|
|
442
454
|
|
|
443
455
|
```grain
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/* grainc-flags --no-pervasives */
|
|
2
|
+
|
|
3
|
+
// This module was based on Rust's dec2flt
|
|
4
|
+
// https://github.com/rust-lang/rust/blob/1cbc45942d5c0f6eb5d94e3b10762ba541958035/library/core/src/num/dec2flt/common.rs
|
|
5
|
+
// Rust's MIT license is provided below:
|
|
6
|
+
/*
|
|
7
|
+
* Permission is hereby granted, free of charge, to any
|
|
8
|
+
* person obtaining a copy of this software and associated
|
|
9
|
+
* documentation files (the "Software"), to deal in the
|
|
10
|
+
* Software without restriction, including without
|
|
11
|
+
* limitation the rights to use, copy, modify, merge,
|
|
12
|
+
* publish, distribute, sublicense, and/or sell copies of
|
|
13
|
+
* the Software, and to permit persons to whom the Software
|
|
14
|
+
* is furnished to do so, subject to the following
|
|
15
|
+
* conditions:
|
|
16
|
+
*
|
|
17
|
+
* The above copyright notice and this permission notice
|
|
18
|
+
* shall be included in all copies or substantial portions
|
|
19
|
+
* of the Software.
|
|
20
|
+
*
|
|
21
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
22
|
+
* ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
23
|
+
* TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
24
|
+
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
25
|
+
* SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
26
|
+
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
27
|
+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
28
|
+
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
29
|
+
* DEALINGS IN THE SOFTWARE.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import WasmI32 from "runtime/unsafe/wasmi32"
|
|
33
|
+
import WasmI64 from "runtime/unsafe/wasmi64"
|
|
34
|
+
import WasmF64 from "runtime/unsafe/wasmf64"
|
|
35
|
+
import { newInt32, newInt64, newFloat64 } from "runtime/dataStructures"
|
|
36
|
+
import { get_POWERS10 } from "runtime/numberUtils"
|
|
37
|
+
import { get_F64_POWERS10_FAST_PATH, get_POWERS5 } from "./table"
|
|
38
|
+
|
|
39
|
+
primitive (&&): (Bool, Bool) -> Bool = "@and"
|
|
40
|
+
primitive (||): (Bool, Bool) -> Bool = "@or"
|
|
41
|
+
primitive (!): Bool -> Bool = "@not"
|
|
42
|
+
|
|
43
|
+
export record BiasedFp {
|
|
44
|
+
f: Int64,
|
|
45
|
+
mut e: Int32,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@unsafe
|
|
49
|
+
export let _MINIMUM_EXPONENT = -1023n
|
|
50
|
+
@unsafe
|
|
51
|
+
export let _MIN_EXPONENT_ROUND_TO_EVEN = -4N
|
|
52
|
+
@unsafe
|
|
53
|
+
export let _MAX_EXPONENT_ROUND_TO_EVEN = 23N
|
|
54
|
+
@unsafe
|
|
55
|
+
export let _MIN_EXPONENT_FAST_PATH = -22n
|
|
56
|
+
@unsafe
|
|
57
|
+
export let _MAX_EXPONENT_FAST_PATH = 22n
|
|
58
|
+
@unsafe
|
|
59
|
+
export let _MAX_EXPONENT_DISGUISED_FAST_PATH = 37n
|
|
60
|
+
@unsafe
|
|
61
|
+
export let _MAX_MANTISSA_FAST_PATH = WasmI64.shl(2N, 52N)
|
|
62
|
+
@unsafe
|
|
63
|
+
export let _MANTISSA_EXPLICIT_BITS_64 = 52N
|
|
64
|
+
@unsafe
|
|
65
|
+
export let _MANTISSA_EXPLICIT_BITS_32 = 52n
|
|
66
|
+
@unsafe
|
|
67
|
+
export let _INFINITE_POWER = 0x7FFn
|
|
68
|
+
@unsafe
|
|
69
|
+
export let _SMALLEST_POWER_OF_TEN = -342N
|
|
70
|
+
@unsafe
|
|
71
|
+
export let _LARGEST_POWER_OF_TEN = 308N
|
|
72
|
+
@unsafe
|
|
73
|
+
export let _SMALLEST_POWER_OF_FIVE = -342N
|
|
74
|
+
@unsafe
|
|
75
|
+
export let _LARGEST_POWER_OF_FIVE = 308N
|
|
76
|
+
|
|
77
|
+
@unsafe
|
|
78
|
+
export let _CHAR_CODE_UNDERSCORE = 0x5fn
|
|
79
|
+
@unsafe
|
|
80
|
+
export let _CHAR_CODE_PLUS = 0x2Bn
|
|
81
|
+
@unsafe
|
|
82
|
+
export let _CHAR_CODE_MINUS = 0x2Dn
|
|
83
|
+
@unsafe
|
|
84
|
+
export let _CHAR_CODE_0 = 0x30n
|
|
85
|
+
@unsafe
|
|
86
|
+
export let _CHAR_CODE_e = 0x65n
|
|
87
|
+
@unsafe
|
|
88
|
+
export let _CHAR_CODE_E = 0x45n
|
|
89
|
+
@unsafe
|
|
90
|
+
export let _CHAR_CODE_DOT = 0x2En
|
|
91
|
+
@unsafe
|
|
92
|
+
export let _CHAR_CODE_A = 0x41n
|
|
93
|
+
@unsafe
|
|
94
|
+
export let _CHAR_CODE_Z = 0x5an
|
|
95
|
+
@unsafe
|
|
96
|
+
export let _CHAR_CODE_a = 0x61n
|
|
97
|
+
@unsafe
|
|
98
|
+
export let _CHAR_CODE_f = 0x66n
|
|
99
|
+
@unsafe
|
|
100
|
+
export let _CHAR_CODE_i = 0x69n
|
|
101
|
+
@unsafe
|
|
102
|
+
export let _CHAR_CODE_n = 0x6en
|
|
103
|
+
@unsafe
|
|
104
|
+
export let _CHAR_CODE_t = 0x74n
|
|
105
|
+
@unsafe
|
|
106
|
+
export let _CHAR_CODE_y = 0x79n
|
|
107
|
+
|
|
108
|
+
export let fpZero = () => { f: 0L, e: 0l }
|
|
109
|
+
@unsafe
|
|
110
|
+
export let fpInf = () =>
|
|
111
|
+
{
|
|
112
|
+
f: 0L,
|
|
113
|
+
e: WasmI32.toGrain(newInt32(_INFINITE_POWER)): Int32,
|
|
114
|
+
}
|
|
115
|
+
export let fpErr = () => { f: 0L, e: -1l }
|
|
116
|
+
export let fpNan = () => { f: 1L, e: -1l }
|
|
117
|
+
|
|
118
|
+
@unsafe
|
|
119
|
+
export let getPowers10 = (i: WasmI32) => {
|
|
120
|
+
WasmI32.load(get_POWERS10(), WasmI32.mul(4n, i))
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
@unsafe
|
|
124
|
+
export let getPowers10FastPath = (i: WasmI32) => {
|
|
125
|
+
WasmF64.load(get_F64_POWERS10_FAST_PATH(), WasmI32.mul(8n, i))
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// https://stdrs.dev/nightly/x86_64-unknown-linux-gnu/src/core/num/dec2flt/common.rs.html#165
|
|
129
|
+
@unsafe
|
|
130
|
+
export let is8Digits = (value: WasmI64) => {
|
|
131
|
+
let (+) = WasmI64.add
|
|
132
|
+
let (-) = WasmI64.sub
|
|
133
|
+
let (|) = WasmI64.or
|
|
134
|
+
let (&) = WasmI64.and
|
|
135
|
+
let (==) = WasmI64.eq
|
|
136
|
+
|
|
137
|
+
let a = value + 0x4646_4646_4646_4646N
|
|
138
|
+
let b = value - 0x3030_3030_3030_3030N
|
|
139
|
+
let c = (a | b) & 0x8080_8080_8080_8080N
|
|
140
|
+
|
|
141
|
+
c == 0N
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// From Rust:
|
|
145
|
+
// Calculate a base 2 exponent from a decimal exponent.
|
|
146
|
+
// This uses a pre-computed integer approximation for
|
|
147
|
+
// log2(10), where 217706 / 2^16 is accurate for the
|
|
148
|
+
// entire range of non-finite decimal exponents.
|
|
149
|
+
@unsafe
|
|
150
|
+
export let power = (q: WasmI32) => {
|
|
151
|
+
let (+) = WasmI32.add
|
|
152
|
+
let (*) = WasmI32.mul
|
|
153
|
+
let (>>) = WasmI32.shrS
|
|
154
|
+
|
|
155
|
+
((q * (152_170n + 65536n)) >> 16n) + 63n
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@unsafe
|
|
159
|
+
export let fullMultiplication = (a: WasmI64, b: WasmI64) => {
|
|
160
|
+
// Adapted from https://www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
|
|
161
|
+
let (+) = WasmI64.add
|
|
162
|
+
let (*) = WasmI64.mul
|
|
163
|
+
let (&) = WasmI64.and
|
|
164
|
+
let (>>) = WasmI64.shrU
|
|
165
|
+
let (<<) = WasmI64.shl
|
|
166
|
+
|
|
167
|
+
let aLo = a & 0xffffffffN
|
|
168
|
+
let bLo = b & 0xffffffffN
|
|
169
|
+
let aLoxbLo = aLo * bLo
|
|
170
|
+
let w3 = aLoxbLo & 0xffffffffN
|
|
171
|
+
let k = aLoxbLo >> 32N
|
|
172
|
+
|
|
173
|
+
let aHi = a >> 32N
|
|
174
|
+
let mid = aHi * bLo + k
|
|
175
|
+
let k = mid & 0xffffffffN
|
|
176
|
+
let w1 = mid >> 32N
|
|
177
|
+
|
|
178
|
+
let bHi = b >> 32N
|
|
179
|
+
let mid = aLo * bHi + k
|
|
180
|
+
let k = mid >> 32N
|
|
181
|
+
|
|
182
|
+
let hi = aHi * bHi + w1 + k
|
|
183
|
+
let lo = (mid << 32N) + w3
|
|
184
|
+
|
|
185
|
+
(WasmI32.toGrain(newInt64(lo)): Int64, WasmI32.toGrain(newInt64(hi)): Int64)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
@unsafe
|
|
189
|
+
export let biasedFpToNumber = (fp, negative) => {
|
|
190
|
+
let f = WasmI64.load(WasmI32.fromGrain(fp.f), 8n)
|
|
191
|
+
let e = WasmI64.extendI32S(WasmI32.load(WasmI32.fromGrain(fp.e), 8n))
|
|
192
|
+
let word = WasmI64.or(f, WasmI64.shl(e, _MANTISSA_EXPLICIT_BITS_64))
|
|
193
|
+
let mut float = WasmF64.reinterpretI64(word)
|
|
194
|
+
if (negative) {
|
|
195
|
+
float = WasmF64.neg(float)
|
|
196
|
+
}
|
|
197
|
+
WasmI32.toGrain(newFloat64(float)): Number
|
|
198
|
+
}
|