@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/queue.gr CHANGED
@@ -5,6 +5,10 @@
5
5
  */
6
6
  import List from "list"
7
7
 
8
+ /**
9
+ * @section Types: Type declarations included in the Queue module.
10
+ */
11
+
8
12
  record Queue<a> {
9
13
  forwards: List<a>,
10
14
  backwards: List<a>,
package/queue.md CHANGED
@@ -13,6 +13,16 @@ No other changes yet.
13
13
  import Queue from "queue"
14
14
  ```
15
15
 
16
+ ## Types
17
+
18
+ Type declarations included in the Queue module.
19
+
20
+ ### Queue.**Queue**
21
+
22
+ ```grain
23
+ type Queue<a>
24
+ ```
25
+
16
26
  ## Values
17
27
 
18
28
  Functions for working with queues.
package/random.gr ADDED
@@ -0,0 +1,196 @@
1
+ /**
2
+ * @module Random: Pseudo-random number generation.
3
+ * @example import Random from "random"
4
+ * @since v0.5.0
5
+ */
6
+ import WasiRandom from "sys/random"
7
+ import Result from "result"
8
+ import Int32 from "int32"
9
+ import Int64 from "int64"
10
+ import WasmI32 from "runtime/unsafe/wasmi32"
11
+ import WasmI64 from "runtime/unsafe/wasmi64"
12
+ import Memory from "runtime/unsafe/memory"
13
+ import DS from "runtime/dataStructures"
14
+
15
+ /**
16
+ * @section Types: Type declarations included in the Random module.
17
+ */
18
+
19
+ record Random {
20
+ seed: Int64,
21
+ mut counter: Int64,
22
+ mut initialized: Bool,
23
+ }
24
+
25
+ /**
26
+ * @section Values: Functions for working with pseudo-random number generators.
27
+ */
28
+
29
+ let incCounter = random => {
30
+ random.counter = Int64.incr(random.counter)
31
+ }
32
+
33
+ // https://arxiv.org/pdf/2004.06278v3.pdf
34
+ @unsafe
35
+ let squares = (ctr: Int64, key: Int64) => {
36
+ // Implemented with @unsafe to boost efficiency
37
+ // and have fine-grained control over overflow semantics
38
+ let ctr = WasmI64.load(WasmI32.fromGrain(ctr), 8n)
39
+ let key = WasmI64.load(WasmI32.fromGrain(key), 8n)
40
+ let mut x = WasmI64.mul(ctr, key)
41
+ let mut y = x
42
+ let mut z = WasmI64.add(y, key)
43
+ // round 1
44
+ x = WasmI64.add(WasmI64.mul(x, x), y)
45
+ x = WasmI64.or(WasmI64.shrU(x, 32N), WasmI64.shl(x, 32N))
46
+ // round 2
47
+ x = WasmI64.add(WasmI64.mul(x, x), z)
48
+ x = WasmI64.or(WasmI64.shrU(x, 32N), WasmI64.shl(x, 32N))
49
+ // round 3
50
+ x = WasmI64.add(WasmI64.mul(x, x), y)
51
+ x = WasmI64.or(WasmI64.shrU(x, 32N), WasmI64.shl(x, 32N))
52
+ let ret = WasmI32.wrapI64(
53
+ WasmI64.shrU(WasmI64.add(WasmI64.mul(x, x), z), 32N)
54
+ )
55
+ WasmI32.toGrain(DS.newInt32(ret)): Int32
56
+ }
57
+
58
+ /**
59
+ * Creates a new pseudo-random number generator with the given seed.
60
+ *
61
+ * @param seed: The seed for the pseudo-random number generator
62
+ * @returns The pseudo-random number generator
63
+ *
64
+ * @since v0.5.0
65
+ */
66
+ export let make = seed => {
67
+ { seed, counter: 0L, initialized: false }
68
+ }
69
+
70
+ /**
71
+ * Creates a new pseudo-random number generator with a random seed.
72
+ *
73
+ * @returns `Ok(generator)` of a pseudo-random number generator if successful or `Err(exception)` otherwise
74
+ *
75
+ * @since v0.5.0
76
+ */
77
+ export let makeUnseeded = () => {
78
+ // TODO: Should we just .expect this result for UX's sake?
79
+ Result.map(seed => {
80
+ { seed, counter: 0L, initialized: false }
81
+ }, WasiRandom.randomInt64())
82
+ }
83
+
84
+ /**
85
+ * [Internal note]
86
+ * For low seed numbers, we sometimes need to churn through
87
+ * some iterations to start getting interesting numbers. Taking
88
+ * a cue from the API in https://pypi.org/project/squares-rng/ ,
89
+ * we churn through until we generate an int with a MSB of 1.
90
+ * Then, to avoid making all of the first generated numbers negative,
91
+ * we do another increment at the end.
92
+ */
93
+ let checkInitialized = (random: Random) => {
94
+ if (!random.initialized) {
95
+ while (Int32.gt(Int32.clz(squares(random.counter, random.seed)), 0l)) {
96
+ incCounter(random)
97
+ }
98
+ // now that it's initialized, increment it again to make it a little more random
99
+ incCounter(random)
100
+ random.initialized = true
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Generates a random 32-bit integer from the given pseudo-random number generator.
106
+ *
107
+ * @param random: The pseudo-random number generator to use
108
+ * @returns The randomly generated number
109
+ *
110
+ * @since v0.5.0
111
+ */
112
+ export let nextInt32 = (random: Random) => {
113
+ checkInitialized(random)
114
+ let ret = squares(random.counter, random.seed)
115
+ incCounter(random)
116
+ ret
117
+ }
118
+
119
+ /**
120
+ * Generates a random 64-bit integer from the given pseudo-random number generator.
121
+ *
122
+ * @param random: The pseudo-random number generator to use
123
+ * @returns The randomly generated number
124
+ *
125
+ * @since v0.5.0
126
+ */
127
+ export let nextInt64 = (random: Random) => {
128
+ checkInitialized(random)
129
+ let ret1 = Int64.fromNumber(
130
+ Int32.toNumber(squares(random.counter, random.seed))
131
+ )
132
+ incCounter(random)
133
+ let ret2 = Int64.fromNumber(
134
+ Int32.toNumber(squares(random.counter, random.seed))
135
+ )
136
+ incCounter(random)
137
+ Int64.lor(Int64.shl(ret1, 32L), ret2)
138
+ }
139
+
140
+ /**
141
+ * Generates a random 32-bit integer from the given pseudo-random number generator
142
+ * from a uniform distribution in the given range.
143
+ *
144
+ * @param random: The pseudo-random number generator to use
145
+ * @param low: The lower bound of the range (inclusive)
146
+ * @param high: The upper bound of the range (exclusive)
147
+ * @returns The randomly generated number
148
+ *
149
+ * @since v0.5.0
150
+ */
151
+ export let nextInt32InRange = (random: Random, low: Int32, high: Int32) => {
152
+ // Algorithm source: https://www.pcg-random.org/posts/bounded-rands.html#bitmask-with-rejection-unbiased-apples-method
153
+ let (+) = Int32.add
154
+ let (-) = Int32.sub
155
+ let (*) = Int32.mul
156
+ let (/) = Int32.divU
157
+ let (&) = Int32.land
158
+ let (>) = Int32.gtU
159
+ let range = high - low - 1l
160
+ let mask = Int32.shrU(Int32.lnot(0l), Int32.clz(Int32.lor(range, 1l)))
161
+ let mut x = nextInt32(random) & mask
162
+ let mut iters = 0l
163
+ while (x > range) {
164
+ x = nextInt32(random) & mask
165
+ iters += 1l
166
+ }
167
+ x + low
168
+ }
169
+
170
+ /**
171
+ * Generates a random 64-bit integer from the given pseudo-random number generator
172
+ * from a uniform distribution in the given range.
173
+ *
174
+ * @param random: The pseudo-random number generator to use
175
+ * @param low: The lower bound of the range (inclusive)
176
+ * @param high: The upper bound of the range (exclusive)
177
+ * @returns The randomly generated number
178
+ *
179
+ * @since v0.5.0
180
+ */
181
+ export let nextInt64InRange = (random: Random, low: Int64, high: Int64) => {
182
+ // Algorithm source: https://www.pcg-random.org/posts/bounded-rands.html#bitmask-with-rejection-unbiased-apples-method
183
+ let (+) = Int64.add
184
+ let (-) = Int64.sub
185
+ let (*) = Int64.mul
186
+ let (/) = Int64.divU
187
+ let (&) = Int64.land
188
+ let (>) = Int64.gtU
189
+ let range = high - low - 1L
190
+ let mask = Int64.shrU(Int64.lnot(0L), Int64.clz(Int64.lor(range, 1L)))
191
+ let mut x = nextInt64(random) & mask
192
+ while (x > range) {
193
+ x = nextInt64(random) & mask
194
+ }
195
+ x + low
196
+ }
package/random.md ADDED
@@ -0,0 +1,179 @@
1
+ ---
2
+ title: Random
3
+ ---
4
+
5
+ Pseudo-random number generation.
6
+
7
+ <details disabled>
8
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
9
+ No other changes yet.
10
+ </details>
11
+
12
+ ```grain
13
+ import Random from "random"
14
+ ```
15
+
16
+ ## Types
17
+
18
+ Type declarations included in the Random module.
19
+
20
+ ### Random.**Random**
21
+
22
+ ```grain
23
+ type Random
24
+ ```
25
+
26
+ ## Values
27
+
28
+ Functions for working with pseudo-random number generators.
29
+
30
+ ### Random.**make**
31
+
32
+ <details disabled>
33
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
34
+ No other changes yet.
35
+ </details>
36
+
37
+ ```grain
38
+ make : Int64 -> Random
39
+ ```
40
+
41
+ Creates a new pseudo-random number generator with the given seed.
42
+
43
+ Parameters:
44
+
45
+ |param|type|description|
46
+ |-----|----|-----------|
47
+ |`seed`|`Int64`|The seed for the pseudo-random number generator|
48
+
49
+ Returns:
50
+
51
+ |type|description|
52
+ |----|-----------|
53
+ |`Random`|The pseudo-random number generator|
54
+
55
+ ### Random.**makeUnseeded**
56
+
57
+ <details disabled>
58
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
59
+ No other changes yet.
60
+ </details>
61
+
62
+ ```grain
63
+ makeUnseeded : () -> Result<Random, Exception>
64
+ ```
65
+
66
+ Creates a new pseudo-random number generator with a random seed.
67
+
68
+ Returns:
69
+
70
+ |type|description|
71
+ |----|-----------|
72
+ |`Result<Random, Exception>`|`Ok(generator)` of a pseudo-random number generator if successful or `Err(exception)` otherwise|
73
+
74
+ ### Random.**nextInt32**
75
+
76
+ <details disabled>
77
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
78
+ No other changes yet.
79
+ </details>
80
+
81
+ ```grain
82
+ nextInt32 : Random -> Int32
83
+ ```
84
+
85
+ Generates a random 32-bit integer from the given pseudo-random number generator.
86
+
87
+ Parameters:
88
+
89
+ |param|type|description|
90
+ |-----|----|-----------|
91
+ |`random`|`Random`|The pseudo-random number generator to use|
92
+
93
+ Returns:
94
+
95
+ |type|description|
96
+ |----|-----------|
97
+ |`Int32`|The randomly generated number|
98
+
99
+ ### Random.**nextInt64**
100
+
101
+ <details disabled>
102
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
103
+ No other changes yet.
104
+ </details>
105
+
106
+ ```grain
107
+ nextInt64 : Random -> Int64
108
+ ```
109
+
110
+ Generates a random 64-bit integer from the given pseudo-random number generator.
111
+
112
+ Parameters:
113
+
114
+ |param|type|description|
115
+ |-----|----|-----------|
116
+ |`random`|`Random`|The pseudo-random number generator to use|
117
+
118
+ Returns:
119
+
120
+ |type|description|
121
+ |----|-----------|
122
+ |`Int64`|The randomly generated number|
123
+
124
+ ### Random.**nextInt32InRange**
125
+
126
+ <details disabled>
127
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
128
+ No other changes yet.
129
+ </details>
130
+
131
+ ```grain
132
+ nextInt32InRange : (Random, Int32, Int32) -> Int32
133
+ ```
134
+
135
+ Generates a random 32-bit integer from the given pseudo-random number generator
136
+ from a uniform distribution in the given range.
137
+
138
+ Parameters:
139
+
140
+ |param|type|description|
141
+ |-----|----|-----------|
142
+ |`random`|`Random`|The pseudo-random number generator to use|
143
+ |`low`|`Int32`|The lower bound of the range (inclusive)|
144
+ |`high`|`Int32`|The upper bound of the range (exclusive)|
145
+
146
+ Returns:
147
+
148
+ |type|description|
149
+ |----|-----------|
150
+ |`Int32`|The randomly generated number|
151
+
152
+ ### Random.**nextInt64InRange**
153
+
154
+ <details disabled>
155
+ <summary tabindex="-1">Added in <code>0.5.0</code></summary>
156
+ No other changes yet.
157
+ </details>
158
+
159
+ ```grain
160
+ nextInt64InRange : (Random, Int64, Int64) -> Int64
161
+ ```
162
+
163
+ Generates a random 64-bit integer from the given pseudo-random number generator
164
+ from a uniform distribution in the given range.
165
+
166
+ Parameters:
167
+
168
+ |param|type|description|
169
+ |-----|----|-----------|
170
+ |`random`|`Random`|The pseudo-random number generator to use|
171
+ |`low`|`Int64`|The lower bound of the range (inclusive)|
172
+ |`high`|`Int64`|The upper bound of the range (exclusive)|
173
+
174
+ Returns:
175
+
176
+ |type|description|
177
+ |----|-----------|
178
+ |`Int64`|The randomly generated number|
179
+