@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.
Files changed (137) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/LICENSE +1 -1
  3. package/README.md +2 -2
  4. package/array.gr +55 -7
  5. package/array.md +606 -560
  6. package/bigint.md +228 -228
  7. package/buffer.gr +85 -53
  8. package/buffer.md +442 -319
  9. package/bytes.gr +112 -35
  10. package/bytes.md +299 -219
  11. package/char.gr +201 -99
  12. package/char.md +447 -120
  13. package/exception.gr +11 -11
  14. package/exception.md +29 -4
  15. package/float32.gr +327 -3
  16. package/float32.md +698 -111
  17. package/float64.gr +320 -3
  18. package/float64.md +698 -111
  19. package/fs.gr +1082 -0
  20. package/fs.md +630 -0
  21. package/hash.gr +142 -88
  22. package/hash.md +105 -17
  23. package/int16.md +178 -178
  24. package/int32.gr +26 -5
  25. package/int32.md +266 -231
  26. package/int64.gr +27 -2
  27. package/int64.md +266 -231
  28. package/int8.md +178 -178
  29. package/json.gr +366 -51
  30. package/json.md +431 -15
  31. package/list.gr +328 -31
  32. package/list.md +759 -336
  33. package/map.gr +20 -12
  34. package/map.md +266 -260
  35. package/marshal.gr +41 -40
  36. package/marshal.md +14 -14
  37. package/number.gr +278 -35
  38. package/number.md +688 -269
  39. package/option.md +162 -162
  40. package/package.json +5 -3
  41. package/path.gr +48 -0
  42. package/path.md +180 -89
  43. package/pervasives.gr +2 -2
  44. package/pervasives.md +275 -275
  45. package/priorityqueue.gr +7 -7
  46. package/priorityqueue.md +131 -131
  47. package/queue.gr +183 -29
  48. package/queue.md +404 -148
  49. package/random.md +43 -43
  50. package/range.gr +4 -4
  51. package/range.md +42 -42
  52. package/rational.md +123 -123
  53. package/regex.gr +52 -51
  54. package/regex.md +102 -102
  55. package/result.md +118 -118
  56. package/runtime/atof/common.md +39 -39
  57. package/runtime/atof/decimal.gr +6 -6
  58. package/runtime/atof/decimal.md +14 -14
  59. package/runtime/atof/lemire.gr +5 -5
  60. package/runtime/atof/lemire.md +1 -1
  61. package/runtime/atof/parse.gr +16 -16
  62. package/runtime/atof/parse.md +2 -2
  63. package/runtime/atof/slow.md +1 -1
  64. package/runtime/atof/table.md +2 -2
  65. package/runtime/atoi/parse.gr +3 -3
  66. package/runtime/atoi/parse.md +1 -1
  67. package/runtime/bigint.gr +15 -47
  68. package/runtime/bigint.md +54 -60
  69. package/runtime/compare.gr +2 -2
  70. package/runtime/compare.md +8 -8
  71. package/runtime/dataStructures.md +211 -211
  72. package/runtime/debugPrint.gr +4 -1
  73. package/runtime/debugPrint.md +9 -9
  74. package/runtime/equal.gr +99 -77
  75. package/runtime/equal.md +8 -8
  76. package/runtime/exception.gr +62 -82
  77. package/runtime/exception.md +62 -11
  78. package/runtime/gc.gr +39 -45
  79. package/runtime/gc.md +4 -4
  80. package/runtime/malloc.gr +7 -7
  81. package/runtime/malloc.md +13 -13
  82. package/runtime/math/kernel/cos.gr +70 -0
  83. package/runtime/math/kernel/cos.md +14 -0
  84. package/runtime/math/kernel/sin.gr +65 -0
  85. package/runtime/math/kernel/sin.md +14 -0
  86. package/runtime/math/kernel/tan.gr +136 -0
  87. package/runtime/math/kernel/tan.md +14 -0
  88. package/runtime/math/rempio2.gr +244 -0
  89. package/runtime/math/rempio2.md +14 -0
  90. package/runtime/math/trig.gr +130 -0
  91. package/runtime/math/trig.md +28 -0
  92. package/runtime/math/umuldi.gr +26 -0
  93. package/runtime/math/umuldi.md +14 -0
  94. package/runtime/numberUtils.gr +29 -29
  95. package/runtime/numberUtils.md +12 -12
  96. package/runtime/numbers.gr +373 -381
  97. package/runtime/numbers.md +348 -342
  98. package/runtime/string.gr +37 -105
  99. package/runtime/string.md +20 -26
  100. package/runtime/unsafe/constants.md +24 -24
  101. package/runtime/unsafe/conv.md +19 -19
  102. package/runtime/unsafe/memory.gr +24 -20
  103. package/runtime/unsafe/memory.md +27 -7
  104. package/runtime/unsafe/offsets.gr +36 -0
  105. package/runtime/unsafe/offsets.md +88 -0
  106. package/runtime/unsafe/panic.gr +28 -0
  107. package/runtime/unsafe/panic.md +14 -0
  108. package/runtime/unsafe/tags.md +32 -32
  109. package/runtime/unsafe/wasmf32.md +28 -28
  110. package/runtime/unsafe/wasmf64.md +28 -28
  111. package/runtime/unsafe/wasmi32.md +47 -47
  112. package/runtime/unsafe/wasmi64.md +50 -50
  113. package/runtime/utf8.gr +189 -0
  114. package/runtime/utf8.md +117 -0
  115. package/runtime/wasi.gr +4 -2
  116. package/runtime/wasi.md +147 -147
  117. package/set.gr +18 -11
  118. package/set.md +253 -247
  119. package/stack.gr +171 -2
  120. package/stack.md +371 -89
  121. package/string.gr +352 -557
  122. package/string.md +298 -255
  123. package/uint16.md +170 -170
  124. package/uint32.gr +25 -4
  125. package/uint32.md +249 -214
  126. package/uint64.gr +25 -5
  127. package/uint64.md +249 -214
  128. package/uint8.md +170 -170
  129. package/uri.gr +57 -53
  130. package/uri.md +88 -89
  131. package/wasi/file.gr +67 -59
  132. package/wasi/file.md +308 -308
  133. package/wasi/process.md +26 -26
  134. package/wasi/random.md +12 -12
  135. package/wasi/time.md +16 -16
  136. package/runtime/utils/printing.gr +0 -60
  137. 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) == Tags._GRAIN_NUMBER_TAG_TYPE ||
761
- (value & Tags._GRAIN_GENERIC_TAG_MASK) ==
762
- Tags._GRAIN_SHORTVAL_TAG_TYPE => None,
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 : (value: a) => Bytes
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
- |`value`|`a`|The value to serialize|
49
+ | param | type | description |
50
+ | ------- | ---- | ---------------------- |
51
+ | `value` | `a` | The value to serialize |
52
52
 
53
53
  Returns:
54
54
 
55
- |type|description|
56
- |----|-----------|
57
- |`Bytes`|A byte-based representation of the value|
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 : (bytes: Bytes) => Result<a, String>
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
- |`bytes`|`Bytes`|The data to deserialize|
89
+ | param | type | description |
90
+ | ------- | ------- | ----------------------- |
91
+ | `bytes` | `Bytes` | The data to deserialize |
92
92
 
93
93
  Returns:
94
94
 
95
- |type|description|
96
- |----|-----------|
97
- |`Result<a, String>`|An in-memory value|
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
- * from Number use { (+) }
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
- * from Number use { (-) }
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
- * from Number use { (*) }
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
- * from Number use { (/) }
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
- * from Number use { (**) }
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
+ }