@grain/stdlib 0.4.6 → 0.5.2

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 (85) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/array.gr +18 -18
  3. package/array.md +18 -18
  4. package/bigint.gr +497 -0
  5. package/bigint.md +811 -0
  6. package/buffer.gr +59 -223
  7. package/buffer.md +24 -17
  8. package/bytes.gr +100 -202
  9. package/bytes.md +19 -0
  10. package/char.gr +63 -133
  11. package/exception.gr +28 -2
  12. package/exception.md +43 -0
  13. package/float32.gr +76 -95
  14. package/float32.md +69 -30
  15. package/float64.gr +81 -95
  16. package/float64.md +69 -30
  17. package/hash.gr +37 -37
  18. package/int32.gr +152 -198
  19. package/int32.md +104 -0
  20. package/int64.gr +151 -197
  21. package/int64.md +104 -0
  22. package/list.gr +467 -70
  23. package/list.md +1141 -0
  24. package/map.gr +192 -7
  25. package/map.md +525 -0
  26. package/number.gr +111 -54
  27. package/number.md +100 -3
  28. package/option.md +1 -1
  29. package/package.json +3 -3
  30. package/pervasives.gr +499 -59
  31. package/pervasives.md +1116 -0
  32. package/queue.gr +4 -0
  33. package/queue.md +10 -0
  34. package/random.gr +196 -0
  35. package/random.md +179 -0
  36. package/regex.gr +1833 -842
  37. package/regex.md +11 -11
  38. package/result.md +1 -1
  39. package/runtime/bigint.gr +2045 -0
  40. package/runtime/bigint.md +326 -0
  41. package/runtime/dataStructures.gr +99 -278
  42. package/runtime/dataStructures.md +391 -0
  43. package/runtime/debug.md +6 -0
  44. package/runtime/equal.gr +5 -23
  45. package/runtime/equal.md +6 -0
  46. package/runtime/exception.md +30 -0
  47. package/runtime/gc.gr +20 -3
  48. package/runtime/gc.md +36 -0
  49. package/runtime/malloc.gr +13 -11
  50. package/runtime/malloc.md +55 -0
  51. package/runtime/numberUtils.gr +91 -41
  52. package/runtime/numberUtils.md +54 -0
  53. package/runtime/numbers.gr +1049 -391
  54. package/runtime/numbers.md +300 -0
  55. package/runtime/string.gr +136 -230
  56. package/runtime/string.md +24 -0
  57. package/runtime/stringUtils.gr +58 -38
  58. package/runtime/stringUtils.md +6 -0
  59. package/runtime/unsafe/constants.gr +17 -0
  60. package/runtime/unsafe/constants.md +72 -0
  61. package/runtime/unsafe/conv.md +71 -0
  62. package/runtime/unsafe/errors.md +204 -0
  63. package/runtime/unsafe/memory.md +54 -0
  64. package/runtime/unsafe/printWasm.md +24 -0
  65. package/runtime/unsafe/tags.gr +9 -8
  66. package/runtime/unsafe/tags.md +120 -0
  67. package/runtime/unsafe/wasmf32.md +168 -0
  68. package/runtime/unsafe/wasmf64.md +168 -0
  69. package/runtime/unsafe/wasmi32.md +282 -0
  70. package/runtime/unsafe/wasmi64.md +300 -0
  71. package/runtime/utils/printing.gr +62 -0
  72. package/runtime/utils/printing.md +18 -0
  73. package/runtime/wasi.gr +1 -1
  74. package/runtime/wasi.md +839 -0
  75. package/set.gr +17 -8
  76. package/set.md +24 -21
  77. package/stack.gr +3 -3
  78. package/stack.md +4 -6
  79. package/string.gr +194 -329
  80. package/string.md +3 -3
  81. package/sys/file.gr +245 -429
  82. package/sys/process.gr +27 -45
  83. package/sys/random.gr +47 -16
  84. package/sys/random.md +38 -0
  85. package/sys/time.gr +11 -27
package/number.gr CHANGED
@@ -19,6 +19,35 @@ import { parseInt } from "runtime/stringUtils"
19
19
  import { newFloat64, newInt64 } from "runtime/dataStructures"
20
20
  import Tags from "runtime/unsafe/tags"
21
21
 
22
+ /**
23
+ * @section Constants: Number constant values.
24
+ */
25
+
26
+ /**
27
+ * Pi represented as a Number value.
28
+ *
29
+ * @since v0.5.2
30
+ */
31
+ export let pi = 3.141592653589793
32
+
33
+ /**
34
+ * Tau represented as a Number value.
35
+ *
36
+ * @since v0.5.2
37
+ */
38
+ export let tau = 6.283185307179586
39
+
40
+ /**
41
+ * Euler's number represented as a Number value.
42
+ *
43
+ * @since v0.5.2
44
+ */
45
+ export let e = 2.718281828459045
46
+
47
+ /**
48
+ * @section Operations: Functions for operating on values of the Number type.
49
+ */
50
+
22
51
  /**
23
52
  * Computes the sum of its operands.
24
53
  *
@@ -71,19 +100,16 @@ export let div = (/)
71
100
  *
72
101
  * @since v0.4.0
73
102
  */
74
- @disableGC
75
- export let rec sqrt = (x: Number) => {
103
+ @unsafe
104
+ export let sqrt = (x: Number) => {
76
105
  let xval = coerceNumberToWasmF64(x)
77
106
  let x = WasmI32.fromGrain(x)
78
107
  let sqrtd = WasmF64.sqrt(xval)
79
- let ret = if (!isFloat(x) && WasmF64.eq(sqrtd, WasmF64.trunc(sqrtd))) {
108
+ if (!isFloat(x) && WasmF64.eq(sqrtd, WasmF64.trunc(sqrtd))) {
80
109
  WasmI32.toGrain(reducedInteger(WasmI64.truncF64S(sqrtd))): Number
81
110
  } else {
82
111
  WasmI32.toGrain(newFloat64(sqrtd)): Number
83
112
  }
84
- Memory.decRef(WasmI32.fromGrain(x))
85
- Memory.decRef(WasmI32.fromGrain(sqrt))
86
- ret
87
113
  }
88
114
 
89
115
  /**
@@ -134,14 +160,11 @@ export let max = (x: Number, y: Number) => if (x > y) x else y
134
160
  *
135
161
  * @since v0.4.0
136
162
  */
137
- @disableGC
138
- export let rec ceil = (x: Number) => {
163
+ @unsafe
164
+ export let ceil = (x: Number) => {
139
165
  let xval = coerceNumberToWasmF64(x)
140
166
  let ceiling = WasmI64.truncF64S(WasmF64.ceil(xval))
141
- let ret = WasmI32.toGrain(reducedInteger(ceiling)): Number
142
- Memory.decRef(WasmI32.fromGrain(x))
143
- Memory.decRef(WasmI32.fromGrain(ceil))
144
- ret
167
+ WasmI32.toGrain(reducedInteger(ceiling)): Number
145
168
  }
146
169
 
147
170
  /**
@@ -152,14 +175,11 @@ export let rec ceil = (x: Number) => {
152
175
  *
153
176
  * @since v0.4.0
154
177
  */
155
- @disableGC
156
- export let rec floor = (x: Number) => {
178
+ @unsafe
179
+ export let floor = (x: Number) => {
157
180
  let xval = coerceNumberToWasmF64(x)
158
181
  let floored = WasmI64.truncF64S(WasmF64.floor(xval))
159
- let ret = WasmI32.toGrain(reducedInteger(floored)): Number
160
- Memory.decRef(WasmI32.fromGrain(x))
161
- Memory.decRef(WasmI32.fromGrain(floor))
162
- ret
182
+ WasmI32.toGrain(reducedInteger(floored)): Number
163
183
  }
164
184
 
165
185
  /**
@@ -170,14 +190,11 @@ export let rec floor = (x: Number) => {
170
190
  *
171
191
  * @since v0.4.0
172
192
  */
173
- @disableGC
174
- export let rec trunc = (x: Number) => {
193
+ @unsafe
194
+ export let trunc = (x: Number) => {
175
195
  let xval = coerceNumberToWasmF64(x)
176
196
  let trunced = WasmI64.truncF64S(xval)
177
- let ret = WasmI32.toGrain(reducedInteger(trunced)): Number
178
- Memory.decRef(WasmI32.fromGrain(x))
179
- Memory.decRef(WasmI32.fromGrain(trunc))
180
- ret
197
+ WasmI32.toGrain(reducedInteger(trunced)): Number
181
198
  }
182
199
 
183
200
  /**
@@ -188,14 +205,11 @@ export let rec trunc = (x: Number) => {
188
205
  *
189
206
  * @since v0.4.0
190
207
  */
191
- @disableGC
192
- export let rec round = (x: Number) => {
208
+ @unsafe
209
+ export let round = (x: Number) => {
193
210
  let xval = coerceNumberToWasmF64(x)
194
211
  let rounded = WasmI64.truncF64S(WasmF64.nearest(xval))
195
- let ret = WasmI32.toGrain(reducedInteger(rounded)): Number
196
- Memory.decRef(WasmI32.fromGrain(x))
197
- Memory.decRef(WasmI32.fromGrain(round))
198
- ret
212
+ WasmI32.toGrain(reducedInteger(rounded)): Number
199
213
  }
200
214
 
201
215
  /**
@@ -216,21 +230,21 @@ export let abs = (x: Number) => if (0 > x) x * -1 else x
216
230
  *
217
231
  * @since v0.4.0
218
232
  */
219
- export let neg = (x: Number) => if (x > 0) x * -1 else x
233
+ export let neg = (x: Number) => x * -1
220
234
 
221
235
  /**
222
236
  * Checks if a number is finite.
223
237
  * All values are finite exept for floating point NaN, infinity or negative infinity.
224
238
  *
225
239
  * @param x: The number to check
226
- * @returns `true` if the value is finite, otherwise `false`
240
+ * @returns `true` if the value is finite or `false` otherwise
227
241
  *
228
242
  * @since v0.4.0
229
243
  */
230
- @disableGC
231
- export let rec isFinite = (x: Number) => {
244
+ @unsafe
245
+ export let isFinite = (x: Number) => {
232
246
  let asPtr = WasmI32.fromGrain(x)
233
- let ret = if (isBoxedNumber(asPtr)) {
247
+ if (isBoxedNumber(asPtr)) {
234
248
  // Boxed numbers can have multiple subtypes, of which float32 and float64 can be infinite.
235
249
  let tag = WasmI32.load(asPtr, 4n)
236
250
  if (WasmI32.eq(tag, Tags._GRAIN_FLOAT64_BOXED_NUM_TAG)) {
@@ -251,9 +265,6 @@ export let rec isFinite = (x: Number) => {
251
265
  // Simple numbers are integers and cannot be infinite.
252
266
  true
253
267
  }
254
- Memory.decRef(asPtr)
255
- Memory.decRef(WasmI32.fromGrain(isFinite))
256
- ret
257
268
  }
258
269
 
259
270
  /**
@@ -265,10 +276,10 @@ export let rec isFinite = (x: Number) => {
265
276
  *
266
277
  * @since v0.4.0
267
278
  */
268
- @disableGC
269
- export let rec isNaN = (x: Number) => {
279
+ @unsafe
280
+ export let isNaN = (x: Number) => {
270
281
  let asPtr = WasmI32.fromGrain(x)
271
- let ret = if (isBoxedNumber(asPtr)) {
282
+ if (isBoxedNumber(asPtr)) {
272
283
  // Boxed numbers can have multiple subtypes, of which float32 and float64 can be NaN.
273
284
  let tag = WasmI32.load(asPtr, 4n)
274
285
  if (WasmI32.eq(tag, Tags._GRAIN_FLOAT64_BOXED_NUM_TAG)) {
@@ -287,9 +298,6 @@ export let rec isNaN = (x: Number) => {
287
298
  // Simple numbers are integers and cannot be NaN.
288
299
  false
289
300
  }
290
- Memory.decRef(asPtr)
291
- Memory.decRef(WasmI32.fromGrain(isNaN))
292
- ret
293
301
  }
294
302
 
295
303
  /**
@@ -297,16 +305,16 @@ export let rec isNaN = (x: Number) => {
297
305
  * Note that this function is not the exact opposite of isFinite(Number) in that it doesn't return true for NaN.
298
306
  *
299
307
  * @param x: The number to check
300
- * @returns `true` if the value is infinite, otherwise `false`
308
+ * @returns `true` if the value is infinite or `false` otherwise
301
309
  *
302
310
  * @since v0.4.0
303
311
  */
304
- @disableGC
305
- export let rec isInfinite = (x: Number) => {
312
+ @unsafe
313
+ export let isInfinite = (x: Number) => {
306
314
  // The following code is equivalent to (!isFinite(x) && !isNaN(x)),
307
315
  // so see those functions to understand what's going on here.
308
316
  let asPtr = WasmI32.fromGrain(x)
309
- let ret = if (isBoxedNumber(asPtr)) {
317
+ if (isBoxedNumber(asPtr)) {
310
318
  let tag = WasmI32.load(asPtr, 4n)
311
319
  if (WasmI32.eq(tag, Tags._GRAIN_FLOAT64_BOXED_NUM_TAG)) {
312
320
  let wf64 = WasmF64.load(asPtr, 8n)
@@ -320,24 +328,73 @@ export let rec isInfinite = (x: Number) => {
320
328
  } else {
321
329
  false
322
330
  }
323
- Memory.decRef(asPtr)
324
- Memory.decRef(WasmI32.fromGrain(isInfinite))
325
- ret
326
331
  }
327
332
 
328
333
  /**
329
334
  * Parses a string representation of an integer into a `Number` using the
330
335
  * specified radix (also known as a number system "base").
331
- *
336
+ *
332
337
  * If the string has a radix prefix (i.e. "0x"/"0X", "0o"/"0O", or "0b"/"0B"
333
338
  * for radixes 16, 8, or 2 respectively), the supplied radix is ignored in
334
339
  * favor of the prefix. Underscores that appear in the numeric portion of the
335
340
  * input are ignored.
336
- *
341
+ *
337
342
  * @param input: The string to parse
338
343
  * @param radix: The number system base to use when parsing the input string
339
344
  * @returns `Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise
340
- *
345
+ *
341
346
  * @since v0.4.5
342
347
  */
343
348
  export parseInt
349
+
350
+ /**
351
+ * Computes how many times pi has to be subtracted to achieve the required bounds for sin.
352
+ */
353
+ let reduceToPiBound = (radians: Number) => {
354
+ floor(radians / pi)
355
+ }
356
+
357
+ /**
358
+ * 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/.
359
+ */
360
+ let chebyshevSine = (radians: Number) => {
361
+ let pi_minor = -0.00000008742278
362
+ let x2 = radians * radians
363
+ let p11 = 0.00000000013291342
364
+ let p9 = p11 * x2 + -0.000000023317787
365
+ let p7 = p9 * x2 + 0.0000025222919
366
+ let p5 = p7 * x2 + -0.00017350505
367
+ let p3 = p5 * x2 + 0.0066208798
368
+ let p1 = p3 * x2 + -0.10132118
369
+ (radians - pi - pi_minor) * (radians + pi + pi_minor) * p1 * radians
370
+ }
371
+
372
+ /**
373
+ * Computes the sine of a number (in radians) using Chebyshev polynomials.
374
+ *
375
+ * @param radians: The input in radians
376
+ * @returns The computed sine
377
+ *
378
+ * @since v0.5.2
379
+ */
380
+ export let sin = (radians: Number) => {
381
+ let quot = reduceToPiBound(radians)
382
+ let bounded = radians - pi * quot
383
+ if (quot % 2 == 0) {
384
+ chebyshevSine(bounded)
385
+ } else {
386
+ neg(chebyshevSine(bounded))
387
+ }
388
+ }
389
+
390
+ /**
391
+ * Computes the cosine of a number (in radians) using Chebyshev polynomials.
392
+ *
393
+ * @param radians: The input in radians
394
+ * @returns The computed cosine
395
+ *
396
+ * @since v0.5.2
397
+ */
398
+ export let cos = (radians: Number) => {
399
+ sin(pi / 2 + radians)
400
+ }
package/number.md CHANGED
@@ -13,6 +13,53 @@ No other changes yet.
13
13
  import Number from "number"
14
14
  ```
15
15
 
16
+ ## Constants
17
+
18
+ Number constant values.
19
+
20
+ ### Number.**pi**
21
+
22
+ <details disabled>
23
+ <summary tabindex="-1">Added in <code>next</code></summary>
24
+ No other changes yet.
25
+ </details>
26
+
27
+ ```grain
28
+ pi : Number
29
+ ```
30
+
31
+ Pi represented as a Number value.
32
+
33
+ ### Number.**tau**
34
+
35
+ <details disabled>
36
+ <summary tabindex="-1">Added in <code>next</code></summary>
37
+ No other changes yet.
38
+ </details>
39
+
40
+ ```grain
41
+ tau : Number
42
+ ```
43
+
44
+ Tau represented as a Number value.
45
+
46
+ ### Number.**e**
47
+
48
+ <details disabled>
49
+ <summary tabindex="-1">Added in <code>next</code></summary>
50
+ No other changes yet.
51
+ </details>
52
+
53
+ ```grain
54
+ e : Number
55
+ ```
56
+
57
+ Euler's number represented as a Number value.
58
+
59
+ ## Operations
60
+
61
+ Functions for operating on values of the Number type.
62
+
16
63
  ### Number.**add**
17
64
 
18
65
  <details disabled>
@@ -402,7 +449,7 @@ Returns:
402
449
 
403
450
  |type|description|
404
451
  |----|-----------|
405
- |`Bool`|`true` if the value is finite, otherwise `false`|
452
+ |`Bool`|`true` if the value is finite or `false` otherwise|
406
453
 
407
454
  ### Number.**isNaN**
408
455
 
@@ -454,12 +501,12 @@ Returns:
454
501
 
455
502
  |type|description|
456
503
  |----|-----------|
457
- |`Bool`|`true` if the value is infinite, otherwise `false`|
504
+ |`Bool`|`true` if the value is infinite or `false` otherwise|
458
505
 
459
506
  ### Number.**parseInt**
460
507
 
461
508
  <details disabled>
462
- <summary tabindex="-1">Added in <code>next</code></summary>
509
+ <summary tabindex="-1">Added in <code>0.4.5</code></summary>
463
510
  No other changes yet.
464
511
  </details>
465
512
 
@@ -488,3 +535,53 @@ Returns:
488
535
  |----|-----------|
489
536
  |`Result<Number, String>`|`Ok(value)` containing the parsed number on a successful parse or `Err(msg)` containing an error message string otherwise|
490
537
 
538
+ ### Number.**sin**
539
+
540
+ <details disabled>
541
+ <summary tabindex="-1">Added in <code>next</code></summary>
542
+ No other changes yet.
543
+ </details>
544
+
545
+ ```grain
546
+ sin : Number -> Number
547
+ ```
548
+
549
+ Computes the sine of a number (in radians) using Chebyshev polynomials.
550
+
551
+ Parameters:
552
+
553
+ |param|type|description|
554
+ |-----|----|-----------|
555
+ |`radians`|`Number`|The input in radians|
556
+
557
+ Returns:
558
+
559
+ |type|description|
560
+ |----|-----------|
561
+ |`Number`|The computed sine|
562
+
563
+ ### Number.**cos**
564
+
565
+ <details disabled>
566
+ <summary tabindex="-1">Added in <code>next</code></summary>
567
+ No other changes yet.
568
+ </details>
569
+
570
+ ```grain
571
+ cos : Number -> Number
572
+ ```
573
+
574
+ Computes the cosine of a number (in radians) using Chebyshev polynomials.
575
+
576
+ Parameters:
577
+
578
+ |param|type|description|
579
+ |-----|----|-----------|
580
+ |`radians`|`Number`|The input in radians|
581
+
582
+ Returns:
583
+
584
+ |type|description|
585
+ |----|-----------|
586
+ |`Number`|The computed cosine|
587
+
package/option.md CHANGED
@@ -533,7 +533,7 @@ No other changes yet.
533
533
  </details>
534
534
 
535
535
  ```grain
536
- ( or ) : (Option<a>, Option<a>) -> Option<a>
536
+ or : (Option<a>, Option<a>) -> Option<a>
537
537
  ```
538
538
 
539
539
  Behaves like a logical OR (`||`) where the first Option is only returned if it is the `Some` variant and falling back to the second Option in all other cases.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grain/stdlib",
3
- "version": "0.4.6",
3
+ "version": "0.5.2",
4
4
  "description": "The standard library for the Grain language.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://grain-lang.org",
@@ -18,7 +18,7 @@
18
18
  "directory": "stdlib"
19
19
  },
20
20
  "engines": {
21
- "node": ">=14"
21
+ "node": ">=16"
22
22
  },
23
23
  "main": "index.js",
24
24
  "files": [
@@ -27,7 +27,7 @@
27
27
  "index.js"
28
28
  ],
29
29
  "scripts": {
30
- "clean": "del-cli '**/*.wasm' '**/*.wat' '**/*.modsig'"
30
+ "clean": "del-cli \"**/*.wasm\" \"**/*.wat\" \"**/*.modsig\""
31
31
  },
32
32
  "dependencies": {},
33
33
  "devDependencies": {