@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.
- package/CHANGELOG.md +193 -0
- package/LICENSE +1 -1
- package/README.md +25 -2
- package/array.gr +1512 -199
- package/array.md +2032 -94
- package/bigint.gr +239 -140
- package/bigint.md +450 -106
- package/buffer.gr +595 -102
- package/buffer.md +903 -145
- package/bytes.gr +401 -110
- package/bytes.md +551 -63
- package/char.gr +228 -49
- package/char.md +373 -7
- package/exception.gr +26 -12
- package/exception.md +29 -5
- package/float32.gr +130 -109
- package/float32.md +185 -57
- package/float64.gr +112 -99
- package/float64.md +185 -57
- package/hash.gr +47 -37
- package/hash.md +21 -3
- package/int16.gr +430 -0
- package/int16.md +618 -0
- package/int32.gr +200 -269
- package/int32.md +254 -289
- package/int64.gr +142 -225
- package/int64.md +254 -289
- package/int8.gr +511 -0
- package/int8.md +786 -0
- package/json.gr +2084 -0
- package/json.md +608 -0
- package/list.gr +120 -68
- package/list.md +125 -80
- package/map.gr +560 -57
- package/map.md +672 -56
- package/marshal.gr +239 -227
- package/marshal.md +36 -4
- package/number.gr +626 -676
- package/number.md +738 -153
- package/option.gr +33 -35
- package/option.md +58 -42
- package/package.json +2 -2
- package/path.gr +148 -187
- package/path.md +47 -96
- package/pervasives.gr +75 -416
- package/pervasives.md +85 -180
- package/priorityqueue.gr +433 -74
- package/priorityqueue.md +422 -54
- package/queue.gr +362 -80
- package/queue.md +433 -38
- package/random.gr +67 -75
- package/random.md +68 -40
- package/range.gr +135 -63
- package/range.md +198 -43
- package/rational.gr +284 -0
- package/rational.md +545 -0
- package/regex.gr +933 -1066
- package/regex.md +59 -60
- package/result.gr +23 -25
- package/result.md +54 -39
- package/runtime/atof/common.gr +78 -82
- package/runtime/atof/common.md +22 -10
- package/runtime/atof/decimal.gr +102 -127
- package/runtime/atof/decimal.md +28 -7
- package/runtime/atof/lemire.gr +56 -71
- package/runtime/atof/lemire.md +9 -1
- package/runtime/atof/parse.gr +83 -110
- package/runtime/atof/parse.md +12 -2
- package/runtime/atof/slow.gr +28 -35
- package/runtime/atof/slow.md +9 -1
- package/runtime/atof/table.gr +19 -18
- package/runtime/atof/table.md +10 -2
- package/runtime/atoi/parse.gr +153 -136
- package/runtime/atoi/parse.md +50 -1
- package/runtime/bigint.gr +410 -517
- package/runtime/bigint.md +71 -57
- package/runtime/compare.gr +176 -85
- package/runtime/compare.md +31 -1
- package/runtime/dataStructures.gr +144 -32
- package/runtime/dataStructures.md +267 -31
- package/runtime/debugPrint.gr +34 -15
- package/runtime/debugPrint.md +37 -5
- package/runtime/equal.gr +53 -52
- package/runtime/equal.md +30 -1
- package/runtime/exception.gr +38 -47
- package/runtime/exception.md +10 -8
- package/runtime/gc.gr +23 -152
- package/runtime/gc.md +13 -17
- package/runtime/malloc.gr +31 -31
- package/runtime/malloc.md +11 -3
- package/runtime/numberUtils.gr +191 -172
- package/runtime/numberUtils.md +17 -9
- package/runtime/numbers.gr +1695 -1021
- package/runtime/numbers.md +1098 -134
- package/runtime/string.gr +540 -242
- package/runtime/string.md +76 -6
- package/runtime/unsafe/constants.gr +30 -13
- package/runtime/unsafe/constants.md +80 -0
- package/runtime/unsafe/conv.gr +55 -28
- package/runtime/unsafe/conv.md +41 -9
- package/runtime/unsafe/memory.gr +10 -30
- package/runtime/unsafe/memory.md +15 -19
- package/runtime/unsafe/tags.gr +37 -21
- package/runtime/unsafe/tags.md +88 -8
- package/runtime/unsafe/wasmf32.gr +30 -36
- package/runtime/unsafe/wasmf32.md +64 -56
- package/runtime/unsafe/wasmf64.gr +30 -36
- package/runtime/unsafe/wasmf64.md +64 -56
- package/runtime/unsafe/wasmi32.gr +49 -66
- package/runtime/unsafe/wasmi32.md +102 -94
- package/runtime/unsafe/wasmi64.gr +52 -79
- package/runtime/unsafe/wasmi64.md +108 -100
- package/runtime/utils/printing.gr +13 -15
- package/runtime/utils/printing.md +11 -3
- package/runtime/wasi.gr +294 -295
- package/runtime/wasi.md +62 -42
- package/set.gr +574 -64
- package/set.md +634 -54
- package/stack.gr +181 -64
- package/stack.md +271 -42
- package/string.gr +453 -533
- package/string.md +241 -151
- package/uint16.gr +369 -0
- package/uint16.md +585 -0
- package/uint32.gr +470 -0
- package/uint32.md +737 -0
- package/uint64.gr +471 -0
- package/uint64.md +737 -0
- package/uint8.gr +369 -0
- package/uint8.md +585 -0
- package/uri.gr +1093 -0
- package/uri.md +477 -0
- package/{sys → wasi}/file.gr +914 -500
- package/{sys → wasi}/file.md +454 -50
- package/wasi/process.gr +292 -0
- package/{sys → wasi}/process.md +164 -6
- package/wasi/random.gr +77 -0
- package/wasi/random.md +80 -0
- package/{sys → wasi}/time.gr +15 -22
- package/{sys → wasi}/time.md +5 -5
- package/immutablearray.gr +0 -929
- package/immutablearray.md +0 -1038
- package/immutablemap.gr +0 -493
- package/immutablemap.md +0 -479
- package/immutablepriorityqueue.gr +0 -360
- package/immutablepriorityqueue.md +0 -291
- package/immutableset.gr +0 -498
- package/immutableset.md +0 -449
- package/runtime/debug.gr +0 -2
- package/runtime/debug.md +0 -6
- package/runtime/unsafe/errors.gr +0 -36
- package/runtime/unsafe/errors.md +0 -204
- package/sys/process.gr +0 -254
- package/sys/random.gr +0 -79
- package/sys/random.md +0 -66
package/char.gr
CHANGED
|
@@ -1,41 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
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
|
|
6
|
+
* @example from "char" include Char
|
|
7
7
|
*
|
|
8
|
-
* @
|
|
8
|
+
* @example 'a'
|
|
9
|
+
* @example '1'
|
|
10
|
+
* @example '🌾'
|
|
11
|
+
*
|
|
12
|
+
* @since v0.3.0
|
|
9
13
|
*/
|
|
14
|
+
module Char
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
25
|
+
* @since v0.3.0
|
|
31
26
|
*/
|
|
32
|
-
|
|
27
|
+
provide let min = 0x0000
|
|
33
28
|
/**
|
|
34
29
|
* The maximum valid Unicode scalar value.
|
|
35
30
|
*
|
|
36
|
-
* @since
|
|
31
|
+
* @since v0.3.0
|
|
37
32
|
*/
|
|
38
|
-
|
|
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
|
-
* @
|
|
41
|
+
* @example Char.isValid(0) == true
|
|
42
|
+
* @example Char.isValid(-1) == false
|
|
43
|
+
*
|
|
44
|
+
* @since v0.3.0
|
|
47
45
|
*/
|
|
48
|
-
|
|
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
|
-
* @
|
|
58
|
+
* @example Char.code('a') == 97
|
|
59
|
+
* @example Char.code('🌾') == 127806
|
|
60
|
+
*
|
|
61
|
+
* @since v0.3.0
|
|
61
62
|
*/
|
|
62
63
|
@unsafe
|
|
63
|
-
|
|
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
|
-
* @
|
|
80
|
+
* @example Char.fromCode(97) == 'a'
|
|
81
|
+
* @example Char.fromCode(127806) == '🌾'
|
|
82
|
+
*
|
|
83
|
+
* @since v0.3.0
|
|
80
84
|
*/
|
|
81
85
|
@unsafe
|
|
82
|
-
|
|
83
|
-
|
|
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
|
-
//
|
|
96
|
-
// by 2
|
|
97
|
-
//
|
|
98
|
-
let char = (usv <<
|
|
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
|
-
* @
|
|
114
|
+
* @example Char.succ('a') == 'b'
|
|
115
|
+
* @example Char.succ('1') == '2'
|
|
116
|
+
*
|
|
117
|
+
* @since v0.3.0
|
|
112
118
|
*/
|
|
113
|
-
|
|
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
|
-
* @
|
|
138
|
+
* @example Char.pred('b') == 'a'
|
|
139
|
+
* @example Char.pred('2') == '1'
|
|
140
|
+
*
|
|
141
|
+
* @since v0.3.0
|
|
133
142
|
*/
|
|
134
|
-
|
|
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
|
-
* @
|
|
160
|
+
* @example Char.toString('a') == "a"
|
|
161
|
+
* @example Char.toString('🌾') == "🌾"
|
|
162
|
+
*
|
|
163
|
+
* @since v0.3.0
|
|
152
164
|
*/
|
|
153
165
|
@unsafe
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
+
}
|