@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/exception.gr CHANGED
@@ -12,8 +12,6 @@
12
12
  */
13
13
  module Exception
14
14
 
15
- from "runtime/unsafe/wasmi32" include WasmI32
16
- from "runtime/unsafe/memory" include Memory
17
15
  from "runtime/exception" include Exception
18
16
 
19
17
  /**
@@ -39,13 +37,15 @@ from "runtime/exception" include Exception
39
37
  *
40
38
  * @since v0.3.0
41
39
  */
42
- @disableGC
43
- provide let rec registerPrinter = (printer: Exception => Option<String>) => {
44
- // This function _must_ be @disableGC because the printer list uses
45
- // unsafe types. Not really a memory leak as this list is never collected
40
+ provide let registerPrinter = Exception.registerPrinter
46
41
 
47
- // no need to increment refcount on f; we just don't decRef it at the end of the function
48
- Exception.printers = WasmI32.fromGrain((printer, Exception.printers))
49
- Memory.decRef(WasmI32.fromGrain(registerPrinter))
50
- void
51
- }
42
+ /**
43
+ * Gets the string representation of the given exception.
44
+ *
45
+ * @param e: The exception to stringify
46
+ *
47
+ * @returns The string representation of the exception
48
+ *
49
+ * @since v0.7.0
50
+ */
51
+ provide let toString = Exception.toString
package/exception.md CHANGED
@@ -35,7 +35,7 @@ No other changes yet.
35
35
  </details>
36
36
 
37
37
  ```grain
38
- registerPrinter : (printer: (Exception => Option<String>)) => Void
38
+ registerPrinter: (printer: (Exception => Option<String>)) => Void
39
39
  ```
40
40
 
41
41
  Registers an exception printer. When an exception is thrown, all registered
@@ -45,9 +45,9 @@ used as the exception's string value.
45
45
 
46
46
  Parameters:
47
47
 
48
- |param|type|description|
49
- |-----|----|-----------|
50
- |`printer`|`Exception => Option<String>`|The exception printer to register|
48
+ | param | type | description |
49
+ | --------- | ----------------------------- | --------------------------------- |
50
+ | `printer` | `Exception => Option<String>` | The exception printer to register |
51
51
 
52
52
  Examples:
53
53
 
@@ -65,3 +65,28 @@ Exception.registerPrinter(e => {
65
65
  throw ExampleError(1) // Error found on line: 1
66
66
  ```
67
67
 
68
+ ### Exception.**toString**
69
+
70
+ <details disabled>
71
+ <summary tabindex="-1">Added in <code>0.7.0</code></summary>
72
+ No other changes yet.
73
+ </details>
74
+
75
+ ```grain
76
+ toString: (e: Exception) => String
77
+ ```
78
+
79
+ Gets the string representation of the given exception.
80
+
81
+ Parameters:
82
+
83
+ | param | type | description |
84
+ | ----- | ----------- | -------------------------- |
85
+ | `e` | `Exception` | The exception to stringify |
86
+
87
+ Returns:
88
+
89
+ | type | description |
90
+ | -------- | ------------------------------------------ |
91
+ | `String` | The string representation of the exception |
92
+
package/float32.gr CHANGED
@@ -12,8 +12,15 @@
12
12
  */
13
13
  module Float32
14
14
 
15
+ from "runtime/unsafe/offsets" include Offsets
16
+ use Offsets.{
17
+ _FLOAT32_VALUE_OFFSET as _VALUE_OFFSET,
18
+ _INT32_VALUE_OFFSET,
19
+ _UINT32_VALUE_OFFSET,
20
+ }
15
21
  from "runtime/unsafe/wasmi32" include WasmI32
16
22
  from "runtime/unsafe/wasmf32" include WasmF32
23
+ from "runtime/unsafe/wasmf64" include WasmF64
17
24
  use WasmF32.{ (+), (-), (*), (/), (<), (<=), (>), (>=) }
18
25
  from "runtime/dataStructures" include DataStructures
19
26
  use DataStructures.{ newFloat32 }
@@ -23,9 +30,8 @@ use Numbers.{
23
30
  coerceNumberToFloat32 as fromNumber,
24
31
  coerceFloat32ToNumber as toNumber,
25
32
  }
26
-
27
- @unsafe
28
- let _VALUE_OFFSET = 4n
33
+ from "runtime/math/trig" include Trig
34
+ use Trig.{ sin, cos, tan }
29
35
 
30
36
  /**
31
37
  * Infinity represented as a Float32 value.
@@ -68,6 +74,41 @@ provide let e = 2.7182817f
68
74
 
69
75
  provide { fromNumber, toNumber }
70
76
 
77
+ /**
78
+ * Interprets an Int32 as a Float32.
79
+ *
80
+ * @param value: The value to convert
81
+ * @returns The Int32 interpreted as an Float32
82
+ *
83
+ * @example assert Float32.reinterpretInt32(1065353216l) == 1.0f
84
+ * @example assert Float32.reinterpretInt32(-1082130432l) == -1.0f
85
+ * @since v0.7.0
86
+ */
87
+ @unsafe
88
+ provide let reinterpretInt32 = (value: Int32) => {
89
+ let x = WasmF32.load(WasmI32.fromGrain(value), _INT32_VALUE_OFFSET)
90
+ let result = newFloat32(x)
91
+ WasmI32.toGrain(result): Float32
92
+ }
93
+
94
+ /**
95
+ * Interprets an Uint32 as a Float32.
96
+ *
97
+ * @param value: The value to convert
98
+ * @returns The Uint32 interpreted as an Float32
99
+ *
100
+ * @example assert Float32.reinterpretUint32(1065353216ul) == 1.0f
101
+ * @example assert Float32.reinterpretUint32(3212836864ul) == -1.0f
102
+ *
103
+ * @since v0.7.0
104
+ */
105
+ @unsafe
106
+ provide let reinterpretUint32 = (value: Uint32) => {
107
+ let x = WasmF32.load(WasmI32.fromGrain(value), _UINT32_VALUE_OFFSET)
108
+ let result = newFloat32(x)
109
+ WasmI32.toGrain(result): Float32
110
+ }
111
+
71
112
  /**
72
113
  * Computes the sum of its operands.
73
114
  *
@@ -156,6 +197,31 @@ provide let (/) = (x: Float32, y: Float32) => {
156
197
  WasmI32.toGrain(ptr): Float32
157
198
  }
158
199
 
200
+ /**
201
+ * Computes the exponentiation of the given base and power.
202
+ *
203
+ * @param base: The base float
204
+ * @param power: The exponent float
205
+ * @returns The base raised to the given power
206
+ *
207
+ * @example
208
+ * use Float64.{ (**) }
209
+ * assert 2.0f ** 2.0f == 4.0f
210
+ *
211
+ * @since v0.7.0
212
+ */
213
+ @unsafe
214
+ provide let (**) = (base: Float32, power: Float32) => {
215
+ let basev = WasmF32.load(WasmI32.fromGrain(base), _VALUE_OFFSET)
216
+ let powerv = WasmF32.load(WasmI32.fromGrain(power), _VALUE_OFFSET)
217
+ let value = Numbers.powf(
218
+ WasmF64.promoteF32(basev),
219
+ WasmF64.promoteF32(powerv)
220
+ )
221
+ let ptr = newFloat32(WasmF32.demoteF64(value))
222
+ WasmI32.toGrain(ptr): Float32
223
+ }
224
+
159
225
  /**
160
226
  * Checks if the first value is less than the second value.
161
227
  *
@@ -248,6 +314,29 @@ provide let (>=) = (x: Float32, y: Float32) => {
248
314
  xv >= yv
249
315
  }
250
316
 
317
+ /**
318
+ * Checks if a float is finite.
319
+ * All values are finite exept for NaN, infinity or negative infinity.
320
+ *
321
+ * @param x: The number to check
322
+ * @returns `true` if the value is finite or `false` otherwise
323
+ *
324
+ * @example Float32.isFinite(0.5f)
325
+ * @example Float32.isFinite(1.0f)
326
+ * @example Float32.isFinite(Infinityf) == false
327
+ * @example Float32.isFinite(-Infinityf) == false
328
+ * @example Float32.isFinite(NaNf) == false
329
+ *
330
+ * @since v0.7.0
331
+ */
332
+ @unsafe
333
+ provide let isFinite = (x: Float32) => {
334
+ // uses the fact that all finite floats minus themselves are zero
335
+ // (NaN - NaN == NaN, inf - inf == NaN,
336
+ // -inf - -inf == NaN, inf - -inf == inf, -inf - inf == -inf)
337
+ x - x == 0.0f
338
+ }
339
+
251
340
  /**
252
341
  * Checks if the value is a float NaN value (Not A Number).
253
342
  *
@@ -280,6 +369,44 @@ provide let isNaN = (x: Float32) => x != x
280
369
  */
281
370
  provide let isInfinite = (x: Float32) => x == Infinityf || x == -Infinityf
282
371
 
372
+ /**
373
+ * Returns the smaller of its operands.
374
+ *
375
+ * @param x: The first operand
376
+ * @param y: The second operand
377
+ * @returns The smaller of the two operands
378
+ *
379
+ * @example Float32.min(5.0f, 2.0f) == 2.0f
380
+ *
381
+ * @since v0.7.0
382
+ */
383
+ @unsafe
384
+ provide let min = (x: Float32, y: Float32) => {
385
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
386
+ let yv = WasmF32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
387
+ let ptr = newFloat32(WasmF32.min(xv, yv))
388
+ WasmI32.toGrain(ptr): Float32
389
+ }
390
+
391
+ /**
392
+ * Returns the larger of its operands.
393
+ *
394
+ * @param x: The first operand
395
+ * @param y: The second operand
396
+ * @returns The larger of the two operands
397
+ *
398
+ * @example Float32.max(5.0f, 2.0f) == 5.0f
399
+ *
400
+ * @since v0.7.0
401
+ */
402
+ @unsafe
403
+ provide let max = (x: Float32, y: Float32) => {
404
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
405
+ let yv = WasmF32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
406
+ let ptr = newFloat32(WasmF32.max(xv, yv))
407
+ WasmI32.toGrain(ptr): Float32
408
+ }
409
+
283
410
  /**
284
411
  * Returns the absolute value. That is, it returns `x` if `x` is positive or zero and the negation of `x` if `x` is negative.
285
412
  *
@@ -315,3 +442,200 @@ provide let neg = (x: Float32) => {
315
442
  let ptr = newFloat32(WasmF32.neg(xv))
316
443
  WasmI32.toGrain(ptr): Float32
317
444
  }
445
+
446
+ /**
447
+ * Rounds its operand up to the next largest whole value.
448
+ *
449
+ * @param x: The operand to ceil
450
+ * @returns The next largest whole value of the operand
451
+ *
452
+ * @example Float32.ceil(5.5f) == 6.0f
453
+ * @example Float32.ceil(-5.5f) == -5.0f
454
+ *
455
+ * @since v0.7.0
456
+ */
457
+ @unsafe
458
+ provide let ceil = (x: Float32) => {
459
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
460
+ let ptr = newFloat32(WasmF32.ceil(xv))
461
+ WasmI32.toGrain(ptr): Float32
462
+ }
463
+
464
+ /**
465
+ * Rounds its operand down to the largest whole value less than the operand.
466
+ *
467
+ * @param x: The operand to floor
468
+ * @returns The previous whole value of the operand
469
+ *
470
+ * @example Float32.floor(5.5f) == 5.0f
471
+ * @example Float32.floor(-5.5f) == -6.0f
472
+ *
473
+ * @since v0.7.0
474
+ */
475
+ @unsafe
476
+ provide let floor = (x: Float32) => {
477
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
478
+ let ptr = newFloat32(WasmF32.floor(xv))
479
+ WasmI32.toGrain(ptr): Float32
480
+ }
481
+
482
+ /**
483
+ * Returns the whole value part of its operand, removing any fractional value.
484
+ *
485
+ * @param x: The operand to truncate
486
+ * @returns The whole value part of the operand
487
+ *
488
+ * @example Float32.trunc(5.5f) == 5.0f
489
+ *
490
+ * @since v0.7.0
491
+ */
492
+ @unsafe
493
+ provide let trunc = (x: Float32) => {
494
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
495
+ let ptr = newFloat32(WasmF32.trunc(xv))
496
+ WasmI32.toGrain(ptr): Float32
497
+ }
498
+
499
+ /**
500
+ * Returns its operand rounded to its nearest integer.
501
+ *
502
+ * @param x: The operand to round
503
+ * @returns The nearest integer to the operand
504
+ *
505
+ * @example Float32.round(5.5f) == 6.0f
506
+ * @example Float32.round(5.4f) == 5.0f
507
+ * @example Float32.round(-5.5f) == -6.0f
508
+ * @example Float32.round(-5.4f) == -5.0f
509
+ *
510
+ * @since v0.7.0
511
+ */
512
+ @unsafe
513
+ provide let round = (x: Float32) => {
514
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
515
+ let ptr = newFloat32(WasmF32.nearest(xv))
516
+ WasmI32.toGrain(ptr): Float32
517
+ }
518
+
519
+ /**
520
+ * Computes the square root of its operand.
521
+ *
522
+ * @param x: The operand to square root
523
+ * @returns The square root of the operand
524
+ *
525
+ * @example Float32.sqrt(25.0f) == 5.0f
526
+ *
527
+ * @since v0.7.0
528
+ */
529
+ @unsafe
530
+ provide let sqrt = (x: Float32) => {
531
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
532
+ let ptr = newFloat32(WasmF32.sqrt(xv))
533
+ WasmI32.toGrain(ptr): Float32
534
+ }
535
+
536
+ /**
537
+ * Copys the sign of the second operand to the first operand.
538
+ *
539
+ * @param x: The operand to modify
540
+ * @param y: The operand to copy the sign from
541
+ * @returns The first operand with the sign of the second operand
542
+ *
543
+ * @example Float32.copySign(2.0f, 1.0f) == 2.0f
544
+ * @example Float32.copySign(3.0f, -1.0f) == -3.0f
545
+ * @example Float32.copySign(-5.0f, 1.0f) == 5.0f
546
+ *
547
+ * @since v0.7.0
548
+ */
549
+ @unsafe
550
+ provide let copySign = (x: Float32, y: Float32) => {
551
+ let xv = WasmF32.load(WasmI32.fromGrain(x), _VALUE_OFFSET)
552
+ let yv = WasmF32.load(WasmI32.fromGrain(y), _VALUE_OFFSET)
553
+ let ptr = newFloat32(WasmF32.copySign(xv, yv))
554
+ WasmI32.toGrain(ptr): Float32
555
+ }
556
+
557
+ /**
558
+ * Determines whether two values are considered close to each other using a relative and absolute tolerance.
559
+ *
560
+ * @param a: The first value
561
+ * @param b: The second value
562
+ * @param relativeTolerance: The maximum tolerance to use relative to the larger absolute value `a` or `b`
563
+ * @param absoluteTolerance: The absolute tolerance to use, regardless of the values of `a` or `b`
564
+ * @returns `true` if the values are considered close to each other or `false` otherwise
565
+ *
566
+ * @example Float32.isClose(1.233f, 1.233f)
567
+ * @example Float32.isClose(1.233f, 1.233000001f)
568
+ * @example Float32.isClose(8.005f, 8.450f, absoluteTolerance=0.5f)
569
+ * @example Float32.isClose(4.0f, 4.1f, relativeTolerance=0.025f)
570
+ * @example Float32.isClose(1.233f, 1.24f) == false
571
+ * @example Float32.isClose(1.233f, 1.4566f) == false
572
+ * @example Float32.isClose(8.005f, 8.450f, absoluteTolerance=0.4f) == false
573
+ * @example Float32.isClose(4.0f, 4.1f, relativeTolerance=0.024f) == false
574
+ *
575
+ * @since v0.7.0
576
+ */
577
+ provide let isClose = (a, b, relativeTolerance=1e-9f, absoluteTolerance=0.0f) => {
578
+ if (a == b) {
579
+ true
580
+ } else if (isFinite(a) && isFinite(b)) {
581
+ abs(a - b)
582
+ <= max(relativeTolerance * max(abs(a), abs(b)), absoluteTolerance)
583
+ } else {
584
+ // NaN and infinities which were not equal
585
+ false
586
+ }
587
+ }
588
+
589
+ /**
590
+ * Computes the sine of a float (in radians).
591
+ *
592
+ * @param radians: The input in radians
593
+ * @returns The computed sine
594
+ *
595
+ * @example Float32.sin(0.0f) == 0.0f
596
+ *
597
+ * @since v0.7.0
598
+ */
599
+ @unsafe
600
+ provide let sin = (radians: Float32) => {
601
+ // TODO(#2167): Implement Float32 optimized trig functions
602
+ let xval = WasmF32.load(WasmI32.fromGrain(radians), _VALUE_OFFSET)
603
+ let value = sin(WasmF64.promoteF32(xval))
604
+ WasmI32.toGrain(newFloat32(WasmF32.demoteF64(value))): Float32
605
+ }
606
+
607
+ /**
608
+ * Computes the cosine of a float (in radians).
609
+ *
610
+ * @param radians: The input in radians
611
+ * @returns The computed cosine
612
+ *
613
+ * @example Float32.cos(0.0f) == 1.0f
614
+ *
615
+ * @since v0.7.0
616
+ */
617
+ @unsafe
618
+ provide let cos = (radians: Float32) => {
619
+ // TODO(#2167): Implement Float32 optimized trig functions
620
+ let xval = WasmF32.load(WasmI32.fromGrain(radians), _VALUE_OFFSET)
621
+ let value = cos(WasmF64.promoteF32(xval))
622
+ WasmI32.toGrain(newFloat32(WasmF32.demoteF64(value))): Float32
623
+ }
624
+
625
+ /**
626
+ * Computes the tangent of a number (in radians).
627
+ *
628
+ * @param radians: The input in radians
629
+ * @returns The computed tangent
630
+ *
631
+ * @example Float32.tan(0.0f) == 0.0f
632
+ *
633
+ * @since v0.7.0
634
+ */
635
+ @unsafe
636
+ provide let tan = (radians: Float32) => {
637
+ // TODO(#2167): Implement Float32 optimized trig functions
638
+ let xval = WasmF32.load(WasmI32.fromGrain(radians), _VALUE_OFFSET)
639
+ let value = tan(WasmF64.promoteF32(xval))
640
+ WasmI32.toGrain(newFloat32(WasmF32.demoteF64(value))): Float32
641
+ }