@grain/stdlib 0.4.5 → 0.5.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 +87 -0
- package/LICENSE +1 -1
- package/array.gr +18 -18
- package/array.md +18 -18
- package/bigint.gr +497 -0
- package/bigint.md +811 -0
- package/buffer.gr +49 -213
- package/buffer.md +24 -17
- package/bytes.gr +100 -202
- package/bytes.md +19 -0
- package/char.gr +63 -133
- package/exception.md +6 -0
- package/float32.gr +159 -82
- package/float32.md +315 -0
- package/float64.gr +163 -82
- package/float64.md +315 -0
- package/hash.gr +37 -37
- package/int32.gr +479 -230
- package/int32.md +937 -0
- package/int64.gr +479 -230
- package/int64.md +937 -0
- package/list.gr +467 -70
- package/list.md +1141 -0
- package/map.gr +192 -7
- package/map.md +525 -0
- package/number.gr +30 -54
- package/number.md +3 -3
- package/option.md +1 -1
- package/package.json +3 -3
- package/pervasives.gr +499 -59
- package/pervasives.md +1116 -0
- package/queue.gr +4 -0
- package/queue.md +10 -0
- package/random.gr +196 -0
- package/random.md +179 -0
- package/regex.gr +1833 -842
- package/regex.md +11 -11
- package/result.md +1 -1
- package/runtime/bigint.gr +2045 -0
- package/runtime/bigint.md +326 -0
- package/runtime/dataStructures.gr +99 -278
- package/runtime/dataStructures.md +391 -0
- package/runtime/debug.md +6 -0
- package/runtime/equal.gr +5 -23
- package/runtime/equal.md +6 -0
- package/runtime/exception.md +30 -0
- package/runtime/gc.gr +20 -3
- package/runtime/gc.md +36 -0
- package/runtime/malloc.gr +13 -11
- package/runtime/malloc.md +55 -0
- package/runtime/numberUtils.gr +93 -41
- package/runtime/numberUtils.md +54 -0
- package/runtime/numbers.gr +1043 -391
- package/runtime/numbers.md +300 -0
- package/runtime/string.gr +136 -230
- package/runtime/string.md +24 -0
- package/runtime/stringUtils.gr +58 -38
- package/runtime/stringUtils.md +6 -0
- package/runtime/unsafe/constants.gr +17 -0
- package/runtime/unsafe/constants.md +72 -0
- package/runtime/unsafe/conv.md +71 -0
- package/runtime/unsafe/errors.md +204 -0
- package/runtime/unsafe/memory.md +54 -0
- package/runtime/unsafe/printWasm.md +24 -0
- package/runtime/unsafe/tags.gr +9 -8
- package/runtime/unsafe/tags.md +120 -0
- package/runtime/unsafe/wasmf32.md +168 -0
- package/runtime/unsafe/wasmf64.md +168 -0
- package/runtime/unsafe/wasmi32.md +282 -0
- package/runtime/unsafe/wasmi64.md +300 -0
- package/runtime/utils/printing.gr +62 -0
- package/runtime/utils/printing.md +18 -0
- package/runtime/wasi.gr +1 -1
- package/runtime/wasi.md +839 -0
- package/set.gr +17 -8
- package/set.md +24 -21
- package/stack.gr +3 -3
- package/stack.md +4 -6
- package/string.gr +196 -331
- package/string.md +3 -3
- package/sys/file.gr +246 -430
- package/sys/process.gr +27 -45
- package/sys/random.gr +47 -16
- package/sys/random.md +38 -0
- package/sys/time.gr +11 -27
package/map.gr
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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
|
}
|