@grain/stdlib 0.6.6 → 0.7.1
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 +67 -0
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/array.gr +55 -7
- package/array.md +606 -560
- package/bigint.md +228 -228
- package/buffer.gr +85 -53
- package/buffer.md +442 -319
- package/bytes.gr +112 -35
- package/bytes.md +299 -219
- package/char.gr +201 -99
- package/char.md +447 -120
- package/exception.gr +11 -11
- package/exception.md +29 -4
- package/float32.gr +327 -3
- package/float32.md +698 -111
- package/float64.gr +320 -3
- package/float64.md +698 -111
- package/fs.gr +1082 -0
- package/fs.md +630 -0
- package/hash.gr +142 -88
- package/hash.md +105 -17
- package/int16.md +178 -178
- package/int32.gr +26 -5
- package/int32.md +266 -231
- package/int64.gr +27 -2
- package/int64.md +266 -231
- package/int8.md +178 -178
- package/json.gr +366 -51
- package/json.md +431 -15
- package/list.gr +328 -31
- package/list.md +759 -336
- package/map.gr +20 -12
- package/map.md +266 -260
- package/marshal.gr +41 -40
- package/marshal.md +14 -14
- package/number.gr +278 -35
- package/number.md +688 -269
- package/option.md +162 -162
- package/package.json +5 -3
- package/path.gr +48 -0
- package/path.md +180 -89
- package/pervasives.gr +2 -2
- package/pervasives.md +275 -275
- package/priorityqueue.gr +7 -7
- package/priorityqueue.md +131 -131
- package/queue.gr +183 -29
- package/queue.md +404 -148
- package/random.md +43 -43
- package/range.gr +4 -4
- package/range.md +42 -42
- package/rational.md +123 -123
- package/regex.gr +52 -51
- package/regex.md +102 -102
- package/result.md +118 -118
- package/runtime/atof/common.md +39 -39
- package/runtime/atof/decimal.gr +6 -6
- package/runtime/atof/decimal.md +14 -14
- package/runtime/atof/lemire.gr +5 -5
- package/runtime/atof/lemire.md +1 -1
- package/runtime/atof/parse.gr +16 -16
- package/runtime/atof/parse.md +2 -2
- package/runtime/atof/slow.md +1 -1
- package/runtime/atof/table.md +2 -2
- package/runtime/atoi/parse.gr +3 -3
- package/runtime/atoi/parse.md +1 -1
- package/runtime/bigint.gr +15 -47
- package/runtime/bigint.md +54 -60
- package/runtime/compare.gr +2 -2
- package/runtime/compare.md +8 -8
- package/runtime/dataStructures.md +211 -211
- package/runtime/debugPrint.gr +4 -1
- package/runtime/debugPrint.md +9 -9
- package/runtime/equal.gr +99 -77
- package/runtime/equal.md +8 -8
- package/runtime/exception.gr +62 -82
- package/runtime/exception.md +62 -11
- package/runtime/gc.gr +39 -45
- package/runtime/gc.md +4 -4
- package/runtime/malloc.gr +7 -7
- package/runtime/malloc.md +13 -13
- package/runtime/math/kernel/cos.gr +70 -0
- package/runtime/math/kernel/cos.md +14 -0
- package/runtime/math/kernel/sin.gr +65 -0
- package/runtime/math/kernel/sin.md +14 -0
- package/runtime/math/kernel/tan.gr +136 -0
- package/runtime/math/kernel/tan.md +14 -0
- package/runtime/math/rempio2.gr +244 -0
- package/runtime/math/rempio2.md +14 -0
- package/runtime/math/trig.gr +130 -0
- package/runtime/math/trig.md +28 -0
- package/runtime/math/umuldi.gr +26 -0
- package/runtime/math/umuldi.md +14 -0
- package/runtime/numberUtils.gr +29 -29
- package/runtime/numberUtils.md +12 -12
- package/runtime/numbers.gr +373 -381
- package/runtime/numbers.md +348 -342
- package/runtime/string.gr +37 -105
- package/runtime/string.md +20 -26
- package/runtime/unsafe/constants.md +24 -24
- package/runtime/unsafe/conv.md +19 -19
- package/runtime/unsafe/memory.gr +24 -20
- package/runtime/unsafe/memory.md +27 -7
- package/runtime/unsafe/offsets.gr +36 -0
- package/runtime/unsafe/offsets.md +88 -0
- package/runtime/unsafe/panic.gr +28 -0
- package/runtime/unsafe/panic.md +14 -0
- package/runtime/unsafe/tags.md +32 -32
- package/runtime/unsafe/wasmf32.md +28 -28
- package/runtime/unsafe/wasmf64.md +28 -28
- package/runtime/unsafe/wasmi32.md +47 -47
- package/runtime/unsafe/wasmi64.md +50 -50
- package/runtime/utf8.gr +189 -0
- package/runtime/utf8.md +117 -0
- package/runtime/wasi.gr +4 -2
- package/runtime/wasi.md +147 -147
- package/set.gr +18 -11
- package/set.md +253 -247
- package/stack.gr +171 -2
- package/stack.md +371 -89
- package/string.gr +352 -557
- package/string.md +298 -255
- package/uint16.md +170 -170
- package/uint32.gr +25 -4
- package/uint32.md +249 -214
- package/uint64.gr +25 -5
- package/uint64.md +249 -214
- package/uint8.md +170 -170
- package/uri.gr +57 -53
- package/uri.md +88 -89
- package/wasi/file.gr +67 -59
- package/wasi/file.md +308 -308
- package/wasi/process.md +26 -26
- package/wasi/random.md +12 -12
- package/wasi/time.md +16 -16
- package/runtime/utils/printing.gr +0 -60
- package/runtime/utils/printing.md +0 -26
package/marshal.gr
CHANGED
|
@@ -75,8 +75,8 @@ let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
|
75
75
|
}
|
|
76
76
|
let heapPtr = value
|
|
77
77
|
match (load(heapPtr, 0n)) {
|
|
78
|
-
t when t == Tags._GRAIN_STRING_HEAP_TAG
|
|
79
|
-
t == Tags._GRAIN_BYTES_HEAP_TAG => {
|
|
78
|
+
t when t == Tags._GRAIN_STRING_HEAP_TAG
|
|
79
|
+
|| t == Tags._GRAIN_BYTES_HEAP_TAG => {
|
|
80
80
|
acc + roundTo8(8n + load(heapPtr, 4n))
|
|
81
81
|
},
|
|
82
82
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
@@ -142,27 +142,27 @@ let rec size = (value, acc, valuesSeen, toplevel) => {
|
|
|
142
142
|
t when t == Tags._GRAIN_BOXED_NUM_HEAP_TAG => {
|
|
143
143
|
let tag = load(heapPtr, 4n)
|
|
144
144
|
match (tag) {
|
|
145
|
-
t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG
|
|
146
|
-
t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => {
|
|
145
|
+
t when t == Tags._GRAIN_INT64_BOXED_NUM_TAG
|
|
146
|
+
|| t == Tags._GRAIN_FLOAT64_BOXED_NUM_TAG => {
|
|
147
147
|
acc + 16n
|
|
148
148
|
},
|
|
149
149
|
t when t == Tags._GRAIN_BIGINT_BOXED_NUM_TAG => {
|
|
150
150
|
acc + 16n + load(heapPtr, 8n) * 8n
|
|
151
151
|
},
|
|
152
152
|
t when t == Tags._GRAIN_RATIONAL_BOXED_NUM_TAG => {
|
|
153
|
-
acc
|
|
154
|
-
16n
|
|
155
|
-
size(load(value, 8n), 0n, valuesSeen, false)
|
|
156
|
-
size(load(value, 12n), 0n, valuesSeen, false)
|
|
153
|
+
acc
|
|
154
|
+
+ 16n
|
|
155
|
+
+ size(load(value, 8n), 0n, valuesSeen, false)
|
|
156
|
+
+ size(load(value, 12n), 0n, valuesSeen, false)
|
|
157
157
|
},
|
|
158
158
|
_ => {
|
|
159
159
|
fail "Unknown number type"
|
|
160
160
|
},
|
|
161
161
|
}
|
|
162
162
|
},
|
|
163
|
-
t when t == Tags._GRAIN_INT32_HEAP_TAG
|
|
164
|
-
t == Tags._GRAIN_FLOAT32_HEAP_TAG
|
|
165
|
-
t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
163
|
+
t when t == Tags._GRAIN_INT32_HEAP_TAG
|
|
164
|
+
|| t == Tags._GRAIN_FLOAT32_HEAP_TAG
|
|
165
|
+
|| t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
166
166
|
acc + 8n
|
|
167
167
|
},
|
|
168
168
|
t when t == Tags._GRAIN_UINT64_HEAP_TAG => {
|
|
@@ -386,9 +386,9 @@ let rec marshalHeap = (heapPtr, buf, offset, valuesSeen) => {
|
|
|
386
386
|
},
|
|
387
387
|
}
|
|
388
388
|
},
|
|
389
|
-
t when t == Tags._GRAIN_INT32_HEAP_TAG
|
|
390
|
-
t == Tags._GRAIN_FLOAT32_HEAP_TAG
|
|
391
|
-
t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
389
|
+
t when t == Tags._GRAIN_INT32_HEAP_TAG
|
|
390
|
+
|| t == Tags._GRAIN_FLOAT32_HEAP_TAG
|
|
391
|
+
|| t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
392
392
|
Memory.copy(buf + offset, heapPtr, 8n)
|
|
393
393
|
offset + 8n
|
|
394
394
|
},
|
|
@@ -449,11 +449,11 @@ let reportError = (message, offset) => {
|
|
|
449
449
|
@unsafe
|
|
450
450
|
let validateStack = (value, offset) => {
|
|
451
451
|
match (value) {
|
|
452
|
-
_ when value == fromGrain(true)
|
|
453
|
-
value == fromGrain(false)
|
|
454
|
-
value == fromGrain(void)
|
|
455
|
-
(value & Tags._GRAIN_NUMBER_TAG_MASK) == Tags._GRAIN_NUMBER_TAG_TYPE
|
|
456
|
-
(value & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_SHORTVAL_TAG_TYPE =>
|
|
452
|
+
_ when value == fromGrain(true)
|
|
453
|
+
|| value == fromGrain(false)
|
|
454
|
+
|| value == fromGrain(void)
|
|
455
|
+
|| (value & Tags._GRAIN_NUMBER_TAG_MASK) == Tags._GRAIN_NUMBER_TAG_TYPE
|
|
456
|
+
|| (value & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_SHORTVAL_TAG_TYPE =>
|
|
457
457
|
None,
|
|
458
458
|
_ => reportError("Unknown value", offset),
|
|
459
459
|
}
|
|
@@ -658,9 +658,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
|
|
|
658
658
|
None => void,
|
|
659
659
|
}
|
|
660
660
|
if (
|
|
661
|
-
load(buf, numeratorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
662
|
-
load(buf, numeratorOffset + 4n)
|
|
663
|
-
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
661
|
+
load(buf, numeratorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
662
|
+
&& load(buf, numeratorOffset + 4n)
|
|
663
|
+
!= Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
664
664
|
) {
|
|
665
665
|
return reportError(
|
|
666
666
|
"Rational/Number numerator was not in the expected format",
|
|
@@ -668,9 +668,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
|
|
|
668
668
|
)
|
|
669
669
|
}
|
|
670
670
|
if (
|
|
671
|
-
load(buf, denominatorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
672
|
-
load(buf, denominatorOffset + 4n)
|
|
673
|
-
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
671
|
+
load(buf, denominatorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
672
|
+
&& load(buf, denominatorOffset + 4n)
|
|
673
|
+
!= Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
674
674
|
) {
|
|
675
675
|
return reportError(
|
|
676
676
|
"Rational/Number denominator was not in the expected format",
|
|
@@ -682,9 +682,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
|
|
|
682
682
|
None => void,
|
|
683
683
|
}
|
|
684
684
|
if (
|
|
685
|
-
load(buf, numeratorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
686
|
-
load(buf, numeratorOffset + 4n)
|
|
687
|
-
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
685
|
+
load(buf, numeratorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
686
|
+
&& load(buf, numeratorOffset + 4n)
|
|
687
|
+
!= Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
688
688
|
) {
|
|
689
689
|
return reportError(
|
|
690
690
|
"Rational/Number numerator was not in the expected format",
|
|
@@ -692,9 +692,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
|
|
|
692
692
|
)
|
|
693
693
|
}
|
|
694
694
|
let denominatorError = if (
|
|
695
|
-
load(buf, denominatorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
696
|
-
load(buf, denominatorOffset + 4n)
|
|
697
|
-
Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
695
|
+
load(buf, denominatorOffset) != Tags._GRAIN_BOXED_NUM_HEAP_TAG
|
|
696
|
+
&& load(buf, denominatorOffset + 4n)
|
|
697
|
+
!= Tags._GRAIN_BIGINT_BOXED_NUM_TAG
|
|
698
698
|
) {
|
|
699
699
|
return reportError(
|
|
700
700
|
"Rational/Number denominator was not in the expected format",
|
|
@@ -754,12 +754,13 @@ let validate = (buf, bufSize) => {
|
|
|
754
754
|
} else {
|
|
755
755
|
// Handle non-heap values: booleans, chars, void, etc.
|
|
756
756
|
match (value) {
|
|
757
|
-
_ when value == fromGrain(true)
|
|
758
|
-
value == fromGrain(false)
|
|
759
|
-
value == fromGrain(void)
|
|
760
|
-
(value & Tags._GRAIN_NUMBER_TAG_MASK)
|
|
761
|
-
|
|
762
|
-
|
|
757
|
+
_ when value == fromGrain(true)
|
|
758
|
+
|| value == fromGrain(false)
|
|
759
|
+
|| value == fromGrain(void)
|
|
760
|
+
|| (value & Tags._GRAIN_NUMBER_TAG_MASK)
|
|
761
|
+
== Tags._GRAIN_NUMBER_TAG_TYPE
|
|
762
|
+
|| (value & Tags._GRAIN_GENERIC_TAG_MASK)
|
|
763
|
+
== Tags._GRAIN_SHORTVAL_TAG_TYPE => None,
|
|
763
764
|
_ => reportError("Unknown value", 0n),
|
|
764
765
|
}
|
|
765
766
|
}
|
|
@@ -1006,9 +1007,9 @@ let rec unmarshalHeap = (buf, offset, valuesUnmarshaled) => {
|
|
|
1006
1007
|
},
|
|
1007
1008
|
}
|
|
1008
1009
|
},
|
|
1009
|
-
t when t == Tags._GRAIN_INT32_HEAP_TAG
|
|
1010
|
-
t == Tags._GRAIN_FLOAT32_HEAP_TAG
|
|
1011
|
-
t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
1010
|
+
t when t == Tags._GRAIN_INT32_HEAP_TAG
|
|
1011
|
+
|| t == Tags._GRAIN_FLOAT32_HEAP_TAG
|
|
1012
|
+
|| t == Tags._GRAIN_UINT32_HEAP_TAG => {
|
|
1012
1013
|
let value = Memory.malloc(8n)
|
|
1013
1014
|
Memory.copy(value, valuePtr, 8n)
|
|
1014
1015
|
|
package/marshal.md
CHANGED
|
@@ -37,7 +37,7 @@ No other changes yet.
|
|
|
37
37
|
</details>
|
|
38
38
|
|
|
39
39
|
```grain
|
|
40
|
-
marshal
|
|
40
|
+
marshal: (value: a) => Bytes
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Serialize a value into a byte-based representation suitable for transmission
|
|
@@ -46,15 +46,15 @@ deserialized at a later time to restore the value.
|
|
|
46
46
|
|
|
47
47
|
Parameters:
|
|
48
48
|
|
|
49
|
-
|param|type|description|
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
| param | type | description |
|
|
50
|
+
| ------- | ---- | ---------------------- |
|
|
51
|
+
| `value` | `a` | The value to serialize |
|
|
52
52
|
|
|
53
53
|
Returns:
|
|
54
54
|
|
|
55
|
-
|type|description|
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
| type | description |
|
|
56
|
+
| ------- | ---------------------------------------- |
|
|
57
|
+
| `Bytes` | A byte-based representation of the value |
|
|
58
58
|
|
|
59
59
|
Examples:
|
|
60
60
|
|
|
@@ -74,7 +74,7 @@ No other changes yet.
|
|
|
74
74
|
</details>
|
|
75
75
|
|
|
76
76
|
```grain
|
|
77
|
-
unmarshal
|
|
77
|
+
unmarshal: (bytes: Bytes) => Result<a, String>
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
Deserialize the byte-based representation of a value back into an in-memory
|
|
@@ -86,15 +86,15 @@ unmarshaled corresponds to the expected type.
|
|
|
86
86
|
|
|
87
87
|
Parameters:
|
|
88
88
|
|
|
89
|
-
|param|type|description|
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
| param | type | description |
|
|
90
|
+
| ------- | ------- | ----------------------- |
|
|
91
|
+
| `bytes` | `Bytes` | The data to deserialize |
|
|
92
92
|
|
|
93
93
|
Returns:
|
|
94
94
|
|
|
95
|
-
|type|description|
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
| type | description |
|
|
96
|
+
| ------------------- | ------------------ |
|
|
97
|
+
| `Result<a, String>` | An in-memory value |
|
|
98
98
|
|
|
99
99
|
Examples:
|
|
100
100
|
|
package/number.gr
CHANGED
|
@@ -48,6 +48,8 @@ from "runtime/atoi/parse" include Parse as Atoi
|
|
|
48
48
|
from "runtime/atof/parse" include Parse as Atof
|
|
49
49
|
from "runtime/unsafe/tags" include Tags
|
|
50
50
|
from "runtime/exception" include Exception
|
|
51
|
+
from "runtime/math/trig" include Trig
|
|
52
|
+
use Trig.{ sin, cos, tan }
|
|
51
53
|
|
|
52
54
|
use Atoi.{ type ParseIntError }
|
|
53
55
|
|
|
@@ -81,7 +83,7 @@ provide let e = 2.718281828459045
|
|
|
81
83
|
* @returns The sum of the two operands
|
|
82
84
|
*
|
|
83
85
|
* @example
|
|
84
|
-
*
|
|
86
|
+
* use Number.{ (+) }
|
|
85
87
|
* assert 1 + 2 == 3
|
|
86
88
|
*
|
|
87
89
|
* @since v0.6.0
|
|
@@ -97,7 +99,7 @@ provide let (+) = (+)
|
|
|
97
99
|
* @returns The difference of the two operands
|
|
98
100
|
*
|
|
99
101
|
* @example
|
|
100
|
-
*
|
|
102
|
+
* use Number.{ (-) }
|
|
101
103
|
* assert 5 - 2 == 3
|
|
102
104
|
*
|
|
103
105
|
* @since v0.6.0
|
|
@@ -113,7 +115,7 @@ provide let (-) = (-)
|
|
|
113
115
|
* @returns The product of the two operands
|
|
114
116
|
*
|
|
115
117
|
* @example
|
|
116
|
-
*
|
|
118
|
+
* use Number.{ (*) }
|
|
117
119
|
* assert 5 * 4 == 20
|
|
118
120
|
*
|
|
119
121
|
* @since v0.6.0
|
|
@@ -129,7 +131,7 @@ provide let (*) = (*)
|
|
|
129
131
|
* @returns The quotient of the two operands
|
|
130
132
|
*
|
|
131
133
|
* @example
|
|
132
|
-
*
|
|
134
|
+
* use Number.{ (/) }
|
|
133
135
|
* assert 10 / 2.5 == 4
|
|
134
136
|
*
|
|
135
137
|
* @since v0.6.0
|
|
@@ -137,6 +139,22 @@ provide let (*) = (*)
|
|
|
137
139
|
*/
|
|
138
140
|
provide let (/) = (/)
|
|
139
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Computes the remainder of the division of the first operand by the second.
|
|
144
|
+
* The result will have the sign of the second operand.
|
|
145
|
+
*
|
|
146
|
+
* @param num1: The first operand
|
|
147
|
+
* @param num2: The second operand
|
|
148
|
+
* @returns The modulus of its operands
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* use Number.{ (%) }
|
|
152
|
+
* assert 10 % 3 == 1
|
|
153
|
+
*
|
|
154
|
+
* @since v0.7.1
|
|
155
|
+
*/
|
|
156
|
+
provide let (%) = (%)
|
|
157
|
+
|
|
140
158
|
/**
|
|
141
159
|
* Computes the exponentiation of the given base and power.
|
|
142
160
|
*
|
|
@@ -145,7 +163,7 @@ provide let (/) = (/)
|
|
|
145
163
|
* @returns The base raised to the given power
|
|
146
164
|
*
|
|
147
165
|
* @example
|
|
148
|
-
*
|
|
166
|
+
* use Number.{ (**) }
|
|
149
167
|
* assert 10 ** 2 == 100
|
|
150
168
|
*
|
|
151
169
|
* @since v0.6.0
|
|
@@ -153,6 +171,104 @@ provide let (/) = (/)
|
|
|
153
171
|
*/
|
|
154
172
|
provide let (**) = (**)
|
|
155
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Checks if the first value is equal to the second value.
|
|
176
|
+
*
|
|
177
|
+
* @param x: The first value
|
|
178
|
+
* @param y: The second value
|
|
179
|
+
* @returns `true` if the first value is equal to the second value or `false` otherwise
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* use Number.{ (==) }
|
|
183
|
+
* assert 1 == 1
|
|
184
|
+
*
|
|
185
|
+
* @since v0.7.1
|
|
186
|
+
*/
|
|
187
|
+
provide let (==) = Numbers.numberEq
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Checks if the first value is equal to the second value.
|
|
191
|
+
*
|
|
192
|
+
* @param x: The first value
|
|
193
|
+
* @param y: The second value
|
|
194
|
+
* @returns `true` if the first value is equal to the second value or `false` otherwise
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* use Number.{ (==) }
|
|
198
|
+
* assert 1 == 1
|
|
199
|
+
*
|
|
200
|
+
* @since v0.7.1
|
|
201
|
+
*/
|
|
202
|
+
provide let (!=) = (x, y) => !Numbers.numberEq(x, y)
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Checks if the first value is less than the second value.
|
|
206
|
+
*
|
|
207
|
+
* @param num1: The first value
|
|
208
|
+
* @param num2: The second value
|
|
209
|
+
* @returns `true` if the first value is less than the second value or `false` otherwise
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* use Number.{ (<) }
|
|
213
|
+
* assert 1 < 5
|
|
214
|
+
*
|
|
215
|
+
* @since v0.7.1
|
|
216
|
+
*/
|
|
217
|
+
provide let (<) = (<)
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Checks if the first value is greater than the second value.
|
|
221
|
+
*
|
|
222
|
+
* @param num1: The first value
|
|
223
|
+
* @param num2: The second value
|
|
224
|
+
* @returns `true` if the first value is greater than the second value or `false` otherwise
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* use Number.{ (>) }
|
|
228
|
+
* assert 5 > 1
|
|
229
|
+
*
|
|
230
|
+
* @since v0.7.1
|
|
231
|
+
*/
|
|
232
|
+
provide let (>) = (>)
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Checks if the first value is less than or equal to the second value.
|
|
236
|
+
*
|
|
237
|
+
* @param num1: The first value
|
|
238
|
+
* @param num2: The second value
|
|
239
|
+
* @returns `true` if the first value is less than or equal to the second value or `false` otherwise
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* use Number.{ (<=) }
|
|
243
|
+
* assert 1 <= 2
|
|
244
|
+
* @example
|
|
245
|
+
* use Number.{ (<=) }
|
|
246
|
+
* assert 1 <= 1
|
|
247
|
+
*
|
|
248
|
+
* @since v0.7.1
|
|
249
|
+
*/
|
|
250
|
+
@unsafe
|
|
251
|
+
provide let (<=) = (<=)
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Checks if the first value is greater than or equal to the second value.
|
|
255
|
+
*
|
|
256
|
+
* @param num1: The first value
|
|
257
|
+
* @param num2: The second value
|
|
258
|
+
* @returns `true` if the first value is greater than or equal to the second value or `false` otherwise
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* use Number.{ (>=) }
|
|
262
|
+
* assert 3 >= 2
|
|
263
|
+
* @example
|
|
264
|
+
* use Number.{ (>=) }
|
|
265
|
+
* assert 1 >= 1
|
|
266
|
+
*
|
|
267
|
+
* @since v0.7.1
|
|
268
|
+
*/
|
|
269
|
+
@unsafe
|
|
270
|
+
provide let (>=) = (>=)
|
|
271
|
+
|
|
156
272
|
/**
|
|
157
273
|
* Computes the exponentiation of Euler's number to the given power.
|
|
158
274
|
*
|
|
@@ -551,8 +667,8 @@ provide let isClose = (a, b, relativeTolerance=1e-9, absoluteTolerance=0.0) => {
|
|
|
551
667
|
if (a == b) {
|
|
552
668
|
true
|
|
553
669
|
} else if (isFinite(a) && isFinite(b)) {
|
|
554
|
-
abs(a - b)
|
|
555
|
-
max(relativeTolerance * max(abs(a), abs(b)), absoluteTolerance)
|
|
670
|
+
abs(a - b)
|
|
671
|
+
<= max(relativeTolerance * max(abs(a), abs(b)), absoluteTolerance)
|
|
556
672
|
} else {
|
|
557
673
|
// NaN and infinities which were not equal
|
|
558
674
|
false
|
|
@@ -659,28 +775,6 @@ provide let parse = input => {
|
|
|
659
775
|
}
|
|
660
776
|
}
|
|
661
777
|
|
|
662
|
-
/**
|
|
663
|
-
* Computes how many times pi has to be subtracted to achieve the required bounds for sin.
|
|
664
|
-
*/
|
|
665
|
-
let reduceToPiBound = (radians: Number) => {
|
|
666
|
-
floor(radians / pi)
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
/**
|
|
670
|
-
* Computes the sine of a number using Chebyshev polynomials. Requires the input to be bounded to (-pi, pi). More information on the algorithm can be found here: http://mooooo.ooo/chebyshev-sine-approximation/.
|
|
671
|
-
*/
|
|
672
|
-
let chebyshevSine = (radians: Number) => {
|
|
673
|
-
let pi_minor = -0.00000008742278
|
|
674
|
-
let x2 = radians * radians
|
|
675
|
-
let p11 = 0.00000000013291342
|
|
676
|
-
let p9 = p11 * x2 + -0.000000023317787
|
|
677
|
-
let p7 = p9 * x2 + 0.0000025222919
|
|
678
|
-
let p5 = p7 * x2 + -0.00017350505
|
|
679
|
-
let p3 = p5 * x2 + 0.0066208798
|
|
680
|
-
let p1 = p3 * x2 + -0.10132118
|
|
681
|
-
(radians - pi - pi_minor) * (radians + pi + pi_minor) * p1 * radians
|
|
682
|
-
}
|
|
683
|
-
|
|
684
778
|
@unsafe
|
|
685
779
|
let rf = z => {
|
|
686
780
|
// see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE at top of file
|
|
@@ -761,8 +855,8 @@ provide let asin = angle => {
|
|
|
761
855
|
WasmI64.reinterpretF64(s) & 0xFFFFFFFF00000000N
|
|
762
856
|
)
|
|
763
857
|
let c = (z - f * f) / (s + f)
|
|
764
|
-
x = 0.5W * pio2_hi
|
|
765
|
-
(2.0W * s * r - (pio2_lo - 2.0W * c) - (0.5W * pio2_hi - 2.0W * f))
|
|
858
|
+
x = 0.5W * pio2_hi
|
|
859
|
+
- (2.0W * s * r - (pio2_lo - 2.0W * c) - (0.5W * pio2_hi - 2.0W * f))
|
|
766
860
|
}
|
|
767
861
|
x = WasmF64.copySign(x, origAngle)
|
|
768
862
|
return WasmI32.toGrain(newFloat64(x)): Number
|
|
@@ -1065,10 +1159,159 @@ provide let linearMap = (inputRange, outputRange, current) => {
|
|
|
1065
1159
|
throw Exception.InvalidArgument("The outputRange must be finite")
|
|
1066
1160
|
if (isNaN(outputRange.rangeStart) || isNaN(outputRange.rangeEnd))
|
|
1067
1161
|
throw Exception.InvalidArgument("The outputRange must not include NaN")
|
|
1068
|
-
let mapped = (current - inputRange.rangeStart)
|
|
1069
|
-
(outputRange.rangeEnd - outputRange.rangeStart)
|
|
1070
|
-
(inputRange.rangeEnd - inputRange.rangeStart)
|
|
1071
|
-
outputRange.rangeStart
|
|
1162
|
+
let mapped = (current - inputRange.rangeStart)
|
|
1163
|
+
* (outputRange.rangeEnd - outputRange.rangeStart)
|
|
1164
|
+
/ (inputRange.rangeEnd - inputRange.rangeStart)
|
|
1165
|
+
+ outputRange.rangeStart
|
|
1072
1166
|
clamp(outputRange, mapped)
|
|
1073
1167
|
}
|
|
1074
1168
|
}
|
|
1169
|
+
|
|
1170
|
+
/**
|
|
1171
|
+
* Computes the sine of a number (in radians).
|
|
1172
|
+
*
|
|
1173
|
+
* @param radians: The input in radians
|
|
1174
|
+
* @returns The computed sine
|
|
1175
|
+
*
|
|
1176
|
+
* @example Number.sin(0) == 0
|
|
1177
|
+
*
|
|
1178
|
+
* @since v0.7.0
|
|
1179
|
+
*/
|
|
1180
|
+
@unsafe
|
|
1181
|
+
provide let sin = (radians: Number) => {
|
|
1182
|
+
use WasmF64.{ (==) }
|
|
1183
|
+
let xval = coerceNumberToWasmF64(radians)
|
|
1184
|
+
let value = sin(xval)
|
|
1185
|
+
return if (!isFloat(radians) && value == WasmF64.trunc(value)) {
|
|
1186
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(value))): Number
|
|
1187
|
+
} else {
|
|
1188
|
+
WasmI32.toGrain(newFloat64(value)): Number
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/**
|
|
1193
|
+
* Computes the cosine of a number (in radians).
|
|
1194
|
+
*
|
|
1195
|
+
* @param radians: The input in radians
|
|
1196
|
+
* @returns The computed cosine
|
|
1197
|
+
*
|
|
1198
|
+
* @example Number.cos(0) == 1
|
|
1199
|
+
*
|
|
1200
|
+
* @since v0.7.0
|
|
1201
|
+
*/
|
|
1202
|
+
@unsafe
|
|
1203
|
+
provide let cos = (radians: Number) => {
|
|
1204
|
+
use WasmF64.{ (==) }
|
|
1205
|
+
let xval = coerceNumberToWasmF64(radians)
|
|
1206
|
+
let value = cos(xval)
|
|
1207
|
+
return if (!isFloat(radians) && value == WasmF64.trunc(value)) {
|
|
1208
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(value))): Number
|
|
1209
|
+
} else {
|
|
1210
|
+
WasmI32.toGrain(newFloat64(value)): Number
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Computes the tangent of a number (in radians).
|
|
1216
|
+
*
|
|
1217
|
+
* @param radians: The input in radians
|
|
1218
|
+
* @returns The computed tangent
|
|
1219
|
+
*
|
|
1220
|
+
* @example Number.tan(0) == 0
|
|
1221
|
+
*
|
|
1222
|
+
* @since v0.7.0
|
|
1223
|
+
*/
|
|
1224
|
+
@unsafe
|
|
1225
|
+
provide let tan = (radians: Number) => {
|
|
1226
|
+
use WasmF64.{ (==) }
|
|
1227
|
+
let xval = coerceNumberToWasmF64(radians)
|
|
1228
|
+
let value = tan(xval)
|
|
1229
|
+
return if (!isFloat(radians) && value == WasmF64.trunc(value)) {
|
|
1230
|
+
WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(value))): Number
|
|
1231
|
+
} else {
|
|
1232
|
+
WasmI32.toGrain(newFloat64(value)): Number
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
// Math.gamma implemented using the Lanczos approximation
|
|
1237
|
+
// https://en.wikipedia.org/wiki/Lanczos_approximation
|
|
1238
|
+
/**
|
|
1239
|
+
* Computes the gamma function of a value using the Lanczos approximation.
|
|
1240
|
+
*
|
|
1241
|
+
* @param z: The value to interpolate
|
|
1242
|
+
* @returns The gamma of the given value
|
|
1243
|
+
*
|
|
1244
|
+
* @example Number.gamma(1) == 1
|
|
1245
|
+
* @example Number.gamma(3) == 2
|
|
1246
|
+
* @example Number.isClose(Number.gamma(0.5), Number.sqrt(Number.pi))
|
|
1247
|
+
*
|
|
1248
|
+
* @since v0.7.0
|
|
1249
|
+
*/
|
|
1250
|
+
provide let rec gamma = z => {
|
|
1251
|
+
if (z == 0 || isInteger(z) && z < 0) {
|
|
1252
|
+
NaN
|
|
1253
|
+
} else if (isInteger(z) && z > 0) {
|
|
1254
|
+
let mut output = 1
|
|
1255
|
+
for (let mut i = 1; i < z; i += 1) {
|
|
1256
|
+
output *= i
|
|
1257
|
+
}
|
|
1258
|
+
output
|
|
1259
|
+
} else {
|
|
1260
|
+
let mut z = z
|
|
1261
|
+
let g = 7
|
|
1262
|
+
let c = [>
|
|
1263
|
+
0.99999999999980993,
|
|
1264
|
+
676.5203681218851,
|
|
1265
|
+
-1259.1392167224028,
|
|
1266
|
+
771.32342877765313,
|
|
1267
|
+
-176.61502916214059,
|
|
1268
|
+
12.507343278686905,
|
|
1269
|
+
-0.13857109526572012,
|
|
1270
|
+
9.9843695780195716e-6,
|
|
1271
|
+
1.5056327351493116e-7,
|
|
1272
|
+
]
|
|
1273
|
+
let mut output = 0
|
|
1274
|
+
if (z < 0.5) {
|
|
1275
|
+
output = pi / sin(pi * z) / gamma(1 - z)
|
|
1276
|
+
} else if (z == 0.5) {
|
|
1277
|
+
// Handle this case separately because it is out of the domain of Number.pow when calculating
|
|
1278
|
+
output = 1.7724538509055159
|
|
1279
|
+
} else {
|
|
1280
|
+
z -= 1
|
|
1281
|
+
let mut x = c[0]
|
|
1282
|
+
for (let mut i = 1; i < g + 2; i += 1) {
|
|
1283
|
+
x += c[i] / (z + i)
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
let t = z + g + 0.5
|
|
1287
|
+
output = sqrt(2 * pi) * (t ** (z + 0.5)) * exp(t * -1) * x
|
|
1288
|
+
}
|
|
1289
|
+
if (abs(output) == Infinity) Infinity else output
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/**
|
|
1294
|
+
* Computes the factorial of an integer input or the gamma function of a non-integer input.
|
|
1295
|
+
*
|
|
1296
|
+
* @param n: The value to factorialize
|
|
1297
|
+
* @returns The factorial of the given value
|
|
1298
|
+
*
|
|
1299
|
+
* @throws InvalidArgument(String): When `n` is a negative integer
|
|
1300
|
+
*
|
|
1301
|
+
* @example Number.factorial(0) == 1
|
|
1302
|
+
* @example Number.factorial(3) == 6
|
|
1303
|
+
* @example Number.isClose(Number.factorial(0.5), (1/2) * Number.sqrt(Number.pi))
|
|
1304
|
+
*
|
|
1305
|
+
* @since v0.7.0
|
|
1306
|
+
*/
|
|
1307
|
+
provide let rec factorial = n => {
|
|
1308
|
+
if (isInteger(n) && n < 0) {
|
|
1309
|
+
gamma(abs(n) + 1) * -1
|
|
1310
|
+
} else if (!isInteger(n) && n < 0) {
|
|
1311
|
+
throw Exception.InvalidArgument(
|
|
1312
|
+
"Cannot compute the factorial of a negative non-integer",
|
|
1313
|
+
)
|
|
1314
|
+
} else {
|
|
1315
|
+
gamma(n + 1)
|
|
1316
|
+
}
|
|
1317
|
+
}
|