@grain/stdlib 0.5.12 → 0.6.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 (155) hide show
  1. package/CHANGELOG.md +200 -0
  2. package/LICENSE +1 -1
  3. package/README.md +25 -2
  4. package/array.gr +1512 -199
  5. package/array.md +2032 -94
  6. package/bigint.gr +239 -140
  7. package/bigint.md +450 -106
  8. package/buffer.gr +595 -102
  9. package/buffer.md +903 -145
  10. package/bytes.gr +401 -110
  11. package/bytes.md +551 -63
  12. package/char.gr +228 -49
  13. package/char.md +373 -7
  14. package/exception.gr +26 -12
  15. package/exception.md +29 -5
  16. package/float32.gr +130 -109
  17. package/float32.md +185 -57
  18. package/float64.gr +112 -99
  19. package/float64.md +185 -57
  20. package/hash.gr +47 -37
  21. package/hash.md +21 -3
  22. package/int16.gr +430 -0
  23. package/int16.md +618 -0
  24. package/int32.gr +200 -269
  25. package/int32.md +254 -289
  26. package/int64.gr +142 -225
  27. package/int64.md +254 -289
  28. package/int8.gr +511 -0
  29. package/int8.md +786 -0
  30. package/json.gr +2084 -0
  31. package/json.md +608 -0
  32. package/list.gr +120 -68
  33. package/list.md +125 -80
  34. package/map.gr +560 -57
  35. package/map.md +672 -56
  36. package/marshal.gr +239 -227
  37. package/marshal.md +36 -4
  38. package/number.gr +626 -676
  39. package/number.md +738 -153
  40. package/option.gr +33 -35
  41. package/option.md +58 -42
  42. package/package.json +2 -2
  43. package/path.gr +148 -187
  44. package/path.md +47 -96
  45. package/pervasives.gr +75 -416
  46. package/pervasives.md +85 -180
  47. package/priorityqueue.gr +433 -74
  48. package/priorityqueue.md +422 -54
  49. package/queue.gr +362 -80
  50. package/queue.md +433 -38
  51. package/random.gr +67 -75
  52. package/random.md +68 -40
  53. package/range.gr +135 -63
  54. package/range.md +198 -43
  55. package/rational.gr +284 -0
  56. package/rational.md +545 -0
  57. package/regex.gr +933 -1066
  58. package/regex.md +59 -60
  59. package/result.gr +23 -25
  60. package/result.md +54 -39
  61. package/runtime/atof/common.gr +78 -82
  62. package/runtime/atof/common.md +22 -10
  63. package/runtime/atof/decimal.gr +102 -127
  64. package/runtime/atof/decimal.md +28 -7
  65. package/runtime/atof/lemire.gr +56 -71
  66. package/runtime/atof/lemire.md +9 -1
  67. package/runtime/atof/parse.gr +83 -110
  68. package/runtime/atof/parse.md +12 -2
  69. package/runtime/atof/slow.gr +28 -35
  70. package/runtime/atof/slow.md +9 -1
  71. package/runtime/atof/table.gr +19 -18
  72. package/runtime/atof/table.md +10 -2
  73. package/runtime/atoi/parse.gr +153 -136
  74. package/runtime/atoi/parse.md +50 -1
  75. package/runtime/bigint.gr +410 -517
  76. package/runtime/bigint.md +71 -57
  77. package/runtime/compare.gr +176 -85
  78. package/runtime/compare.md +31 -1
  79. package/runtime/dataStructures.gr +144 -32
  80. package/runtime/dataStructures.md +267 -31
  81. package/runtime/debugPrint.gr +34 -15
  82. package/runtime/debugPrint.md +37 -5
  83. package/runtime/equal.gr +53 -52
  84. package/runtime/equal.md +30 -1
  85. package/runtime/exception.gr +38 -47
  86. package/runtime/exception.md +10 -8
  87. package/runtime/gc.gr +23 -152
  88. package/runtime/gc.md +13 -17
  89. package/runtime/malloc.gr +31 -31
  90. package/runtime/malloc.md +11 -3
  91. package/runtime/numberUtils.gr +191 -172
  92. package/runtime/numberUtils.md +17 -9
  93. package/runtime/numbers.gr +1695 -1021
  94. package/runtime/numbers.md +1098 -134
  95. package/runtime/string.gr +540 -242
  96. package/runtime/string.md +76 -6
  97. package/runtime/unsafe/constants.gr +30 -13
  98. package/runtime/unsafe/constants.md +80 -0
  99. package/runtime/unsafe/conv.gr +55 -28
  100. package/runtime/unsafe/conv.md +41 -9
  101. package/runtime/unsafe/memory.gr +10 -30
  102. package/runtime/unsafe/memory.md +15 -19
  103. package/runtime/unsafe/tags.gr +37 -21
  104. package/runtime/unsafe/tags.md +88 -8
  105. package/runtime/unsafe/wasmf32.gr +30 -36
  106. package/runtime/unsafe/wasmf32.md +64 -56
  107. package/runtime/unsafe/wasmf64.gr +30 -36
  108. package/runtime/unsafe/wasmf64.md +64 -56
  109. package/runtime/unsafe/wasmi32.gr +49 -66
  110. package/runtime/unsafe/wasmi32.md +102 -94
  111. package/runtime/unsafe/wasmi64.gr +52 -79
  112. package/runtime/unsafe/wasmi64.md +108 -100
  113. package/runtime/utils/printing.gr +13 -15
  114. package/runtime/utils/printing.md +11 -3
  115. package/runtime/wasi.gr +294 -295
  116. package/runtime/wasi.md +62 -42
  117. package/set.gr +574 -64
  118. package/set.md +634 -54
  119. package/stack.gr +181 -64
  120. package/stack.md +271 -42
  121. package/string.gr +453 -533
  122. package/string.md +241 -151
  123. package/uint16.gr +369 -0
  124. package/uint16.md +585 -0
  125. package/uint32.gr +470 -0
  126. package/uint32.md +737 -0
  127. package/uint64.gr +471 -0
  128. package/uint64.md +737 -0
  129. package/uint8.gr +369 -0
  130. package/uint8.md +585 -0
  131. package/uri.gr +1093 -0
  132. package/uri.md +477 -0
  133. package/{sys → wasi}/file.gr +914 -500
  134. package/{sys → wasi}/file.md +454 -50
  135. package/wasi/process.gr +292 -0
  136. package/{sys → wasi}/process.md +164 -6
  137. package/wasi/random.gr +77 -0
  138. package/wasi/random.md +80 -0
  139. package/{sys → wasi}/time.gr +15 -22
  140. package/{sys → wasi}/time.md +5 -5
  141. package/immutablearray.gr +0 -929
  142. package/immutablearray.md +0 -1038
  143. package/immutablemap.gr +0 -493
  144. package/immutablemap.md +0 -479
  145. package/immutablepriorityqueue.gr +0 -360
  146. package/immutablepriorityqueue.md +0 -291
  147. package/immutableset.gr +0 -498
  148. package/immutableset.md +0 -449
  149. package/runtime/debug.gr +0 -2
  150. package/runtime/debug.md +0 -6
  151. package/runtime/unsafe/errors.gr +0 -36
  152. package/runtime/unsafe/errors.md +0 -204
  153. package/sys/process.gr +0 -254
  154. package/sys/random.gr +0 -79
  155. package/sys/random.md +0 -66
package/char.gr CHANGED
@@ -1,41 +1,36 @@
1
1
  /**
2
- * @module Char: Utilities for working with the Char type.
2
+ * Utilities for working with the Char type.
3
3
  *
4
4
  * The Char type represents a single [Unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value).
5
5
  *
6
- * @example import Char from "char"
6
+ * @example from "char" include Char
7
7
  *
8
- * @since 0.3.0
8
+ * @example 'a'
9
+ * @example '1'
10
+ * @example '🌾'
11
+ *
12
+ * @since v0.3.0
9
13
  */
14
+ module Char
10
15
 
11
- import WasmI32 from "runtime/unsafe/wasmi32"
12
- import Errors from "runtime/unsafe/errors"
13
- import Tags from "runtime/unsafe/tags"
14
- import {
15
- tagSimpleNumber,
16
- tagChar,
17
- untagChar,
18
- allocateString,
19
- } from "runtime/dataStructures"
16
+ from "runtime/unsafe/wasmi32" include WasmI32
17
+ from "runtime/dataStructures" include DataStructures
18
+ use DataStructures.{ tagSimpleNumber, tagChar, untagChar, allocateString }
20
19
 
21
20
  exception MalformedUtf8
22
21
 
23
- /**
24
- * @section Values: Functions and constants included in the Char module.
25
- */
26
-
27
22
  /**
28
23
  * The minimum valid Unicode scalar value.
29
24
  *
30
- * @since 0.3.0
25
+ * @since v0.3.0
31
26
  */
32
- export let min = 0x0000
27
+ provide let min = 0x0000
33
28
  /**
34
29
  * The maximum valid Unicode scalar value.
35
30
  *
36
- * @since 0.3.0
31
+ * @since v0.3.0
37
32
  */
38
- export let max = 0x10FFFF
33
+ provide let max = 0x10FFFF
39
34
 
40
35
  /**
41
36
  * Determines whether the given character code is a valid Unicode scalar value.
@@ -43,9 +38,12 @@ export let max = 0x10FFFF
43
38
  * @param charCode: The number to check
44
39
  * @returns `true` if the number refers to a valid Unicode scalar value or `false` otherwise
45
40
  *
46
- * @since 0.3.0
41
+ * @example Char.isValid(0) == true
42
+ * @example Char.isValid(-1) == false
43
+ *
44
+ * @since v0.3.0
47
45
  */
48
- export let isValid = charCode => {
46
+ provide let isValid = charCode => {
49
47
  charCode >= min &&
50
48
  (charCode <= 0xD7FF || charCode >= 0xE000) &&
51
49
  charCode <= max
@@ -57,10 +55,13 @@ export let isValid = charCode => {
57
55
  * @param char: The character
58
56
  * @returns The Unicode scalar value for the given character
59
57
  *
60
- * @since 0.3.0
58
+ * @example Char.code('a') == 97
59
+ * @example Char.code('🌾') == 127806
60
+ *
61
+ * @since v0.3.0
61
62
  */
62
63
  @unsafe
63
- export let code = (char: Char) => {
64
+ provide let code = (char: Char) => {
64
65
  let usv = untagChar(char)
65
66
 
66
67
  // This could save an instruction by combining the two tagging operations,
@@ -76,12 +77,14 @@ export let code = (char: Char) => {
76
77
  *
77
78
  * @throws InvalidArgument(String): When the Unicode scalar value is invalid
78
79
  *
79
- * @since 0.3.0
80
+ * @example Char.fromCode(97) == 'a'
81
+ * @example Char.fromCode(127806) == '🌾'
82
+ *
83
+ * @since v0.3.0
80
84
  */
81
85
  @unsafe
82
- export let fromCode = (usv: Number) => {
83
- let (-) = WasmI32.sub
84
- let (<<) = WasmI32.shl
86
+ provide let fromCode = (usv: Number) => {
87
+ use WasmI32.{ (-), (<<) }
85
88
 
86
89
  if (!isValid(usv)) {
87
90
  throw InvalidArgument("Invalid character code")
@@ -92,10 +95,10 @@ export let fromCode = (usv: Number) => {
92
95
 
93
96
  // Here we use a math trick to avoid fully untagging and retagging.
94
97
  // Simple numbers are represented as 2n + 1 and chars are represented as
95
- // 8n + 2. Quick reminder that shifting left is the equivalent of multiplying
96
- // by 2, and that _GRAIN_CHAR_TAG_TYPE is equal to 2:
97
- // 4(2n + 1) - 2 = 8n + 2
98
- let char = (usv << 2n) - Tags._GRAIN_CHAR_TAG_TYPE
98
+ // (2^8)n + 2. Quick reminder that shifting left is the equivalent of multiplying
99
+ // by 2
100
+ // 2^7(2n + 1) - (2^7 - 2) = (2^8)n + 2
101
+ let char = (usv << 7n) - 126n
99
102
 
100
103
  WasmI32.toGrain(char): Char
101
104
  }
@@ -108,9 +111,12 @@ export let fromCode = (usv: Number) => {
108
111
  *
109
112
  * @throws Failure(String): When the input character is the maximum valid Unicode scalar value
110
113
  *
111
- * @since 0.3.0
114
+ * @example Char.succ('a') == 'b'
115
+ * @example Char.succ('1') == '2'
116
+ *
117
+ * @since v0.3.0
112
118
  */
113
- export let succ = char => {
119
+ provide let succ = char => {
114
120
  let codePoint = code(char)
115
121
  if (codePoint == max) {
116
122
  fail "no valid Unicode scalar value past U+10FFF"
@@ -129,9 +135,12 @@ export let succ = char => {
129
135
  *
130
136
  * @throws Failure(String): When the input character is the minimum valid Unicode scalar value
131
137
  *
132
- * @since 0.3.0
138
+ * @example Char.pred('b') == 'a'
139
+ * @example Char.pred('2') == '1'
140
+ *
141
+ * @since v0.3.0
133
142
  */
134
- export let pred = char => {
143
+ provide let pred = char => {
135
144
  let codePoint = code(char)
136
145
  if (codePoint == min) {
137
146
  fail "no valid Unicode scalar value below U+0000"
@@ -148,19 +157,24 @@ export let pred = char => {
148
157
  * @param char: The character to convert
149
158
  * @returns A string containing the given character
150
159
  *
151
- * @since 0.3.0
160
+ * @example Char.toString('a') == "a"
161
+ * @example Char.toString('🌾') == "🌾"
162
+ *
163
+ * @since v0.3.0
152
164
  */
153
165
  @unsafe
154
- export let toString = (char: Char) => {
155
- let (+) = WasmI32.add
156
- let (-) = WasmI32.sub
157
- let (*) = WasmI32.mul
158
- let (&) = WasmI32.and
159
- let (|) = WasmI32.or
160
- let (>>>) = WasmI32.shrU
161
- let (<) = WasmI32.ltU
162
- let (>) = WasmI32.gtU
163
- let (<=) = WasmI32.leU
166
+ provide let toString = (char: Char) => {
167
+ use WasmI32.{
168
+ (+),
169
+ (-),
170
+ (*),
171
+ (&),
172
+ (|),
173
+ (>>>),
174
+ ltU as (<),
175
+ gtU as (>),
176
+ leU as (<=),
177
+ }
164
178
 
165
179
  let usv = untagChar(char)
166
180
 
@@ -182,12 +196,12 @@ export let toString = (char: Char) => {
182
196
  offset = 0xF0n
183
197
  }
184
198
  let string = allocateString(count + 1n)
185
- WasmI32.store8(string, (usv >>> 6n * count) + offset, 8n)
199
+ WasmI32.store8(string, (usv >>> (6n * count)) + offset, 8n)
186
200
 
187
201
  let mut n = 0n
188
202
  while (count > 0n) {
189
203
  n += 1n
190
- let temp = usv >>> 6n * (count - 1n)
204
+ let temp = usv >>> (6n * (count - 1n))
191
205
  WasmI32.store8(string + n, 0x80n | temp & 0x3Fn, 8n)
192
206
  count -= 1n
193
207
  }
@@ -197,3 +211,168 @@ export let toString = (char: Char) => {
197
211
 
198
212
  result
199
213
  }
214
+
215
+ /**
216
+ * Checks if the first character is less than the second character by Unicode scalar value.
217
+ *
218
+ * @param x: The first character
219
+ * @param y: The second character
220
+ * @returns `true` if the first character is less than the second character or `false` otherwise
221
+ *
222
+ * @example
223
+ * use Char.{ (<) }
224
+ * assert 'a' < 'b'
225
+ * @example
226
+ * use Char.{ (<) }
227
+ * assert '1' < '2'
228
+ *
229
+ * @since v0.6.0
230
+ */
231
+ @unsafe
232
+ provide let (<) = (x: Char, y: Char) => {
233
+ use WasmI32.{ (<) }
234
+ let x = WasmI32.fromGrain(x)
235
+ let y = WasmI32.fromGrain(y)
236
+ x < y
237
+ }
238
+
239
+ /**
240
+ * Checks if the first character is less than or equal to the second character by Unicode scalar value.
241
+ *
242
+ * @param x: The first character
243
+ * @param y: The second character
244
+ * @returns `true` if the first character is less than or equal to the second character or `false` otherwise
245
+ *
246
+ * @example
247
+ * use Char.{ (<=) }
248
+ * assert 'a' <= 'b'
249
+ * @example
250
+ * use Char.{ (<=) }
251
+ * assert '1' <= '2'
252
+ * @example
253
+ * use Char.{ (<=) }
254
+ * assert 'a' <= 'a'
255
+ *
256
+ * @since v0.6.0
257
+ */
258
+ @unsafe
259
+ provide let (<=) = (x: Char, y: Char) => {
260
+ use WasmI32.{ (<=) }
261
+ let x = WasmI32.fromGrain(x)
262
+ let y = WasmI32.fromGrain(y)
263
+ x <= y
264
+ }
265
+
266
+ /**
267
+ * Checks if the first character is greater than the second character by Unicode scalar value.
268
+ *
269
+ * @param x: The first character
270
+ * @param y: The second character
271
+ * @returns `true` if the first character is greater than the second character or `false` otherwise
272
+ *
273
+ * @example
274
+ * use Char.{ (>) }
275
+ * assert 'b' > 'a'
276
+ * @example
277
+ * use Char.{ (>) }
278
+ * assert '2' > '1'
279
+ *
280
+ * @since v0.6.0
281
+ */
282
+ @unsafe
283
+ provide let (>) = (x: Char, y: Char) => {
284
+ use WasmI32.{ (>) }
285
+ let x = WasmI32.fromGrain(x)
286
+ let y = WasmI32.fromGrain(y)
287
+ x > y
288
+ }
289
+
290
+ /**
291
+ * Checks if the first character is greater than or equal to the second character by Unicode scalar value.
292
+ *
293
+ * @param x: The first character
294
+ * @param y: The second character
295
+ * @returns `true` if the first character is greater than or equal to the second character or `false` otherwise
296
+ *
297
+ * @example
298
+ * use Char.{ (>=) }
299
+ * assert 'b' >= 'a'
300
+ * @example
301
+ * use Char.{ (>=) }
302
+ * assert '2' >= '1'
303
+ * @example
304
+ * use Char.{ (>=) }
305
+ * assert 'a' >= 'a'
306
+ *
307
+ * @since v0.6.0
308
+ */
309
+ @unsafe
310
+ provide let (>=) = (x: Char, y: Char) => {
311
+ use WasmI32.{ (>=) }
312
+ let x = WasmI32.fromGrain(x)
313
+ let y = WasmI32.fromGrain(y)
314
+ x >= y
315
+ }
316
+
317
+ /**
318
+ * Checks if the character is an ASCII digit.
319
+ *
320
+ * @param char: The character to check
321
+ * @returns `true` if the character is an ASCII digit or `false` otherwise
322
+ *
323
+ * @example assert Char.isAsciiDigit('1')
324
+ * @example assert !Char.isAsciiDigit('a')
325
+ *
326
+ * @since v0.6.0
327
+ */
328
+ provide let isAsciiDigit = char => char >= '0' && char <= '9'
329
+
330
+ /**
331
+ * Checks if the character is an ASCII alphabetical character.
332
+ *
333
+ * @param char: The character to check
334
+ * @returns `true` if the character is an ASCII alphabetical or `false` otherwise
335
+ *
336
+ * @example assert Char.isAsciiAlpha('a')
337
+ * @example assert !Char.isAsciiAlpha('1')
338
+ *
339
+ * @since v0.6.0
340
+ */
341
+ provide let isAsciiAlpha = char =>
342
+ char >= 'a' && char <= 'z' || char >= 'A' && char <= 'Z'
343
+
344
+ /**
345
+ * Converts the character to ASCII lowercase if it is an ASCII uppercase character.
346
+ *
347
+ * @param char: The character to convert
348
+ * @returns The lowercased character
349
+ *
350
+ * @example assert Char.toAsciiLowercase('B') == 'b'
351
+ *
352
+ * @since v0.6.0
353
+ */
354
+ provide let toAsciiLowercase = char => {
355
+ if (char >= 'A' && char <= 'Z') {
356
+ fromCode(code(char) + 0x20)
357
+ } else {
358
+ char
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Converts the character to ASCII uppercase if it is an ASCII lowercase character.
364
+ *
365
+ * @param char: The character to convert
366
+ * @returns The uppercased character
367
+ *
368
+ * @example assert Char.toAsciiUppercase('b') == 'B'
369
+ *
370
+ * @since v0.6.0
371
+ */
372
+ provide let toAsciiUppercase = char => {
373
+ if (char >= 'a' && char <= 'z') {
374
+ fromCode(code(char) - 0x20)
375
+ } else {
376
+ char
377
+ }
378
+ }