@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/map.gr CHANGED
@@ -1,5 +1,9 @@
1
- // Standard library for Map (aka HashMap) functionality
2
-
1
+ /**
2
+ * @module Map: A Map holds key-value pairs. Any value may be used as a key or value. Operations on a Map mutate the internal state, so it never needs to be re-assigned.
3
+ * @example import Map from "map"
4
+ *
5
+ * @since v0.2.0
6
+ */
3
7
  import List from "list"
4
8
  import Array from "array"
5
9
  import { hash } from "hash"
@@ -14,17 +18,39 @@ record Bucket<k, v> {
14
18
  mut next: Option<Bucket<k, v>>,
15
19
  }
16
20
 
21
+ /**
22
+ * @section Types: Type declarations included in the Map module.
23
+ */
24
+
17
25
  record Map<k, v> {
18
26
  mut size: Number,
19
27
  mut buckets: Array<Option<Bucket<k, v>>>,
20
28
  }
21
29
 
22
- // TODO: This could take an `eq` function to custom comparisons
23
- export let makeSized = size => {
30
+ /**
31
+ * @section Values: Functions for working with Maps.
32
+ */
33
+
34
+ /**
35
+ * Creates a new empty map with an initial storage of the given size. As values are added or removed, the internal storage may grow or shrink. Generally, you won't need to care about the storage size of your map and can use `Map.make()` instead.
36
+ *
37
+ * @param size: The initial storage size of the map
38
+ * @returns An empty map with the given initial storage size
39
+ *
40
+ * @since v0.2.0
41
+ */
42
+ export let makeSized = size => { // TODO: This could take an `eq` function to custom comparisons
24
43
  let buckets = Array.make(size, None)
25
44
  { size: 0, buckets }
26
45
  }
27
46
 
47
+ /**
48
+ * Creates a new, empty map.
49
+ *
50
+ * @returns An empty map
51
+ *
52
+ * @since v0.2.0
53
+ */
28
54
  export let make = () => {
29
55
  makeSized(16)
30
56
  }
@@ -95,6 +121,15 @@ let rec replaceInBucket = (key, value, node) => {
95
121
  }
96
122
  }
97
123
 
124
+ /**
125
+ * Adds a new key-value pair to the map. If the key already exists in the map, the value is replaced.
126
+ *
127
+ * @param key: The unique key in the map
128
+ * @param value: The value to store
129
+ * @param map: The map to modify
130
+ *
131
+ * @since v0.2.0
132
+ */
98
133
  export let set = (key, value, map) => {
99
134
  let buckets = map.buckets
100
135
  let idx = getBucketIndex(key, buckets)
@@ -130,6 +165,15 @@ let rec valueFromBucket = (key, node) => {
130
165
  }
131
166
  }
132
167
 
168
+ /**
169
+ * Retrieves the value for the given key.
170
+ *
171
+ * @param key: The key to access
172
+ * @param map: The map to access
173
+ * @returns `Some(value)` if the key exists in the map or `None` otherwise
174
+ *
175
+ * @since v0.2.0
176
+ */
133
177
  export let get = (key, map) => {
134
178
  let buckets = map.buckets
135
179
  let idx = getBucketIndex(key, buckets)
@@ -151,6 +195,15 @@ let rec nodeInBucket = (key, node) => {
151
195
  }
152
196
  }
153
197
 
198
+ /**
199
+ * Determines if the map contains the given key. In such a case, it will always contain a value for the given key.
200
+ *
201
+ * @param key: The key to search for
202
+ * @param map: The map to search
203
+ * @returns `true` if the map contains the given key or `false` otherwise
204
+ *
205
+ * @since v0.2.0
206
+ */
154
207
  export let contains = (key, map) => {
155
208
  let buckets = map.buckets
156
209
  let idx = getBucketIndex(key, buckets)
@@ -175,6 +228,14 @@ let rec removeInBucket = (key, node) => {
175
228
  }
176
229
  }
177
230
 
231
+ /**
232
+ * Removes the given key from the map, which also removes the value. If the key pair doesn't exist, nothing happens.
233
+ *
234
+ * @param key: The key to remove
235
+ * @param map: The map to update
236
+ *
237
+ * @since v0.2.0
238
+ */
178
239
  export let remove = (key, map) => {
179
240
  let buckets = map.buckets
180
241
  let idx = getBucketIndex(key, buckets)
@@ -195,6 +256,15 @@ export let remove = (key, map) => {
195
256
  }
196
257
  }
197
258
 
259
+ /**
260
+ * Updates a value in the map by calling an updater function that receives the previously stored value as an `Option` and returns the new value to be stored as an `Option`. If the key didn't exist previously, the value will be `None`. If `None` is returned from the updater function, the key-value pair is removed.
261
+ *
262
+ * @param key: The unique key in the map
263
+ * @param fn: The updater function
264
+ * @param map: The map to modify
265
+ *
266
+ * @since v0.3.0
267
+ */
198
268
  export let update = (key, fn, map) => {
199
269
  let val = get(key, map)
200
270
  match (fn(val)) {
@@ -203,14 +273,37 @@ export let update = (key, fn, map) => {
203
273
  }
204
274
  }
205
275
 
276
+ /**
277
+ * Provides the count of key-value pairs stored within the map.
278
+ *
279
+ * @param map: The map to inspect
280
+ * @returns The count of key-value pairs in the map
281
+ *
282
+ * @since v0.2.0
283
+ */
206
284
  export let size = map => {
207
285
  map.size
208
286
  }
209
287
 
288
+ /**
289
+ * Determines if the map contains no key-value pairs.
290
+ *
291
+ * @param map: The map to inspect
292
+ * @returns `true` if the given map is empty or `false` otherwise
293
+ *
294
+ * @since v0.2.0
295
+ */
210
296
  export let isEmpty = map => {
211
297
  size(map) == 0
212
298
  }
213
299
 
300
+ /**
301
+ * Resets the map by removing all key-value pairs.
302
+ *
303
+ * @param map: The map to reset
304
+ *
305
+ * @since v0.2.0
306
+ */
214
307
  export let clear = map => {
215
308
  map.size = 0
216
309
  let buckets = map.buckets
@@ -223,12 +316,21 @@ let rec forEachBucket = (fn, node) => {
223
316
  match (node) {
224
317
  None => void,
225
318
  Some({ key, value, next }) => {
226
- fn(key, value)
319
+ fn(key, value): Void
227
320
  forEachBucket(fn, next)
228
321
  },
229
322
  }
230
323
  }
231
324
 
325
+ /**
326
+ * Iterates the map, calling an iterator function with each key and value.
327
+ *
328
+ * @param fn: The iterator function to call with each key and value
329
+ * @param map: The map to iterate
330
+ *
331
+ * @since v0.2.0
332
+ * @history v0.5.0: Ensured the iterator function return type is always `Void`
333
+ */
232
334
  export let forEach = (fn, map) => {
233
335
  let buckets = map.buckets
234
336
  Array.forEach(bucket => {
@@ -244,6 +346,16 @@ let rec reduceEachBucket = (fn, node, acc) => {
244
346
  }
245
347
  }
246
348
 
349
+ /**
350
+ * Combines all key-value pairs of a map using a reducer function.
351
+ *
352
+ * @param fn: The reducer function to call on each key and value, where the value returned will be the next accumulator value
353
+ * @param init: The initial value to use for the accumulator on the first iteration
354
+ * @param map: The map to iterate
355
+ * @returns The final accumulator returned from `fn`
356
+ *
357
+ * @since v0.2.0
358
+ */
247
359
  export let reduce = (fn, init, map) => {
248
360
  let buckets = map.buckets
249
361
  let mut acc = init
@@ -253,18 +365,50 @@ export let reduce = (fn, init, map) => {
253
365
  acc
254
366
  }
255
367
 
368
+ /**
369
+ * Enumerates all keys in the given map.
370
+ *
371
+ * @param map: The map to enumerate
372
+ * @returns A list containing all keys from the given map
373
+ *
374
+ * @since v0.2.0
375
+ */
256
376
  export let keys = map => {
257
377
  reduce((list, key, _value) => [key, ...list], [], map)
258
378
  }
259
379
 
380
+ /**
381
+ * Enumerates all values in the given map.
382
+ *
383
+ * @param map: The map to enumerate
384
+ * @returns A list containing all values from the given map
385
+ *
386
+ * @since v0.2.0
387
+ */
260
388
  export let values = map => {
261
389
  reduce((list, _key, value) => [value, ...list], [], map)
262
390
  }
263
391
 
392
+ /**
393
+ * Enumerates all key-value pairs in the given map.
394
+ *
395
+ * @param map: The map to enumerate
396
+ * @returns A list containing all key-value pairs from the given map
397
+ *
398
+ * @since v0.2.0
399
+ */
264
400
  export let toList = map => {
265
401
  reduce((list, key, value) => [(key, value), ...list], [], map)
266
402
  }
267
403
 
404
+ /**
405
+ * Creates a map from a list.
406
+ *
407
+ * @param list: The list to convert
408
+ * @returns A map containing all key-value pairs from the list
409
+ *
410
+ * @since v0.2.0
411
+ */
268
412
  export let fromList = list => {
269
413
  let map = make()
270
414
  List.forEach(pair => {
@@ -280,16 +424,25 @@ let setInArray = array => {
280
424
  array[i] = (key, value)
281
425
  // no decRef on key and value, since they are stored in array
282
426
  Memory.decRef(WasmI32.fromGrain(iter))
427
+ Memory.incRef(WasmI32.fromGrain((+)))
428
+ Memory.incRef(WasmI32.fromGrain(i))
283
429
  i + 1
284
430
  }
285
431
  iter
286
432
  }
287
433
 
434
+ /**
435
+ * Converts a map into an array of its key-value pairs.
436
+ *
437
+ * @param map: The map to convert
438
+ * @returns An array containing all key-value pairs from the given map
439
+ *
440
+ * @since v0.2.0
441
+ */
288
442
  @disableGC
289
443
  export let rec toArray = map => {
290
444
  let length = WasmI32.shrS(WasmI32.fromGrain(map.size), 1n)
291
- // TODO(#783): Removing parens around Array<a> causes a parse error
292
- let array = WasmI32.toGrain(allocateArray(length)): (Array<a>)
445
+ let array = WasmI32.toGrain(allocateArray(length)): Array<a>
293
446
  Memory.incRef(WasmI32.fromGrain(setInArray))
294
447
  Memory.incRef(WasmI32.fromGrain(array))
295
448
  let setInArray = setInArray(array)
@@ -303,6 +456,14 @@ export let rec toArray = map => {
303
456
  array
304
457
  }
305
458
 
459
+ /**
460
+ * Creates a map from an array.
461
+ *
462
+ * @param array: The array to convert
463
+ * @returns A map containing all key-value pairs from the array
464
+ *
465
+ * @since v0.2.0
466
+ */
306
467
  export let fromArray = array => {
307
468
  let map = make()
308
469
  Array.forEach(pair => {
@@ -312,6 +473,14 @@ export let fromArray = array => {
312
473
  map
313
474
  }
314
475
 
476
+ /**
477
+ * Removes key-value pairs from a map where a predicate function returns `false`.
478
+ *
479
+ * @param fn: The predicate function to indicate which key-value pairs to remove from the map, where returning `false` indicates the key-value pair should be removed
480
+ * @param map: The map to iterate
481
+ *
482
+ * @since v0.2.0
483
+ */
315
484
  export let filter = (predicate, map) => {
316
485
  let keysToRemove = reduce((list, key, value) => if (!predicate(key, value)) {
317
486
  [key, ...list]
@@ -323,12 +492,28 @@ export let filter = (predicate, map) => {
323
492
  }, keysToRemove)
324
493
  }
325
494
 
495
+ /**
496
+ * Removes key-value pairs from a map where a predicate function returns `true`.
497
+ *
498
+ * @param fn: The predicate function to indicate which key-value pairs to remove from the map, where returning `true` indicates the key-value pair should be removed
499
+ * @param map: The map to iterate
500
+ *
501
+ * @since v0.2.0
502
+ */
326
503
  export let reject = (predicate, map) => {
327
504
  filter((key, value) => !predicate(key, value), map)
328
505
  }
329
506
 
330
507
  // TODO: Should return a Record type instead of a Tuple
331
508
  // Waiting on https://github.com/grain-lang/grain/issues/190
509
+ /**
510
+ * Provides data representing the internal state state of the map.
511
+ *
512
+ * @param map: The map to inspect
513
+ * @returns The internal state of the map
514
+ *
515
+ * @since v0.2.0
516
+ */
332
517
  export let getInternalStats = map => {
333
518
  (map.size, Array.length(map.buckets))
334
519
  }