@grain/stdlib 0.4.4 → 0.4.5

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/char.gr CHANGED
@@ -1,35 +1,68 @@
1
+ /**
2
+ * @module Char: Utilities for working with the Char type.
3
+ *
4
+ * The Char type represents a single [Unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value).
5
+ *
6
+ * @example import Char from "char"
7
+ *
8
+ * @since 0.3.0
9
+ */
10
+
1
11
  import WasmI32 from "runtime/unsafe/wasmi32"
2
12
  import Memory from "runtime/unsafe/memory"
3
13
  import Errors from "runtime/unsafe/errors"
4
- import { tagSimpleNumber, allocateChar, allocateString } from "runtime/dataStructures"
5
-
6
- export *
14
+ import {
15
+ tagSimpleNumber,
16
+ allocateChar,
17
+ allocateString,
18
+ } from "runtime/dataStructures"
7
19
 
8
20
  exception MalformedUtf8
9
21
 
10
- // The minimum value of Unicode characters
11
- // Number
12
- let min = 0x0000
22
+ /**
23
+ * @section Values: Functions and constants included in the Char module.
24
+ */
13
25
 
14
- // The maximum value of Unicode characters
15
- // Number
16
- let max = 0x10FFFF
26
+ /**
27
+ * The minimum valid Unicode scalar value.
28
+ *
29
+ * @since 0.3.0
30
+ */
31
+ export let min = 0x0000
32
+ /**
33
+ * The maximum valid Unicode scalar value.
34
+ *
35
+ * @since 0.3.0
36
+ */
37
+ export let max = 0x10FFFF
17
38
 
18
- // Returns true if the given number is a valid Unicode scalar value.
19
- // @param n: Number - the value to check
20
- // @returns Bool
21
- let isValid = (n) => {
22
- n >= min && (n <= 0xD7FF || n >= 0xE000) && n <= max
39
+ /**
40
+ * Determines whether the given character code is a valid Unicode scalar value.
41
+ *
42
+ * @param charCode: The number to check
43
+ * @returns `true` if the number refers to a valid Unicode scalar value or `false` otherwise
44
+ *
45
+ * @since 0.3.0
46
+ */
47
+ export let isValid = charCode => {
48
+ charCode >= min &&
49
+ (charCode <= 0xD7FF || charCode >= 0xE000) &&
50
+ charCode <= max
23
51
  }
24
52
 
25
- // Returns the Unicode code point for the character
26
- // @param char: Char - the input character
27
- // @returns Number
53
+ /**
54
+ * Determines the Unicode scalar value for a character.
55
+ *
56
+ * @param char: The character
57
+ * @returns The Unicode scalar value for the given character
58
+ *
59
+ * @since 0.3.0
60
+ */
28
61
  @disableGC
29
- let rec code = (c: Char) => {
62
+ export let rec code = (char: Char) => {
30
63
  // Algorithm from https://encoding.spec.whatwg.org/#utf-8-decoder
31
64
 
32
- let c = WasmI32.fromGrain(c)
65
+ let char = WasmI32.fromGrain(char)
33
66
 
34
67
  let (+) = WasmI32.add
35
68
  let (==) = WasmI32.eq
@@ -50,7 +83,7 @@ let rec code = (c: Char) => {
50
83
  let mut result = 0n
51
84
 
52
85
  while (true) {
53
- let byte = WasmI32.load8U(c + offset, 4n)
86
+ let byte = WasmI32.load8U(char + offset, 4n)
54
87
  offset += 1n
55
88
  if (bytesNeeded == 0n) {
56
89
  if (byte >= 0x00n && byte <= 0x7Fn) {
@@ -79,7 +112,7 @@ let rec code = (c: Char) => {
79
112
  }
80
113
  lowerBoundary = 0x80n
81
114
  upperBoundary = 0xBFn
82
- codePoint = (codePoint << 6n) | (byte & 0x3Fn)
115
+ codePoint = codePoint << 6n | byte & 0x3Fn
83
116
  bytesSeen += 1n
84
117
  if (bytesSeen == bytesNeeded) {
85
118
  result = codePoint
@@ -87,16 +120,22 @@ let rec code = (c: Char) => {
87
120
  }
88
121
  }
89
122
 
90
- Memory.decRef(c)
123
+ Memory.decRef(char)
91
124
  Memory.decRef(WasmI32.fromGrain(code))
92
125
  tagSimpleNumber(result)
93
126
  }
94
127
 
95
- // Returns the Char for the given code point. Fails if the code point is invalid.
96
- // @param codePoint: Number - the Unicode code point
97
- // @returns Char
128
+ /**
129
+ * Creates a character from the given Unicode scalar value.
130
+ * Throws an exception if the Unicode scalar value is invalid.
131
+ *
132
+ * @param usv: The Unicode scalar value
133
+ * @returns The character for the given Unicode scalar value
134
+ *
135
+ * @since 0.3.0
136
+ */
98
137
  @disableGC
99
- let rec fromCode = (code: Number) => {
138
+ export let rec fromCode = (usv: Number) => {
100
139
  // Algorithm from https://encoding.spec.whatwg.org/#utf-8-encoder
101
140
 
102
141
  let (+) = WasmI32.add
@@ -110,23 +149,23 @@ let rec fromCode = (code: Number) => {
110
149
  let (&) = WasmI32.and
111
150
  let (|) = WasmI32.or
112
151
 
113
- let code = WasmI32.fromGrain(code)
114
- if ((code & 1n) == 0n) {
152
+ let usv = WasmI32.fromGrain(usv)
153
+ if ((usv & 1n) == 0n) {
115
154
  throw InvalidArgument("Invalid character code")
116
155
  }
117
156
 
118
- let code = code >>> 1n
119
- let result = if (code < 0x80n) {
157
+ let usv = usv >>> 1n
158
+ let result = if (usv < 0x80n) {
120
159
  let char = allocateChar()
121
- WasmI32.store8(char, code, 4n)
160
+ WasmI32.store8(char, usv, 4n)
122
161
  WasmI32.toGrain(char): Char
123
162
  } else {
124
163
  let mut count = 0n
125
164
  let mut offset = 0n
126
- if (code <= 0x07FFn) {
165
+ if (usv <= 0x07FFn) {
127
166
  count = 1n
128
167
  offset = 0xC0n
129
- } else if (code <= 0xFFFFn) {
168
+ } else if (usv <= 0xFFFFn) {
130
169
  count = 2n
131
170
  offset = 0xE0n
132
171
  } else {
@@ -134,13 +173,13 @@ let rec fromCode = (code: Number) => {
134
173
  offset = 0xF0n
135
174
  }
136
175
  let char = allocateChar()
137
- WasmI32.store8(char, (code >>> (6n * count)) + offset, 4n)
176
+ WasmI32.store8(char, (usv >>> 6n * count) + offset, 4n)
138
177
 
139
178
  let mut n = 0n
140
179
  while (count > 0n) {
141
180
  n += 1n
142
- let temp = code >>> (6n * (count - 1n))
143
- WasmI32.store8(char + n, 0x80n | (temp & 0x3Fn), 4n)
181
+ let temp = usv >>> 6n * (count - 1n)
182
+ WasmI32.store8(char + n, 0x80n | temp & 0x3Fn, 4n)
144
183
  count -= 1n
145
184
  }
146
185
 
@@ -153,13 +192,19 @@ let rec fromCode = (code: Number) => {
153
192
  result
154
193
  }
155
194
 
156
- // Returns the next valid Unicode character by code point. Fails if the input character is U+10FFFF.
157
- // @param char: Char - the input character
158
- // @returns Char
159
- let succ = (c) => {
160
- let codePoint = code(c)
195
+ /**
196
+ * Returns the next valid character by Unicode scalar value.
197
+ * Throws if the input character is the max valid Unicode scalar value.
198
+ *
199
+ * @param char: The character
200
+ * @returns The next valid character by Unicode scalar value
201
+ *
202
+ * @since 0.3.0
203
+ */
204
+ export let succ = char => {
205
+ let codePoint = code(char)
161
206
  if (codePoint == max) {
162
- fail "no valid Unicode code point past U+10FFF"
207
+ fail "no valid Unicode scalar value past U+10FFF"
163
208
  } else if (codePoint == 0xD7FF) {
164
209
  fromCode(0xE000)
165
210
  } else {
@@ -167,13 +212,19 @@ let succ = (c) => {
167
212
  }
168
213
  }
169
214
 
170
- // Returns the previous valid Unicode character by code point. Fails if the input character is U+0000.
171
- // @param char: Char - the input character
172
- // @returns Char
173
- let pred = (c) => {
174
- let codePoint = code(c)
215
+ /**
216
+ * Returns the previous valid character by Unicode scalar value.
217
+ * Throws if the input character is the min valid Unicode scalar value.
218
+ *
219
+ * @param char: The character
220
+ * @returns The previous valid character by Unicode scalar value
221
+ *
222
+ * @since 0.3.0
223
+ */
224
+ export let pred = char => {
225
+ let codePoint = code(char)
175
226
  if (codePoint == min) {
176
- fail "no valid Unicode code point below U+0000"
227
+ fail "no valid Unicode scalar value below U+0000"
177
228
  } else if (codePoint == 0xE000) {
178
229
  fromCode(0xD7FF)
179
230
  } else {
@@ -181,17 +232,22 @@ let pred = (c) => {
181
232
  }
182
233
  }
183
234
 
184
- // Creates a new string containing the character.
185
- // @param char: Char - the character to convert
186
- // @returns String
235
+ /**
236
+ * Converts the given character to a string.
237
+ *
238
+ * @param char: The character to convert
239
+ * @returns A string containing the given character
240
+ *
241
+ * @since 0.3.0
242
+ */
187
243
  @disableGC
188
- export let rec toString = (c: Char) => {
244
+ export let rec toString = (char: Char) => {
189
245
  let (+) = WasmI32.add
190
246
  let (&) = WasmI32.and
191
247
  let (==) = WasmI32.eq
192
248
 
193
- let c = WasmI32.fromGrain(c)
194
- let byte = WasmI32.load8U(c, 4n)
249
+ let char = WasmI32.fromGrain(char)
250
+ let byte = WasmI32.load8U(char, 4n)
195
251
  let n = if ((byte & 0x80n) == 0x00n) {
196
252
  1n
197
253
  } else if ((byte & 0xF0n) == 0xF0n) {
@@ -202,9 +258,9 @@ export let rec toString = (c: Char) => {
202
258
  2n
203
259
  }
204
260
  let str = allocateString(n)
205
- Memory.copy(str + 8n, c + 4n, n)
261
+ Memory.copy(str + 8n, char + 4n, n)
206
262
  let ret = WasmI32.toGrain(str): String
207
- Memory.decRef(WasmI32.fromGrain(c))
263
+ Memory.decRef(WasmI32.fromGrain(char))
208
264
  Memory.decRef(WasmI32.fromGrain(toString))
209
265
  ret
210
266
  }
package/char.md ADDED
@@ -0,0 +1,200 @@
1
+ ---
2
+ title: Char
3
+ ---
4
+
5
+ Utilities for working with the Char type.
6
+
7
+ The Char type represents a single [Unicode scalar value](https://www.unicode.org/glossary/#unicode_scalar_value).
8
+
9
+ <details disabled>
10
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
11
+ No other changes yet.
12
+ </details>
13
+
14
+ ```grain
15
+ import Char from "char"
16
+ ```
17
+
18
+ ## Values
19
+
20
+ Functions and constants included in the Char module.
21
+
22
+ ### Char.**min**
23
+
24
+ <details disabled>
25
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
26
+ No other changes yet.
27
+ </details>
28
+
29
+ ```grain
30
+ min : Number
31
+ ```
32
+
33
+ The minimum valid Unicode scalar value.
34
+
35
+ ### Char.**max**
36
+
37
+ <details disabled>
38
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
39
+ No other changes yet.
40
+ </details>
41
+
42
+ ```grain
43
+ max : Number
44
+ ```
45
+
46
+ The maximum valid Unicode scalar value.
47
+
48
+ ### Char.**isValid**
49
+
50
+ <details disabled>
51
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
52
+ No other changes yet.
53
+ </details>
54
+
55
+ ```grain
56
+ isValid : Number -> Bool
57
+ ```
58
+
59
+ Determines whether the given character code is a valid Unicode scalar value.
60
+
61
+ Parameters:
62
+
63
+ |param|type|description|
64
+ |-----|----|-----------|
65
+ |`charCode`|`Number`|The number to check|
66
+
67
+ Returns:
68
+
69
+ |type|description|
70
+ |----|-----------|
71
+ |`Bool`|`true` if the number refers to a valid Unicode scalar value or `false` otherwise|
72
+
73
+ ### Char.**code**
74
+
75
+ <details disabled>
76
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
77
+ No other changes yet.
78
+ </details>
79
+
80
+ ```grain
81
+ code : Char -> Number
82
+ ```
83
+
84
+ Determines the Unicode scalar value for a character.
85
+
86
+ Parameters:
87
+
88
+ |param|type|description|
89
+ |-----|----|-----------|
90
+ |`char`|`Char`|The character|
91
+
92
+ Returns:
93
+
94
+ |type|description|
95
+ |----|-----------|
96
+ |`Number`|The Unicode scalar value for the given character|
97
+
98
+ ### Char.**fromCode**
99
+
100
+ <details disabled>
101
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
102
+ No other changes yet.
103
+ </details>
104
+
105
+ ```grain
106
+ fromCode : Number -> Char
107
+ ```
108
+
109
+ Creates a character from the given Unicode scalar value.
110
+ Throws an exception if the Unicode scalar value is invalid.
111
+
112
+ Parameters:
113
+
114
+ |param|type|description|
115
+ |-----|----|-----------|
116
+ |`usv`|`Number`|The Unicode scalar value|
117
+
118
+ Returns:
119
+
120
+ |type|description|
121
+ |----|-----------|
122
+ |`Char`|The character for the given Unicode scalar value|
123
+
124
+ ### Char.**succ**
125
+
126
+ <details disabled>
127
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
128
+ No other changes yet.
129
+ </details>
130
+
131
+ ```grain
132
+ succ : Char -> Char
133
+ ```
134
+
135
+ Returns the next valid character by Unicode scalar value.
136
+ Throws if the input character is the max valid Unicode scalar value.
137
+
138
+ Parameters:
139
+
140
+ |param|type|description|
141
+ |-----|----|-----------|
142
+ |`char`|`Char`|The character|
143
+
144
+ Returns:
145
+
146
+ |type|description|
147
+ |----|-----------|
148
+ |`Char`|The next valid character by Unicode scalar value|
149
+
150
+ ### Char.**pred**
151
+
152
+ <details disabled>
153
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
154
+ No other changes yet.
155
+ </details>
156
+
157
+ ```grain
158
+ pred : Char -> Char
159
+ ```
160
+
161
+ Returns the previous valid character by Unicode scalar value.
162
+ Throws if the input character is the min valid Unicode scalar value.
163
+
164
+ Parameters:
165
+
166
+ |param|type|description|
167
+ |-----|----|-----------|
168
+ |`char`|`Char`|The character|
169
+
170
+ Returns:
171
+
172
+ |type|description|
173
+ |----|-----------|
174
+ |`Char`|The previous valid character by Unicode scalar value|
175
+
176
+ ### Char.**toString**
177
+
178
+ <details disabled>
179
+ <summary tabindex="-1">Added in <code>0.3.0</code></summary>
180
+ No other changes yet.
181
+ </details>
182
+
183
+ ```grain
184
+ toString : Char -> String
185
+ ```
186
+
187
+ Converts the given character to a string.
188
+
189
+ Parameters:
190
+
191
+ |param|type|description|
192
+ |-----|----|-----------|
193
+ |`char`|`Char`|The character to convert|
194
+
195
+ Returns:
196
+
197
+ |type|description|
198
+ |----|-----------|
199
+ |`String`|A string containing the given character|
200
+
package/hash.gr CHANGED
@@ -25,7 +25,7 @@ import WasmI32, {
25
25
  eq as (==),
26
26
  ne as (!=),
27
27
  gtU as (>),
28
- ltU as (<)
28
+ ltU as (<),
29
29
  } from "runtime/unsafe/wasmi32"
30
30
  import Tags from "runtime/unsafe/tags"
31
31
  import Memory from "runtime/unsafe/memory"
@@ -55,17 +55,17 @@ let n = 0xe6546b64n
55
55
 
56
56
  let mut h = seed
57
57
 
58
- let hash32 = (k) => {
58
+ let hash32 = k => {
59
59
  let mut k = k * c1
60
60
  k = WasmI32.rotl(k, r1)
61
61
  k *= c2
62
62
 
63
63
  h = h ^ k
64
64
  h = WasmI32.rotl(h, r2)
65
- h = (h * m) + n
65
+ h = h * m + n
66
66
  }
67
67
 
68
- let hashRemaining = (r) => {
68
+ let hashRemaining = r => {
69
69
  // Note: wasm is little-endian so no swap is necessary
70
70
 
71
71
  let mut r = r * c1
@@ -75,14 +75,14 @@ let hashRemaining = (r) => {
75
75
  h = h ^ r
76
76
  }
77
77
 
78
- let finalize = (len) => {
78
+ let finalize = len => {
79
79
  h = h ^ len
80
80
 
81
- h = h ^ (h >>> 16n)
81
+ h = h ^ h >>> 16n
82
82
  h *= 0x85ebca6bn
83
- h = h ^ (h >>> 13n)
83
+ h = h ^ h >>> 13n
84
84
  h *= 0xc2b2ae35n
85
- h = h ^ (h >>> 16n)
85
+ h = h ^ h >>> 16n
86
86
  }
87
87
 
88
88
  let rec hashOne = (val, depth) => {
@@ -90,10 +90,14 @@ let rec hashOne = (val, depth) => {
90
90
  void
91
91
  } else if ((val & Tags._GRAIN_NUMBER_TAG_MASK) != 0n) {
92
92
  hash32(val)
93
- } else if ((val & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE) {
93
+ } else if (
94
+ (val & Tags._GRAIN_GENERIC_TAG_MASK) == Tags._GRAIN_GENERIC_HEAP_TAG_TYPE
95
+ ) {
94
96
  let heapPtr = val
95
97
  match (WasmI32.load(heapPtr, 0n)) {
96
- t when t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG => {
98
+ t when (
99
+ t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
100
+ ) => {
97
101
  let length = WasmI32.load(heapPtr, 4n)
98
102
  let extra = length % 4n
99
103
  let l = length - extra
@@ -198,12 +202,12 @@ let rec hashOne = (val, depth) => {
198
202
  },
199
203
  _ => {
200
204
  hash32(heapPtr)
201
- }
205
+ },
202
206
  }
203
207
  },
204
208
  _ => {
205
209
  hash32(heapPtr)
206
- }
210
+ },
207
211
  }
208
212
  } else if (val == WasmI32.fromGrain(true)) {
209
213
  hash32(val)
@@ -227,7 +231,7 @@ let rec hashOne = (val, depth) => {
227
231
  *
228
232
  * @since v0.1.0
229
233
  */
230
- export let rec hash = (anything) => {
234
+ export let rec hash = anything => {
231
235
  h = seed
232
236
 
233
237
  hashOne(WasmI32.fromGrain(anything), 0n)