@shd101wyy/yo 0.1.26 → 0.1.27
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/.github/skills/yo-async-effects/SKILL.md +4 -4
- package/.github/skills/yo-async-effects/async-effects-recipes.md +34 -34
- package/.github/skills/yo-core-patterns/SKILL.md +1 -1
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +26 -26
- package/.github/skills/yo-project-workflow/SKILL.md +6 -3
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +34 -11
- package/.github/skills/yo-syntax/SKILL.md +7 -6
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +73 -60
- package/.github/skills/yo-wasm-integration/wasm-integration-cheatsheet.md +3 -3
- package/README.md +10 -8
- package/out/cjs/index.cjs +456 -438
- package/out/cjs/yo-cli.cjs +576 -543
- package/out/cjs/yo-lsp.cjs +559 -532
- package/out/esm/index.mjs +281 -263
- package/out/types/src/formatter.d.ts +11 -0
- package/out/types/src/lsp/formatting.d.ts +2 -0
- package/out/types/src/tests/formatter.test.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/alg/hash.yo +13 -21
- package/std/allocator.yo +25 -40
- package/std/async.yo +3 -7
- package/std/build.yo +105 -151
- package/std/cli/arg_parser.yo +184 -169
- package/std/collections/array_list.yo +350 -314
- package/std/collections/btree_map.yo +142 -131
- package/std/collections/deque.yo +132 -128
- package/std/collections/hash_map.yo +542 -566
- package/std/collections/hash_set.yo +623 -687
- package/std/collections/linked_list.yo +275 -293
- package/std/collections/ordered_map.yo +113 -85
- package/std/collections/priority_queue.yo +73 -73
- package/std/crypto/md5.yo +191 -95
- package/std/crypto/random.yo +56 -64
- package/std/crypto/sha256.yo +151 -107
- package/std/encoding/base64.yo +87 -81
- package/std/encoding/hex.yo +43 -50
- package/std/encoding/html.yo +56 -81
- package/std/encoding/html_char_utils.yo +7 -13
- package/std/encoding/html_entities.yo +2248 -2253
- package/std/encoding/json.yo +316 -224
- package/std/encoding/punycode.yo +86 -116
- package/std/encoding/toml.yo +67 -66
- package/std/encoding/utf16.yo +37 -44
- package/std/env.yo +62 -91
- package/std/error.yo +7 -15
- package/std/fmt/display.yo +5 -9
- package/std/fmt/index.yo +8 -14
- package/std/fmt/to_string.yo +330 -315
- package/std/fmt/writer.yo +58 -87
- package/std/fs/dir.yo +83 -102
- package/std/fs/file.yo +147 -180
- package/std/fs/metadata.yo +45 -78
- package/std/fs/temp.yo +55 -65
- package/std/fs/types.yo +27 -40
- package/std/fs/walker.yo +53 -68
- package/std/gc.yo +5 -8
- package/std/glob.yo +30 -43
- package/std/http/client.yo +107 -120
- package/std/http/http.yo +106 -96
- package/std/http/index.yo +4 -6
- package/std/imm/list.yo +88 -93
- package/std/imm/map.yo +528 -464
- package/std/imm/set.yo +52 -57
- package/std/imm/sorted_map.yo +340 -286
- package/std/imm/sorted_set.yo +57 -63
- package/std/imm/string.yo +404 -345
- package/std/imm/vec.yo +173 -181
- package/std/io/reader.yo +3 -6
- package/std/io/writer.yo +4 -8
- package/std/libc/assert.yo +5 -9
- package/std/libc/ctype.yo +32 -22
- package/std/libc/dirent.yo +26 -25
- package/std/libc/errno.yo +164 -90
- package/std/libc/fcntl.yo +52 -45
- package/std/libc/float.yo +66 -44
- package/std/libc/limits.yo +42 -33
- package/std/libc/math.yo +53 -82
- package/std/libc/signal.yo +72 -47
- package/std/libc/stdatomic.yo +217 -188
- package/std/libc/stdint.yo +5 -29
- package/std/libc/stdio.yo +5 -29
- package/std/libc/stdlib.yo +32 -39
- package/std/libc/string.yo +5 -23
- package/std/libc/sys/stat.yo +58 -56
- package/std/libc/time.yo +5 -19
- package/std/libc/unistd.yo +5 -20
- package/std/libc/wctype.yo +6 -9
- package/std/libc/windows.yo +26 -30
- package/std/log.yo +41 -55
- package/std/net/addr.yo +102 -97
- package/std/net/dns.yo +27 -28
- package/std/net/errors.yo +50 -49
- package/std/net/tcp.yo +113 -124
- package/std/net/udp.yo +55 -66
- package/std/os/env.yo +35 -33
- package/std/os/signal.yo +15 -25
- package/std/path.yo +276 -311
- package/std/prelude.yo +6304 -4315
- package/std/process/command.yo +87 -103
- package/std/process/index.yo +12 -31
- package/std/regex/compiler.yo +196 -95
- package/std/regex/flags.yo +58 -39
- package/std/regex/index.yo +157 -173
- package/std/regex/match.yo +20 -31
- package/std/regex/node.yo +134 -152
- package/std/regex/parser.yo +283 -259
- package/std/regex/unicode.yo +172 -202
- package/std/regex/vm.yo +155 -171
- package/std/string/index.yo +5 -7
- package/std/string/rune.yo +45 -55
- package/std/string/string.yo +937 -964
- package/std/string/string_builder.yo +94 -104
- package/std/string/unicode.yo +46 -64
- package/std/sync/channel.yo +72 -73
- package/std/sync/cond.yo +31 -36
- package/std/sync/mutex.yo +30 -32
- package/std/sync/once.yo +13 -16
- package/std/sync/rwlock.yo +26 -31
- package/std/sync/waitgroup.yo +20 -25
- package/std/sys/advise.yo +16 -24
- package/std/sys/bufio/buf_reader.yo +77 -93
- package/std/sys/bufio/buf_writer.yo +52 -65
- package/std/sys/clock.yo +4 -9
- package/std/sys/constants.yo +77 -61
- package/std/sys/copy.yo +4 -10
- package/std/sys/dir.yo +26 -43
- package/std/sys/dns.yo +41 -61
- package/std/sys/errors.yo +95 -103
- package/std/sys/events.yo +45 -57
- package/std/sys/externs.yo +319 -267
- package/std/sys/fallocate.yo +7 -11
- package/std/sys/fcntl.yo +14 -22
- package/std/sys/file.yo +26 -40
- package/std/sys/future.yo +5 -8
- package/std/sys/iov.yo +12 -25
- package/std/sys/lock.yo +12 -13
- package/std/sys/mmap.yo +38 -43
- package/std/sys/path.yo +3 -8
- package/std/sys/perm.yo +7 -21
- package/std/sys/pipe.yo +5 -12
- package/std/sys/process.yo +23 -29
- package/std/sys/seek.yo +10 -12
- package/std/sys/signal.yo +7 -13
- package/std/sys/signals.yo +52 -35
- package/std/sys/socket.yo +63 -58
- package/std/sys/socketpair.yo +3 -6
- package/std/sys/sockinfo.yo +11 -20
- package/std/sys/statfs.yo +11 -34
- package/std/sys/statx.yo +25 -52
- package/std/sys/sysinfo.yo +15 -20
- package/std/sys/tcp.yo +62 -92
- package/std/sys/temp.yo +5 -9
- package/std/sys/time.yo +5 -15
- package/std/sys/timer.yo +6 -11
- package/std/sys/tty.yo +10 -18
- package/std/sys/udp.yo +22 -39
- package/std/sys/umask.yo +3 -6
- package/std/sys/unix.yo +33 -52
- package/std/testing/bench.yo +49 -52
- package/std/thread.yo +10 -15
- package/std/time/datetime.yo +105 -89
- package/std/time/duration.yo +43 -56
- package/std/time/instant.yo +13 -18
- package/std/time/sleep.yo +5 -9
- package/std/url/index.yo +184 -209
- package/std/worker.yo +6 -10
package/std/encoding/punycode.yo
CHANGED
|
@@ -12,10 +12,8 @@
|
|
|
12
12
|
//! ascii_domain := to_ascii(`münchen.de`); // "xn--mnchen-3ya.de"
|
|
13
13
|
//! unicode_domain := to_unicode(ascii_domain); // "münchen.de"
|
|
14
14
|
//! ```
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{ ArrayList } :: import "../collections/array_list";
|
|
18
|
-
|
|
15
|
+
open(import("../string"));
|
|
16
|
+
{ ArrayList } :: import("../collections/array_list");
|
|
19
17
|
// Punycode constants (RFC 3492 section 5)
|
|
20
18
|
_BASE :: i32(36);
|
|
21
19
|
_TMIN :: i32(1);
|
|
@@ -24,71 +22,66 @@ _SKEW :: i32(38);
|
|
|
24
22
|
_DAMP :: i32(700);
|
|
25
23
|
_INITIAL_BIAS :: i32(72);
|
|
26
24
|
_INITIAL_N :: i32(128);
|
|
27
|
-
|
|
28
25
|
// Decode a single punycode digit character to its value.
|
|
29
|
-
_decode_digit :: (fn(cp: i32) -> i32)(
|
|
26
|
+
_decode_digit :: (fn(cp : i32) -> i32)(
|
|
30
27
|
cond(
|
|
31
28
|
((cp >= i32(0x30)) && (cp <= i32(0x39))) => (cp - i32(22)),
|
|
32
29
|
((cp >= i32(0x41)) && (cp <= i32(0x5A))) => (cp - i32(0x41)),
|
|
33
30
|
((cp >= i32(0x61)) && (cp <= i32(0x7A))) => (cp - i32(0x61)),
|
|
34
|
-
true => i32(-1)
|
|
31
|
+
true => i32(-(1))
|
|
35
32
|
)
|
|
36
33
|
);
|
|
37
|
-
|
|
38
34
|
// Encode a digit value to its punycode character.
|
|
39
|
-
_encode_digit :: (fn(d: i32) -> u8)(
|
|
35
|
+
_encode_digit :: (fn(d : i32) -> u8)(
|
|
40
36
|
cond(
|
|
41
|
-
(d < i32(26)) => u8(
|
|
42
|
-
true => u8((
|
|
37
|
+
(d < i32(26)) => u8(d + i32(0x61)),
|
|
38
|
+
true => u8((d - i32(26)) + i32(0x30))
|
|
43
39
|
)
|
|
44
40
|
);
|
|
45
|
-
|
|
46
41
|
// Bias adaptation function (RFC 3492 section 3.4)
|
|
47
|
-
_adapt :: (fn(delta_val: i32, num_points: i32, first_time: bool) -> i32)({
|
|
42
|
+
_adapt :: (fn(delta_val : i32, num_points : i32, first_time : bool) -> i32)({
|
|
48
43
|
(d : i32) = cond(
|
|
49
44
|
first_time => (delta_val / _DAMP),
|
|
50
45
|
true => (delta_val / i32(2))
|
|
51
46
|
);
|
|
52
47
|
d = (d + (d / num_points));
|
|
53
48
|
(k : i32) = i32(0);
|
|
54
|
-
while
|
|
49
|
+
while(d > (((_BASE - _TMIN) * _TMAX) / i32(2)), {
|
|
55
50
|
d = (d / (_BASE - _TMIN));
|
|
56
51
|
k = (k + _BASE);
|
|
57
|
-
};
|
|
58
|
-
|
|
52
|
+
});
|
|
53
|
+
k + ((((_BASE - _TMIN) + i32(1)) * d) / (d + _SKEW))
|
|
59
54
|
});
|
|
60
|
-
|
|
61
55
|
// Encode a single Unicode code point as UTF-8 bytes.
|
|
62
|
-
_encode_codepoint :: (fn(cp: i32, out: *(ArrayList(u8))) -> unit)(
|
|
56
|
+
_encode_codepoint :: (fn(cp : i32, out : *(ArrayList(u8))) -> unit)(
|
|
63
57
|
cond(
|
|
64
58
|
(cp < i32(0x80)) => {
|
|
65
59
|
out.*.push(u8(cp));
|
|
66
60
|
},
|
|
67
61
|
(cp < i32(0x800)) => {
|
|
68
|
-
out.*.push(u8(
|
|
69
|
-
out.*.push(u8(
|
|
62
|
+
out.*.push(u8(i32(0xC0) | (cp >> i32(6))));
|
|
63
|
+
out.*.push(u8(i32(0x80) | (cp & i32(0x3F))));
|
|
70
64
|
},
|
|
71
65
|
(cp < i32(0x10000)) => {
|
|
72
|
-
out.*.push(u8(
|
|
73
|
-
out.*.push(u8(
|
|
74
|
-
out.*.push(u8(
|
|
66
|
+
out.*.push(u8(i32(0xE0) | (cp >> i32(12))));
|
|
67
|
+
out.*.push(u8(i32(0x80) | ((cp >> i32(6)) & i32(0x3F))));
|
|
68
|
+
out.*.push(u8(i32(0x80) | (cp & i32(0x3F))));
|
|
75
69
|
},
|
|
76
70
|
true => {
|
|
77
|
-
out.*.push(u8(
|
|
78
|
-
out.*.push(u8(
|
|
79
|
-
out.*.push(u8(
|
|
80
|
-
out.*.push(u8(
|
|
71
|
+
out.*.push(u8(i32(0xF0) | (cp >> i32(18))));
|
|
72
|
+
out.*.push(u8(i32(0x80) | ((cp >> i32(12)) & i32(0x3F))));
|
|
73
|
+
out.*.push(u8(i32(0x80) | ((cp >> i32(6)) & i32(0x3F))));
|
|
74
|
+
out.*.push(u8(i32(0x80) | (cp & i32(0x3F))));
|
|
81
75
|
}
|
|
82
76
|
)
|
|
83
77
|
);
|
|
84
|
-
|
|
85
78
|
// Decode a UTF-8 string into an array of code points.
|
|
86
|
-
_string_to_codepoints :: (fn(s: String) -> ArrayList(i32))({
|
|
79
|
+
_string_to_codepoints :: (fn(s : String) -> ArrayList(i32))({
|
|
87
80
|
(bytes : ArrayList(u8)) = s.as_bytes();
|
|
88
81
|
(cps : ArrayList(i32)) = ArrayList(i32).new();
|
|
89
82
|
(i : usize) = usize(0);
|
|
90
83
|
(blen : usize) = bytes.len();
|
|
91
|
-
while
|
|
84
|
+
while(i < blen, {
|
|
92
85
|
(b : i32) = i32(bytes.get(i).unwrap());
|
|
93
86
|
(cp : i32) = i32(0);
|
|
94
87
|
(size : usize) = usize(1);
|
|
@@ -113,51 +106,46 @@ _string_to_codepoints :: (fn(s: String) -> ArrayList(i32))({
|
|
|
113
106
|
}
|
|
114
107
|
);
|
|
115
108
|
(j : usize) = usize(1);
|
|
116
|
-
while
|
|
117
|
-
if((
|
|
118
|
-
cp = ((cp << i32(6)) | (i32(bytes.get(
|
|
109
|
+
while(j < size, {
|
|
110
|
+
if((i + j) < blen, {
|
|
111
|
+
cp = ((cp << i32(6)) | (i32(bytes.get(i + j).unwrap()) & i32(0x3F)));
|
|
119
112
|
});
|
|
120
113
|
j = (j + usize(1));
|
|
121
|
-
};
|
|
114
|
+
});
|
|
122
115
|
cps.push(cp);
|
|
123
116
|
i = (i + size);
|
|
124
|
-
};
|
|
117
|
+
});
|
|
125
118
|
cps
|
|
126
119
|
});
|
|
127
|
-
|
|
128
120
|
/// Decode a punycode-encoded string (without the `xn--` prefix).
|
|
129
121
|
///
|
|
130
122
|
/// Returns `.Some(decoded)` on success, `.None` on invalid input.
|
|
131
|
-
punycode_decode :: (fn(input: String) -> Option(String))({
|
|
123
|
+
punycode_decode :: (fn(input : String) -> Option(String))({
|
|
132
124
|
(bytes : ArrayList(u8)) = input.as_bytes();
|
|
133
125
|
(input_len : i32) = i32(bytes.len());
|
|
134
|
-
|
|
135
126
|
// Find the last '-' separator
|
|
136
|
-
(basic_end : i32) = i32(-1);
|
|
127
|
+
(basic_end : i32) = i32(-(1));
|
|
137
128
|
(j : i32) = (input_len - i32(1));
|
|
138
|
-
while
|
|
139
|
-
if(
|
|
129
|
+
while((j >= i32(0)) && (basic_end < i32(0)), {
|
|
130
|
+
if(i32(bytes.get(usize(j)).unwrap()) == i32(0x2D), {
|
|
140
131
|
basic_end = j;
|
|
141
132
|
});
|
|
142
133
|
j = (j - i32(1));
|
|
143
|
-
};
|
|
144
|
-
|
|
134
|
+
});
|
|
145
135
|
(output : ArrayList(i32)) = ArrayList(i32).new();
|
|
146
136
|
(basic_length : i32) = cond(
|
|
147
137
|
(basic_end >= i32(0)) => basic_end,
|
|
148
138
|
true => i32(0)
|
|
149
139
|
);
|
|
150
|
-
|
|
151
140
|
(bi : i32) = i32(0);
|
|
152
|
-
while
|
|
141
|
+
while(bi < basic_length, {
|
|
153
142
|
(cp : i32) = i32(bytes.get(usize(bi)).unwrap());
|
|
154
|
-
if(
|
|
155
|
-
return
|
|
143
|
+
if(cp >= i32(0x80), {
|
|
144
|
+
return(.None);
|
|
156
145
|
});
|
|
157
146
|
output.push(cp);
|
|
158
147
|
bi = (bi + i32(1));
|
|
159
|
-
};
|
|
160
|
-
|
|
148
|
+
});
|
|
161
149
|
(idx : i32) = cond(
|
|
162
150
|
(basic_end >= i32(0)) => (basic_end + i32(1)),
|
|
163
151
|
true => i32(0)
|
|
@@ -165,161 +153,145 @@ punycode_decode :: (fn(input: String) -> Option(String))({
|
|
|
165
153
|
(n : i32) = _INITIAL_N;
|
|
166
154
|
(bias : i32) = _INITIAL_BIAS;
|
|
167
155
|
(i_val : i32) = i32(0);
|
|
168
|
-
|
|
169
|
-
while (idx < input_len), {
|
|
156
|
+
while(idx < input_len, {
|
|
170
157
|
(old_i : i32) = i_val;
|
|
171
158
|
(w : i32) = i32(1);
|
|
172
159
|
(k : i32) = _BASE;
|
|
173
160
|
(decode_done : bool) = false;
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return .None;
|
|
161
|
+
while(!(decode_done), {
|
|
162
|
+
if(idx >= input_len, {
|
|
163
|
+
return(.None);
|
|
178
164
|
});
|
|
179
165
|
(digit : i32) = _decode_digit(i32(bytes.get(usize(idx)).unwrap()));
|
|
180
166
|
idx = (idx + i32(1));
|
|
181
|
-
if(
|
|
182
|
-
return
|
|
167
|
+
if(digit < i32(0), {
|
|
168
|
+
return(.None);
|
|
183
169
|
});
|
|
184
|
-
|
|
185
170
|
i_val = (i_val + (digit * w));
|
|
186
|
-
|
|
187
171
|
(t : i32) = cond(
|
|
188
172
|
(k <= bias) => _TMIN,
|
|
189
173
|
(k >= (bias + _TMAX)) => _TMAX,
|
|
190
174
|
true => (k - bias)
|
|
191
175
|
);
|
|
192
|
-
|
|
193
|
-
if((digit < t), {
|
|
176
|
+
if(digit < t, {
|
|
194
177
|
decode_done = true;
|
|
195
178
|
}, {
|
|
196
179
|
w = (w * (_BASE - t));
|
|
197
180
|
k = (k + _BASE);
|
|
198
181
|
});
|
|
199
|
-
};
|
|
200
|
-
|
|
182
|
+
});
|
|
201
183
|
(out_len : i32) = (i32(output.len()) + i32(1));
|
|
202
|
-
bias = _adapt(
|
|
184
|
+
bias = _adapt(i_val - old_i, out_len, old_i == i32(0));
|
|
203
185
|
n = (n + (i_val / out_len));
|
|
204
186
|
i_val = (i_val % out_len);
|
|
205
|
-
|
|
206
187
|
// Insert code point at position i_val
|
|
207
188
|
output.push(i32(0));
|
|
208
189
|
(shift_idx : i32) = (i32(output.len()) - i32(1));
|
|
209
|
-
while
|
|
210
|
-
&(output(usize(shift_idx))).* = output(usize(
|
|
190
|
+
while(shift_idx > i_val, {
|
|
191
|
+
&(output(usize(shift_idx))).* = output(usize(shift_idx - i32(1)));
|
|
211
192
|
shift_idx = (shift_idx - i32(1));
|
|
212
|
-
};
|
|
193
|
+
});
|
|
213
194
|
&(output(usize(i_val))).* = n;
|
|
214
195
|
i_val = (i_val + i32(1));
|
|
215
|
-
};
|
|
216
|
-
|
|
196
|
+
});
|
|
217
197
|
// Convert code points to UTF-8
|
|
218
198
|
(result_bytes : ArrayList(u8)) = ArrayList(u8).new();
|
|
219
199
|
(ri : usize) = usize(0);
|
|
220
|
-
while
|
|
221
|
-
_encode_codepoint(output.get(ri).unwrap(), (
|
|
200
|
+
while(ri < output.len(), {
|
|
201
|
+
_encode_codepoint(output.get(ri).unwrap(), &(result_bytes));
|
|
222
202
|
ri = (ri + usize(1));
|
|
223
|
-
};
|
|
203
|
+
});
|
|
224
204
|
.Some(String.from_bytes(result_bytes))
|
|
225
205
|
});
|
|
226
|
-
|
|
227
206
|
/// Encode a Unicode string to punycode (without the `xn--` prefix).
|
|
228
|
-
punycode_encode :: (fn(input: String) -> String)({
|
|
207
|
+
punycode_encode :: (fn(input : String) -> String)({
|
|
229
208
|
(cps : ArrayList(i32)) = _string_to_codepoints(input);
|
|
230
209
|
(cp_count : i32) = i32(cps.len());
|
|
231
|
-
|
|
232
210
|
// Separate basic and non-basic code points
|
|
233
211
|
(out : ArrayList(u8)) = ArrayList(u8).new();
|
|
234
212
|
(basic_count : i32) = i32(0);
|
|
235
213
|
(ci : i32) = i32(0);
|
|
236
|
-
while
|
|
214
|
+
while(ci < cp_count, {
|
|
237
215
|
(cp : i32) = cps.get(usize(ci)).unwrap();
|
|
238
|
-
if(
|
|
216
|
+
if(cp < i32(0x80), {
|
|
239
217
|
out.push(u8(cp));
|
|
240
218
|
basic_count = (basic_count + i32(1));
|
|
241
219
|
});
|
|
242
220
|
ci = (ci + i32(1));
|
|
243
|
-
};
|
|
244
|
-
|
|
245
|
-
if((basic_count > i32(0)), {
|
|
221
|
+
});
|
|
222
|
+
if(basic_count > i32(0), {
|
|
246
223
|
out.push(u8(0x2D));
|
|
247
224
|
});
|
|
248
|
-
|
|
249
225
|
(handled : i32) = basic_count;
|
|
250
226
|
(n : i32) = _INITIAL_N;
|
|
251
227
|
(delta : i32) = i32(0);
|
|
252
228
|
(bias : i32) = _INITIAL_BIAS;
|
|
253
|
-
|
|
254
|
-
while (handled < cp_count), {
|
|
229
|
+
while(handled < cp_count, {
|
|
255
230
|
// Find minimum code point >= n
|
|
256
231
|
(m : i32) = i32(0x7FFFFFFF);
|
|
257
232
|
(mi : i32) = i32(0);
|
|
258
|
-
while
|
|
233
|
+
while(mi < cp_count, {
|
|
259
234
|
(cp : i32) = cps.get(usize(mi)).unwrap();
|
|
260
|
-
if((
|
|
235
|
+
if((cp >= n) && (cp < m), {
|
|
261
236
|
m = cp;
|
|
262
237
|
});
|
|
263
238
|
mi = (mi + i32(1));
|
|
264
|
-
};
|
|
265
|
-
|
|
239
|
+
});
|
|
266
240
|
delta = (delta + ((m - n) * (handled + i32(1))));
|
|
267
241
|
n = m;
|
|
268
|
-
|
|
269
242
|
(ei : i32) = i32(0);
|
|
270
|
-
while
|
|
243
|
+
while(ei < cp_count, {
|
|
271
244
|
(cp : i32) = cps.get(usize(ei)).unwrap();
|
|
272
|
-
if(
|
|
245
|
+
if(cp < n, {
|
|
273
246
|
delta = (delta + i32(1));
|
|
274
247
|
});
|
|
275
|
-
if(
|
|
248
|
+
if(cp == n, {
|
|
276
249
|
(q : i32) = delta;
|
|
277
250
|
(k : i32) = _BASE;
|
|
278
251
|
(encode_done : bool) = false;
|
|
279
|
-
while
|
|
252
|
+
while(!(encode_done), {
|
|
280
253
|
(t : i32) = cond(
|
|
281
254
|
(k <= bias) => _TMIN,
|
|
282
255
|
(k >= (bias + _TMAX)) => _TMAX,
|
|
283
256
|
true => (k - bias)
|
|
284
257
|
);
|
|
285
|
-
if(
|
|
258
|
+
if(q < t, {
|
|
286
259
|
out.push(_encode_digit(q));
|
|
287
260
|
encode_done = true;
|
|
288
261
|
}, {
|
|
289
|
-
out.push(_encode_digit(
|
|
262
|
+
out.push(_encode_digit(t + ((q - t) % (_BASE - t))));
|
|
290
263
|
q = ((q - t) / (_BASE - t));
|
|
291
264
|
k = (k + _BASE);
|
|
292
265
|
});
|
|
293
|
-
};
|
|
294
|
-
bias = _adapt(delta,
|
|
266
|
+
});
|
|
267
|
+
bias = _adapt(delta, handled + i32(1), handled == basic_count);
|
|
295
268
|
delta = i32(0);
|
|
296
269
|
handled = (handled + i32(1));
|
|
297
270
|
});
|
|
298
271
|
ei = (ei + i32(1));
|
|
299
|
-
};
|
|
272
|
+
});
|
|
300
273
|
delta = (delta + i32(1));
|
|
301
274
|
n = (n + i32(1));
|
|
302
|
-
};
|
|
303
|
-
|
|
275
|
+
});
|
|
304
276
|
String.from_bytes(out)
|
|
305
277
|
});
|
|
306
|
-
|
|
307
278
|
/// Convert an IDN hostname to Unicode display form.
|
|
308
279
|
///
|
|
309
280
|
/// Splits on `.`, decodes `xn--` labels via punycode, and keeps original labels on failure.
|
|
310
|
-
to_unicode :: (fn(hostname: String) -> String)({
|
|
281
|
+
to_unicode :: (fn(hostname : String) -> String)({
|
|
311
282
|
(parts : ArrayList(String)) = hostname.split(`.`);
|
|
312
283
|
(result : String) = ``;
|
|
313
284
|
(pi : usize) = usize(0);
|
|
314
|
-
while
|
|
285
|
+
while(pi < parts.len(), {
|
|
315
286
|
(part : String) = parts.get(pi).unwrap();
|
|
316
|
-
if(
|
|
287
|
+
if(pi > usize(0), {
|
|
317
288
|
result = `${result}.`;
|
|
318
289
|
});
|
|
319
290
|
(part_lower : String) = part.to_lowercase();
|
|
320
291
|
if(part_lower.starts_with(`xn--`), {
|
|
321
292
|
(encoded : String) = part.substring(usize(4), part.len());
|
|
322
|
-
match(
|
|
293
|
+
match(
|
|
294
|
+
punycode_decode(encoded),
|
|
323
295
|
.Some(decoded) => {
|
|
324
296
|
result = `${result}${decoded}`;
|
|
325
297
|
},
|
|
@@ -332,32 +304,31 @@ to_unicode :: (fn(hostname: String) -> String)({
|
|
|
332
304
|
result = `${result}${part}`;
|
|
333
305
|
});
|
|
334
306
|
pi = (pi + usize(1));
|
|
335
|
-
};
|
|
307
|
+
});
|
|
336
308
|
result
|
|
337
309
|
});
|
|
338
|
-
|
|
339
310
|
/// Convert a Unicode hostname to ASCII-compatible encoding.
|
|
340
311
|
///
|
|
341
312
|
/// Non-ASCII labels are punycode-encoded with the `xn--` prefix.
|
|
342
|
-
to_ascii :: (fn(hostname: String) -> String)({
|
|
313
|
+
to_ascii :: (fn(hostname : String) -> String)({
|
|
343
314
|
(parts : ArrayList(String)) = hostname.split(`.`);
|
|
344
315
|
(result : String) = ``;
|
|
345
316
|
(pi : usize) = usize(0);
|
|
346
|
-
while
|
|
317
|
+
while(pi < parts.len(), {
|
|
347
318
|
(part : String) = parts.get(pi).unwrap();
|
|
348
|
-
if(
|
|
319
|
+
if(pi > usize(0), {
|
|
349
320
|
result = `${result}.`;
|
|
350
321
|
});
|
|
351
322
|
// Check if the label has non-ASCII characters
|
|
352
323
|
(has_non_ascii : bool) = false;
|
|
353
324
|
(bytes : ArrayList(u8)) = part.as_bytes();
|
|
354
325
|
(bi : usize) = usize(0);
|
|
355
|
-
while
|
|
356
|
-
if(
|
|
326
|
+
while(bi < bytes.len(), {
|
|
327
|
+
if(i32(bytes.get(bi).unwrap()) >= i32(0x80), {
|
|
357
328
|
has_non_ascii = true;
|
|
358
329
|
});
|
|
359
330
|
bi = (bi + usize(1));
|
|
360
|
-
};
|
|
331
|
+
});
|
|
361
332
|
if(has_non_ascii, {
|
|
362
333
|
(encoded : String) = punycode_encode(part);
|
|
363
334
|
result = `${result}xn--${encoded}`;
|
|
@@ -365,8 +336,7 @@ to_ascii :: (fn(hostname: String) -> String)({
|
|
|
365
336
|
result = `${result}${part}`;
|
|
366
337
|
});
|
|
367
338
|
pi = (pi + usize(1));
|
|
368
|
-
};
|
|
339
|
+
});
|
|
369
340
|
result
|
|
370
341
|
});
|
|
371
|
-
|
|
372
|
-
export punycode_decode, punycode_encode, to_unicode, to_ascii;
|
|
342
|
+
export(punycode_decode, punycode_encode, to_unicode, to_ascii);
|
package/std/encoding/toml.yo
CHANGED
|
@@ -10,60 +10,57 @@
|
|
|
10
10
|
//! // Or via the encoding index:
|
|
11
11
|
//! { toml_parse, TomlValue } :: import "std/encoding";
|
|
12
12
|
//! ```
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
{ ArrayList } :: import "../collections/array_list";
|
|
16
|
-
|
|
13
|
+
open(import("../string"));
|
|
14
|
+
{ ArrayList } :: import("../collections/array_list");
|
|
17
15
|
/// TOML value type — the result of parsing a TOML document.
|
|
18
16
|
TomlValue :: enum(
|
|
19
17
|
/// A TOML string value.
|
|
20
|
-
Str(value: String),
|
|
18
|
+
Str(value : String),
|
|
21
19
|
/// A TOML integer value.
|
|
22
|
-
Int(value: i64),
|
|
20
|
+
Int(value : i64),
|
|
23
21
|
/// A TOML boolean value.
|
|
24
|
-
Bool(value: bool),
|
|
22
|
+
Bool(value : bool),
|
|
25
23
|
/// A TOML table (ordered key-value map).
|
|
26
|
-
Table(keys: ArrayList(String), values: ArrayList(Self))
|
|
24
|
+
Table(keys : ArrayList(String), values : ArrayList(Self))
|
|
27
25
|
);
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
impl(
|
|
27
|
+
TomlValue,
|
|
30
28
|
/// Create a new empty table.
|
|
31
29
|
new_table : (fn() -> Self)(
|
|
32
|
-
Self.Table(keys: ArrayList(String).new(), values: ArrayList(TomlValue).new())
|
|
30
|
+
Self.Table(keys : ArrayList(String).new(), values : ArrayList(TomlValue).new())
|
|
33
31
|
),
|
|
34
|
-
|
|
35
32
|
/// Look up a value by key in a table. Returns `.None` if not a table or key is missing.
|
|
36
|
-
get : (fn(self: Self, key: String) -> Option(TomlValue))(
|
|
37
|
-
match(
|
|
33
|
+
get : (fn(self : Self, key : String) -> Option(TomlValue))(
|
|
34
|
+
match(
|
|
35
|
+
self,
|
|
38
36
|
.Table(keys, values) => {
|
|
39
37
|
i := usize(0);
|
|
40
|
-
while
|
|
38
|
+
while(i < keys.len(), i = (i + usize(1)), {
|
|
41
39
|
cond(
|
|
42
40
|
(keys.get(i).unwrap() == key) => {
|
|
43
|
-
return
|
|
41
|
+
return(.Some(values.get(i).unwrap()));
|
|
44
42
|
},
|
|
45
43
|
true => ()
|
|
46
44
|
);
|
|
47
|
-
};
|
|
45
|
+
});
|
|
48
46
|
.None
|
|
49
47
|
},
|
|
50
|
-
_
|
|
48
|
+
_ =>.None
|
|
51
49
|
)
|
|
52
50
|
),
|
|
53
|
-
|
|
54
51
|
/// Check whether the table contains the given key.
|
|
55
|
-
has_key : (fn(self: Self, key: String) -> bool)(
|
|
52
|
+
has_key : (fn(self : Self, key : String) -> bool)(
|
|
56
53
|
self.get(key).is_some()
|
|
57
54
|
),
|
|
58
|
-
|
|
59
55
|
/// Insert or update a key-value pair in the table.
|
|
60
|
-
set : (fn(self: Self, key: String, value: TomlValue) -> unit)(
|
|
61
|
-
match(
|
|
56
|
+
set : (fn(self : Self, key : String, value : TomlValue) -> unit)(
|
|
57
|
+
match(
|
|
58
|
+
self,
|
|
62
59
|
.Table(keys, values) => {
|
|
63
60
|
i := usize(0);
|
|
64
61
|
len := keys.len();
|
|
65
62
|
found := false;
|
|
66
|
-
while
|
|
63
|
+
while(i < len, i = (i + usize(1)), {
|
|
67
64
|
cond(
|
|
68
65
|
(keys.get(i).unwrap() == key) => {
|
|
69
66
|
&(values(i)).* = value;
|
|
@@ -71,7 +68,7 @@ impl(TomlValue,
|
|
|
71
68
|
},
|
|
72
69
|
true => ()
|
|
73
70
|
);
|
|
74
|
-
};
|
|
71
|
+
});
|
|
75
72
|
cond(
|
|
76
73
|
(!(found)) => {
|
|
77
74
|
keys.push(key);
|
|
@@ -83,70 +80,72 @@ impl(TomlValue,
|
|
|
83
80
|
_ => ()
|
|
84
81
|
)
|
|
85
82
|
),
|
|
86
|
-
|
|
87
83
|
/// Return the number of keys in the table, or `0` if not a table.
|
|
88
|
-
table_len : (fn(self: Self) -> usize)(
|
|
89
|
-
match(
|
|
84
|
+
table_len : (fn(self : Self) -> usize)(
|
|
85
|
+
match(
|
|
86
|
+
self,
|
|
90
87
|
.Table(keys, _) => keys.len(),
|
|
91
88
|
_ => usize(0)
|
|
92
89
|
)
|
|
93
90
|
),
|
|
94
|
-
|
|
95
91
|
/// Extract the string value, or `.None` if not a `Str`.
|
|
96
|
-
as_string : (fn(self: Self) -> Option(String))(
|
|
97
|
-
match(self
|
|
92
|
+
as_string : (fn(self : Self) -> Option(String))(
|
|
93
|
+
match(self,.Str(s) =>.Some(s), _ =>.None)
|
|
98
94
|
),
|
|
99
|
-
|
|
100
95
|
/// Extract the integer value, or `.None` if not an `Int`.
|
|
101
|
-
as_int : (fn(self: Self) -> Option(i64))(
|
|
102
|
-
match(self
|
|
96
|
+
as_int : (fn(self : Self) -> Option(i64))(
|
|
97
|
+
match(self,.Int(n) =>.Some(n), _ =>.None)
|
|
103
98
|
),
|
|
104
|
-
|
|
105
99
|
/// Extract the boolean value, or `.None` if not a `Bool`.
|
|
106
|
-
as_bool : (fn(self: Self) -> Option(bool))(
|
|
107
|
-
match(self
|
|
100
|
+
as_bool : (fn(self : Self) -> Option(bool))(
|
|
101
|
+
match(self,.Bool(b) =>.Some(b), _ =>.None)
|
|
108
102
|
)
|
|
109
103
|
);
|
|
110
|
-
|
|
111
|
-
_parse_toml_value :: (fn(raw: String) -> Result(TomlValue, String))({
|
|
104
|
+
_parse_toml_value :: (fn(raw : String) -> Result(TomlValue, String))({
|
|
112
105
|
trimmed := raw.trim();
|
|
113
106
|
cond(
|
|
114
|
-
trimmed.is_empty() => {
|
|
107
|
+
trimmed.is_empty() => {
|
|
108
|
+
return(.Err(`Empty value`));
|
|
109
|
+
},
|
|
115
110
|
true => ()
|
|
116
111
|
);
|
|
117
|
-
|
|
118
112
|
// Quoted string: starts and ends with "
|
|
119
113
|
cond(
|
|
120
114
|
(trimmed.starts_with(`"`) && trimmed.ends_with(`"`)) => {
|
|
121
115
|
len := trimmed.len();
|
|
122
116
|
cond(
|
|
123
|
-
(len < usize(2)) => {
|
|
117
|
+
(len < usize(2)) => {
|
|
118
|
+
return(.Err(`Unterminated string`));
|
|
119
|
+
},
|
|
124
120
|
true => {
|
|
125
|
-
return
|
|
121
|
+
return(.Ok(.Str(trimmed.substring(usize(1), len - usize(1)))));
|
|
126
122
|
}
|
|
127
123
|
);
|
|
128
124
|
},
|
|
129
125
|
true => ()
|
|
130
126
|
);
|
|
131
|
-
|
|
132
127
|
// Booleans
|
|
133
128
|
cond(
|
|
134
|
-
(trimmed == `true`) => {
|
|
135
|
-
|
|
129
|
+
(trimmed == `true`) => {
|
|
130
|
+
return(.Ok(.Bool(true)));
|
|
131
|
+
},
|
|
132
|
+
(trimmed == `false`) => {
|
|
133
|
+
return(.Ok(.Bool(false)));
|
|
134
|
+
},
|
|
136
135
|
true => ()
|
|
137
136
|
);
|
|
138
|
-
|
|
139
137
|
// Integer
|
|
140
|
-
match(
|
|
141
|
-
.
|
|
138
|
+
match(
|
|
139
|
+
trimmed.parse_i64(),
|
|
140
|
+
.Some(n) => {
|
|
141
|
+
return(.Ok(.Int(n)));
|
|
142
|
+
},
|
|
142
143
|
.None => ()
|
|
143
144
|
);
|
|
144
|
-
|
|
145
145
|
.Err(`Unknown value: ${trimmed}`)
|
|
146
146
|
});
|
|
147
|
-
|
|
148
147
|
/// Parse a TOML string into a `TomlValue` tree. Returns `Result(TomlValue, String)`.
|
|
149
|
-
toml_parse :: (fn(input: String) -> Result(TomlValue, String))({
|
|
148
|
+
toml_parse :: (fn(input : String) -> Result(TomlValue, String))({
|
|
150
149
|
root_keys := ArrayList(String).new();
|
|
151
150
|
root_vals := ArrayList(TomlValue).new();
|
|
152
151
|
cur_keys := root_keys;
|
|
@@ -154,9 +153,9 @@ toml_parse :: (fn(input: String) -> Result(TomlValue, String))({
|
|
|
154
153
|
lines := input.split(`\n`);
|
|
155
154
|
i := usize(0);
|
|
156
155
|
line_count := lines.len();
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
156
|
+
while(i < line_count, i = (i + usize(1)), {
|
|
157
|
+
match(
|
|
158
|
+
lines.get(i),
|
|
160
159
|
.Some(raw_line) => {
|
|
161
160
|
line := raw_line.trim();
|
|
162
161
|
cond(
|
|
@@ -164,26 +163,30 @@ toml_parse :: (fn(input: String) -> Result(TomlValue, String))({
|
|
|
164
163
|
line.starts_with(`#`) => (),
|
|
165
164
|
// Table header: [name]
|
|
166
165
|
(line.starts_with(`[`) && line.ends_with(`]`)) => {
|
|
167
|
-
table_name := line.substring(usize(1),
|
|
166
|
+
table_name := line.substring(usize(1), line.len() - usize(1)).trim();
|
|
168
167
|
new_keys := ArrayList(String).new();
|
|
169
168
|
new_vals := ArrayList(TomlValue).new();
|
|
170
169
|
root_keys.push(table_name);
|
|
171
|
-
root_vals.push(.Table(keys: new_keys, values: new_vals));
|
|
170
|
+
root_vals.push(.Table(keys : new_keys, values : new_vals));
|
|
172
171
|
cur_keys = new_keys;
|
|
173
172
|
cur_vals = new_vals;
|
|
174
173
|
},
|
|
175
174
|
// Key = value
|
|
176
175
|
true => {
|
|
177
|
-
match(
|
|
176
|
+
match(
|
|
177
|
+
line.index_of(`=`),
|
|
178
178
|
.Some(pos) => {
|
|
179
179
|
key := line.substring(usize(0), pos).trim();
|
|
180
|
-
val_str := line.substring(
|
|
181
|
-
match(
|
|
180
|
+
val_str := line.substring(pos + usize(1), line.len()).trim();
|
|
181
|
+
match(
|
|
182
|
+
_parse_toml_value(val_str),
|
|
182
183
|
.Ok(val) => {
|
|
183
184
|
cur_keys.push(key);
|
|
184
185
|
cur_vals.push(val);
|
|
185
186
|
},
|
|
186
|
-
.Err(e) => {
|
|
187
|
+
.Err(e) => {
|
|
188
|
+
return(.Err(e));
|
|
189
|
+
}
|
|
187
190
|
);
|
|
188
191
|
},
|
|
189
192
|
.None => ()
|
|
@@ -193,9 +196,7 @@ toml_parse :: (fn(input: String) -> Result(TomlValue, String))({
|
|
|
193
196
|
},
|
|
194
197
|
.None => ()
|
|
195
198
|
);
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
.Ok(.Table(keys: root_keys, values: root_vals))
|
|
199
|
+
});
|
|
200
|
+
.Ok(.Table(keys : root_keys, values : root_vals))
|
|
199
201
|
});
|
|
200
|
-
|
|
201
|
-
export TomlValue, toml_parse;
|
|
202
|
+
export(TomlValue, toml_parse);
|