@grain/stdlib 0.6.5 → 0.7.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 (139) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/LICENSE +1 -1
  3. package/README.md +2 -2
  4. package/array.gr +55 -7
  5. package/array.md +123 -77
  6. package/bigint.md +30 -30
  7. package/buffer.gr +20 -53
  8. package/buffer.md +47 -47
  9. package/bytes.gr +111 -35
  10. package/bytes.md +111 -32
  11. package/char.gr +201 -99
  12. package/char.md +361 -34
  13. package/exception.gr +11 -11
  14. package/exception.md +26 -1
  15. package/float32.gr +327 -3
  16. package/float32.md +606 -19
  17. package/float64.gr +320 -3
  18. package/float64.md +606 -19
  19. package/fs.gr +1082 -0
  20. package/fs.md +630 -0
  21. package/hash.gr +142 -88
  22. package/hash.md +102 -14
  23. package/int16.md +23 -23
  24. package/int32.gr +25 -4
  25. package/int32.md +65 -30
  26. package/int64.gr +26 -1
  27. package/int64.md +65 -30
  28. package/int8.md +23 -23
  29. package/json.gr +366 -51
  30. package/json.md +418 -2
  31. package/list.gr +387 -49
  32. package/list.md +492 -69
  33. package/map.gr +20 -12
  34. package/map.md +44 -38
  35. package/marshal.gr +41 -40
  36. package/marshal.md +2 -2
  37. package/number.gr +159 -30
  38. package/number.md +215 -38
  39. package/option.md +21 -21
  40. package/package.json +5 -3
  41. package/path.gr +48 -0
  42. package/path.md +103 -12
  43. package/pervasives.gr +2 -2
  44. package/pervasives.md +37 -37
  45. package/priorityqueue.gr +7 -7
  46. package/priorityqueue.md +19 -19
  47. package/queue.gr +183 -29
  48. package/queue.md +296 -40
  49. package/random.md +6 -6
  50. package/range.gr +4 -4
  51. package/range.md +6 -6
  52. package/rational.md +16 -16
  53. package/regex.gr +52 -51
  54. package/regex.md +11 -11
  55. package/result.md +16 -16
  56. package/runtime/atof/common.md +39 -39
  57. package/runtime/atof/decimal.gr +6 -6
  58. package/runtime/atof/decimal.md +8 -8
  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 +1 -1
  71. package/runtime/dataStructures.md +33 -33
  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 +1 -1
  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 +4 -4
  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 +79 -73
  98. package/runtime/string.gr +37 -105
  99. package/runtime/string.md +3 -9
  100. package/runtime/unsafe/constants.md +24 -24
  101. package/runtime/unsafe/conv.md +13 -13
  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 +138 -138
  117. package/set.gr +18 -11
  118. package/set.md +42 -36
  119. package/stack.gr +171 -2
  120. package/stack.md +297 -15
  121. package/string.gr +352 -557
  122. package/string.md +77 -34
  123. package/uint16.gr +81 -0
  124. package/uint16.md +183 -22
  125. package/uint32.gr +25 -4
  126. package/uint32.md +63 -28
  127. package/uint64.gr +25 -5
  128. package/uint64.md +63 -28
  129. package/uint8.gr +81 -0
  130. package/uint8.md +183 -22
  131. package/uri.gr +57 -53
  132. package/uri.md +11 -12
  133. package/wasi/file.gr +67 -59
  134. package/wasi/file.md +39 -39
  135. package/wasi/process.md +5 -5
  136. package/wasi/random.md +3 -3
  137. package/wasi/time.md +4 -4
  138. package/runtime/utils/printing.gr +0 -60
  139. package/runtime/utils/printing.md +0 -26
@@ -9,300 +9,300 @@ Functions and constants included in the WasmI64 module.
9
9
  ### WasmI64.**load**
10
10
 
11
11
  ```grain
12
- load : (ptr: WasmI32, offset: WasmI32) => WasmI64
12
+ load: (ptr: WasmI32, offset: WasmI32) => WasmI64
13
13
  ```
14
14
 
15
15
  ### WasmI64.**load8S**
16
16
 
17
17
  ```grain
18
- load8S : (ptr: WasmI32, offset: WasmI32) => WasmI64
18
+ load8S: (ptr: WasmI32, offset: WasmI32) => WasmI64
19
19
  ```
20
20
 
21
21
  ### WasmI64.**load8U**
22
22
 
23
23
  ```grain
24
- load8U : (ptr: WasmI32, offset: WasmI32) => WasmI64
24
+ load8U: (ptr: WasmI32, offset: WasmI32) => WasmI64
25
25
  ```
26
26
 
27
27
  ### WasmI64.**load16S**
28
28
 
29
29
  ```grain
30
- load16S : (ptr: WasmI32, offset: WasmI32) => WasmI64
30
+ load16S: (ptr: WasmI32, offset: WasmI32) => WasmI64
31
31
  ```
32
32
 
33
33
  ### WasmI64.**load16U**
34
34
 
35
35
  ```grain
36
- load16U : (ptr: WasmI32, offset: WasmI32) => WasmI64
36
+ load16U: (ptr: WasmI32, offset: WasmI32) => WasmI64
37
37
  ```
38
38
 
39
39
  ### WasmI64.**load32S**
40
40
 
41
41
  ```grain
42
- load32S : (ptr: WasmI32, offset: WasmI32) => WasmI64
42
+ load32S: (ptr: WasmI32, offset: WasmI32) => WasmI64
43
43
  ```
44
44
 
45
45
  ### WasmI64.**load32U**
46
46
 
47
47
  ```grain
48
- load32U : (ptr: WasmI32, offset: WasmI32) => WasmI64
48
+ load32U: (ptr: WasmI32, offset: WasmI32) => WasmI64
49
49
  ```
50
50
 
51
51
  ### WasmI64.**store**
52
52
 
53
53
  ```grain
54
- store : (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
54
+ store: (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
55
55
  ```
56
56
 
57
57
  ### WasmI64.**store8**
58
58
 
59
59
  ```grain
60
- store8 : (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
60
+ store8: (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
61
61
  ```
62
62
 
63
63
  ### WasmI64.**store16**
64
64
 
65
65
  ```grain
66
- store16 : (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
66
+ store16: (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
67
67
  ```
68
68
 
69
69
  ### WasmI64.**store32**
70
70
 
71
71
  ```grain
72
- store32 : (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
72
+ store32: (ptr: WasmI32, value: WasmI64, offset: WasmI32) => Void
73
73
  ```
74
74
 
75
75
  ### WasmI64.**clz**
76
76
 
77
77
  ```grain
78
- clz : (num: WasmI64) => WasmI64
78
+ clz: (num: WasmI64) => WasmI64
79
79
  ```
80
80
 
81
81
  ### WasmI64.**ctz**
82
82
 
83
83
  ```grain
84
- ctz : (num: WasmI64) => WasmI64
84
+ ctz: (num: WasmI64) => WasmI64
85
85
  ```
86
86
 
87
87
  ### WasmI64.**popcnt**
88
88
 
89
89
  ```grain
90
- popcnt : (num: WasmI64) => WasmI64
90
+ popcnt: (num: WasmI64) => WasmI64
91
91
  ```
92
92
 
93
93
  ### WasmI64.**eqz**
94
94
 
95
95
  ```grain
96
- eqz : (num: WasmI64) => Bool
96
+ eqz: (num: WasmI64) => Bool
97
97
  ```
98
98
 
99
99
  ### WasmI64.**(+)**
100
100
 
101
101
  ```grain
102
- (+) : (left: WasmI64, right: WasmI64) => WasmI64
102
+ (+): (left: WasmI64, right: WasmI64) => WasmI64
103
103
  ```
104
104
 
105
105
  ### WasmI64.**(-)**
106
106
 
107
107
  ```grain
108
- (-) : (left: WasmI64, right: WasmI64) => WasmI64
108
+ (-): (left: WasmI64, right: WasmI64) => WasmI64
109
109
  ```
110
110
 
111
111
  ### WasmI64.**(*)**
112
112
 
113
113
  ```grain
114
- (*) : (left: WasmI64, right: WasmI64) => WasmI64
114
+ (*): (left: WasmI64, right: WasmI64) => WasmI64
115
115
  ```
116
116
 
117
117
  ### WasmI64.**(/)**
118
118
 
119
119
  ```grain
120
- (/) : (left: WasmI64, right: WasmI64) => WasmI64
120
+ (/): (left: WasmI64, right: WasmI64) => WasmI64
121
121
  ```
122
122
 
123
123
  ### WasmI64.**divU**
124
124
 
125
125
  ```grain
126
- divU : (left: WasmI64, right: WasmI64) => WasmI64
126
+ divU: (left: WasmI64, right: WasmI64) => WasmI64
127
127
  ```
128
128
 
129
129
  ### WasmI64.**remS**
130
130
 
131
131
  ```grain
132
- remS : (left: WasmI64, right: WasmI64) => WasmI64
132
+ remS: (left: WasmI64, right: WasmI64) => WasmI64
133
133
  ```
134
134
 
135
135
  ### WasmI64.**remU**
136
136
 
137
137
  ```grain
138
- remU : (left: WasmI64, right: WasmI64) => WasmI64
138
+ remU: (left: WasmI64, right: WasmI64) => WasmI64
139
139
  ```
140
140
 
141
141
  ### WasmI64.**(&)**
142
142
 
143
143
  ```grain
144
- (&) : (left: WasmI64, right: WasmI64) => WasmI64
144
+ (&): (left: WasmI64, right: WasmI64) => WasmI64
145
145
  ```
146
146
 
147
147
  ### WasmI64.**(|)**
148
148
 
149
149
  ```grain
150
- (|) : (left: WasmI64, right: WasmI64) => WasmI64
150
+ (|): (left: WasmI64, right: WasmI64) => WasmI64
151
151
  ```
152
152
 
153
153
  ### WasmI64.**(^)**
154
154
 
155
155
  ```grain
156
- (^) : (left: WasmI64, right: WasmI64) => WasmI64
156
+ (^): (left: WasmI64, right: WasmI64) => WasmI64
157
157
  ```
158
158
 
159
159
  ### WasmI64.**(<<)**
160
160
 
161
161
  ```grain
162
- (<<) : (left: WasmI64, right: WasmI64) => WasmI64
162
+ (<<): (left: WasmI64, right: WasmI64) => WasmI64
163
163
  ```
164
164
 
165
165
  ### WasmI64.**(>>>)**
166
166
 
167
167
  ```grain
168
- (>>>) : (left: WasmI64, right: WasmI64) => WasmI64
168
+ (>>>): (left: WasmI64, right: WasmI64) => WasmI64
169
169
  ```
170
170
 
171
171
  ### WasmI64.**(>>)**
172
172
 
173
173
  ```grain
174
- (>>) : (left: WasmI64, right: WasmI64) => WasmI64
174
+ (>>): (left: WasmI64, right: WasmI64) => WasmI64
175
175
  ```
176
176
 
177
177
  ### WasmI64.**rotl**
178
178
 
179
179
  ```grain
180
- rotl : (left: WasmI64, right: WasmI64) => WasmI64
180
+ rotl: (left: WasmI64, right: WasmI64) => WasmI64
181
181
  ```
182
182
 
183
183
  ### WasmI64.**rotr**
184
184
 
185
185
  ```grain
186
- rotr : (left: WasmI64, right: WasmI64) => WasmI64
186
+ rotr: (left: WasmI64, right: WasmI64) => WasmI64
187
187
  ```
188
188
 
189
189
  ### WasmI64.**(==)**
190
190
 
191
191
  ```grain
192
- (==) : (left: WasmI64, right: WasmI64) => Bool
192
+ (==): (left: WasmI64, right: WasmI64) => Bool
193
193
  ```
194
194
 
195
195
  ### WasmI64.**(!=)**
196
196
 
197
197
  ```grain
198
- (!=) : (left: WasmI64, right: WasmI64) => Bool
198
+ (!=): (left: WasmI64, right: WasmI64) => Bool
199
199
  ```
200
200
 
201
201
  ### WasmI64.**(<)**
202
202
 
203
203
  ```grain
204
- (<) : (left: WasmI64, right: WasmI64) => Bool
204
+ (<): (left: WasmI64, right: WasmI64) => Bool
205
205
  ```
206
206
 
207
207
  ### WasmI64.**ltU**
208
208
 
209
209
  ```grain
210
- ltU : (left: WasmI64, right: WasmI64) => Bool
210
+ ltU: (left: WasmI64, right: WasmI64) => Bool
211
211
  ```
212
212
 
213
213
  ### WasmI64.**(<=)**
214
214
 
215
215
  ```grain
216
- (<=) : (left: WasmI64, right: WasmI64) => Bool
216
+ (<=): (left: WasmI64, right: WasmI64) => Bool
217
217
  ```
218
218
 
219
219
  ### WasmI64.**leU**
220
220
 
221
221
  ```grain
222
- leU : (left: WasmI64, right: WasmI64) => Bool
222
+ leU: (left: WasmI64, right: WasmI64) => Bool
223
223
  ```
224
224
 
225
225
  ### WasmI64.**(>)**
226
226
 
227
227
  ```grain
228
- (>) : (left: WasmI64, right: WasmI64) => Bool
228
+ (>): (left: WasmI64, right: WasmI64) => Bool
229
229
  ```
230
230
 
231
231
  ### WasmI64.**gtU**
232
232
 
233
233
  ```grain
234
- gtU : (left: WasmI64, right: WasmI64) => Bool
234
+ gtU: (left: WasmI64, right: WasmI64) => Bool
235
235
  ```
236
236
 
237
237
  ### WasmI64.**(>=)**
238
238
 
239
239
  ```grain
240
- (>=) : (left: WasmI64, right: WasmI64) => Bool
240
+ (>=): (left: WasmI64, right: WasmI64) => Bool
241
241
  ```
242
242
 
243
243
  ### WasmI64.**geU**
244
244
 
245
245
  ```grain
246
- geU : (left: WasmI64, right: WasmI64) => Bool
246
+ geU: (left: WasmI64, right: WasmI64) => Bool
247
247
  ```
248
248
 
249
249
  ### WasmI64.**extendI32S**
250
250
 
251
251
  ```grain
252
- extendI32S : (num: WasmI32) => WasmI64
252
+ extendI32S: (num: WasmI32) => WasmI64
253
253
  ```
254
254
 
255
255
  ### WasmI64.**extendI32U**
256
256
 
257
257
  ```grain
258
- extendI32U : (num: WasmI32) => WasmI64
258
+ extendI32U: (num: WasmI32) => WasmI64
259
259
  ```
260
260
 
261
261
  ### WasmI64.**truncF32S**
262
262
 
263
263
  ```grain
264
- truncF32S : (num: WasmF32) => WasmI64
264
+ truncF32S: (num: WasmF32) => WasmI64
265
265
  ```
266
266
 
267
267
  ### WasmI64.**truncF32U**
268
268
 
269
269
  ```grain
270
- truncF32U : (num: WasmF32) => WasmI64
270
+ truncF32U: (num: WasmF32) => WasmI64
271
271
  ```
272
272
 
273
273
  ### WasmI64.**truncF64S**
274
274
 
275
275
  ```grain
276
- truncF64S : (num: WasmF64) => WasmI64
276
+ truncF64S: (num: WasmF64) => WasmI64
277
277
  ```
278
278
 
279
279
  ### WasmI64.**truncF64U**
280
280
 
281
281
  ```grain
282
- truncF64U : (num: WasmF64) => WasmI64
282
+ truncF64U: (num: WasmF64) => WasmI64
283
283
  ```
284
284
 
285
285
  ### WasmI64.**reinterpretF64**
286
286
 
287
287
  ```grain
288
- reinterpretF64 : (num: WasmF64) => WasmI64
288
+ reinterpretF64: (num: WasmF64) => WasmI64
289
289
  ```
290
290
 
291
291
  ### WasmI64.**extendS8**
292
292
 
293
293
  ```grain
294
- extendS8 : (num: WasmI64) => WasmI64
294
+ extendS8: (num: WasmI64) => WasmI64
295
295
  ```
296
296
 
297
297
  ### WasmI64.**extendS16**
298
298
 
299
299
  ```grain
300
- extendS16 : (num: WasmI64) => WasmI64
300
+ extendS16: (num: WasmI64) => WasmI64
301
301
  ```
302
302
 
303
303
  ### WasmI64.**extendS32**
304
304
 
305
305
  ```grain
306
- extendS32 : (num: WasmI64) => WasmI64
306
+ extendS32: (num: WasmI64) => WasmI64
307
307
  ```
308
308
 
@@ -0,0 +1,189 @@
1
+ @noPervasives
2
+ /**
3
+ * The `Utf8` module provides functions for working with UTF-8 encoded strings.
4
+ */
5
+ module Utf8
6
+
7
+ primitive (!) = "@not"
8
+ primitive (&&) = "@and"
9
+ primitive throw = "@throw"
10
+
11
+ from "runtime/unsafe/wasmi32" include WasmI32
12
+
13
+ /**
14
+ * An exception thrown when a string is not valid UTF-8.
15
+ */
16
+ provide exception MalformedUnicode
17
+
18
+ /**
19
+ * Determines if the given byte is a leading byte in a UTF-8 sequence.
20
+ *
21
+ * @param byte: The byte to check
22
+ *
23
+ * @returns `true` if the byte is a leading byte, `false` otherwise
24
+ */
25
+ @unsafe
26
+ provide let isLeadingByte = byte => {
27
+ use WasmI32.{ (&), (!=) }
28
+ (byte & 0xC0n) != 0x80n
29
+ }
30
+
31
+ /**
32
+ * Returns the total number of bytes for a UTF-8 code point given the first byte.
33
+ *
34
+ * @param byte: The first byte of the UTF-8 code point
35
+ *
36
+ * @returns The number of bytes in the UTF-8 code point
37
+ */
38
+ @unsafe
39
+ provide let utf8ByteCount = byte => {
40
+ use WasmI32.{ (&), (==) }
41
+ if ((byte & 0x80n) == 0x00n) {
42
+ 1n
43
+ } else if ((byte & 0xF0n) == 0xF0n) {
44
+ 4n
45
+ } else if ((byte & 0xE0n) == 0xE0n) {
46
+ 3n
47
+ } else {
48
+ 2n
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Returns the number of bytes required to encode the given USV as UTF-8.
54
+ *
55
+ * @param usv: The Unicode scalar value
56
+ *
57
+ * @returns The number of bytes required to encode the given USV as UTF-8
58
+ */
59
+ @unsafe
60
+ provide let usvEncodeLength = usv => {
61
+ use WasmI32.{ (<=) }
62
+ if (usv <= 0x007Fn) {
63
+ 1n
64
+ } else if (usv <= 0x07FFn) {
65
+ 2n
66
+ } else if (usv <= 0xFFFFn) {
67
+ 3n
68
+ } else {
69
+ 4n
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Returns the Unicode code point of the encoded value at the given pointer.
75
+ *
76
+ * @param ptr: The pointer to the encoded value in memory
77
+ *
78
+ * @returns The Unicode code point of the encoded value at the given pointer
79
+ *
80
+ * @throws MalformedUnicode: if the encoded value is not a valid UTF-8 sequence
81
+ */
82
+ @unsafe
83
+ provide let getCodePoint = (ptr: WasmI32) => {
84
+ // Algorithm from https://encoding.spec.whatwg.org/#utf-8-decoder
85
+ use WasmI32.{ (+), (&), (|), (<<), leU as (<=), geU as (>=), (==) }
86
+
87
+ let mut codePoint = 0n
88
+ let mut bytesSeen = 0n
89
+ let mut bytesNeeded = 0n
90
+ let mut lowerBoundary = 0x80n
91
+ let mut upperBoundary = 0xBFn
92
+
93
+ let mut offset = 0n
94
+
95
+ while (true) {
96
+ let byte = WasmI32.load8U(ptr + offset, 0n)
97
+ offset += 1n
98
+ if (bytesNeeded == 0n) {
99
+ if (byte >= 0x00n && byte <= 0x7Fn) {
100
+ return byte
101
+ } else if (byte >= 0xC2n && byte <= 0xDFn) {
102
+ bytesNeeded = 1n
103
+ codePoint = byte & 0x1Fn
104
+ } else if (byte >= 0xE0n && byte <= 0xEFn) {
105
+ if (byte == 0xE0n) lowerBoundary = 0xA0n
106
+ if (byte == 0xEDn) upperBoundary = 0x9Fn
107
+ bytesNeeded = 2n
108
+ codePoint = byte & 0xFn
109
+ } else if (byte >= 0xF0n && byte <= 0xF4n) {
110
+ if (byte == 0xF0n) lowerBoundary = 0x90n
111
+ if (byte == 0xF4n) upperBoundary = 0x8Fn
112
+ bytesNeeded = 3n
113
+ codePoint = byte & 0x7n
114
+ } else {
115
+ throw MalformedUnicode
116
+ }
117
+ continue
118
+ }
119
+ if (!(lowerBoundary <= byte && byte <= upperBoundary)) {
120
+ throw MalformedUnicode
121
+ }
122
+ lowerBoundary = 0x80n
123
+ upperBoundary = 0xBFn
124
+ codePoint = codePoint << 6n | byte & 0x3Fn
125
+ bytesSeen += 1n
126
+ if (bytesSeen == bytesNeeded) {
127
+ return codePoint
128
+ }
129
+ }
130
+ return 0n
131
+ }
132
+
133
+ /**
134
+ * Writes the given Unicode code point to the given pointer as encoded UTF-8.
135
+ *
136
+ * @param ptr: The pointer to write the UTF-8 character to
137
+ * @param codePoint: The Unicode code point to write
138
+ *
139
+ * @returns The number of bytes written
140
+ */
141
+ @unsafe
142
+ provide let writeUtf8CodePoint = (ptr, codePoint) => {
143
+ use WasmI32.{ (+), (-), (&), (|), (>>>), ltU as (<), leU as (<=), (==) }
144
+ if (codePoint <= 0x007Fn) {
145
+ // Code points in the ASCII range are written as just one byte with the
146
+ // leading bit equal to zero (0xxxxxxx). Just store the value as one byte
147
+ // directly. Note that the value is already guaranteed to start with most
148
+ // significant bit equal to zero because of the check in the if statement
149
+ // above, so there's no need to bit-mask it.
150
+ WasmI32.store8(ptr, codePoint, 0n)
151
+ 1n
152
+ } else if (codePoint <= 0x07FFn) {
153
+ // Code points in the range 0x0080..0x07FF are written as two bytes.
154
+ // The first byte has a three bit prefix of 110, followed by 5 bits of the
155
+ // codepoint. The second byte has a two bit prefix of 10, followed by 6 bits
156
+ // of the codepoint.
157
+ let high = codePoint >>> 6n & 0b000_11111n | 0b110_00000n
158
+ let low = codePoint & 0b00_111111n | 0b10_000000n
159
+ WasmI32.store8(ptr, high, 0n)
160
+ WasmI32.store8(ptr, low, 1n)
161
+ 2n
162
+ } else if (codePoint <= 0xFFFFn) {
163
+ // Code points in the range 0x0800..0xFFFF are written as three bytes.
164
+ // The first byte has a four bit prefix of 1110, followed by 4 bits of the
165
+ // codepoint. Remaining bytes each have a two bit prefix of 10, followed by
166
+ // 6 bits of the codepoint.
167
+ let high = codePoint >>> 12n & 0b0000_1111n | 0b1110_0000n
168
+ let mid = codePoint >>> 6n & 0b00_111111n | 0b10_000000n
169
+ let low = codePoint & 0b00_111111n | 0b10_000000n
170
+ WasmI32.store8(ptr, high, 0n)
171
+ WasmI32.store8(ptr, mid, 1n)
172
+ WasmI32.store8(ptr, low, 2n)
173
+ 3n
174
+ } else {
175
+ // Code points in the range 0x10000..0x10FFFF are written as four bytes.
176
+ // The first byte has a five bit prefix of 11110, followed by 3 bits of the
177
+ // codepoint. Remaining bytes each have a two bit prefix of 10, followed by
178
+ // 6 bits of the codepoint.
179
+ let high = codePoint >>> 18n & 0b00000_111n | 0b11110_000n
180
+ let mid1 = codePoint >>> 12n & 0b00_111111n | 0b10_000000n
181
+ let mid2 = codePoint >>> 6n & 0b00_111111n | 0b10_000000n
182
+ let low = codePoint & 0b00_111111n | 0b10_000000n
183
+ WasmI32.store8(ptr, high, 0n)
184
+ WasmI32.store8(ptr, mid1, 1n)
185
+ WasmI32.store8(ptr, mid2, 2n)
186
+ WasmI32.store8(ptr, low, 3n)
187
+ 4n
188
+ }
189
+ }
@@ -0,0 +1,117 @@
1
+ ---
2
+ title: Utf8
3
+ ---
4
+
5
+ The `Utf8` module provides functions for working with UTF-8 encoded strings.
6
+
7
+ ## Values
8
+
9
+ Functions and constants included in the Utf8 module.
10
+
11
+ ### Utf8.**isLeadingByte**
12
+
13
+ ```grain
14
+ isLeadingByte: (byte: WasmI32) => Bool
15
+ ```
16
+
17
+ Determines if the given byte is a leading byte in a UTF-8 sequence.
18
+
19
+ Parameters:
20
+
21
+ |param|type|description|
22
+ |-----|----|-----------|
23
+ |`byte`|`WasmI32`|The byte to check|
24
+
25
+ Returns:
26
+
27
+ |type|description|
28
+ |----|-----------|
29
+ |`Bool`|`true` if the byte is a leading byte, `false` otherwise|
30
+
31
+ ### Utf8.**utf8ByteCount**
32
+
33
+ ```grain
34
+ utf8ByteCount: (byte: WasmI32) => WasmI32
35
+ ```
36
+
37
+ Returns the total number of bytes for a UTF-8 code point given the first byte.
38
+
39
+ Parameters:
40
+
41
+ |param|type|description|
42
+ |-----|----|-----------|
43
+ |`byte`|`WasmI32`|The first byte of the UTF-8 code point|
44
+
45
+ Returns:
46
+
47
+ |type|description|
48
+ |----|-----------|
49
+ |`WasmI32`|The number of bytes in the UTF-8 code point|
50
+
51
+ ### Utf8.**usvEncodeLength**
52
+
53
+ ```grain
54
+ usvEncodeLength: (usv: WasmI32) => WasmI32
55
+ ```
56
+
57
+ Returns the number of bytes required to encode the given USV as UTF-8.
58
+
59
+ Parameters:
60
+
61
+ |param|type|description|
62
+ |-----|----|-----------|
63
+ |`usv`|`WasmI32`|The Unicode scalar value|
64
+
65
+ Returns:
66
+
67
+ |type|description|
68
+ |----|-----------|
69
+ |`WasmI32`|The number of bytes required to encode the given USV as UTF-8|
70
+
71
+ ### Utf8.**getCodePoint**
72
+
73
+ ```grain
74
+ getCodePoint: (ptr: WasmI32) => WasmI32
75
+ ```
76
+
77
+ Returns the Unicode code point of the encoded value at the given pointer.
78
+
79
+ Parameters:
80
+
81
+ |param|type|description|
82
+ |-----|----|-----------|
83
+ |`ptr`|`WasmI32`|The pointer to the encoded value in memory|
84
+
85
+ Returns:
86
+
87
+ |type|description|
88
+ |----|-----------|
89
+ |`WasmI32`|The Unicode code point of the encoded value at the given pointer|
90
+
91
+ Throws:
92
+
93
+ `MalformedUnicode`
94
+
95
+ * if the encoded value is not a valid UTF-8 sequence
96
+
97
+ ### Utf8.**writeUtf8CodePoint**
98
+
99
+ ```grain
100
+ writeUtf8CodePoint: (ptr: WasmI32, codePoint: WasmI32) => WasmI32
101
+ ```
102
+
103
+ Writes the given Unicode code point to the given pointer as encoded UTF-8.
104
+
105
+ Parameters:
106
+
107
+ |param|type|description|
108
+ |-----|----|-----------|
109
+ |`ptr`|`WasmI32`|The pointer to write the UTF-8 character to|
110
+ |`codePoint`|`WasmI32`|The Unicode code point to write|
111
+
112
+ Returns:
113
+
114
+ |type|description|
115
+ |----|-----------|
116
+ |`WasmI32`|The number of bytes written|
117
+
package/runtime/wasi.gr CHANGED
@@ -4,6 +4,8 @@ from "runtime/unsafe/wasmi32" include WasmI32
4
4
  from "exception" include Exception
5
5
  from "runtime/string" include String
6
6
  use String.{ concat as (++), toString }
7
+ from "runtime/dataStructures" include DataStructures
8
+ use DataStructures.{ untagSimpleNumber }
7
9
 
8
10
  // env
9
11
  provide foreign wasm args_get:
@@ -322,9 +324,9 @@ provide let _ENOTCAPABLE = 76n
322
324
  provide exception SystemError(Number)
323
325
 
324
326
  @disableGC
325
- provide let stringOfSystemError = code => {
327
+ provide let stringOfSystemError = (code: Number) => {
326
328
  use WasmI32.{ (==), (>>) }
327
- let n = WasmI32.fromGrain(code) >> 1n
329
+ let n = untagSimpleNumber(code)
328
330
  match (n) {
329
331
  n when n == _ESUCCESS =>
330
332
  "SystemError: No error occurred. System call completed successfully.",