@grain/stdlib 0.4.2 → 0.4.6

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 (61) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +1 -1
  3. package/array.gr +200 -89
  4. package/array.md +81 -5
  5. package/buffer.gr +93 -36
  6. package/bytes.gr +10 -10
  7. package/char.gr +112 -56
  8. package/char.md +200 -0
  9. package/float32.gr +120 -4
  10. package/float32.md +315 -0
  11. package/float64.gr +120 -4
  12. package/float64.md +315 -0
  13. package/hash.gr +42 -15
  14. package/hash.md +44 -0
  15. package/int32.gr +370 -75
  16. package/int32.md +833 -0
  17. package/int64.gr +370 -75
  18. package/int64.md +833 -0
  19. package/list.gr +121 -50
  20. package/map.gr +106 -110
  21. package/number.gr +37 -1
  22. package/number.md +66 -0
  23. package/option.gr +260 -53
  24. package/option.md +579 -0
  25. package/package.json +1 -1
  26. package/pervasives.gr +32 -20
  27. package/queue.gr +102 -30
  28. package/queue.md +191 -0
  29. package/range.gr +26 -26
  30. package/range.md +1 -1
  31. package/regex.md +9 -9
  32. package/result.gr +216 -70
  33. package/result.md +446 -0
  34. package/runtime/dataStructures.gr +28 -29
  35. package/runtime/debug.gr +0 -1
  36. package/runtime/equal.gr +37 -16
  37. package/runtime/exception.gr +28 -15
  38. package/runtime/gc.gr +33 -20
  39. package/runtime/malloc.gr +19 -11
  40. package/runtime/numberUtils.gr +208 -103
  41. package/runtime/numbers.gr +217 -118
  42. package/runtime/string.gr +98 -39
  43. package/runtime/stringUtils.gr +176 -0
  44. package/runtime/unsafe/conv.gr +10 -10
  45. package/runtime/unsafe/memory.gr +14 -3
  46. package/runtime/unsafe/printWasm.gr +4 -4
  47. package/runtime/unsafe/tags.gr +2 -2
  48. package/runtime/unsafe/wasmf32.gr +9 -2
  49. package/runtime/unsafe/wasmf64.gr +9 -2
  50. package/runtime/unsafe/wasmi32.gr +65 -47
  51. package/runtime/unsafe/wasmi64.gr +78 -50
  52. package/runtime/wasi.gr +199 -45
  53. package/set.gr +281 -119
  54. package/set.md +502 -0
  55. package/stack.gr +26 -26
  56. package/string.gr +657 -341
  57. package/string.md +815 -0
  58. package/sys/file.gr +356 -177
  59. package/sys/process.gr +10 -6
  60. package/sys/random.gr +3 -6
  61. package/sys/time.gr +3 -3
package/list.gr CHANGED
@@ -16,11 +16,11 @@ let init = (length, fn) => {
16
16
  iter(0, length)
17
17
  }
18
18
 
19
- let length = (list) => {
19
+ let length = list => {
20
20
  let rec iter = (len, list) => {
21
21
  match (list) {
22
22
  [] => len,
23
- [_, ...rest] => iter(len + 1, rest)
23
+ [_, ...rest] => iter(len + 1, rest),
24
24
  }
25
25
  }
26
26
  iter(0, list)
@@ -30,17 +30,17 @@ let sum = list => {
30
30
  let rec iter = (n, list) => {
31
31
  match (list) {
32
32
  [] => n,
33
- [first, ...rest] => iter(n + first, rest)
33
+ [first, ...rest] => iter(n + first, rest),
34
34
  }
35
35
  }
36
36
  iter(0, list)
37
37
  }
38
38
 
39
- let reverse = (list) => {
39
+ let reverse = list => {
40
40
  let rec iter = (list, acc) => {
41
41
  match (list) {
42
42
  [] => acc,
43
- [first, ...rest] => iter(rest, [first, ...acc])
43
+ [first, ...rest] => iter(rest, [first, ...acc]),
44
44
  }
45
45
  }
46
46
  iter(list, [])
@@ -49,35 +49,35 @@ let reverse = (list) => {
49
49
  let rec append = (list1, list2) => {
50
50
  match (list1) {
51
51
  [] => list2,
52
- [first, ...rest] => [first, ...append(rest, list2)]
52
+ [first, ...rest] => [first, ...append(rest, list2)],
53
53
  }
54
54
  }
55
55
 
56
56
  let rec contains = (value, list) => {
57
57
  match (list) {
58
58
  [] => false,
59
- [first, ...rest] => (first == value) || contains(value, rest)
59
+ [first, ...rest] => first == value || contains(value, rest),
60
60
  }
61
61
  }
62
62
 
63
63
  let rec reduce = (fn, acc, list) => {
64
64
  match (list) {
65
65
  [] => acc,
66
- [first, ...rest] => reduce(fn, fn(acc, first), rest)
66
+ [first, ...rest] => reduce(fn, fn(acc, first), rest),
67
67
  }
68
68
  }
69
69
 
70
70
  let rec reduceRight = (fn, acc, list) => {
71
71
  match (list) {
72
72
  [] => acc,
73
- [first, ...rest] => fn(first, reduceRight(fn, acc, rest))
73
+ [first, ...rest] => fn(first, reduceRight(fn, acc, rest)),
74
74
  }
75
75
  }
76
76
 
77
77
  let rec map = (fn, list) => {
78
78
  match (list) {
79
79
  [] => [],
80
- [first, ...rest] => [fn(first), ...map(fn, rest)]
80
+ [first, ...rest] => [fn(first), ...map(fn, rest)],
81
81
  }
82
82
  }
83
83
 
@@ -85,7 +85,7 @@ let mapi = (fn, list) => {
85
85
  let rec iter = (fn, list, index) => {
86
86
  match (list) {
87
87
  [] => [],
88
- [first, ...rest] => [fn(first, index), ...iter(fn, rest, index + 1)]
88
+ [first, ...rest] => [fn(first, index), ...iter(fn, rest, index + 1)],
89
89
  }
90
90
  }
91
91
  iter(fn, list, 0)
@@ -94,16 +94,20 @@ let mapi = (fn, list) => {
94
94
  let rec flatMap = (fn, list) => {
95
95
  match (list) {
96
96
  [] => [],
97
- [first, ...rest] => append(fn(first), flatMap(fn, rest))
97
+ [first, ...rest] => append(fn(first), flatMap(fn, rest)),
98
98
  }
99
99
  }
100
100
 
101
101
  let every = (fn, list) => {
102
- reduce((acc, value) => { acc && fn(value) }, true, list)
102
+ reduce((acc, value) => {
103
+ acc && fn(value)
104
+ }, true, list)
103
105
  }
104
106
 
105
107
  let some = (fn, list) => {
106
- reduce((acc, value) => { acc || fn(value) }, false, list)
108
+ reduce((acc, value) => {
109
+ acc || fn(value)
110
+ }, false, list)
107
111
  }
108
112
 
109
113
  let rec forEach = (fn, list) => {
@@ -112,7 +116,7 @@ let rec forEach = (fn, list) => {
112
116
  [first, ...rest] => {
113
117
  fn(first)
114
118
  forEach(fn, rest)
115
- }
119
+ },
116
120
  }
117
121
  }
118
122
 
@@ -123,7 +127,7 @@ let forEachi = (fn, list) => {
123
127
  [first, ...rest] => {
124
128
  fn(first, index)
125
129
  iter(fn, rest, index + 1)
126
- }
130
+ },
127
131
  }
128
132
  }
129
133
  iter(fn, list, 0)
@@ -132,7 +136,8 @@ let forEachi = (fn, list) => {
132
136
  let rec filter = (fn, list) => {
133
137
  match (list) {
134
138
  [] => [],
135
- [first, ...rest] => if (fn(first)) [first, ...filter(fn, rest)] else filter(fn, rest)
139
+ [first, ...rest] =>
140
+ if (fn(first)) [first, ...filter(fn, rest)] else filter(fn, rest),
136
141
  }
137
142
  }
138
143
 
@@ -140,7 +145,9 @@ let filteri = (fn, list) => {
140
145
  let rec iter = (fn, list, index) => {
141
146
  match (list) {
142
147
  [] => [],
143
- [first, ...rest] => if (fn(first, index)) [first, ...iter(fn, rest, index + 1)] else iter(fn, rest, index + 1)
148
+ [first, ...rest] =>
149
+ if (fn(first, index)) [first, ...iter(fn, rest, index + 1)]
150
+ else iter(fn, rest, index + 1),
144
151
  }
145
152
  }
146
153
  iter(fn, list, 0)
@@ -149,21 +156,22 @@ let filteri = (fn, list) => {
149
156
  let rec reject = (fn, list) => {
150
157
  match (list) {
151
158
  [] => [],
152
- [first, ...rest] => if (!fn(first)) [first, ...reject(fn, rest)] else reject(fn, rest)
159
+ [first, ...rest] =>
160
+ if (!fn(first)) [first, ...reject(fn, rest)] else reject(fn, rest),
153
161
  }
154
162
  }
155
163
 
156
- let head = (list) => {
164
+ let head = list => {
157
165
  match (list) {
158
166
  [] => None,
159
- [first, ..._] => Some(first)
167
+ [first, ..._] => Some(first),
160
168
  }
161
169
  }
162
170
 
163
- let tail = (list) => {
171
+ let tail = list => {
164
172
  match (list) {
165
173
  [] => None,
166
- [_, ...rest] => Some(rest)
174
+ [_, ...rest] => Some(rest),
167
175
  }
168
176
  }
169
177
 
@@ -173,15 +181,15 @@ let rec nth = (index, list) => {
173
181
  } else {
174
182
  match (list) {
175
183
  [] => None,
176
- [first, ...rest] => if (index == 0) Some(first) else nth(index - 1, rest)
184
+ [first, ...rest] => if (index == 0) Some(first) else nth(index - 1, rest),
177
185
  }
178
186
  }
179
187
  }
180
188
 
181
- let rec flatten = (list) => {
189
+ let rec flatten = list => {
182
190
  match (list) {
183
191
  [] => [],
184
- [first, ...rest] => append(first, flatten(rest))
192
+ [first, ...rest] => append(first, flatten(rest)),
185
193
  }
186
194
  }
187
195
 
@@ -189,9 +197,11 @@ let rec insert = (value, index, list) => {
189
197
  if (index < 0) {
190
198
  fail "insert index cannot be a negative number"
191
199
  } else {
192
- match(list) {
200
+ match (list) {
193
201
  [] => if (index == 0) [value] else fail "insert index is out-of-bounds",
194
- [first, ...rest] => if (index == 0) [value, ...list] else [first, ...insert(value, index - 1, rest)]
202
+ [first, ...rest] =>
203
+ if (index == 0) [value, ...list]
204
+ else [first, ...insert(value, index - 1, rest)],
195
205
  }
196
206
  }
197
207
  }
@@ -200,7 +210,7 @@ let count = (fn, list) => {
200
210
  let rec iter = (n, list) => {
201
211
  match (list) {
202
212
  [] => n,
203
- [first, ...rest] => if (fn(first)) iter(n + 1, rest) else iter(n, rest)
213
+ [first, ...rest] => if (fn(first)) iter(n + 1, rest) else iter(n, rest),
204
214
  }
205
215
  }
206
216
  iter(0, list)
@@ -212,8 +222,11 @@ let part = (count, list) => {
212
222
  } else {
213
223
  let rec iter = (list1, list2, count) => {
214
224
  match (list2) {
215
- [] => if (count > 0) fail "part count is out-of-bounds" else (list1, list2),
216
- [first, ...rest] => if (count > 0) iter([first, ...list1], rest, count - 1) else (list1, list2)
225
+ [] =>
226
+ if (count > 0) fail "part count is out-of-bounds" else (list1, list2),
227
+ [first, ...rest] =>
228
+ if (count > 0) iter([first, ...list1], rest, count - 1)
229
+ else (list1, list2),
217
230
  }
218
231
  }
219
232
  let (pt1, pt2) = iter([], list, count)
@@ -222,15 +235,18 @@ let part = (count, list) => {
222
235
  }
223
236
 
224
237
  let rotate = (count, list) => {
225
- let (beginning, end) = if (count >= 0) part(count, list) else part(length(list) + count, list)
238
+ let (beginning, end) = if (count >= 0) part(count, list)
239
+ else part(length(list) + count, list)
226
240
  append(end, beginning)
227
241
  }
228
242
 
229
- let unique = (list) => {
243
+ let unique = list => {
230
244
  let rec iter = (list, acc) => {
231
245
  match (list) {
232
246
  [] => reverse(acc),
233
- [first, ...rest] => if (contains(first, acc)) iter(rest, acc) else iter(rest, [first, ...acc])
247
+ [first, ...rest] =>
248
+ if (contains(first, acc)) iter(rest, acc)
249
+ else iter(rest, [first, ...acc]),
234
250
  }
235
251
  }
236
252
  iter(list, [])
@@ -241,9 +257,9 @@ let rec drop = (n, list) => {
241
257
  fail "number of items to drop cannot be a negative number"
242
258
  } else {
243
259
  match ((n, list)) {
244
- (_,[]) => [],
260
+ (_, []) => [],
245
261
  (n, _) when n == 0 => list,
246
- (n, [first, ...rest]) => drop(n - 1, rest)
262
+ (n, [first, ...rest]) => drop(n - 1, rest),
247
263
  }
248
264
  }
249
265
  }
@@ -251,7 +267,7 @@ let rec drop = (n, list) => {
251
267
  let rec dropWhile = (fn, list) => {
252
268
  match (list) {
253
269
  [] => list,
254
- [first, ...rest] => if (fn(first)) dropWhile(fn, rest) else list
270
+ [first, ...rest] => if (fn(first)) dropWhile(fn, rest) else list,
255
271
  }
256
272
  }
257
273
 
@@ -262,7 +278,7 @@ let rec take = (n, list) => {
262
278
  match ((n, list)) {
263
279
  (_, []) => list,
264
280
  (n, _) when n == 0 => [],
265
- (n, [first, ...rest]) => [first, ...take(n-1, rest)]
281
+ (n, [first, ...rest]) => [first, ...take(n - 1, rest)],
266
282
  }
267
283
  }
268
284
  }
@@ -270,14 +286,14 @@ let rec take = (n, list) => {
270
286
  let rec takeWhile = (p, list) => {
271
287
  match (list) {
272
288
  [] => [],
273
- [first, ...rest] => if (p(first)) [first, ...takeWhile(p, rest)] else []
289
+ [first, ...rest] => if (p(first)) [first, ...takeWhile(p, rest)] else [],
274
290
  }
275
291
  }
276
292
 
277
293
  let rec find = (fn, list) => {
278
294
  match (list) {
279
295
  [] => None,
280
- [first, ...rest] => if (fn(first)) Some(first) else find(fn, rest)
296
+ [first, ...rest] => if (fn(first)) Some(first) else find(fn, rest),
281
297
  }
282
298
  }
283
299
 
@@ -285,7 +301,8 @@ let findIndex = (fn, list) => {
285
301
  let rec findItemIndex = (l, index) => {
286
302
  match (l) {
287
303
  [] => None,
288
- [first, ...rest] => if (fn(first)) Some(index) else findItemIndex(rest, index + 1)
304
+ [first, ...rest] =>
305
+ if (fn(first)) Some(index) else findItemIndex(rest, index + 1),
289
306
  }
290
307
  }
291
308
  findItemIndex(list, 0)
@@ -293,10 +310,10 @@ let findIndex = (fn, list) => {
293
310
 
294
311
  let product = (a, b) => {
295
312
  let mut list = []
296
- forEach((aItem) => {
297
- forEach((bItem) => {
298
- list = [(aItem, bItem), ...list]
299
- },b)
313
+ forEach(aItem => {
314
+ forEach(bItem => {
315
+ list = [(aItem, bItem), ...list]
316
+ }, b)
300
317
  }, a)
301
318
  reverse(list)
302
319
  }
@@ -311,21 +328,75 @@ let sub = (start, length, list) => {
311
328
  // @returns String
312
329
  let join = (separator: String, items: List<String>) => {
313
330
  let rec iter = (sep, acc, rem) => {
314
- match(rem) {
331
+ match (rem) {
315
332
  [] => acc,
316
333
  [hd, ...tl] => {
317
- let newAcc = match(acc) {
334
+ let newAcc = match (acc) {
318
335
  None => Some(hd),
319
- Some(s) => Some(hd ++ sep ++ s)
336
+ Some(s) => Some(hd ++ sep ++ s),
320
337
  }
321
338
  iter(sep, newAcc, tl)
322
- }
339
+ },
323
340
  }
324
341
  }
325
342
 
326
343
  // Reverse and reduce to take advantage of TCE
327
- match(iter(separator, None, reverse(items))) {
344
+ match (iter(separator, None, reverse(items))) {
328
345
  None => "",
329
346
  Some(s) => s,
330
347
  }
331
348
  }
349
+
350
+ /**
351
+ * Reverses the first list and appends the second list to the end.
352
+ *
353
+ * @param list1: The list to reverse
354
+ * @param list2: The list to append
355
+ * @since v0.4.5
356
+ */
357
+ let rec revAppend = (list1, list2) => {
358
+ match (list1) {
359
+ [hd, ...tl] => revAppend(tl, [hd, ...list2]),
360
+ [] => list2,
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Sorts the given list based on a given comparator function. The resulting list is sorted in increasing order.
366
+ *
367
+ * Ordering is calculated using a comparator function which takes two list elements and must return 0 if both are equal, a positive number if the first is greater, and a negative number if the first is smaller.
368
+ * @param comp: The comparator function used to indicate sort order
369
+ * @param list: The list to be sorted
370
+ * @since v0.4.5
371
+ */
372
+ let sort = (comp, list) => {
373
+ let rec merge = (left, right, list) => {
374
+ match ((left, right)) {
375
+ (_, []) => {
376
+ revAppend(list, left)
377
+ },
378
+ ([], _) => {
379
+ revAppend(list, right)
380
+ },
381
+ ([lhd, ...ltl], [rhd, ...rtl]) => {
382
+ if (comp(lhd, rhd) < 0) {
383
+ merge(ltl, right, append([lhd], list))
384
+ } else {
385
+ merge(left, rtl, append([rhd], list))
386
+ }
387
+ },
388
+ }
389
+ }
390
+
391
+ let rec mergesort = list => {
392
+ if (length(list) <= 1) {
393
+ list
394
+ } else {
395
+ let middle = length(list) / 2
396
+ let (left, right) = part(middle, list)
397
+ merge(mergesort(left), mergesort(right), [])
398
+ }
399
+ }
400
+
401
+ mergesort(list)
402
+ }