@grain/stdlib 0.4.1 → 0.4.5

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 (57) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/LICENSE +21 -0
  3. package/README.md +34 -0
  4. package/array.gr +200 -89
  5. package/array.md +81 -5
  6. package/buffer.gr +93 -36
  7. package/bytes.gr +512 -407
  8. package/bytes.md +621 -0
  9. package/char.gr +119 -55
  10. package/char.md +200 -0
  11. package/hash.gr +42 -15
  12. package/hash.md +44 -0
  13. package/list.gr +121 -50
  14. package/map.gr +106 -110
  15. package/number.gr +37 -1
  16. package/number.md +66 -0
  17. package/option.gr +260 -53
  18. package/option.md +579 -0
  19. package/package.json +33 -29
  20. package/pervasives.gr +32 -20
  21. package/queue.gr +102 -30
  22. package/queue.md +191 -0
  23. package/range.gr +26 -26
  24. package/range.md +1 -1
  25. package/regex.gr +3055 -0
  26. package/regex.md +449 -0
  27. package/result.gr +216 -70
  28. package/result.md +446 -0
  29. package/runtime/dataStructures.gr +28 -29
  30. package/runtime/debug.gr +0 -1
  31. package/runtime/equal.gr +37 -16
  32. package/runtime/exception.gr +28 -15
  33. package/runtime/gc.gr +33 -20
  34. package/runtime/malloc.gr +19 -11
  35. package/runtime/numberUtils.gr +208 -105
  36. package/runtime/numbers.gr +217 -118
  37. package/runtime/string.gr +150 -59
  38. package/runtime/stringUtils.gr +176 -0
  39. package/runtime/unsafe/conv.gr +51 -8
  40. package/runtime/unsafe/memory.gr +14 -3
  41. package/runtime/unsafe/printWasm.gr +4 -4
  42. package/runtime/unsafe/tags.gr +2 -2
  43. package/runtime/unsafe/wasmf32.gr +9 -2
  44. package/runtime/unsafe/wasmf64.gr +9 -2
  45. package/runtime/unsafe/wasmi32.gr +65 -47
  46. package/runtime/unsafe/wasmi64.gr +78 -50
  47. package/runtime/wasi.gr +199 -45
  48. package/set.gr +281 -119
  49. package/set.md +502 -0
  50. package/stack.gr +26 -26
  51. package/stack.md +143 -0
  52. package/string.gr +697 -329
  53. package/string.md +815 -0
  54. package/sys/file.gr +356 -177
  55. package/sys/process.gr +10 -6
  56. package/sys/random.gr +3 -6
  57. package/sys/time.gr +3 -3
package/pervasives.gr CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  (^),
25
25
  (<<),
26
26
  (>>>),
27
- (>>)
27
+ (>>),
28
28
  } from "runtime/numbers"
29
29
 
30
30
  // Math operations
@@ -53,7 +53,6 @@ export (<<)
53
53
  export (>>>)
54
54
  export (>>)
55
55
 
56
-
57
56
  // Number coercions & conversions
58
57
 
59
58
  // [TODO] (#311) Commented until we nail down semantics
@@ -61,23 +60,23 @@ export (>>)
61
60
  // import foreign wasm convertInexactToExact : Number -> Number as exact from "stdlib-external/runtime"
62
61
 
63
62
  // Boolean operations
64
- primitive (!) : Bool -> Bool = "@not"
65
- primitive (&&) : (Bool, Bool) -> Bool = "@and"
66
- primitive (||) : (Bool, Bool) -> Bool = "@or"
63
+ primitive (!): Bool -> Bool = "@not"
64
+ primitive (&&): (Bool, Bool) -> Bool = "@and"
65
+ primitive (||): (Bool, Bool) -> Bool = "@or"
67
66
 
68
67
  // Box operations
69
- primitive box : a -> Box<a> = "@box"
70
- primitive unbox : Box<a> -> a = "@unbox"
68
+ primitive box: a -> Box<a> = "@box"
69
+ primitive unbox: Box<a> -> a = "@unbox"
71
70
 
72
71
  // Exceptions
73
72
  exception Failure(String)
74
73
  exception InvalidArgument(String)
75
74
 
76
75
  // Other operations
77
- primitive ignore : a -> Void = "@ignore"
78
- primitive assert : Bool -> Void = "@assert"
79
- primitive throw : Exception -> a = "@throw"
80
- let fail : String -> a = msg => throw Failure(msg)
76
+ primitive ignore: a -> Void = "@ignore"
77
+ primitive assert: Bool -> Void = "@assert"
78
+ primitive throw: Exception -> a = "@throw"
79
+ let fail: String -> a = msg => throw Failure(msg)
81
80
 
82
81
  import { toString, print, concat as (++) } from "runtime/string"
83
82
 
@@ -91,28 +90,41 @@ export (++)
91
90
 
92
91
  // Checks the given items for structural equality.
93
92
  export (==)
94
- let (!=) : (a, a) -> Bool = (x, y) => !(x == y)
93
+ let (!=): (a, a) -> Bool = (x, y) => !(x == y)
95
94
  // Checks the given items for physical equality.
96
- primitive (is) : (a, a) -> Bool = "@is"
95
+ primitive (is): (a, a) -> Bool = "@is"
97
96
  // The opposite of is operator
98
- let (isnt) : (a, a) -> Bool = (x, y) => !(x is y)
97
+ let (isnt): (a, a) -> Bool = (x, y) => !(x is y)
99
98
 
100
- export enum List<a> { [], [...](a, List<a>) }
99
+ export enum List<a> {
100
+ [],
101
+ [...](a, List<a>),
102
+ }
101
103
 
102
104
  /**
103
105
  * @deprecated This will be removed in a future release of Grain.
104
106
  */
105
- let cons = (a, b) => [a, ...b] // <- workaround for (grain-lang/grain#802) [TODO] fix #802 and delete
107
+ let cons = (a, b) =>
108
+ [
109
+ a,
110
+ ...b
111
+ ] // <- workaround for (grain-lang/grain#802) [TODO] fix #802 and delete
106
112
  let empty = [] // <- for parity with `cons`, but should be deleted as well
107
113
 
108
114
  // Maybe some data, maybe not!
109
- enum Option<a> { Some(a), None }
115
+ enum Option<a> {
116
+ Some(a),
117
+ None,
118
+ }
110
119
 
111
120
  // Maybe some data, maybe an error!
112
- enum Result<t, e> { Ok(t), Err(e) }
121
+ enum Result<t, e> {
122
+ Ok(t),
123
+ Err(e),
124
+ }
113
125
 
114
126
  // Identity function
115
- let identity = (x) => x
127
+ let identity = x => x
116
128
 
117
129
  // Setup exception printing
118
130
  @disableGC
@@ -121,7 +133,7 @@ let rec setupExceptions = () => {
121
133
  match (e) {
122
134
  Failure(msg) => Some("Failure: " ++ msg),
123
135
  InvalidArgument(msg) => Some("Invalid argument: " ++ msg),
124
- _ => None
136
+ _ => None,
125
137
  }
126
138
  })
127
139
 
package/queue.gr CHANGED
@@ -1,46 +1,118 @@
1
+ /**
2
+ * @module Queue: An immutable queue implementation. A queue is a FIFO (first-in-first-out) data structure where new values are added to the end and retrieved or removed from the beginning.
3
+ * @example import Queue from "queue"
4
+ * @since v0.2.0
5
+ */
1
6
  import List from "list"
2
7
 
3
- record Queue<a> { forwards: List<a>, backwards: List<a> }
8
+ record Queue<a> {
9
+ forwards: List<a>,
10
+ backwards: List<a>,
11
+ }
12
+
13
+ /**
14
+ * @section Values: Functions for working with queues.
15
+ */
4
16
 
17
+ /**
18
+ * Creates an empty queue.
19
+ *
20
+ * @returns An empty queue
21
+ * @since v0.2.0
22
+ */
5
23
  export let make = () => {
6
- { forwards: [], backwards: [] }
24
+ { forwards: [], backwards: [] }
7
25
  }
8
26
 
9
- export let isEmpty = (queue) => {
10
- match (queue) {
11
- { forwards: [], backwards: [] } => true,
12
- _ => false
13
- }
27
+ /**
28
+ * Checks if the given queue contains any values.
29
+ *
30
+ * @param queue: The queue to check
31
+ * @returns `true` if the given queue is empty or `false` otherwise
32
+ *
33
+ * @since v0.2.0
34
+ */
35
+ export let isEmpty = queue => {
36
+ match (queue) {
37
+ { forwards: [], backwards: [] } => true,
38
+ _ => false,
39
+ }
14
40
  }
15
41
 
16
- export let peek = (queue) => {
17
- match (queue) {
18
- { forwards: [], backwards: [] } => None,
19
- { forwards, backwards } => List.head(forwards)
20
- }
42
+ /**
43
+ * Returns the value at the beginning of the queue. It is not removed from the queue.
44
+ *
45
+ * @param queue: The queue to inspect
46
+ * @returns `Some(value)` containing the value at the beginning of the queue, or `None` if the queue is empty
47
+ *
48
+ * @since v0.3.2
49
+ * @history v0.2.0: Originally named `head`
50
+ * @history v0.3.2: Deprecated `head` function
51
+ * @history v0.4.0: Removed `head` function
52
+ */
53
+ export let peek = queue => {
54
+ match (queue) {
55
+ { forwards: [], backwards: [] } => None,
56
+ { forwards, backwards } => List.head(forwards),
57
+ }
21
58
  }
22
59
 
60
+ /**
61
+ * Adds a value to the end of the queue.
62
+ *
63
+ * @param value: The value to append
64
+ * @param queue: The queue to update
65
+ * @returns An updated queue
66
+ *
67
+ * @since v0.3.2
68
+ * @history v0.2.0: Originally named `enqueue`
69
+ * @history v0.3.2: Deprecated `enqueue` function
70
+ * @history v0.4.0: Removed `enqueue` function
71
+ */
23
72
  export let push = (value, queue) => {
24
- match (queue) {
25
- { forwards: [], backwards: [] } => { forwards: [value], backwards: [] },
26
- { forwards, backwards } => { forwards, backwards: [value, ...backwards] }
27
- }
73
+ match (queue) {
74
+ { forwards: [], backwards: [] } => { forwards: [value], backwards: [] },
75
+ { forwards, backwards } => { forwards, backwards: [value, ...backwards] },
76
+ }
28
77
  }
29
78
 
30
- export let pop = (queue) => {
31
- match (queue) {
32
- { forwards: [], backwards: [] } => queue,
33
- { forwards: [head], backwards: [] } => { forwards: [], backwards: [] },
34
- { forwards: [head], backwards } => { forwards: List.reverse(backwards), backwards: [] },
35
- { forwards: [head, ...ftail], backwards } => { forwards: ftail, backwards }
36
- }
79
+ /**
80
+ * Dequeues the next value in the queue.
81
+ *
82
+ * @param queue: The queue to change
83
+ * @returns An updated queue
84
+ *
85
+ * @since v0.3.2
86
+ * @history v0.2.0: Originally named `dequeue`
87
+ * @history v0.3.2: Deprecated `dequeue` function
88
+ * @history v0.4.0: Removed `dequeue` function
89
+ */
90
+ export let pop = queue => {
91
+ match (queue) {
92
+ { forwards: [], backwards: [] } => queue,
93
+ { forwards: [head], backwards: [] } => { forwards: [], backwards: [] },
94
+ { forwards: [head], backwards } =>
95
+ {
96
+ forwards: List.reverse(backwards),
97
+ backwards: [],
98
+ },
99
+ { forwards: [head, ...ftail], backwards } => { forwards: ftail, backwards },
100
+ }
37
101
  }
38
102
 
39
- export let size = (queue) => {
40
- match (queue) {
41
- { forwards: [], backwards: [] } => 0,
42
- { forwards, backwards: [] } => List.length(forwards),
43
- { forwards: [], backwards } => List.length(backwards),
44
- { forwards, backwards } => List.length(forwards) + List.length(backwards),
45
- }
103
+ /**
104
+ * Get the number of values in a queue.
105
+ *
106
+ * @param queue: The queue to inspect
107
+ * @returns The number of values in the queue
108
+ *
109
+ * @since v0.3.2
110
+ */
111
+ export let size = queue => {
112
+ match (queue) {
113
+ { forwards: [], backwards: [] } => 0,
114
+ { forwards, backwards: [] } => List.length(forwards),
115
+ { forwards: [], backwards } => List.length(backwards),
116
+ { forwards, backwards } => List.length(forwards) + List.length(backwards),
117
+ }
46
118
  }
package/queue.md ADDED
@@ -0,0 +1,191 @@
1
+ ---
2
+ title: Queue
3
+ ---
4
+
5
+ An immutable queue implementation. A queue is a FIFO (first-in-first-out) data structure where new values are added to the end and retrieved or removed from the beginning.
6
+
7
+ <details disabled>
8
+ <summary tabindex="-1">Added in <code>0.2.0</code></summary>
9
+ No other changes yet.
10
+ </details>
11
+
12
+ ```grain
13
+ import Queue from "queue"
14
+ ```
15
+
16
+ ## Values
17
+
18
+ Functions for working with queues.
19
+
20
+ ### Queue.**make**
21
+
22
+ <details disabled>
23
+ <summary tabindex="-1">Added in <code>0.2.0</code></summary>
24
+ No other changes yet.
25
+ </details>
26
+
27
+ ```grain
28
+ make : () -> Queue<a>
29
+ ```
30
+
31
+ Creates an empty queue.
32
+
33
+ Returns:
34
+
35
+ |type|description|
36
+ |----|-----------|
37
+ |`Queue<a>`|An empty queue|
38
+
39
+ ### Queue.**isEmpty**
40
+
41
+ <details disabled>
42
+ <summary tabindex="-1">Added in <code>0.2.0</code></summary>
43
+ No other changes yet.
44
+ </details>
45
+
46
+ ```grain
47
+ isEmpty : Queue<a> -> Bool
48
+ ```
49
+
50
+ Checks if the given queue contains any values.
51
+
52
+ Parameters:
53
+
54
+ |param|type|description|
55
+ |-----|----|-----------|
56
+ |`queue`|`Queue<a>`|The queue to check|
57
+
58
+ Returns:
59
+
60
+ |type|description|
61
+ |----|-----------|
62
+ |`Bool`|`true` if the given queue is empty or `false` otherwise|
63
+
64
+ ### Queue.**peek**
65
+
66
+ <details>
67
+ <summary>Added in <code>0.3.2</code></summary>
68
+ <table>
69
+ <thead>
70
+ <tr><th>version</th><th>changes</th></tr>
71
+ </thead>
72
+ <tbody>
73
+ <tr><td><code>0.2.0</code></td><td>Originally named `head`</td></tr>
74
+ <tr><td><code>0.3.2</code></td><td>Deprecated `head` function</td></tr>
75
+ <tr><td><code>0.4.0</code></td><td>Removed `head` function</td></tr>
76
+ </tbody>
77
+ </table>
78
+ </details>
79
+
80
+ ```grain
81
+ peek : Queue<a> -> Option<a>
82
+ ```
83
+
84
+ Returns the value at the beginning of the queue. It is not removed from the queue.
85
+
86
+ Parameters:
87
+
88
+ |param|type|description|
89
+ |-----|----|-----------|
90
+ |`queue`|`Queue<a>`|The queue to inspect|
91
+
92
+ Returns:
93
+
94
+ |type|description|
95
+ |----|-----------|
96
+ |`Option<a>`|`Some(value)` containing the value at the beginning of the queue, or `None` if the queue is empty|
97
+
98
+ ### Queue.**push**
99
+
100
+ <details>
101
+ <summary>Added in <code>0.3.2</code></summary>
102
+ <table>
103
+ <thead>
104
+ <tr><th>version</th><th>changes</th></tr>
105
+ </thead>
106
+ <tbody>
107
+ <tr><td><code>0.2.0</code></td><td>Originally named `enqueue`</td></tr>
108
+ <tr><td><code>0.3.2</code></td><td>Deprecated `enqueue` function</td></tr>
109
+ <tr><td><code>0.4.0</code></td><td>Removed `enqueue` function</td></tr>
110
+ </tbody>
111
+ </table>
112
+ </details>
113
+
114
+ ```grain
115
+ push : (a, Queue<a>) -> Queue<a>
116
+ ```
117
+
118
+ Adds a value to the end of the queue.
119
+
120
+ Parameters:
121
+
122
+ |param|type|description|
123
+ |-----|----|-----------|
124
+ |`value`|`a`|The value to append|
125
+ |`queue`|`Queue<a>`|The queue to update|
126
+
127
+ Returns:
128
+
129
+ |type|description|
130
+ |----|-----------|
131
+ |`Queue<a>`|An updated queue|
132
+
133
+ ### Queue.**pop**
134
+
135
+ <details>
136
+ <summary>Added in <code>0.3.2</code></summary>
137
+ <table>
138
+ <thead>
139
+ <tr><th>version</th><th>changes</th></tr>
140
+ </thead>
141
+ <tbody>
142
+ <tr><td><code>0.2.0</code></td><td>Originally named `dequeue`</td></tr>
143
+ <tr><td><code>0.3.2</code></td><td>Deprecated `dequeue` function</td></tr>
144
+ <tr><td><code>0.4.0</code></td><td>Removed `dequeue` function</td></tr>
145
+ </tbody>
146
+ </table>
147
+ </details>
148
+
149
+ ```grain
150
+ pop : Queue<a> -> Queue<a>
151
+ ```
152
+
153
+ Dequeues the next value in the queue.
154
+
155
+ Parameters:
156
+
157
+ |param|type|description|
158
+ |-----|----|-----------|
159
+ |`queue`|`Queue<a>`|The queue to change|
160
+
161
+ Returns:
162
+
163
+ |type|description|
164
+ |----|-----------|
165
+ |`Queue<a>`|An updated queue|
166
+
167
+ ### Queue.**size**
168
+
169
+ <details disabled>
170
+ <summary tabindex="-1">Added in <code>0.3.2</code></summary>
171
+ No other changes yet.
172
+ </details>
173
+
174
+ ```grain
175
+ size : Queue<a> -> Number
176
+ ```
177
+
178
+ Get the number of values in a queue.
179
+
180
+ Parameters:
181
+
182
+ |param|type|description|
183
+ |-----|----|-----------|
184
+ |`queue`|`Queue<a>`|The queue to inspect|
185
+
186
+ Returns:
187
+
188
+ |type|description|
189
+ |----|-----------|
190
+ |`Number`|The number of values in the queue|
191
+
package/range.gr CHANGED
@@ -38,7 +38,7 @@ export let inRange = (value, range) => {
38
38
  Inclusive(upper, lower) when value >= lower && value <= upper => true,
39
39
  Exclusive(lower, upper) when value >= lower && value < upper => true,
40
40
  Exclusive(upper, lower) when value >= lower && value < upper => true,
41
- _ => false
41
+ _ => false,
42
42
  }
43
43
  }
44
44
 
@@ -52,34 +52,34 @@ export let inRange = (value, range) => {
52
52
  *
53
53
  * @since v0.3.0
54
54
  */
55
- export let forEach = (fn: (Number) -> Void, range) => {
55
+ export let forEach = (fn: Number -> Void, range) => {
56
56
  match (range) {
57
57
  Inclusive(lower, upper) when lower <= upper => {
58
- let mut idx = lower;
58
+ let mut idx = lower
59
59
  while (idx <= upper) {
60
- fn(idx);
61
- idx += 1;
60
+ fn(idx)
61
+ idx += 1
62
62
  }
63
63
  },
64
64
  Inclusive(upper, lower) => {
65
- let mut idx = upper;
65
+ let mut idx = upper
66
66
  while (idx >= lower) {
67
- fn(idx);
68
- idx -= 1;
67
+ fn(idx)
68
+ idx -= 1
69
69
  }
70
70
  },
71
71
  Exclusive(lower, upper) when lower <= upper => {
72
- let mut idx = lower;
72
+ let mut idx = lower
73
73
  while (idx < upper) {
74
- fn(idx);
75
- idx += 1;
74
+ fn(idx)
75
+ idx += 1
76
76
  }
77
77
  },
78
78
  Exclusive(upper, lower) => {
79
- let mut idx = upper;
79
+ let mut idx = upper
80
80
  while (idx > lower) {
81
- fn(idx);
82
- idx -= 1;
81
+ fn(idx)
82
+ idx -= 1
83
83
  }
84
84
  },
85
85
  }
@@ -100,31 +100,31 @@ export let map = (fn, range) => {
100
100
  let mut result = []
101
101
  match (range) {
102
102
  Inclusive(lower, upper) when lower <= upper => {
103
- let mut idx = upper;
103
+ let mut idx = upper
104
104
  while (idx >= lower) {
105
- result = [fn(idx), ...result];
106
- idx -= 1;
105
+ result = [fn(idx), ...result]
106
+ idx -= 1
107
107
  }
108
108
  },
109
109
  Inclusive(upper, lower) => {
110
- let mut idx = lower;
110
+ let mut idx = lower
111
111
  while (idx <= upper) {
112
- result = [fn(idx), ...result];
113
- idx += 1;
112
+ result = [fn(idx), ...result]
113
+ idx += 1
114
114
  }
115
115
  },
116
116
  Exclusive(lower, upper) when lower <= upper => {
117
- let mut idx = upper - 1;
117
+ let mut idx = upper - 1
118
118
  while (idx >= lower) {
119
- result = [fn(idx), ...result];
120
- idx -= 1;
119
+ result = [fn(idx), ...result]
120
+ idx -= 1
121
121
  }
122
122
  },
123
123
  Exclusive(upper, lower) => {
124
- let mut idx = lower + 1;
124
+ let mut idx = lower + 1
125
125
  while (idx <= upper) {
126
- result = [fn(idx), ...result];
127
- idx += 1;
126
+ result = [fn(idx), ...result]
127
+ idx += 1
128
128
  }
129
129
  },
130
130
  }
package/range.md CHANGED
@@ -102,7 +102,7 @@ No other changes yet.
102
102
  </details>
103
103
 
104
104
  ```grain
105
- map : ((Number -> a), Range) -> List<b>
105
+ map : ((Number -> a), Range) -> List<a>
106
106
  ```
107
107
 
108
108
  Produces a list by calling the given function on each number included in the range. For increasing ranges, the value is increased by `1` in each iteration, and for decreasing ranges, the value is decreased by `1`. The value is always changed by `1`, even if non-integer values were provided in the range.