@grain/stdlib 0.5.13 → 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 +193 -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/int16.gr ADDED
@@ -0,0 +1,430 @@
1
+ /**
2
+ * Utilities for working with the Int16 type.
3
+ * @example from "int16" include Int16
4
+ *
5
+ * @since v0.6.0
6
+ */
7
+ module Int16
8
+
9
+ from "runtime/unsafe/wasmi32" include WasmI32
10
+ use WasmI32.{
11
+ (+),
12
+ (-),
13
+ (*),
14
+ (/),
15
+ (&),
16
+ (|),
17
+ (^),
18
+ (<<),
19
+ (>>),
20
+ (==),
21
+ (!=),
22
+ (<),
23
+ (<=),
24
+ (>),
25
+ (>=),
26
+ }
27
+ from "runtime/exception" include Exception
28
+ from "runtime/numbers" include Numbers
29
+ use Numbers.{
30
+ coerceNumberToInt16 as fromNumber,
31
+ coerceInt16ToNumber as toNumber,
32
+ }
33
+ from "runtime/dataStructures" include DataStructures
34
+ use DataStructures.{ tagInt16, untagInt16 }
35
+
36
+ @unsafe
37
+ let _DATA_OFFSET = 8n
38
+ @unsafe
39
+ let _TAG_BYTE = 0b10010n
40
+ @unsafe
41
+ let _DATA_MASK = 0xffffff00n
42
+
43
+ provide { fromNumber, toNumber }
44
+
45
+ @unsafe
46
+ let signExtend = x => (x << _DATA_OFFSET) >> _DATA_OFFSET
47
+
48
+ /**
49
+ * Converts a Uint16 to an Int16.
50
+ *
51
+ * @param number: The value to convert
52
+ * @returns The Uint16 represented as an Int16
53
+ *
54
+ * @since v0.6.0
55
+ */
56
+ @unsafe
57
+ provide let fromUint16 = (number: Uint16) => {
58
+ let x = WasmI32.fromGrain(number)
59
+ // Trick: convert from Uint16 tag 100010 to Int16 tag 10010
60
+ let result = x ^ 0b110000n
61
+ WasmI32.toGrain(signExtend(result)): Int16
62
+ }
63
+
64
+ /**
65
+ * Increments the value by one.
66
+ *
67
+ * @param value: The value to increment
68
+ * @returns The incremented value
69
+ *
70
+ * @since v0.6.0
71
+ */
72
+ @unsafe
73
+ provide let incr = (value: Int16) => {
74
+ let value = WasmI32.fromGrain(value)
75
+ // Trick: since the data is at offset 8, can just add 1 << 8 == 0x100
76
+ let result = value + 0x100n
77
+ WasmI32.toGrain(signExtend(result)): Int16
78
+ }
79
+
80
+ /**
81
+ * Decrements the value by one.
82
+ *
83
+ * @param value: The value to decrement
84
+ * @returns The decremented value
85
+ *
86
+ * @since v0.6.0
87
+ */
88
+ @unsafe
89
+ provide let decr = (value: Int16) => {
90
+ let value = WasmI32.fromGrain(value)
91
+ // Trick: since the data is at offset 8, can just subtract 1 << 8 == 0x100
92
+ let result = value - 0x100n
93
+ WasmI32.toGrain(signExtend(result)): Int16
94
+ }
95
+
96
+ /**
97
+ * Computes the sum of its operands.
98
+ *
99
+ * @param x: The first operand
100
+ * @param y: The second operand
101
+ * @returns The sum of the two operands
102
+ *
103
+ * @since v0.6.0
104
+ */
105
+ @unsafe
106
+ provide let (+) = (x: Int16, y: Int16) => {
107
+ // Trick: add the values as-is without shifting right 8; this will cause
108
+ // the data to be added correctly but the trailing tag bits will be corrupted:
109
+ // 10010 + 10010 = 100100; xor with 110110 to correct to 10010
110
+ let x = WasmI32.fromGrain(x)
111
+ let y = WasmI32.fromGrain(y)
112
+ let val = x + y
113
+ let tagged = val ^ 0b110110n
114
+ WasmI32.toGrain(signExtend(tagged)): Int16
115
+ }
116
+
117
+ /**
118
+ * Computes the difference of its operands.
119
+ *
120
+ * @param x: The first operand
121
+ * @param y: The second operand
122
+ * @returns The difference of the two operands
123
+ *
124
+ * @since v0.6.0
125
+ */
126
+ @unsafe
127
+ provide let (-) = (x: Int16, y: Int16) => {
128
+ let x = WasmI32.fromGrain(x)
129
+ let y = WasmI32.fromGrain(y)
130
+ let val = x - y
131
+ let tagged = val | _TAG_BYTE
132
+ WasmI32.toGrain(signExtend(tagged)): Int16
133
+ }
134
+
135
+ /**
136
+ * Computes the product of its operands.
137
+ *
138
+ * @param x: The first operand
139
+ * @param y: The second operand
140
+ * @returns The product of the two operands
141
+ *
142
+ * @since v0.6.0
143
+ */
144
+ @unsafe
145
+ provide let (*) = (x: Int16, y: Int16) => {
146
+ let x = untagInt16(x)
147
+ let y = untagInt16(y)
148
+ let val = WasmI32.extendS16(x * y)
149
+ tagInt16(val)
150
+ }
151
+
152
+ /**
153
+ * Computes the quotient of its operands using signed division.
154
+ *
155
+ * @param x: The first operand
156
+ * @param y: The second operand
157
+ * @returns The quotient of its operands
158
+ *
159
+ * @since v0.6.0
160
+ */
161
+ @unsafe
162
+ provide let (/) = (x: Int16, y: Int16) => {
163
+ let x = untagInt16(x)
164
+ let y = untagInt16(y)
165
+ // No need to re-sign-extend
166
+ let val = x / y
167
+ tagInt16(val)
168
+ }
169
+
170
+ /**
171
+ * Computes the remainder of the division of its operands using signed division.
172
+ *
173
+ * @param x: The first operand
174
+ * @param y: The second operand
175
+ * @returns The remainder of its operands
176
+ *
177
+ * @since v0.6.0
178
+ */
179
+ @unsafe
180
+ provide let rem = (x: Int16, y: Int16) => {
181
+ let x = untagInt16(x)
182
+ let y = untagInt16(y)
183
+ // No need to re-sign-extend
184
+ let val = WasmI32.remS(x, y)
185
+ tagInt16(val)
186
+ }
187
+
188
+ @unsafe
189
+ let abs = n => {
190
+ use WasmI32.{ (-) }
191
+ let mask = n >> 31n
192
+ (n ^ mask) - mask
193
+ }
194
+
195
+ /**
196
+ * Computes the remainder of the division of the first operand by the second.
197
+ * The result will have the sign of the second operand.
198
+ *
199
+ * @param x: The first operand
200
+ * @param y: The second operand
201
+ * @returns The modulus of its operands
202
+ *
203
+ * @throws ModuloByZero: When `y` is zero
204
+ *
205
+ * @since v0.6.0
206
+ */
207
+ @unsafe
208
+ provide let (%) = (x: Int16, y: Int16) => {
209
+ use WasmI32.{ (-) }
210
+ let xval = untagInt16(x)
211
+ let yval = untagInt16(y)
212
+
213
+ if (WasmI32.eqz(yval)) {
214
+ throw Exception.ModuloByZero
215
+ }
216
+
217
+ let val = if ((xval ^ yval) < 0n) {
218
+ let xabs = abs(xval)
219
+ let yabs = abs(yval)
220
+ let mval = WasmI32.remS(xabs, yabs)
221
+ let mres = yabs - mval
222
+ if (mval != 0n) (if (yval < 0n) 0n - mres else mres) else 0n
223
+ } else {
224
+ WasmI32.remS(xval, yval)
225
+ }
226
+ tagInt16(val)
227
+ }
228
+
229
+ /**
230
+ * Shifts the bits of the value left by the given number of bits.
231
+ *
232
+ * @param value: The value to shift
233
+ * @param amount: The number of bits to shift by
234
+ * @returns The shifted value
235
+ *
236
+ * @since v0.6.0
237
+ */
238
+ @unsafe
239
+ provide let (<<) = (value: Int16, amount: Int16) => {
240
+ // Trick: do not shift `value` right, just correct tag afterwards
241
+ let x = WasmI32.fromGrain(value) & _DATA_MASK
242
+ let y = untagInt16(amount)
243
+ let val = x << y
244
+ let tagged = val | _TAG_BYTE
245
+ WasmI32.toGrain(signExtend(tagged)): Int16
246
+ }
247
+
248
+ /**
249
+ * Shifts the bits of the value right by the given number of bits, preserving the sign bit.
250
+ *
251
+ * @param value: The value to shift
252
+ * @param amount: The amount to shift by
253
+ * @returns The shifted value
254
+ *
255
+ * @since v0.6.0
256
+ */
257
+ @unsafe
258
+ provide let (>>) = (value: Int16, amount: Int16) => {
259
+ // Trick: do not shift `value` right, just correct tag afterwards
260
+ let x = WasmI32.fromGrain(value)
261
+ let y = untagInt16(amount)
262
+ let val = x >> y
263
+ let tagged = val & _DATA_MASK | _TAG_BYTE
264
+ WasmI32.toGrain(tagged): Int16
265
+ }
266
+
267
+ /**
268
+ * Checks if the first value is equal to the second value.
269
+ *
270
+ * @param x: The first value
271
+ * @param y: The second value
272
+ * @returns `true` if the first value is equal to the second value or `false` otherwise
273
+ *
274
+ * @since v0.6.0
275
+ */
276
+ @unsafe
277
+ provide let (==) = (x: Int16, y: Int16) => {
278
+ let x = WasmI32.fromGrain(x)
279
+ let y = WasmI32.fromGrain(y)
280
+ x == y
281
+ }
282
+
283
+ /**
284
+ * Checks if the first value is not equal to the second value.
285
+ *
286
+ * @param x: The first value
287
+ * @param y: The second value
288
+ * @returns `true` if the first value is not equal to the second value or `false` otherwise
289
+ *
290
+ * @since v0.6.0
291
+ */
292
+ @unsafe
293
+ provide let (!=) = (x: Int16, y: Int16) => {
294
+ let x = WasmI32.fromGrain(x)
295
+ let y = WasmI32.fromGrain(y)
296
+ x != y
297
+ }
298
+
299
+ /**
300
+ * Checks if the first value is less than the second value.
301
+ *
302
+ * @param x: The first value
303
+ * @param y: The second value
304
+ * @returns `true` if the first value is less than the second value or `false` otherwise
305
+ *
306
+ * @since v0.6.0
307
+ */
308
+ @unsafe
309
+ provide let (<) = (x: Int16, y: Int16) => {
310
+ let x = WasmI32.fromGrain(x)
311
+ let y = WasmI32.fromGrain(y)
312
+ x < y
313
+ }
314
+
315
+ /**
316
+ * Checks if the first value is greater than the second value.
317
+ *
318
+ * @param x: The first value
319
+ * @param y: The second value
320
+ * @returns `true` if the first value is greater than the second value or `false` otherwise
321
+ *
322
+ * @since v0.6.0
323
+ */
324
+ @unsafe
325
+ provide let (>) = (x: Int16, y: Int16) => {
326
+ let x = WasmI32.fromGrain(x)
327
+ let y = WasmI32.fromGrain(y)
328
+ x > y
329
+ }
330
+
331
+ /**
332
+ * Checks if the first value is less than or equal to the second value.
333
+ *
334
+ * @param x: The first value
335
+ * @param y: The second value
336
+ * @returns `true` if the first value is less than or equal to the second value or `false` otherwise
337
+ *
338
+ * @since v0.6.0
339
+ */
340
+ @unsafe
341
+ provide let (<=) = (x: Int16, y: Int16) => {
342
+ let x = WasmI32.fromGrain(x)
343
+ let y = WasmI32.fromGrain(y)
344
+ x <= y
345
+ }
346
+
347
+ /**
348
+ * Checks if the first value is greater than or equal to the second value.
349
+ *
350
+ * @param x: The first value
351
+ * @param y: The second value
352
+ * @returns `true` if the first value is greater than or equal to the second value or `false` otherwise
353
+ *
354
+ * @since v0.6.0
355
+ */
356
+ @unsafe
357
+ provide let (>=) = (x: Int16, y: Int16) => {
358
+ let x = WasmI32.fromGrain(x)
359
+ let y = WasmI32.fromGrain(y)
360
+ x >= y
361
+ }
362
+
363
+ /**
364
+ * Computes the bitwise NOT of the given value.
365
+ *
366
+ * @param value: The given value
367
+ * @returns Containing the inverted bits of the given value
368
+ *
369
+ * @since v0.6.0
370
+ */
371
+ @unsafe
372
+ provide let lnot = (value: Int16) => {
373
+ let x = WasmI32.fromGrain(value)
374
+ WasmI32.toGrain(x ^ _DATA_MASK): Int16
375
+ }
376
+
377
+ /**
378
+ * Computes the bitwise AND (`&`) on the given operands.
379
+ *
380
+ * @param x: The first operand
381
+ * @param y: The second operand
382
+ * @returns Containing a `1` in each bit position for which the corresponding bits of both operands are `1`
383
+ *
384
+ * @since v0.6.0
385
+ */
386
+ @unsafe
387
+ provide let (&) = (x: Int16, y: Int16) => {
388
+ // Tags getting `and`ed together is not a problem
389
+ let x = WasmI32.fromGrain(x)
390
+ let y = WasmI32.fromGrain(y)
391
+ let val = x & y
392
+ WasmI32.toGrain(val): Int16
393
+ }
394
+
395
+ /**
396
+ * Computes the bitwise OR (`|`) on the given operands.
397
+ *
398
+ * @param x: The first operand
399
+ * @param y: The second operand
400
+ * @returns Containing a `1` in each bit position for which the corresponding bits of either or both operands are `1`
401
+ *
402
+ * @since v0.6.0
403
+ */
404
+ @unsafe
405
+ provide let (|) = (x: Int16, y: Int16) => {
406
+ // Tags getting `or`ed together is not a problem
407
+ let x = WasmI32.fromGrain(x)
408
+ let y = WasmI32.fromGrain(y)
409
+ let val = x | y
410
+ WasmI32.toGrain(val): Int16
411
+ }
412
+
413
+ /**
414
+ * Computes the bitwise XOR (`^`) on the given operands.
415
+ *
416
+ * @param x: The first operand
417
+ * @param y: The second operand
418
+ * @returns Containing a `1` in each bit position for which the corresponding bits of either but not both operands are `1`
419
+ *
420
+ * @since v0.6.0
421
+ */
422
+ @unsafe
423
+ provide let (^) = (x: Int16, y: Int16) => {
424
+ use WasmI32.{ (|) }
425
+ // Tags getting `xor`ed together will cancel each other out; add back tag with or
426
+ let x = WasmI32.fromGrain(x)
427
+ let y = WasmI32.fromGrain(y)
428
+ let val = x ^ y
429
+ WasmI32.toGrain(val | _TAG_BYTE): Int16
430
+ }