@grain/stdlib 0.4.4 → 0.5.0

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 (97) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/LICENSE +1 -1
  3. package/array.gr +92 -73
  4. package/array.md +18 -18
  5. package/bigint.gr +497 -0
  6. package/bigint.md +811 -0
  7. package/buffer.gr +56 -217
  8. package/buffer.md +24 -17
  9. package/bytes.gr +103 -205
  10. package/bytes.md +19 -0
  11. package/char.gr +152 -166
  12. package/char.md +200 -0
  13. package/exception.md +6 -0
  14. package/float32.gr +159 -82
  15. package/float32.md +315 -0
  16. package/float64.gr +163 -82
  17. package/float64.md +315 -0
  18. package/hash.gr +53 -49
  19. package/int32.gr +479 -230
  20. package/int32.md +937 -0
  21. package/int64.gr +479 -230
  22. package/int64.md +937 -0
  23. package/list.gr +530 -116
  24. package/list.md +1141 -0
  25. package/map.gr +302 -121
  26. package/map.md +525 -0
  27. package/number.gr +51 -57
  28. package/number.md +37 -3
  29. package/option.gr +25 -25
  30. package/option.md +1 -1
  31. package/package.json +3 -3
  32. package/pervasives.gr +504 -52
  33. package/pervasives.md +1116 -0
  34. package/queue.gr +8 -1
  35. package/queue.md +10 -0
  36. package/random.gr +196 -0
  37. package/random.md +179 -0
  38. package/range.gr +26 -26
  39. package/regex.gr +1833 -842
  40. package/regex.md +11 -11
  41. package/result.md +1 -1
  42. package/runtime/bigint.gr +2045 -0
  43. package/runtime/bigint.md +326 -0
  44. package/runtime/dataStructures.gr +99 -279
  45. package/runtime/dataStructures.md +391 -0
  46. package/runtime/debug.gr +0 -1
  47. package/runtime/debug.md +6 -0
  48. package/runtime/equal.gr +40 -37
  49. package/runtime/equal.md +6 -0
  50. package/runtime/exception.gr +28 -15
  51. package/runtime/exception.md +30 -0
  52. package/runtime/gc.gr +50 -20
  53. package/runtime/gc.md +36 -0
  54. package/runtime/malloc.gr +32 -22
  55. package/runtime/malloc.md +55 -0
  56. package/runtime/numberUtils.gr +297 -142
  57. package/runtime/numberUtils.md +54 -0
  58. package/runtime/numbers.gr +1204 -453
  59. package/runtime/numbers.md +300 -0
  60. package/runtime/string.gr +193 -228
  61. package/runtime/string.md +24 -0
  62. package/runtime/stringUtils.gr +62 -38
  63. package/runtime/stringUtils.md +6 -0
  64. package/runtime/unsafe/constants.gr +17 -0
  65. package/runtime/unsafe/constants.md +72 -0
  66. package/runtime/unsafe/conv.gr +10 -10
  67. package/runtime/unsafe/conv.md +71 -0
  68. package/runtime/unsafe/errors.md +204 -0
  69. package/runtime/unsafe/memory.gr +14 -3
  70. package/runtime/unsafe/memory.md +54 -0
  71. package/runtime/unsafe/printWasm.gr +4 -4
  72. package/runtime/unsafe/printWasm.md +24 -0
  73. package/runtime/unsafe/tags.gr +11 -10
  74. package/runtime/unsafe/tags.md +120 -0
  75. package/runtime/unsafe/wasmf32.gr +9 -2
  76. package/runtime/unsafe/wasmf32.md +168 -0
  77. package/runtime/unsafe/wasmf64.gr +9 -2
  78. package/runtime/unsafe/wasmf64.md +168 -0
  79. package/runtime/unsafe/wasmi32.gr +65 -47
  80. package/runtime/unsafe/wasmi32.md +282 -0
  81. package/runtime/unsafe/wasmi64.gr +78 -50
  82. package/runtime/unsafe/wasmi64.md +300 -0
  83. package/runtime/utils/printing.gr +62 -0
  84. package/runtime/utils/printing.md +18 -0
  85. package/runtime/wasi.gr +200 -46
  86. package/runtime/wasi.md +839 -0
  87. package/set.gr +125 -121
  88. package/set.md +24 -21
  89. package/stack.gr +29 -29
  90. package/stack.md +4 -6
  91. package/string.gr +434 -415
  92. package/string.md +3 -3
  93. package/sys/file.gr +477 -482
  94. package/sys/process.gr +33 -47
  95. package/sys/random.gr +48 -20
  96. package/sys/random.md +38 -0
  97. package/sys/time.gr +12 -28
package/sys/process.gr CHANGED
@@ -1,4 +1,3 @@
1
- /* grainc-flags --no-gc */
2
1
  /**
3
2
  * @module Sys/Process: Utilities for accessing functionality and information about the Grain program's process.
4
3
  *
@@ -15,11 +14,15 @@ import WasmI32, {
15
14
  and as (&),
16
15
  eq as (==),
17
16
  ne as (!=),
18
- ltS as (<)
17
+ ltS as (<),
19
18
  } from "runtime/unsafe/wasmi32"
20
19
  import Memory from "runtime/unsafe/memory"
21
20
  import Wasi from "runtime/wasi"
22
- import { tagSimpleNumber, allocateArray, allocateString } from "runtime/dataStructures"
21
+ import {
22
+ tagSimpleNumber,
23
+ allocateArray,
24
+ allocateString,
25
+ } from "runtime/dataStructures"
23
26
 
24
27
  /**
25
28
  * @section Types: Type declarations included in the Sys/Process module.
@@ -91,31 +94,20 @@ export enum Signal {
91
94
  * @section Values: Functions and constants included in the Sys/Process module.
92
95
  */
93
96
 
94
- let wasmSafeOk = (val) => {
95
- Memory.incRef(WasmI32.fromGrain(Ok))
96
- Memory.incRef(WasmI32.fromGrain(val))
97
- Ok(val)
98
- }
99
-
100
- let wasmSafeErr = (err) => {
101
- Memory.incRef(WasmI32.fromGrain(Err))
102
- Memory.incRef(WasmI32.fromGrain(err))
103
- Err(err)
104
- }
105
-
106
97
  /**
107
98
  * Access command line arguments.
108
99
  *
109
100
  * @returns `Ok(args)` of an array containing positional string arguments to the process if successful or `Err(exception)` otherwise
110
101
  */
111
- export let rec argv = () => {
102
+ @unsafe
103
+ export let argv = () => {
112
104
  let argcPtr = Memory.malloc(8n)
113
105
  let argvBufSizePtr = argcPtr + 4n
114
106
 
115
107
  let mut err = Wasi.args_sizes_get(argcPtr, argvBufSizePtr)
116
- let ret = if (err != Wasi._ESUCCESS) {
108
+ if (err != Wasi._ESUCCESS) {
117
109
  Memory.free(argcPtr)
118
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
110
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
119
111
  } else {
120
112
  let argc = WasmI32.load(argcPtr, 0n)
121
113
  let argvBufSize = WasmI32.load(argvBufSizePtr, 0n)
@@ -128,7 +120,7 @@ export let rec argv = () => {
128
120
  Memory.free(argcPtr)
129
121
  Memory.free(argvPtr)
130
122
  Memory.free(argvBufPtr)
131
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
123
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
132
124
  } else {
133
125
  let arr = allocateArray(argc)
134
126
 
@@ -150,11 +142,9 @@ export let rec argv = () => {
150
142
  Memory.free(argvPtr)
151
143
  Memory.free(argvBufPtr)
152
144
 
153
- wasmSafeOk(WasmI32.toGrain(arr): Array<String>)
145
+ Ok(WasmI32.toGrain(arr): Array<String>)
154
146
  }
155
147
  }
156
- Memory.decRef(WasmI32.fromGrain(argv))
157
- ret
158
148
  }
159
149
 
160
150
  /**
@@ -162,14 +152,15 @@ export let rec argv = () => {
162
152
  *
163
153
  * @returns `Ok(vars)` of an array containing environment variables supplied to the process if successful or `Err(exception)` otherwise
164
154
  */
165
- export let rec env = () => {
155
+ @unsafe
156
+ export let env = () => {
166
157
  let envcPtr = Memory.malloc(8n)
167
158
  let envvBufSizePtr = envcPtr + 4n
168
159
 
169
160
  let mut err = Wasi.environ_sizes_get(envcPtr, envvBufSizePtr)
170
- let ret = if (err != Wasi._ESUCCESS) {
161
+ if (err != Wasi._ESUCCESS) {
171
162
  Memory.free(envcPtr)
172
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
163
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
173
164
  } else {
174
165
  let envc = WasmI32.load(envcPtr, 0n)
175
166
  let envvBufSize = WasmI32.load(envvBufSizePtr, 0n)
@@ -182,7 +173,7 @@ export let rec env = () => {
182
173
  Memory.free(envcPtr)
183
174
  Memory.free(envvPtr)
184
175
  Memory.free(envvBufPtr)
185
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
176
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
186
177
  } else {
187
178
  let arr = allocateArray(envc)
188
179
 
@@ -204,11 +195,9 @@ export let rec env = () => {
204
195
  Memory.free(envvPtr)
205
196
  Memory.free(envvBufPtr)
206
197
 
207
- wasmSafeOk(WasmI32.toGrain(arr): Array<String>)
198
+ Ok(WasmI32.toGrain(arr): Array<String>)
208
199
  }
209
200
  }
210
- Memory.decRef(WasmI32.fromGrain(env))
211
- ret
212
201
  }
213
202
 
214
203
  /**
@@ -217,19 +206,18 @@ export let rec env = () => {
217
206
  * @param code: The value to exit with. An exit code of 0 is considered normal, with other values having meaning depending on the platform
218
207
  * @returns `Err(exception)` if unsuccessful. Will not actually return a value if successful, as the process has ended
219
208
  */
220
- export let rec exit = (code: Number) => {
209
+ @unsafe
210
+ export let exit = (code: Number) => {
221
211
  let mut code = WasmI32.fromGrain(code)
222
212
 
223
- let ret = if ((code & 1n) == 0n) {
224
- wasmSafeErr(InvalidArgument("Invalid exit code"))
213
+ if ((code & 1n) == 0n) {
214
+ Err(InvalidArgument("Invalid exit code"))
225
215
  } else {
226
216
  code = code >> 1n
227
217
  Wasi.proc_exit(code)
228
218
  // Never actually hit because it exited
229
- wasmSafeOk(void)
219
+ Ok(void)
230
220
  }
231
- Memory.decRef(WasmI32.fromGrain(exit))
232
- ret
233
221
  }
234
222
 
235
223
  /**
@@ -238,17 +226,16 @@ export let rec exit = (code: Number) => {
238
226
  * @param signal: The signal to send
239
227
  * @returns `Ok(void)` if successful or `Err(exception)` otherwise
240
228
  */
241
- export let rec sigRaise = (signalPtr: Signal) => {
229
+ @unsafe
230
+ export let sigRaise = (signalPtr: Signal) => {
242
231
  let signal = WasmI32.fromGrain(signalPtr)
243
232
  let signal = WasmI32.load(signal, 12n) >> 1n
244
233
  let err = Wasi.proc_raise(signal)
245
- let ret = if (err != Wasi._ESUCCESS) {
246
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
234
+ if (err != Wasi._ESUCCESS) {
235
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
247
236
  } else {
248
- wasmSafeOk(void)
237
+ Ok(void)
249
238
  }
250
- Memory.decRef(WasmI32.fromGrain(sigRaise))
251
- ret
252
239
  }
253
240
 
254
241
  /**
@@ -256,13 +243,12 @@ export let rec sigRaise = (signalPtr: Signal) => {
256
243
  *
257
244
  * @returns `Ok(void)` if successful or `Err(exception)` otherwise
258
245
  */
259
- export let rec schedYield = () => {
246
+ @unsafe
247
+ export let schedYield = () => {
260
248
  let err = Wasi.sched_yield()
261
- let ret = if (err != Wasi._ESUCCESS) {
262
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
249
+ if (err != Wasi._ESUCCESS) {
250
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
263
251
  } else {
264
- wasmSafeOk(void)
252
+ Ok(void)
265
253
  }
266
- Memory.decRef(WasmI32.fromGrain(schedYield))
267
- ret
268
254
  }
package/sys/random.gr CHANGED
@@ -1,32 +1,61 @@
1
- /* grainc-flags --no-gc */
2
1
  /**
3
2
  * @module Sys/Random: System access to random values.
4
3
  *
5
4
  * @example import Random from "sys/random"
6
5
  */
7
6
 
8
- import WasmI32, {
9
- eq as (==),
10
- ne as (!=)
11
- } from "runtime/unsafe/wasmi32"
7
+ import WasmI32, { eq as (==), ne as (!=) } from "runtime/unsafe/wasmi32"
8
+ import WasmI64 from "runtime/unsafe/wasmi64"
12
9
  import Memory from "runtime/unsafe/memory"
13
10
  import Wasi from "runtime/wasi"
14
- import { tagSimpleNumber } from "runtime/dataStructures"
11
+ import { tagSimpleNumber, newInt32, newInt64 } from "runtime/dataStructures"
15
12
 
16
13
  /**
17
14
  * @section Values: Functions and constants included in the Sys/Random module.
18
15
  */
19
16
 
20
- let wasmSafeOk = (val) => {
21
- Memory.incRef(WasmI32.fromGrain(Ok))
22
- Memory.incRef(WasmI32.fromGrain(val))
23
- Ok(val)
17
+ /**
18
+ * Produce a random 32-bit integer. This function can be slow, so it's best to seed a generator if lots of random data is needed.
19
+ *
20
+ * @returns `Ok(num)` of a random Int32 if successful or `Err(exception)` otherwise
21
+ *
22
+ * @since v0.5.0
23
+ */
24
+ @unsafe
25
+ export let randomInt32 = () => {
26
+ let buf = Memory.malloc(4n)
27
+
28
+ let err = Wasi.random_get(buf, 4n)
29
+ if (err != Wasi._ESUCCESS) {
30
+ Memory.free(buf)
31
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
32
+ } else {
33
+ let rand = WasmI32.load(buf, 0n)
34
+ Memory.free(buf)
35
+ Ok(WasmI32.toGrain(newInt32(rand)): Int32)
36
+ }
24
37
  }
25
38
 
26
- let wasmSafeErr = (err) => {
27
- Memory.incRef(WasmI32.fromGrain(Err))
28
- Memory.incRef(WasmI32.fromGrain(err))
29
- Err(err)
39
+ /**
40
+ * Produce a random 64-bit integer. This function can be slow, so it's best to seed a generator if lots of random data is needed.
41
+ *
42
+ * @returns `Ok(num)` of a random Int64 if successful or `Err(exception)` otherwise
43
+ *
44
+ * @since v0.5.0
45
+ */
46
+ @unsafe
47
+ export let randomInt64 = () => {
48
+ let buf = Memory.malloc(8n)
49
+
50
+ let err = Wasi.random_get(buf, 8n)
51
+ if (err != Wasi._ESUCCESS) {
52
+ Memory.free(buf)
53
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
54
+ } else {
55
+ let rand = WasmI64.load(buf, 0n)
56
+ Memory.free(buf)
57
+ Ok(WasmI32.toGrain(newInt64(rand)): Int64)
58
+ }
30
59
  }
31
60
 
32
61
  /**
@@ -34,18 +63,17 @@ let wasmSafeErr = (err) => {
34
63
  *
35
64
  * @returns `Ok(num)` of a random number if successful or `Err(exception)` otherwise
36
65
  */
37
- export let rec random = () => {
66
+ @unsafe
67
+ export let random = () => {
38
68
  let buf = Memory.malloc(4n)
39
69
 
40
70
  let err = Wasi.random_get(buf, 4n)
41
- let ret = if (err != Wasi._ESUCCESS) {
71
+ if (err != Wasi._ESUCCESS) {
42
72
  Memory.free(buf)
43
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
73
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
44
74
  } else {
45
75
  let rand = WasmI32.load(buf, 0n)
46
76
  Memory.free(buf)
47
- wasmSafeOk(tagSimpleNumber(rand))
77
+ Ok(tagSimpleNumber(rand))
48
78
  }
49
- Memory.decRef(WasmI32.fromGrain(random))
50
- ret
51
79
  }
package/sys/random.md CHANGED
@@ -12,6 +12,44 @@ import Random from "sys/random"
12
12
 
13
13
  Functions and constants included in the Sys/Random module.
14
14
 
15
+ ### Random.**randomInt32**
16
+
17
+ <details disabled>
18
+ <summary tabindex="-1">Added in <code>next</code></summary>
19
+ No other changes yet.
20
+ </details>
21
+
22
+ ```grain
23
+ randomInt32 : () -> Result<Int32, Exception>
24
+ ```
25
+
26
+ Produce a random 32-bit integer. This function can be slow, so it's best to seed a generator if lots of random data is needed.
27
+
28
+ Returns:
29
+
30
+ |type|description|
31
+ |----|-----------|
32
+ |`Result<Int32, Exception>`|`Ok(num)` of a random Int32 if successful or `Err(exception)` otherwise|
33
+
34
+ ### Random.**randomInt64**
35
+
36
+ <details disabled>
37
+ <summary tabindex="-1">Added in <code>next</code></summary>
38
+ No other changes yet.
39
+ </details>
40
+
41
+ ```grain
42
+ randomInt64 : () -> Result<Int64, Exception>
43
+ ```
44
+
45
+ Produce a random 64-bit integer. This function can be slow, so it's best to seed a generator if lots of random data is needed.
46
+
47
+ Returns:
48
+
49
+ |type|description|
50
+ |----|-----------|
51
+ |`Result<Int64, Exception>`|`Ok(num)` of a random Int64 if successful or `Err(exception)` otherwise|
52
+
15
53
  ### Random.**random**
16
54
 
17
55
  ```grain
package/sys/time.gr CHANGED
@@ -1,4 +1,3 @@
1
- /* grainc-flags --no-gc */
2
1
  /**
3
2
  * @module Sys/Time: Access to system clocks.
4
3
  *
@@ -8,7 +7,7 @@
8
7
  import WasmI32, {
9
8
  add as (+),
10
9
  eq as (==),
11
- ne as (!=)
10
+ ne as (!=),
12
11
  } from "runtime/unsafe/wasmi32"
13
12
  import Memory from "runtime/unsafe/memory"
14
13
  import Wasi from "runtime/wasi"
@@ -19,27 +18,16 @@ import { allocateInt64, tagSimpleNumber } from "runtime/dataStructures"
19
18
  * @section Values: Functions and constants included in the Sys/Time module.
20
19
  */
21
20
 
22
- let wasmSafeOk = (val) => {
23
- Memory.incRef(WasmI32.fromGrain(Ok))
24
- Memory.incRef(WasmI32.fromGrain(val))
25
- Ok(val)
26
- }
27
-
28
- let wasmSafeErr = (err) => {
29
- Memory.incRef(WasmI32.fromGrain(Err))
30
- Memory.incRef(WasmI32.fromGrain(err))
31
- Err(err)
32
- }
33
-
21
+ @unsafe
34
22
  let getClockTime = (clockid, precision) => {
35
23
  let int64Ptr = allocateInt64()
36
24
  let timePtr = int64Ptr + 8n
37
25
  let err = Wasi.clock_time_get(clockid, precision, timePtr)
38
26
  if (err != Wasi._ESUCCESS) {
39
27
  Memory.free(int64Ptr)
40
- wasmSafeErr(Wasi.SystemError(tagSimpleNumber(err)))
28
+ Err(Wasi.SystemError(tagSimpleNumber(err)))
41
29
  } else {
42
- wasmSafeOk(WasmI32.toGrain(int64Ptr): Int64)
30
+ Ok(WasmI32.toGrain(int64Ptr): Int64)
43
31
  }
44
32
  }
45
33
 
@@ -49,10 +37,9 @@ let getClockTime = (clockid, precision) => {
49
37
  *
50
38
  * @returns `Ok(time)` of the current time if successful or `Err(exception)` otherwise
51
39
  */
40
+ @unsafe
52
41
  export let rec realTime = () => {
53
- let ret = getClockTime(Wasi._CLOCK_REALTIME, 1000N)
54
- Memory.decRef(WasmI32.fromGrain(realTime))
55
- ret
42
+ getClockTime(Wasi._CLOCK_REALTIME, 1000N)
56
43
  }
57
44
 
58
45
  /**
@@ -63,10 +50,9 @@ export let rec realTime = () => {
63
50
  *
64
51
  * @returns `Ok(time)` of the current time if successful or `Err(exception)` otherwise
65
52
  */
53
+ @unsafe
66
54
  export let rec monotonicTime = () => {
67
- let ret = getClockTime(Wasi._CLOCK_MONOTONIC, 1N)
68
- Memory.decRef(WasmI32.fromGrain(monotonicTime))
69
- ret
55
+ getClockTime(Wasi._CLOCK_MONOTONIC, 1N)
70
56
  }
71
57
 
72
58
  /**
@@ -74,10 +60,9 @@ export let rec monotonicTime = () => {
74
60
  *
75
61
  * @returns `Ok(elapsed)` of the elapsed nanoseconds if successful or `Err(exception)` otherwise
76
62
  */
63
+ @unsafe
77
64
  export let rec processCpuTime = () => {
78
- let ret = getClockTime(Wasi._CLOCK_PROCESS_CPUTIME, 1N)
79
- Memory.decRef(WasmI32.fromGrain(processCpuTime))
80
- ret
65
+ getClockTime(Wasi._CLOCK_PROCESS_CPUTIME, 1N)
81
66
  }
82
67
 
83
68
  /**
@@ -85,8 +70,7 @@ export let rec processCpuTime = () => {
85
70
  *
86
71
  * @returns `Ok(elapsed)` of the elapsed nanoseconds if successful or `Err(exception)` otherwise
87
72
  */
73
+ @unsafe
88
74
  export let rec threadCpuTime = () => {
89
- let ret = getClockTime(Wasi._CLOCK_THREAD_CPUTIME, 1N)
90
- Memory.decRef(WasmI32.fromGrain(threadCpuTime))
91
- ret
75
+ getClockTime(Wasi._CLOCK_THREAD_CPUTIME, 1N)
92
76
  }