@grain/stdlib 0.6.6 → 0.7.1

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 (137) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/LICENSE +1 -1
  3. package/README.md +2 -2
  4. package/array.gr +55 -7
  5. package/array.md +606 -560
  6. package/bigint.md +228 -228
  7. package/buffer.gr +85 -53
  8. package/buffer.md +442 -319
  9. package/bytes.gr +112 -35
  10. package/bytes.md +299 -219
  11. package/char.gr +201 -99
  12. package/char.md +447 -120
  13. package/exception.gr +11 -11
  14. package/exception.md +29 -4
  15. package/float32.gr +327 -3
  16. package/float32.md +698 -111
  17. package/float64.gr +320 -3
  18. package/float64.md +698 -111
  19. package/fs.gr +1082 -0
  20. package/fs.md +630 -0
  21. package/hash.gr +142 -88
  22. package/hash.md +105 -17
  23. package/int16.md +178 -178
  24. package/int32.gr +26 -5
  25. package/int32.md +266 -231
  26. package/int64.gr +27 -2
  27. package/int64.md +266 -231
  28. package/int8.md +178 -178
  29. package/json.gr +366 -51
  30. package/json.md +431 -15
  31. package/list.gr +328 -31
  32. package/list.md +759 -336
  33. package/map.gr +20 -12
  34. package/map.md +266 -260
  35. package/marshal.gr +41 -40
  36. package/marshal.md +14 -14
  37. package/number.gr +278 -35
  38. package/number.md +688 -269
  39. package/option.md +162 -162
  40. package/package.json +5 -3
  41. package/path.gr +48 -0
  42. package/path.md +180 -89
  43. package/pervasives.gr +2 -2
  44. package/pervasives.md +275 -275
  45. package/priorityqueue.gr +7 -7
  46. package/priorityqueue.md +131 -131
  47. package/queue.gr +183 -29
  48. package/queue.md +404 -148
  49. package/random.md +43 -43
  50. package/range.gr +4 -4
  51. package/range.md +42 -42
  52. package/rational.md +123 -123
  53. package/regex.gr +52 -51
  54. package/regex.md +102 -102
  55. package/result.md +118 -118
  56. package/runtime/atof/common.md +39 -39
  57. package/runtime/atof/decimal.gr +6 -6
  58. package/runtime/atof/decimal.md +14 -14
  59. package/runtime/atof/lemire.gr +5 -5
  60. package/runtime/atof/lemire.md +1 -1
  61. package/runtime/atof/parse.gr +16 -16
  62. package/runtime/atof/parse.md +2 -2
  63. package/runtime/atof/slow.md +1 -1
  64. package/runtime/atof/table.md +2 -2
  65. package/runtime/atoi/parse.gr +3 -3
  66. package/runtime/atoi/parse.md +1 -1
  67. package/runtime/bigint.gr +15 -47
  68. package/runtime/bigint.md +54 -60
  69. package/runtime/compare.gr +2 -2
  70. package/runtime/compare.md +8 -8
  71. package/runtime/dataStructures.md +211 -211
  72. package/runtime/debugPrint.gr +4 -1
  73. package/runtime/debugPrint.md +9 -9
  74. package/runtime/equal.gr +99 -77
  75. package/runtime/equal.md +8 -8
  76. package/runtime/exception.gr +62 -82
  77. package/runtime/exception.md +62 -11
  78. package/runtime/gc.gr +39 -45
  79. package/runtime/gc.md +4 -4
  80. package/runtime/malloc.gr +7 -7
  81. package/runtime/malloc.md +13 -13
  82. package/runtime/math/kernel/cos.gr +70 -0
  83. package/runtime/math/kernel/cos.md +14 -0
  84. package/runtime/math/kernel/sin.gr +65 -0
  85. package/runtime/math/kernel/sin.md +14 -0
  86. package/runtime/math/kernel/tan.gr +136 -0
  87. package/runtime/math/kernel/tan.md +14 -0
  88. package/runtime/math/rempio2.gr +244 -0
  89. package/runtime/math/rempio2.md +14 -0
  90. package/runtime/math/trig.gr +130 -0
  91. package/runtime/math/trig.md +28 -0
  92. package/runtime/math/umuldi.gr +26 -0
  93. package/runtime/math/umuldi.md +14 -0
  94. package/runtime/numberUtils.gr +29 -29
  95. package/runtime/numberUtils.md +12 -12
  96. package/runtime/numbers.gr +373 -381
  97. package/runtime/numbers.md +348 -342
  98. package/runtime/string.gr +37 -105
  99. package/runtime/string.md +20 -26
  100. package/runtime/unsafe/constants.md +24 -24
  101. package/runtime/unsafe/conv.md +19 -19
  102. package/runtime/unsafe/memory.gr +24 -20
  103. package/runtime/unsafe/memory.md +27 -7
  104. package/runtime/unsafe/offsets.gr +36 -0
  105. package/runtime/unsafe/offsets.md +88 -0
  106. package/runtime/unsafe/panic.gr +28 -0
  107. package/runtime/unsafe/panic.md +14 -0
  108. package/runtime/unsafe/tags.md +32 -32
  109. package/runtime/unsafe/wasmf32.md +28 -28
  110. package/runtime/unsafe/wasmf64.md +28 -28
  111. package/runtime/unsafe/wasmi32.md +47 -47
  112. package/runtime/unsafe/wasmi64.md +50 -50
  113. package/runtime/utf8.gr +189 -0
  114. package/runtime/utf8.md +117 -0
  115. package/runtime/wasi.gr +4 -2
  116. package/runtime/wasi.md +147 -147
  117. package/set.gr +18 -11
  118. package/set.md +253 -247
  119. package/stack.gr +171 -2
  120. package/stack.md +371 -89
  121. package/string.gr +352 -557
  122. package/string.md +298 -255
  123. package/uint16.md +170 -170
  124. package/uint32.gr +25 -4
  125. package/uint32.md +249 -214
  126. package/uint64.gr +25 -5
  127. package/uint64.md +249 -214
  128. package/uint8.md +170 -170
  129. package/uri.gr +57 -53
  130. package/uri.md +88 -89
  131. package/wasi/file.gr +67 -59
  132. package/wasi/file.md +308 -308
  133. package/wasi/process.md +26 -26
  134. package/wasi/random.md +12 -12
  135. package/wasi/time.md +16 -16
  136. package/runtime/utils/printing.gr +0 -60
  137. package/runtime/utils/printing.md +0 -26
package/char.gr CHANGED
@@ -16,8 +16,8 @@ module Char
16
16
  from "runtime/unsafe/wasmi32" include WasmI32
17
17
  from "runtime/dataStructures" include DataStructures
18
18
  use DataStructures.{ tagSimpleNumber, tagChar, untagChar, allocateString }
19
-
20
- exception MalformedUtf8
19
+ from "runtime/utf8" include Utf8
20
+ use Utf8.{ usvEncodeLength, writeUtf8CodePoint }
21
21
 
22
22
  /**
23
23
  * The minimum valid Unicode scalar value.
@@ -44,9 +44,9 @@ provide let max = 0x10FFFF
44
44
  * @since v0.3.0
45
45
  */
46
46
  provide let isValid = charCode => {
47
- charCode >= min &&
48
- (charCode <= 0xD7FF || charCode >= 0xE000) &&
49
- charCode <= max
47
+ charCode >= min
48
+ && (charCode <= 0xD7FF || charCode >= 0xE000)
49
+ && charCode <= max
50
50
  }
51
51
 
52
52
  /**
@@ -164,52 +164,48 @@ provide let pred = char => {
164
164
  */
165
165
  @unsafe
166
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
- }
178
-
167
+ use WasmI32.{ (+) }
179
168
  let usv = untagChar(char)
169
+ let byteCount = usvEncodeLength(usv)
170
+ let string = allocateString(byteCount)
171
+ writeUtf8CodePoint(string + 8n, usv)
172
+ WasmI32.toGrain(string): String
173
+ }
180
174
 
181
- let result = if (usv < 0x80n) {
182
- let string = allocateString(1n)
183
- WasmI32.store8(string, usv, 8n)
184
- WasmI32.toGrain(string): String
185
- } else {
186
- let mut count = 0n
187
- let mut offset = 0n
188
- if (usv <= 0x07FFn) {
189
- count = 1n
190
- offset = 0xC0n
191
- } else if (usv <= 0xFFFFn) {
192
- count = 2n
193
- offset = 0xE0n
194
- } else {
195
- count = 3n
196
- offset = 0xF0n
197
- }
198
- let string = allocateString(count + 1n)
199
- WasmI32.store8(string, (usv >>> (6n * count)) + offset, 8n)
200
-
201
- let mut n = 0n
202
- while (count > 0n) {
203
- n += 1n
204
- let temp = usv >>> (6n * (count - 1n))
205
- WasmI32.store8(string + n, 0x80n | temp & 0x3Fn, 8n)
206
- count -= 1n
207
- }
175
+ /**
176
+ * Byte encodings
177
+ *
178
+ * @since v0.7.0
179
+ */
180
+ provide enum Encoding {
181
+ UTF8,
182
+ UTF16,
183
+ UTF32,
184
+ }
208
185
 
209
- WasmI32.toGrain(string): String
186
+ /**
187
+ * Returns the byte count of a character if encoded in the given encoding.
188
+ *
189
+ * @param encoding: The encoding to check
190
+ * @param char: The character
191
+ * @returns The byte count of the character in the given encoding
192
+ *
193
+ * @example Char.encodedLength(Char.UTF8, 'a') == 1
194
+ * @example Char.encodedLength(Char.UTF8, '🌾') == 4
195
+ * @example Char.encodedLength(Char.UTF16, '©') == 1
196
+ *
197
+ * @since v0.7.0
198
+ */
199
+ @unsafe
200
+ provide let encodedLength = (encoding, char: Char) => {
201
+ let usv = untagChar(char)
202
+ let utf8ByteCount = usvEncodeLength(usv)
203
+ let utf8ByteCount = tagSimpleNumber(utf8ByteCount)
204
+ match (encoding) {
205
+ UTF32 => 4,
206
+ UTF16 => if (utf8ByteCount == 4) 2 else 1,
207
+ UTF8 => utf8ByteCount,
210
208
  }
211
-
212
- result
213
209
  }
214
210
 
215
211
  /**
@@ -315,64 +311,170 @@ provide let (>=) = (x: Char, y: Char) => {
315
311
  }
316
312
 
317
313
  /**
318
- * Checks if the character is an ASCII digit.
314
+ * Utilities for working with ASCII characters.
319
315
  *
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')
316
+ * @example Char.Ascii.isAscii('1')
325
317
  *
326
- * @since v0.6.0
318
+ * @since v0.7.0
327
319
  */
328
- provide let isAsciiDigit = char => char >= '0' && char <= '9'
320
+ provide module Ascii {
321
+ /**
322
+ * The minimum valid ASCII character code.
323
+ *
324
+ * @since v0.7.0
325
+ */
326
+ provide let min = 0x00
329
327
 
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'
328
+ /**
329
+ * The maximum valid ASCII character code.
330
+ *
331
+ * @since v0.7.0
332
+ */
333
+ provide let max = 0x7F
343
334
 
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
335
+ /**
336
+ * Checks if the character is a valid ASCII character.
337
+ *
338
+ * @param char: The character to check
339
+ * @returns `true` if the character is an ASCII character or `false` otherwise
340
+ *
341
+ * @example assert Char.Ascii.isValid('1')
342
+ * @example assert Char.Ascii.isValid('a')
343
+ * @example assert !Char.Ascii.isValid('🌾')
344
+ *
345
+ * @since v0.7.0
346
+ */
347
+ provide let isValid = char => char <= '\u{007F}'
348
+
349
+ /**
350
+ * Checks if the character is an ASCII digit.
351
+ *
352
+ * @param char: The character to check
353
+ * @returns `true` if the character is an ASCII digit or `false` otherwise
354
+ *
355
+ * @example assert Char.Ascii.isDigit('1')
356
+ * @example assert !Char.Ascii.isDigit('a')
357
+ *
358
+ * @since v0.7.0
359
+ * @history v0.6.0: Originally `Char.isAsciiDigit`
360
+ */
361
+ provide let isDigit = char => char >= '0' && char <= '9'
362
+
363
+ /**
364
+ * Checks if the character is an ASCII alphabetical character.
365
+ *
366
+ * @param char: The character to check
367
+ * @returns `true` if the character is an ASCII alphabetical or `false` otherwise
368
+ *
369
+ * @example assert Char.Ascii.isAlpha('a')
370
+ * @example assert !Char.Ascii.isAlpha('1')
371
+ *
372
+ * @since v0.7.0
373
+ * @history v0.6.0: Originally `Char.isAsciiAlpha`
374
+ */
375
+ provide let isAlpha = char =>
376
+ char >= 'a' && char <= 'z' || char >= 'A' && char <= 'Z'
377
+
378
+ /**
379
+ * Checks if the character is an ASCII control character.
380
+ *
381
+ * @param char: The character to check
382
+ * @returns `true` if the character is an ASCII control character or `false` otherwise
383
+ *
384
+ * @example assert Char.Ascii.isControl('\t')
385
+ * @example assert Char.Ascii.isControl('\n')
386
+ * @example assert !Char.Ascii.isControl('1')
387
+ * @example assert !Char.Ascii.isControl('a')
388
+ *
389
+ * @since v0.7.0
390
+ */
391
+ provide let isControl = char => char <= '\u{001F}' || char == '\u{007F}'
392
+
393
+ /**
394
+ * Checks if the character is an ASCII whitespace character.
395
+ *
396
+ * @param char: The character to check
397
+ * @returns `true` if the character is an ASCII whitespace character or `false` otherwise
398
+ *
399
+ * @example assert Char.isWhitespace('\t')
400
+ * @example assert Char.isWhitespace('\n')
401
+ * @example assert !Char.isWhitespace('1')
402
+ * @example assert !Char.isWhitespace('a')
403
+ *
404
+ * @since v0.7.0
405
+ */
406
+ provide let isWhitespace = char => {
407
+ match (char) {
408
+ '\t' | '\n' | '\x0C' | '\r' | ' ' => true,
409
+ _ => false,
410
+ }
359
411
  }
360
- }
361
412
 
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
413
+ /**
414
+ * Checks if the character is an ASCII punctuation character.
415
+ *
416
+ * @param char: The character to check
417
+ * @returns `true` if the character is an ASCII punctuation character or `false` otherwise
418
+ *
419
+ * @example assert Char.Ascii.isPunctuation('!')
420
+ * @example assert !Char.Ascii.isPunctuation('1')
421
+ *
422
+ * @since v0.7.0
423
+ */
424
+ provide let isPunctuation = char =>
425
+ char >= '!' && char <= '/'
426
+ || char >= ':' && char <= '@'
427
+ || char >= '[' && char <= '`'
428
+ || char >= '{' && char <= '~'
429
+
430
+ /**
431
+ * Checks if the character is an ASCII graphic character.
432
+ *
433
+ * @param char: The character to check
434
+ * @returns `true` if the character is an ASCII graphic character or `false` otherwise
435
+ *
436
+ * @example assert Char.Ascii.isGraphic('!')
437
+ * @example assert !Char.Ascii.isGraphic('\t')
438
+ *
439
+ * @since v0.7.0
440
+ */
441
+ provide let isGraphic = char => char >= '!' && char <= '~'
442
+
443
+ /**
444
+ * Converts the character to ASCII lowercase if it is an ASCII uppercase character.
445
+ *
446
+ * @param char: The character to convert
447
+ * @returns The lowercased character
448
+ *
449
+ * @example assert Char.Ascii.toLowercase('B') == 'b'
450
+ *
451
+ * @since v0.7.0
452
+ * @history v0.6.0: Originally `Char.toAsciiLowercase`
453
+ */
454
+ provide let toLowercase = char => {
455
+ if (char >= 'A' && char <= 'Z') {
456
+ fromCode(code(char) + 0x20)
457
+ } else {
458
+ char
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Converts the character to ASCII uppercase if it is an ASCII lowercase character.
464
+ *
465
+ * @param char: The character to convert
466
+ * @returns The uppercased character
467
+ *
468
+ * @example assert Char.Ascii.toUppercase('b') == 'B'
469
+ *
470
+ * @since v0.7.0
471
+ * @history v0.6.0: Originally `Char.toAsciiUppercase`
472
+ */
473
+ provide let toUppercase = char => {
474
+ if (char >= 'a' && char <= 'z') {
475
+ fromCode(code(char) - 0x20)
476
+ } else {
477
+ char
478
+ }
377
479
  }
378
480
  }