@shd101wyy/yo 0.1.28 → 0.1.30
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 +15 -15
- package/.github/skills/yo-async-effects/async-effects-recipes.md +118 -121
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +33 -13
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +1 -1
- package/.github/skills/yo-syntax/SKILL.md +2 -2
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +108 -96
- package/README.md +6 -3
- package/out/cjs/index.cjs +812 -706
- package/out/cjs/yo-cli.cjs +1023 -907
- package/out/cjs/yo-lsp.cjs +836 -730
- package/out/esm/index.mjs +757 -651
- package/out/types/src/codegen/exprs/async.d.ts +2 -0
- package/out/types/src/codegen/exprs/await.d.ts +1 -0
- package/out/types/src/codegen/exprs/closures.d.ts +4 -0
- package/out/types/src/codegen/functions/context.d.ts +6 -0
- package/out/types/src/codegen/functions/declarations.d.ts +1 -1
- package/out/types/src/doc/model.d.ts +0 -1
- package/out/types/src/env.d.ts +2 -2
- package/out/types/src/evaluator/builtins/pragma.d.ts +9 -0
- package/out/types/src/evaluator/builtins/unsafe.d.ts +8 -0
- package/out/types/src/evaluator/context.d.ts +3 -1
- package/out/types/src/evaluator/exprs/{escape.d.ts → unwind.d.ts} +1 -1
- package/out/types/src/evaluator/index.d.ts +1 -1
- package/out/types/src/evaluator/memory-safety.d.ts +14 -0
- package/out/types/src/evaluator/types/flowability.d.ts +6 -0
- package/out/types/src/evaluator/types/function.d.ts +1 -2
- package/out/types/src/evaluator/utils.d.ts +0 -1
- package/out/types/src/expr-traversal.d.ts +1 -0
- package/out/types/src/expr.d.ts +9 -7
- package/out/types/src/public-safe-report.d.ts +19 -0
- package/out/types/src/tests/comptime-ref-gate.test.d.ts +1 -0
- package/out/types/src/tests/pragma-validation.test.d.ts +1 -0
- package/out/types/src/tests/public-safe-report.test.d.ts +1 -0
- package/out/types/src/tests/type-representation-pointer.test.d.ts +1 -0
- package/out/types/src/tests/unsafe-gate.test.d.ts +1 -0
- package/out/types/src/tests/unsafe-report-classify.test.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +4 -6
- package/out/types/src/types/definitions.d.ts +9 -16
- package/out/types/src/types/guards.d.ts +1 -2
- package/out/types/src/types/tags.d.ts +0 -1
- package/out/types/src/types/utils.d.ts +5 -0
- package/out/types/src/unsafe-report.d.ts +29 -0
- package/out/types/src/value.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/add-pragma-for-pointer-decls.ts +134 -0
- package/scripts/add-pragma.ts +58 -0
- package/scripts/migrate-amp-method-calls.ts +186 -0
- package/scripts/migrate-clone-calls.ts +93 -0
- package/scripts/migrate-get-unwrap.ts +166 -0
- package/scripts/migrate-index-patterns.ts +210 -0
- package/scripts/migrate-index-trait.ts +142 -0
- package/scripts/migrate-iterator.ts +150 -0
- package/scripts/migrate-self-ptr.ts +220 -0
- package/scripts/migrate-skip-pragmas.ts +109 -0
- package/scripts/migrate-tostring.ts +134 -0
- package/scripts/trim-pragma.ts +130 -0
- package/scripts/wrap-extern-calls.ts +161 -0
- package/std/alg/hash.yo +3 -2
- package/std/allocator.yo +6 -5
- package/std/async.yo +2 -2
- package/std/collections/array_list.yo +59 -40
- package/std/collections/btree_map.yo +19 -18
- package/std/collections/deque.yo +9 -8
- package/std/collections/hash_map.yo +101 -13
- package/std/collections/hash_set.yo +5 -4
- package/std/collections/linked_list.yo +39 -4
- package/std/collections/ordered_map.yo +3 -3
- package/std/collections/priority_queue.yo +14 -13
- package/std/crypto/md5.yo +2 -1
- package/std/crypto/random.yo +21 -20
- package/std/crypto/sha256.yo +2 -1
- package/std/encoding/base64.yo +18 -18
- package/std/encoding/hex.yo +5 -5
- package/std/encoding/json.yo +62 -13
- package/std/encoding/punycode.yo +24 -23
- package/std/encoding/toml.yo +4 -3
- package/std/encoding/utf16.yo +3 -3
- package/std/env.yo +43 -28
- package/std/error.yo +15 -3
- package/std/fmt/display.yo +2 -2
- package/std/fmt/index.yo +6 -5
- package/std/fmt/to_string.yo +39 -38
- package/std/fmt/writer.yo +9 -8
- package/std/fs/dir.yo +61 -66
- package/std/fs/file.yo +121 -126
- package/std/fs/metadata.yo +13 -18
- package/std/fs/temp.yo +35 -30
- package/std/fs/walker.yo +14 -19
- package/std/gc.yo +1 -0
- package/std/glob.yo +7 -7
- package/std/http/client.yo +33 -36
- package/std/http/http.yo +6 -6
- package/std/http/index.yo +4 -4
- package/std/imm/list.yo +33 -0
- package/std/imm/map.yo +2 -1
- package/std/imm/set.yo +1 -0
- package/std/imm/sorted_map.yo +1 -0
- package/std/imm/sorted_set.yo +1 -0
- package/std/imm/string.yo +27 -23
- package/std/imm/vec.yo +18 -2
- package/std/io/reader.yo +2 -1
- package/std/io/writer.yo +3 -2
- package/std/libc/assert.yo +1 -0
- package/std/libc/ctype.yo +1 -0
- package/std/libc/dirent.yo +1 -0
- package/std/libc/errno.yo +1 -0
- package/std/libc/fcntl.yo +1 -0
- package/std/libc/float.yo +1 -0
- package/std/libc/limits.yo +1 -0
- package/std/libc/math.yo +1 -0
- package/std/libc/signal.yo +1 -0
- package/std/libc/stdatomic.yo +1 -0
- package/std/libc/stdint.yo +1 -0
- package/std/libc/stdio.yo +1 -0
- package/std/libc/stdlib.yo +1 -0
- package/std/libc/string.yo +1 -0
- package/std/libc/sys/stat.yo +1 -0
- package/std/libc/time.yo +1 -0
- package/std/libc/unistd.yo +1 -0
- package/std/libc/wctype.yo +1 -0
- package/std/libc/windows.yo +2 -0
- package/std/log.yo +7 -6
- package/std/net/addr.yo +6 -5
- package/std/net/dns.yo +13 -16
- package/std/net/errors.yo +9 -9
- package/std/net/tcp.yo +71 -74
- package/std/net/udp.yo +40 -43
- package/std/os/signal.yo +5 -5
- package/std/path.yo +1 -0
- package/std/prelude.yo +377 -200
- package/std/process/command.yo +57 -46
- package/std/process/index.yo +2 -1
- package/std/regex/compiler.yo +10 -9
- package/std/regex/index.yo +41 -41
- package/std/regex/match.yo +2 -2
- package/std/regex/parser.yo +31 -31
- package/std/regex/vm.yo +42 -41
- package/std/string/string.yo +95 -40
- package/std/string/string_builder.yo +9 -9
- package/std/string/unicode.yo +50 -49
- package/std/sync/channel.yo +2 -1
- package/std/sync/cond.yo +5 -4
- package/std/sync/mutex.yo +4 -3
- package/std/sys/advise.yo +1 -0
- package/std/sys/bufio/buf_reader.yo +27 -26
- package/std/sys/bufio/buf_writer.yo +22 -21
- package/std/sys/clock.yo +1 -0
- package/std/sys/copy.yo +1 -0
- package/std/sys/dir.yo +10 -9
- package/std/sys/dns.yo +6 -5
- package/std/sys/errors.yo +12 -12
- package/std/sys/events.yo +1 -0
- package/std/sys/externs.yo +38 -37
- package/std/sys/file.yo +17 -16
- package/std/sys/future.yo +4 -3
- package/std/sys/iov.yo +1 -0
- package/std/sys/mmap.yo +1 -0
- package/std/sys/path.yo +1 -0
- package/std/sys/perm.yo +2 -1
- package/std/sys/pipe.yo +1 -0
- package/std/sys/process.yo +5 -4
- package/std/sys/signal.yo +1 -0
- package/std/sys/socketpair.yo +1 -0
- package/std/sys/sockinfo.yo +1 -0
- package/std/sys/statfs.yo +2 -1
- package/std/sys/statx.yo +1 -0
- package/std/sys/sysinfo.yo +1 -0
- package/std/sys/tcp.yo +15 -14
- package/std/sys/temp.yo +1 -0
- package/std/sys/time.yo +2 -1
- package/std/sys/timer.yo +6 -6
- package/std/sys/tty.yo +2 -1
- package/std/sys/udp.yo +13 -12
- package/std/sys/unix.yo +12 -11
- package/std/testing/bench.yo +4 -3
- package/std/thread.yo +7 -6
- package/std/time/datetime.yo +18 -15
- package/std/time/duration.yo +11 -10
- package/std/time/instant.yo +4 -4
- package/std/time/sleep.yo +1 -0
- package/std/url/index.yo +5 -5
- package/std/worker.yo +4 -3
package/std/encoding/hex.yo
CHANGED
|
@@ -48,7 +48,7 @@ _hex_encode_impl :: (fn(data : ArrayList(u8), hex_chars : str) -> String)({
|
|
|
48
48
|
out := ArrayList(u8).with_capacity(data.len() * usize(2));
|
|
49
49
|
i := usize(0);
|
|
50
50
|
while(i < data.len(), i = (i + usize(1)), {
|
|
51
|
-
b := data
|
|
51
|
+
b := data(i);
|
|
52
52
|
hi := usize((b >> u8(4)) & u8(0xF));
|
|
53
53
|
lo := usize(b & u8(0xF));
|
|
54
54
|
out.push(hex_chars.bytes(hi));
|
|
@@ -64,7 +64,7 @@ export(hex_encode);
|
|
|
64
64
|
// ============================================================================
|
|
65
65
|
// Decoding
|
|
66
66
|
// ============================================================================
|
|
67
|
-
_hex_nibble :: (fn(c : u8,
|
|
67
|
+
_hex_nibble :: (fn(c : u8, exn : Exception) -> u8)(
|
|
68
68
|
cond(
|
|
69
69
|
((c >= u8(48)) && (c <= u8(57))) => (c - u8(48)),
|
|
70
70
|
// '0'-'9'
|
|
@@ -76,7 +76,7 @@ _hex_nibble :: (fn(c : u8, using(exn : Exception)) -> u8)(
|
|
|
76
76
|
)
|
|
77
77
|
);
|
|
78
78
|
/// Decode a hexadecimal string to bytes. Throws via `Exception` on invalid input.
|
|
79
|
-
hex_decode :: (fn(s : str,
|
|
79
|
+
hex_decode :: (fn(s : str, exn : Exception) -> ArrayList(u8))({
|
|
80
80
|
cond(
|
|
81
81
|
((s.len() % usize(2)) != usize(0)) => {
|
|
82
82
|
exn.throw(dyn(EncodingError.OddLength));
|
|
@@ -86,8 +86,8 @@ hex_decode :: (fn(s : str, using(exn : Exception)) -> ArrayList(u8))({
|
|
|
86
86
|
out := ArrayList(u8).with_capacity(s.len() / usize(2));
|
|
87
87
|
i := usize(0);
|
|
88
88
|
while(i < s.len(), i = (i + usize(2)), {
|
|
89
|
-
hi := _hex_nibble(s.bytes(i));
|
|
90
|
-
lo := _hex_nibble(s.bytes(i + usize(1)));
|
|
89
|
+
hi := _hex_nibble(s.bytes(i), exn);
|
|
90
|
+
lo := _hex_nibble(s.bytes(i + usize(1)), exn);
|
|
91
91
|
out.push((hi << u8(4)) | lo);
|
|
92
92
|
});
|
|
93
93
|
out
|
package/std/encoding/json.yo
CHANGED
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
//! { json_parse, json_stringify, JsonValue } :: import "std/encoding/json";
|
|
9
9
|
//! { Exception } :: import "std/error";
|
|
10
10
|
//!
|
|
11
|
-
//!
|
|
11
|
+
//! exn := Exception(throw : ((err) -> { unwind (); }));
|
|
12
12
|
//! v := json_parse(`{"x": 1}`);
|
|
13
13
|
//! println(json_stringify(v));
|
|
14
14
|
//! ```
|
|
15
|
+
pragma(Pragma.AllowUnsafe);
|
|
15
16
|
open(import("../string"));
|
|
16
17
|
{ ArrayList } :: import("../collections/array_list");
|
|
17
18
|
{ snprintf } :: import("../libc/stdio");
|
|
@@ -30,7 +31,7 @@ JsonError :: enum(
|
|
|
30
31
|
InvalidNumber,
|
|
31
32
|
/// Invalid escape sequence in a string.
|
|
32
33
|
InvalidEscape,
|
|
33
|
-
/// Invalid Unicode
|
|
34
|
+
/// Invalid Unicode unwind in a string.
|
|
34
35
|
InvalidUnicode,
|
|
35
36
|
/// Other error with a descriptive message.
|
|
36
37
|
Other(msg : String)
|
|
@@ -90,8 +91,8 @@ impl(
|
|
|
90
91
|
i := usize(0);
|
|
91
92
|
while(i < keys.len(), i = (i + usize(1)), {
|
|
92
93
|
cond(
|
|
93
|
-
(keys
|
|
94
|
-
return(.Some(values
|
|
94
|
+
(keys(i) == key) => {
|
|
95
|
+
return(.Some(values(i)));
|
|
95
96
|
},
|
|
96
97
|
true => ()
|
|
97
98
|
);
|
|
@@ -149,7 +150,7 @@ impl(
|
|
|
149
150
|
result := ArrayList(JsonKV).new();
|
|
150
151
|
i := usize(0);
|
|
151
152
|
while(i < keys.len(), i = (i + usize(1)), {
|
|
152
|
-
result.push(JsonKV(key : keys
|
|
153
|
+
result.push(JsonKV(key : keys(i), value : values(i)));
|
|
153
154
|
});
|
|
154
155
|
.Some(result)
|
|
155
156
|
},
|
|
@@ -157,6 +158,54 @@ impl(
|
|
|
157
158
|
)
|
|
158
159
|
)
|
|
159
160
|
);
|
|
161
|
+
/// Index trait — `v(key)` returns the child JsonValue for `key`, panicking
|
|
162
|
+
/// if `v` is not an Object or the key is missing.
|
|
163
|
+
impl(
|
|
164
|
+
JsonValue,
|
|
165
|
+
Index(String)(
|
|
166
|
+
Output : JsonValue,
|
|
167
|
+
index : (fn(ref(self) : Self, key : String) -> *(Self.Output))(
|
|
168
|
+
match(
|
|
169
|
+
self,
|
|
170
|
+
.Object(keys, values) => {
|
|
171
|
+
i := usize(0);
|
|
172
|
+
while(i < keys.len(), i = (i + usize(1)), {
|
|
173
|
+
if(keys(i) == key, {
|
|
174
|
+
// SAFETY: `i` is bounded by `keys.len()` and the
|
|
175
|
+
// Object variant invariant says `values.len() ==
|
|
176
|
+
// keys.len()`, so `values.project(i)` yields a valid
|
|
177
|
+
// ref into the Rc-managed values list.
|
|
178
|
+
return(unsafe(&(values.project(i))));
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
panic("JsonValue: key not found in Object")
|
|
182
|
+
},
|
|
183
|
+
_ => panic("JsonValue: index by String requires .Object variant")
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
/// Index trait — `v(i)` returns the i-th JsonValue, panicking if `v` is
|
|
189
|
+
/// not an Array or `i` is out of bounds.
|
|
190
|
+
impl(
|
|
191
|
+
JsonValue,
|
|
192
|
+
Index(usize)(
|
|
193
|
+
Output : JsonValue,
|
|
194
|
+
index : (fn(ref(self) : Self, idx : usize) -> *(Self.Output))(
|
|
195
|
+
match(
|
|
196
|
+
self,
|
|
197
|
+
.Array(items) => {
|
|
198
|
+
assert(idx < items.len(), "JsonValue: Array index out of bounds");
|
|
199
|
+
// SAFETY: assert above bounds `idx`; `items` is the
|
|
200
|
+
// Rc-managed Array list whose storage outlives this call
|
|
201
|
+
// (ref(self) keeps `self` and therefore `items` alive).
|
|
202
|
+
return(unsafe(&(items.project(idx))));
|
|
203
|
+
},
|
|
204
|
+
_ => panic("JsonValue: index by usize requires .Array variant")
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
);
|
|
160
209
|
export(JsonValue, JsonKV);
|
|
161
210
|
// ============================================================================
|
|
162
211
|
// Parser state
|
|
@@ -364,7 +413,7 @@ impl(
|
|
|
364
413
|
num_buf.push(u8(0));
|
|
365
414
|
num_ptr := *(char)(num_buf.ptr().unwrap());
|
|
366
415
|
{ atof } :: import("../libc/stdlib");
|
|
367
|
-
val := atof(num_ptr);
|
|
416
|
+
val := unsafe(atof(num_ptr));
|
|
368
417
|
.Ok(val)
|
|
369
418
|
})
|
|
370
419
|
);
|
|
@@ -553,7 +602,7 @@ _parse_value :: (fn(p : _Parser) -> Result(JsonValue, JsonError))({
|
|
|
553
602
|
// Public API
|
|
554
603
|
// ============================================================================
|
|
555
604
|
/// Parse a JSON string into a `JsonValue` tree. Throws via `Exception` on invalid input.
|
|
556
|
-
json_parse :: (fn(s : str,
|
|
605
|
+
json_parse :: (fn(s : str, exn : Exception) -> JsonValue)({
|
|
557
606
|
p := _Parser.new(s);
|
|
558
607
|
match(
|
|
559
608
|
_parse_value(p),
|
|
@@ -570,7 +619,7 @@ _write_str_escaped :: (fn(s : String, out : ArrayList(u8)) -> unit)({
|
|
|
570
619
|
bytes := s.as_bytes();
|
|
571
620
|
i := usize(0);
|
|
572
621
|
while(i < bytes.len(), i = (i + usize(1)), {
|
|
573
|
-
b := bytes
|
|
622
|
+
b := bytes(i);
|
|
574
623
|
cond(
|
|
575
624
|
(b == u8(34)) => {
|
|
576
625
|
out.push(u8(92));
|
|
@@ -628,12 +677,12 @@ _stringify_into :: (fn(value : JsonValue, out : ArrayList(u8)) -> unit)({
|
|
|
628
677
|
.Number(n) => {
|
|
629
678
|
buf := Array(u8, usize(32)).fill(u8(0));
|
|
630
679
|
buf_ptr := &(buf(usize(0)));
|
|
631
|
-
snprintf(*(char)(buf_ptr), usize(32), "%g", n);
|
|
680
|
+
unsafe(snprintf(*(char)(buf_ptr), usize(32), "%g", n));
|
|
632
681
|
s2 := String.from_cstr(buf_ptr).unwrap();
|
|
633
682
|
bytes := s2.as_bytes();
|
|
634
683
|
i := usize(0);
|
|
635
684
|
while(i < bytes.len(), i = (i + usize(1)), {
|
|
636
|
-
out.push(bytes
|
|
685
|
+
out.push(bytes(i));
|
|
637
686
|
});
|
|
638
687
|
},
|
|
639
688
|
.Str(s) => {
|
|
@@ -649,7 +698,7 @@ _stringify_into :: (fn(value : JsonValue, out : ArrayList(u8)) -> unit)({
|
|
|
649
698
|
},
|
|
650
699
|
true => ()
|
|
651
700
|
);
|
|
652
|
-
recur(items
|
|
701
|
+
recur(items(i), out);
|
|
653
702
|
});
|
|
654
703
|
out.push(u8(93)); // ']'
|
|
655
704
|
},
|
|
@@ -663,9 +712,9 @@ _stringify_into :: (fn(value : JsonValue, out : ArrayList(u8)) -> unit)({
|
|
|
663
712
|
},
|
|
664
713
|
true => ()
|
|
665
714
|
);
|
|
666
|
-
_write_str_escaped(keys
|
|
715
|
+
_write_str_escaped(keys(i), out);
|
|
667
716
|
out.push(u8(58)); // ':'
|
|
668
|
-
recur(values
|
|
717
|
+
recur(values(i), out);
|
|
669
718
|
});
|
|
670
719
|
out.push(u8(125)); // '}'
|
|
671
720
|
}
|
package/std/encoding/punycode.yo
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
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
|
+
pragma(Pragma.AllowUnsafe);
|
|
15
16
|
open(import("../string"));
|
|
16
17
|
{ ArrayList } :: import("../collections/array_list");
|
|
17
18
|
// Punycode constants (RFC 3492 section 5)
|
|
@@ -53,25 +54,25 @@ _adapt :: (fn(delta_val : i32, num_points : i32, first_time : bool) -> i32)({
|
|
|
53
54
|
k + ((((_BASE - _TMIN) + i32(1)) * d) / (d + _SKEW))
|
|
54
55
|
});
|
|
55
56
|
// Encode a single Unicode code point as UTF-8 bytes.
|
|
56
|
-
_encode_codepoint :: (fn(cp : i32, out :
|
|
57
|
+
_encode_codepoint :: (fn(cp : i32, out : ArrayList(u8)) -> unit)(
|
|
57
58
|
cond(
|
|
58
59
|
(cp < i32(0x80)) => {
|
|
59
|
-
out
|
|
60
|
+
out.push(u8(cp));
|
|
60
61
|
},
|
|
61
62
|
(cp < i32(0x800)) => {
|
|
62
|
-
out
|
|
63
|
-
out
|
|
63
|
+
out.push(u8(i32(0xC0) | (cp >> i32(6))));
|
|
64
|
+
out.push(u8(i32(0x80) | (cp & i32(0x3F))));
|
|
64
65
|
},
|
|
65
66
|
(cp < i32(0x10000)) => {
|
|
66
|
-
out
|
|
67
|
-
out
|
|
68
|
-
out
|
|
67
|
+
out.push(u8(i32(0xE0) | (cp >> i32(12))));
|
|
68
|
+
out.push(u8(i32(0x80) | ((cp >> i32(6)) & i32(0x3F))));
|
|
69
|
+
out.push(u8(i32(0x80) | (cp & i32(0x3F))));
|
|
69
70
|
},
|
|
70
71
|
true => {
|
|
71
|
-
out
|
|
72
|
-
out
|
|
73
|
-
out
|
|
74
|
-
out
|
|
72
|
+
out.push(u8(i32(0xF0) | (cp >> i32(18))));
|
|
73
|
+
out.push(u8(i32(0x80) | ((cp >> i32(12)) & i32(0x3F))));
|
|
74
|
+
out.push(u8(i32(0x80) | ((cp >> i32(6)) & i32(0x3F))));
|
|
75
|
+
out.push(u8(i32(0x80) | (cp & i32(0x3F))));
|
|
75
76
|
}
|
|
76
77
|
)
|
|
77
78
|
);
|
|
@@ -82,7 +83,7 @@ _string_to_codepoints :: (fn(s : String) -> ArrayList(i32))({
|
|
|
82
83
|
(i : usize) = usize(0);
|
|
83
84
|
(blen : usize) = bytes.len();
|
|
84
85
|
while(i < blen, {
|
|
85
|
-
(b : i32) = i32(bytes
|
|
86
|
+
(b : i32) = i32(bytes(i));
|
|
86
87
|
(cp : i32) = i32(0);
|
|
87
88
|
(size : usize) = usize(1);
|
|
88
89
|
cond(
|
|
@@ -108,7 +109,7 @@ _string_to_codepoints :: (fn(s : String) -> ArrayList(i32))({
|
|
|
108
109
|
(j : usize) = usize(1);
|
|
109
110
|
while(j < size, {
|
|
110
111
|
if((i + j) < blen, {
|
|
111
|
-
cp = ((cp << i32(6)) | (i32(bytes
|
|
112
|
+
cp = ((cp << i32(6)) | (i32(bytes(i + j)) & i32(0x3F)));
|
|
112
113
|
});
|
|
113
114
|
j = (j + usize(1));
|
|
114
115
|
});
|
|
@@ -127,7 +128,7 @@ punycode_decode :: (fn(input : String) -> Option(String))({
|
|
|
127
128
|
(basic_end : i32) = i32(-(1));
|
|
128
129
|
(j : i32) = (input_len - i32(1));
|
|
129
130
|
while((j >= i32(0)) && (basic_end < i32(0)), {
|
|
130
|
-
if(i32(bytes
|
|
131
|
+
if(i32(bytes(usize(j))) == i32(0x2D), {
|
|
131
132
|
basic_end = j;
|
|
132
133
|
});
|
|
133
134
|
j = (j - i32(1));
|
|
@@ -139,7 +140,7 @@ punycode_decode :: (fn(input : String) -> Option(String))({
|
|
|
139
140
|
);
|
|
140
141
|
(bi : i32) = i32(0);
|
|
141
142
|
while(bi < basic_length, {
|
|
142
|
-
(cp : i32) = i32(bytes
|
|
143
|
+
(cp : i32) = i32(bytes(usize(bi)));
|
|
143
144
|
if(cp >= i32(0x80), {
|
|
144
145
|
return(.None);
|
|
145
146
|
});
|
|
@@ -162,7 +163,7 @@ punycode_decode :: (fn(input : String) -> Option(String))({
|
|
|
162
163
|
if(idx >= input_len, {
|
|
163
164
|
return(.None);
|
|
164
165
|
});
|
|
165
|
-
(digit : i32) = _decode_digit(i32(bytes
|
|
166
|
+
(digit : i32) = _decode_digit(i32(bytes(usize(idx))));
|
|
166
167
|
idx = (idx + i32(1));
|
|
167
168
|
if(digit < i32(0), {
|
|
168
169
|
return(.None);
|
|
@@ -198,7 +199,7 @@ punycode_decode :: (fn(input : String) -> Option(String))({
|
|
|
198
199
|
(result_bytes : ArrayList(u8)) = ArrayList(u8).new();
|
|
199
200
|
(ri : usize) = usize(0);
|
|
200
201
|
while(ri < output.len(), {
|
|
201
|
-
_encode_codepoint(output
|
|
202
|
+
_encode_codepoint(output(ri), result_bytes);
|
|
202
203
|
ri = (ri + usize(1));
|
|
203
204
|
});
|
|
204
205
|
.Some(String.from_bytes(result_bytes))
|
|
@@ -212,7 +213,7 @@ punycode_encode :: (fn(input : String) -> String)({
|
|
|
212
213
|
(basic_count : i32) = i32(0);
|
|
213
214
|
(ci : i32) = i32(0);
|
|
214
215
|
while(ci < cp_count, {
|
|
215
|
-
(cp : i32) = cps
|
|
216
|
+
(cp : i32) = cps(usize(ci));
|
|
216
217
|
if(cp < i32(0x80), {
|
|
217
218
|
out.push(u8(cp));
|
|
218
219
|
basic_count = (basic_count + i32(1));
|
|
@@ -231,7 +232,7 @@ punycode_encode :: (fn(input : String) -> String)({
|
|
|
231
232
|
(m : i32) = i32(0x7FFFFFFF);
|
|
232
233
|
(mi : i32) = i32(0);
|
|
233
234
|
while(mi < cp_count, {
|
|
234
|
-
(cp : i32) = cps
|
|
235
|
+
(cp : i32) = cps(usize(mi));
|
|
235
236
|
if((cp >= n) && (cp < m), {
|
|
236
237
|
m = cp;
|
|
237
238
|
});
|
|
@@ -241,7 +242,7 @@ punycode_encode :: (fn(input : String) -> String)({
|
|
|
241
242
|
n = m;
|
|
242
243
|
(ei : i32) = i32(0);
|
|
243
244
|
while(ei < cp_count, {
|
|
244
|
-
(cp : i32) = cps
|
|
245
|
+
(cp : i32) = cps(usize(ei));
|
|
245
246
|
if(cp < n, {
|
|
246
247
|
delta = (delta + i32(1));
|
|
247
248
|
});
|
|
@@ -283,7 +284,7 @@ to_unicode :: (fn(hostname : String) -> String)({
|
|
|
283
284
|
(result : String) = ``;
|
|
284
285
|
(pi : usize) = usize(0);
|
|
285
286
|
while(pi < parts.len(), {
|
|
286
|
-
(part : String) = parts
|
|
287
|
+
(part : String) = parts(pi);
|
|
287
288
|
if(pi > usize(0), {
|
|
288
289
|
result = `${result}.`;
|
|
289
290
|
});
|
|
@@ -315,7 +316,7 @@ to_ascii :: (fn(hostname : String) -> String)({
|
|
|
315
316
|
(result : String) = ``;
|
|
316
317
|
(pi : usize) = usize(0);
|
|
317
318
|
while(pi < parts.len(), {
|
|
318
|
-
(part : String) = parts
|
|
319
|
+
(part : String) = parts(pi);
|
|
319
320
|
if(pi > usize(0), {
|
|
320
321
|
result = `${result}.`;
|
|
321
322
|
});
|
|
@@ -324,7 +325,7 @@ to_ascii :: (fn(hostname : String) -> String)({
|
|
|
324
325
|
(bytes : ArrayList(u8)) = part.as_bytes();
|
|
325
326
|
(bi : usize) = usize(0);
|
|
326
327
|
while(bi < bytes.len(), {
|
|
327
|
-
if(i32(bytes
|
|
328
|
+
if(i32(bytes(bi)) >= i32(0x80), {
|
|
328
329
|
has_non_ascii = true;
|
|
329
330
|
});
|
|
330
331
|
bi = (bi + usize(1));
|
package/std/encoding/toml.yo
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
//! // Or via the encoding index:
|
|
11
11
|
//! { toml_parse, TomlValue } :: import "std/encoding";
|
|
12
12
|
//! ```
|
|
13
|
+
pragma(Pragma.AllowUnsafe);
|
|
13
14
|
open(import("../string"));
|
|
14
15
|
{ ArrayList } :: import("../collections/array_list");
|
|
15
16
|
/// TOML value type — the result of parsing a TOML document.
|
|
@@ -37,8 +38,8 @@ impl(
|
|
|
37
38
|
i := usize(0);
|
|
38
39
|
while(i < keys.len(), i = (i + usize(1)), {
|
|
39
40
|
cond(
|
|
40
|
-
(keys
|
|
41
|
-
return(.Some(values
|
|
41
|
+
(keys(i) == key) => {
|
|
42
|
+
return(.Some(values(i)));
|
|
42
43
|
},
|
|
43
44
|
true => ()
|
|
44
45
|
);
|
|
@@ -62,7 +63,7 @@ impl(
|
|
|
62
63
|
found := false;
|
|
63
64
|
while(i < len, i = (i + usize(1)), {
|
|
64
65
|
cond(
|
|
65
|
-
(keys
|
|
66
|
+
(keys(i) == key) => {
|
|
66
67
|
&(values(i)).* = value;
|
|
67
68
|
found = true;
|
|
68
69
|
},
|
package/std/encoding/utf16.yo
CHANGED
|
@@ -68,11 +68,11 @@ export(utf8_to_utf16);
|
|
|
68
68
|
///
|
|
69
69
|
/// Decodes surrogate pairs back into supplementary code points.
|
|
70
70
|
/// Throws via `Exception` on unpaired surrogates.
|
|
71
|
-
utf16_to_utf8 :: (fn(data : ArrayList(u16),
|
|
71
|
+
utf16_to_utf8 :: (fn(data : ArrayList(u16), exn : Exception) -> String)({
|
|
72
72
|
out := ArrayList(u8).new();
|
|
73
73
|
i := usize(0);
|
|
74
74
|
while(i < data.len(), {
|
|
75
|
-
w := u32(data
|
|
75
|
+
w := u32(data(i));
|
|
76
76
|
cond(
|
|
77
77
|
// Surrogate pair: high surrogate 0xD800-0xDBFF
|
|
78
78
|
((w >= u32(0xD800)) && (w <= u32(0xDBFF))) => {
|
|
@@ -82,7 +82,7 @@ utf16_to_utf8 :: (fn(data : ArrayList(u16), using(exn : Exception)) -> String)({
|
|
|
82
82
|
},
|
|
83
83
|
true => ()
|
|
84
84
|
);
|
|
85
|
-
w2 := u32(data
|
|
85
|
+
w2 := u32(data(i + usize(1)));
|
|
86
86
|
cond(
|
|
87
87
|
((w2 < u32(0xDC00)) || (w2 > u32(0xDFFF))) => {
|
|
88
88
|
exn.throw(dyn(EncodingError.InvalidChar(u8(0))));
|
package/std/env.yo
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
//!
|
|
4
4
|
//! Mirrors the layout of Rust's `std::env`. Platform/architecture detection
|
|
5
5
|
//! and child-process spawning live in `std/process`.
|
|
6
|
+
pragma(Pragma.AllowUnsafe);
|
|
6
7
|
open(import("./collections/array_list"));
|
|
7
8
|
open(import("./string"));
|
|
8
9
|
open(import("./path"));
|
|
@@ -57,7 +58,7 @@ env :: impl({
|
|
|
57
58
|
/// Returns `.None` if the variable is not set.
|
|
58
59
|
get :: (fn(name : String) -> Option(String))({
|
|
59
60
|
name_cstr := name.to_cstr().ptr().unwrap();
|
|
60
|
-
val_ptr := getenv(*(char)(name_cstr));
|
|
61
|
+
val_ptr := unsafe(getenv(*(char)(name_cstr)));
|
|
61
62
|
match(
|
|
62
63
|
val_ptr,
|
|
63
64
|
.None =>.None,
|
|
@@ -75,13 +76,13 @@ env :: impl({
|
|
|
75
76
|
{ _putenv_s } :: import("./libc/windows");
|
|
76
77
|
cond(
|
|
77
78
|
overwrite =>
|
|
78
|
-
_putenv_s(*(char)(name_cstr), *(char)(value_cstr)),
|
|
79
|
+
unsafe(_putenv_s(*(char)(name_cstr), *(char)(value_cstr))),
|
|
79
80
|
true => {
|
|
80
|
-
existing := getenv(*(char)(name_cstr));
|
|
81
|
+
existing := unsafe(getenv(*(char)(name_cstr)));
|
|
81
82
|
match(
|
|
82
83
|
existing,
|
|
83
84
|
.Some(_) => int(0),
|
|
84
|
-
.None => _putenv_s(*(char)(name_cstr), *(char)(value_cstr))
|
|
85
|
+
.None => unsafe(_putenv_s(*(char)(name_cstr), *(char)(value_cstr)))
|
|
85
86
|
)
|
|
86
87
|
}
|
|
87
88
|
)
|
|
@@ -91,7 +92,7 @@ env :: impl({
|
|
|
91
92
|
overwrite => int(1),
|
|
92
93
|
true => int(0)
|
|
93
94
|
);
|
|
94
|
-
setenv(*(char)(name_cstr), *(char)(value_cstr), overwrite_int)
|
|
95
|
+
unsafe(setenv(*(char)(name_cstr), *(char)(value_cstr), overwrite_int))
|
|
95
96
|
}
|
|
96
97
|
);
|
|
97
98
|
return(result == int(0));
|
|
@@ -105,27 +106,29 @@ cwd :: (fn() -> Result(Path, String))(
|
|
|
105
106
|
cond(
|
|
106
107
|
(platform == Platform.Windows) => {
|
|
107
108
|
{ GetCurrentDirectoryW, WideCharToMultiByte, CP_UTF8, WCHAR, DWORD } :: import("./libc/windows");
|
|
108
|
-
required_size := GetCurrentDirectoryW(ulong(0),.None);
|
|
109
|
+
required_size := unsafe(GetCurrentDirectoryW(ulong(0),.None));
|
|
109
110
|
cond(
|
|
110
111
|
(required_size == ulong(0)) =>.Err(`Failed to get current working directory on Windows`),
|
|
111
112
|
true => {
|
|
112
113
|
wbuf := *(WCHAR)(malloc(usize(required_size) * usize(2)).unwrap());
|
|
113
|
-
actual_size := GetCurrentDirectoryW(required_size,.Some(wbuf));
|
|
114
|
+
actual_size := unsafe(GetCurrentDirectoryW(required_size,.Some(wbuf)));
|
|
114
115
|
cond(
|
|
115
116
|
(actual_size == ulong(0)) => {
|
|
116
117
|
free(.Some(*(void)(wbuf)));
|
|
117
118
|
.Err(`Failed to get current working directory on Windows`)
|
|
118
119
|
},
|
|
119
120
|
true => {
|
|
120
|
-
utf8_size :=
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
utf8_size := unsafe(
|
|
122
|
+
WideCharToMultiByte(
|
|
123
|
+
CP_UTF8,
|
|
124
|
+
ulong(0),
|
|
125
|
+
.Some(wbuf),
|
|
126
|
+
i32(actual_size),
|
|
127
|
+
.None,
|
|
128
|
+
i32(0),
|
|
129
|
+
.None,
|
|
130
|
+
.None
|
|
131
|
+
)
|
|
129
132
|
);
|
|
130
133
|
cond(
|
|
131
134
|
(utf8_size <= i32(0)) => {
|
|
@@ -134,15 +137,17 @@ cwd :: (fn() -> Result(Path, String))(
|
|
|
134
137
|
},
|
|
135
138
|
true => {
|
|
136
139
|
utf8_buf := *(u8)(malloc(usize(utf8_size) + usize(1)).unwrap());
|
|
137
|
-
result :=
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
result := unsafe(
|
|
141
|
+
WideCharToMultiByte(
|
|
142
|
+
CP_UTF8,
|
|
143
|
+
ulong(0),
|
|
144
|
+
.Some(wbuf),
|
|
145
|
+
i32(actual_size),
|
|
146
|
+
.Some(utf8_buf),
|
|
147
|
+
utf8_size,
|
|
148
|
+
.None,
|
|
149
|
+
.None
|
|
150
|
+
)
|
|
146
151
|
);
|
|
147
152
|
free(.Some(*(void)(wbuf)));
|
|
148
153
|
cond(
|
|
@@ -166,9 +171,16 @@ cwd :: (fn() -> Result(Path, String))(
|
|
|
166
171
|
},
|
|
167
172
|
true => {
|
|
168
173
|
{ getcwd } :: import("./libc/unistd");
|
|
174
|
+
// 4096 is PATH_MAX on Linux/macOS and exceeds MAX_PATH (260) on Windows;
|
|
175
|
+
// the few systems with longer paths fail gracefully via the .None branch
|
|
176
|
+
// below (getcwd returns NULL and sets errno=ERANGE).
|
|
169
177
|
buf_size := usize(4096);
|
|
170
178
|
buf := *(char)(malloc(buf_size).unwrap());
|
|
171
|
-
|
|
179
|
+
// SAFETY: `buf` points at a fresh malloc'd `buf_size`-byte buffer and
|
|
180
|
+
// is freed in both branches below. `getcwd(buf, buf_size)` writes at
|
|
181
|
+
// most `buf_size - 1` bytes plus a terminating NUL, then returns either
|
|
182
|
+
// `buf` (success) or NULL (failure — buffer too small / cwd unlinked).
|
|
183
|
+
result_ptr := unsafe(getcwd(buf, buf_size));
|
|
172
184
|
match(
|
|
173
185
|
result_ptr,
|
|
174
186
|
.None => {
|
|
@@ -193,7 +205,7 @@ chdir :: (fn(path : Path) -> Result(unit, String))(
|
|
|
193
205
|
{ SetCurrentDirectoryA, BOOL } :: import("./libc/windows");
|
|
194
206
|
path_str := path.to_string();
|
|
195
207
|
path_cstr := path_str.to_cstr().ptr().unwrap();
|
|
196
|
-
result := SetCurrentDirectoryA(*(char)(path_cstr));
|
|
208
|
+
result := unsafe(SetCurrentDirectoryA(*(char)(path_cstr)));
|
|
197
209
|
cond(
|
|
198
210
|
(result == int(0)) =>.Err(`Failed to change directory to: ${path_str}`),
|
|
199
211
|
true =>.Ok(())
|
|
@@ -203,7 +215,10 @@ chdir :: (fn(path : Path) -> Result(unit, String))(
|
|
|
203
215
|
{ chdir : unix_chdir } :: import("./libc/unistd");
|
|
204
216
|
path_str := path.to_string();
|
|
205
217
|
path_cstr := path_str.to_cstr().ptr().unwrap();
|
|
206
|
-
|
|
218
|
+
// SAFETY: `unix_chdir` is libc `chdir` aliased on import;
|
|
219
|
+
// `path_cstr` is the null-terminated buffer that `to_cstr()`
|
|
220
|
+
// just produced and `path_str` keeps alive across this call.
|
|
221
|
+
result := unsafe(unix_chdir(*(char)(path_cstr)));
|
|
207
222
|
cond(
|
|
208
223
|
(result != int(0)) =>.Err(`Failed to change directory to: ${path_str}`),
|
|
209
224
|
true =>.Ok(())
|
package/std/error.yo
CHANGED
|
@@ -4,7 +4,7 @@ open(import("./fmt"));
|
|
|
4
4
|
/// Standard error trait for typed error propagation.
|
|
5
5
|
/// All error types should implement this trait along with `ToString`.
|
|
6
6
|
Error :: trait(
|
|
7
|
-
(source : (fn(self :
|
|
7
|
+
(source : (fn(ref(self) : Self) -> Option(Dyn(SelfTrait)))) ?= ((self) ->.None),
|
|
8
8
|
where(Self <: ToString)
|
|
9
9
|
);
|
|
10
10
|
export(Error);
|
|
@@ -15,15 +15,27 @@ export(AnyError);
|
|
|
15
15
|
impl(String, Error());
|
|
16
16
|
/// Non-resumable exception handling effect record.
|
|
17
17
|
/// Use `throw` to raise an `AnyError` and abort the current computation.
|
|
18
|
+
/// `throw` is `ctl(...)` — handler body may contain `unwind`, and the
|
|
19
|
+
/// handler value is frame-bound (see plans/EXPLICIT_EFFECTS.md §4).
|
|
18
20
|
Exception :: struct(
|
|
19
|
-
throw : (
|
|
21
|
+
throw : (ctl(forall(ResumeType : Type), error : AnyError) -> ResumeType)
|
|
20
22
|
);
|
|
21
23
|
export(Exception);
|
|
22
24
|
/// Creates a resumable exception effect record parameterized by the resume type.
|
|
23
25
|
/// Unlike `Exception`, the handler can return a value to resume the computation.
|
|
26
|
+
/// `throw` is still `ctl(...)` because the handler MAY choose to unwind;
|
|
27
|
+
/// regular `fn` returns are also valid via subtyping `fn <: ctl`.
|
|
24
28
|
ResumableException :: (fn(comptime(ResumeType) : Type) -> comptime(Type))(
|
|
25
29
|
struct(
|
|
26
|
-
throw : (
|
|
30
|
+
throw : (ctl(error : AnyError) -> ResumeType)
|
|
27
31
|
)
|
|
28
32
|
);
|
|
29
33
|
export(ResumableException);
|
|
34
|
+
/// Common effect bundle: Io + Exception.
|
|
35
|
+
/// Used as the effect parameter for Futures that perform Io and may throw.
|
|
36
|
+
/// Construct with `{ io, exn }`; project with `e.io` or `e.exn`.
|
|
37
|
+
IoExn :: struct(
|
|
38
|
+
io : Io,
|
|
39
|
+
exn : Exception
|
|
40
|
+
);
|
|
41
|
+
export(IoExn);
|
package/std/fmt/display.yo
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
//!
|
|
5
5
|
//! ```rust
|
|
6
6
|
//! impl(MyType, Display(
|
|
7
|
-
//! display : (fn(self:
|
|
7
|
+
//! display : (fn(ref(self) : Self, writer : Writer) -> Writer)(
|
|
8
8
|
//! writer.write_str("MyType(").write_i64(i64(self.value)).write_str(")")
|
|
9
9
|
//! )
|
|
10
10
|
//! ));
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
/// Complement to `ToString` for streaming output into an existing buffer.
|
|
15
15
|
Display :: (fn(comptime(T) : Type) -> comptime(Trait))(
|
|
16
16
|
trait(
|
|
17
|
-
display : (fn(self :
|
|
17
|
+
display : (fn(ref(self) : T, writer : Writer) -> Writer)
|
|
18
18
|
)
|
|
19
19
|
);
|
|
20
20
|
export(Display);
|
package/std/fmt/index.yo
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//! Formatted output to stdout and stderr.
|
|
2
|
+
pragma(Pragma.AllowUnsafe);
|
|
2
3
|
{ fwrite, stdout, stderr } :: import("../libc/stdio");
|
|
3
4
|
{ String } :: import("../string");
|
|
4
5
|
{ ToString } :: import("./to_string.yo");
|
|
@@ -11,11 +12,11 @@ println :: (fn(forall(T : Type), v : T, where(T <: ToString)) -> unit)({
|
|
|
11
12
|
cond(
|
|
12
13
|
(str_bytes_len > usize(0)) => {
|
|
13
14
|
str_bytes_ptr := str_bytes.ptr().unwrap();
|
|
14
|
-
fwrite(*(void)(str_bytes_ptr), usize(1), str_bytes_len, stdout);
|
|
15
|
+
unsafe(fwrite(*(void)(str_bytes_ptr), usize(1), str_bytes_len, stdout));
|
|
15
16
|
},
|
|
16
17
|
true => ()
|
|
17
18
|
);
|
|
18
|
-
fwrite(*(void)(*(u8)("\n")), usize(1), usize(1), stdout);
|
|
19
|
+
unsafe(fwrite(*(void)(*(u8)("\n")), usize(1), usize(1), stdout));
|
|
19
20
|
});
|
|
20
21
|
export(println);
|
|
21
22
|
/// Print a value that implements `ToString` to stdout, without a trailing newline.
|
|
@@ -26,7 +27,7 @@ print :: (fn(forall(T : Type), v : T, where(T <: ToString)) -> unit)({
|
|
|
26
27
|
cond(
|
|
27
28
|
(str_bytes_len > usize(0)) => {
|
|
28
29
|
str_bytes_ptr := str_bytes.ptr().unwrap();
|
|
29
|
-
fwrite(*(void)(str_bytes_ptr), usize(1), str_bytes_len, stdout);
|
|
30
|
+
unsafe(fwrite(*(void)(str_bytes_ptr), usize(1), str_bytes_len, stdout));
|
|
30
31
|
},
|
|
31
32
|
true => ()
|
|
32
33
|
);
|
|
@@ -40,11 +41,11 @@ eprintln :: (fn(forall(T : Type), v : T, where(T <: ToString)) -> unit)({
|
|
|
40
41
|
cond(
|
|
41
42
|
(str_bytes_len > usize(0)) => {
|
|
42
43
|
str_bytes_ptr := str_bytes.ptr().unwrap();
|
|
43
|
-
fwrite(*(void)(str_bytes_ptr), usize(1), str_bytes_len, stderr);
|
|
44
|
+
unsafe(fwrite(*(void)(str_bytes_ptr), usize(1), str_bytes_len, stderr));
|
|
44
45
|
},
|
|
45
46
|
true => ()
|
|
46
47
|
);
|
|
47
|
-
fwrite(*(void)(*(u8)("\n")), usize(1), usize(1), stderr);
|
|
48
|
+
unsafe(fwrite(*(void)(*(u8)("\n")), usize(1), usize(1), stderr));
|
|
48
49
|
});
|
|
49
50
|
export(eprintln);
|
|
50
51
|
/// Print a value that implements `ToString` to stderr, without a trailing newline.
|