@shd101wyy/yo 0.0.25 → 0.0.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/README.md +9 -9
- package/out/cjs/index.cjs +568 -563
- package/out/cjs/yo-cli.cjs +569 -564
- package/out/esm/index.mjs +487 -482
- package/out/types/src/codegen/async/state-machine.d.ts +1 -1
- package/out/types/src/codegen/exprs/await.d.ts +1 -0
- package/out/types/src/codegen/exprs/downcast.d.ts +3 -0
- package/out/types/src/codegen/exprs/return.d.ts +1 -0
- package/out/types/src/codegen/exprs/typeid.d.ts +3 -0
- package/out/types/src/codegen/exprs/while.d.ts +1 -1
- package/out/types/src/codegen/functions/context.d.ts +6 -18
- package/out/types/src/codegen/functions/declarations.d.ts +10 -2
- package/out/types/src/codegen/types/dyn.d.ts +1 -0
- package/out/types/src/codegen/types/generation.d.ts +1 -1
- package/out/types/src/codegen/utils/index.d.ts +1 -0
- package/out/types/src/evaluator/async/await-analysis.d.ts +1 -0
- package/out/types/src/evaluator/builtins/downcast.d.ts +8 -0
- package/out/types/src/evaluator/builtins/rc-fns.d.ts +5 -0
- package/out/types/src/evaluator/builtins/typeid.d.ts +8 -0
- package/out/types/src/evaluator/context.d.ts +2 -0
- package/out/types/src/expr.d.ts +3 -0
- package/out/types/src/function-value.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +3 -1
- package/out/types/src/types/definitions.d.ts +3 -1
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/crypto/random.yo +25 -13
- package/std/encoding/base64.yo +24 -49
- package/std/encoding/hex.yo +25 -22
- package/std/encoding/json.yo +25 -3
- package/std/encoding/utf16.yo +6 -5
- package/std/error.yo +39 -23
- package/std/fs/dir.yo +106 -103
- package/std/fs/file.yo +122 -158
- package/std/fs/metadata.yo +23 -22
- package/std/fs/temp.yo +41 -47
- package/std/fs/walker.yo +48 -55
- package/std/net/addr.yo +8 -7
- package/std/net/dns.yo +27 -33
- package/std/net/errors.yo +13 -8
- package/std/net/tcp.yo +92 -113
- package/std/net/udp.yo +50 -54
- package/std/os/signal.yo +13 -8
- package/std/prelude.yo +21 -16
- package/std/sys/errors.yo +45 -33
- package/std/url/url.yo +19 -32
- package/out/types/src/codegen/effects/effect-state-machine.d.ts +0 -34
package/package.json
CHANGED
package/std/crypto/random.yo
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
open import "../string";
|
|
16
16
|
{ snprintf } :: import "../libc/stdio";
|
|
17
17
|
{ hex_encode } :: import "../encoding/hex";
|
|
18
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
19
|
+
{ ToString } :: import "../fmt";
|
|
18
20
|
|
|
19
21
|
// ============================================================================
|
|
20
22
|
// Error type
|
|
@@ -25,6 +27,17 @@ CryptoError :: enum(
|
|
|
25
27
|
Other(msg: String)
|
|
26
28
|
);
|
|
27
29
|
|
|
30
|
+
impl(CryptoError, ToString(
|
|
31
|
+
to_string : (self ->
|
|
32
|
+
match(self,
|
|
33
|
+
.Unavailable => `crypto: platform random unavailable`,
|
|
34
|
+
.Other(msg) => `crypto error: ${msg}`
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
));
|
|
38
|
+
|
|
39
|
+
impl(CryptoError, Error());
|
|
40
|
+
|
|
28
41
|
export CryptoError;
|
|
29
42
|
|
|
30
43
|
// ============================================================================
|
|
@@ -41,26 +54,25 @@ extern "Yo",
|
|
|
41
54
|
// Fill a buffer with cryptographically secure random bytes.
|
|
42
55
|
// ============================================================================
|
|
43
56
|
|
|
44
|
-
random_bytes :: (fn(buf: *(u8), size: usize) ->
|
|
57
|
+
random_bytes :: (fn(buf: *(u8), size: usize, using(exn : Exception)) -> unit)(
|
|
45
58
|
cond(
|
|
46
59
|
(platform == Platform.Darwin) => {
|
|
47
60
|
__yo_arc4random_buf(buf, size);
|
|
48
|
-
.Ok(())
|
|
49
61
|
},
|
|
50
62
|
(platform == Platform.Win32) => {
|
|
51
63
|
r := __yo_bcrypt_gen_random(buf, u32(size));
|
|
52
64
|
cond(
|
|
53
|
-
(r == i32(0)) =>
|
|
54
|
-
true => .
|
|
55
|
-
)
|
|
65
|
+
(r == i32(0)) => (),
|
|
66
|
+
true => { exn.throw(dyn CryptoError.Unavailable); }
|
|
67
|
+
);
|
|
56
68
|
},
|
|
57
69
|
true => {
|
|
58
70
|
// Linux: getrandom syscall
|
|
59
71
|
ret := __yo_getrandom(buf, size, u32(0));
|
|
60
72
|
cond(
|
|
61
|
-
(ret < isize(0)) => .
|
|
62
|
-
true =>
|
|
63
|
-
)
|
|
73
|
+
(ret < isize(0)) => { exn.throw(dyn CryptoError.Unavailable); },
|
|
74
|
+
true => ()
|
|
75
|
+
);
|
|
64
76
|
}
|
|
65
77
|
)
|
|
66
78
|
);
|
|
@@ -71,7 +83,7 @@ export random_bytes;
|
|
|
71
83
|
// Typed helpers
|
|
72
84
|
// ============================================================================
|
|
73
85
|
|
|
74
|
-
random_u32 :: (fn() -> u32)({
|
|
86
|
+
random_u32 :: (fn(using(exn : Exception)) -> u32)({
|
|
75
87
|
buf := Array(u8, usize(4)).fill(u8(0));
|
|
76
88
|
buf_ptr := &(buf(usize(0)));
|
|
77
89
|
random_bytes(buf_ptr, usize(4));
|
|
@@ -81,18 +93,18 @@ random_u32 :: (fn() -> u32)({
|
|
|
81
93
|
(u32(buf(usize(3))) << u32(24)))
|
|
82
94
|
});
|
|
83
95
|
|
|
84
|
-
random_u64 :: (fn() -> u64)({
|
|
96
|
+
random_u64 :: (fn(using(exn : Exception)) -> u64)({
|
|
85
97
|
lo := u64(random_u32());
|
|
86
98
|
hi := u64(random_u32());
|
|
87
99
|
(lo | (hi << u64(32)))
|
|
88
100
|
});
|
|
89
101
|
|
|
90
|
-
random_f64 :: (fn() -> f64)(
|
|
102
|
+
random_f64 :: (fn(using(exn : Exception)) -> f64)(
|
|
91
103
|
(f64(random_u64()) / f64(18446744073709551615.0))
|
|
92
104
|
);
|
|
93
105
|
|
|
94
106
|
// Return a random integer in the half-open range [min, max).
|
|
95
|
-
random_range :: (fn(min: i64, max: i64) -> i64)({
|
|
107
|
+
random_range :: (fn(min: i64, max: i64, using(exn : Exception)) -> i64)({
|
|
96
108
|
span := (max - min);
|
|
97
109
|
cond(
|
|
98
110
|
(span <= i64(0)) => min,
|
|
@@ -110,7 +122,7 @@ export random_u32, random_u64, random_f64, random_range;
|
|
|
110
122
|
// ============================================================================
|
|
111
123
|
|
|
112
124
|
// Generate a random UUID v4 string: "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"
|
|
113
|
-
uuid_v4 :: (fn() -> String)({
|
|
125
|
+
uuid_v4 :: (fn(using(exn : Exception)) -> String)({
|
|
114
126
|
bytes := ArrayList(u8).with_capacity(usize(16));
|
|
115
127
|
buf := Array(u8, usize(16)).fill(u8(0));
|
|
116
128
|
buf_ptr := &(buf(usize(0)));
|
package/std/encoding/base64.yo
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
open import "../string";
|
|
12
12
|
{ ArrayList } :: import "../collections/array_list";
|
|
13
13
|
{ EncodingError } :: import "./hex";
|
|
14
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
14
15
|
|
|
15
16
|
// ============================================================================
|
|
16
17
|
// Standard alphabet
|
|
@@ -73,81 +74,55 @@ export base64_encode, base64_encode_url;
|
|
|
73
74
|
// Decoding
|
|
74
75
|
// ============================================================================
|
|
75
76
|
|
|
76
|
-
_decode_char :: (fn(c: u8, alpha: str) ->
|
|
77
|
+
_decode_char :: (fn(c: u8, alpha: str, using(exn : Exception)) -> u8)({
|
|
77
78
|
i := usize(0);
|
|
78
79
|
while (i < usize(64)), (i = (i + usize(1))), {
|
|
79
80
|
cond(
|
|
80
|
-
(alpha.bytes(i) == c) => { return
|
|
81
|
+
(alpha.bytes(i) == c) => { return u8(i); },
|
|
81
82
|
true => ()
|
|
82
83
|
);
|
|
83
84
|
};
|
|
84
|
-
.
|
|
85
|
+
exn.throw(dyn EncodingError.InvalidChar(c))
|
|
85
86
|
});
|
|
86
87
|
|
|
87
|
-
_decode_with :: (fn(s: str, alpha: str) ->
|
|
88
|
+
_decode_with :: (fn(s: str, alpha: str, using(exn : Exception)) -> ArrayList(u8))({
|
|
88
89
|
// Strip trailing padding
|
|
89
90
|
len := s.len();
|
|
90
91
|
while ((len > usize(0)) && (s.bytes((len - usize(1))) == _PAD)), (len = (len - usize(1))), ();
|
|
91
92
|
out := ArrayList(u8).with_capacity(((len * usize(3)) / usize(4)));
|
|
92
93
|
i := usize(0);
|
|
93
94
|
while (i < len), (i = (i + usize(4))), {
|
|
94
|
-
|
|
95
|
-
|
|
95
|
+
c0 := _decode_char(s.bytes(i), alpha);
|
|
96
|
+
c1 := cond(
|
|
96
97
|
((i + usize(1)) < len) => _decode_char(s.bytes((i + usize(1))), alpha),
|
|
97
|
-
true =>
|
|
98
|
+
true => u8(0)
|
|
98
99
|
);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
match(c1_r,
|
|
111
|
-
.Err(e) => { return .Err(e); },
|
|
112
|
-
.Ok(c1) => {
|
|
113
|
-
out.push(((c0 << u8(2)) | (c1 >> u8(4))));
|
|
114
|
-
cond(
|
|
115
|
-
((i + usize(2)) < len) => {
|
|
116
|
-
match(c2_r,
|
|
117
|
-
.Err(e) => { return .Err(e); },
|
|
118
|
-
.Ok(c2) => {
|
|
119
|
-
out.push((((c1 & u8(15)) << u8(4)) | (c2 >> u8(2))));
|
|
120
|
-
cond(
|
|
121
|
-
((i + usize(3)) < len) => {
|
|
122
|
-
match(c3_r,
|
|
123
|
-
.Err(e) => { return .Err(e); },
|
|
124
|
-
.Ok(c3) => {
|
|
125
|
-
out.push((((c2 & u8(3)) << u8(6)) | c3));
|
|
126
|
-
}
|
|
127
|
-
);
|
|
128
|
-
},
|
|
129
|
-
true => ()
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
);
|
|
133
|
-
},
|
|
134
|
-
true => ()
|
|
135
|
-
);
|
|
136
|
-
}
|
|
100
|
+
out.push(((c0 << u8(2)) | (c1 >> u8(4))));
|
|
101
|
+
cond(
|
|
102
|
+
((i + usize(2)) < len) => {
|
|
103
|
+
c2 := _decode_char(s.bytes((i + usize(2))), alpha);
|
|
104
|
+
out.push((((c1 & u8(15)) << u8(4)) | (c2 >> u8(2))));
|
|
105
|
+
cond(
|
|
106
|
+
((i + usize(3)) < len) => {
|
|
107
|
+
c3 := _decode_char(s.bytes((i + usize(3))), alpha);
|
|
108
|
+
out.push((((c2 & u8(3)) << u8(6)) | c3));
|
|
109
|
+
},
|
|
110
|
+
true => ()
|
|
137
111
|
);
|
|
138
|
-
}
|
|
112
|
+
},
|
|
113
|
+
true => ()
|
|
139
114
|
);
|
|
140
115
|
};
|
|
141
|
-
|
|
116
|
+
out
|
|
142
117
|
});
|
|
143
118
|
|
|
144
119
|
// Decode standard base64.
|
|
145
|
-
base64_decode :: (fn(s: str) ->
|
|
120
|
+
base64_decode :: (fn(s: str, using(exn : Exception)) -> ArrayList(u8))(
|
|
146
121
|
_decode_with(s, _STD_ALPHA)
|
|
147
122
|
);
|
|
148
123
|
|
|
149
124
|
// Decode URL-safe base64.
|
|
150
|
-
base64_decode_url :: (fn(s: str) ->
|
|
125
|
+
base64_decode_url :: (fn(s: str, using(exn : Exception)) -> ArrayList(u8))(
|
|
151
126
|
_decode_with(s, _URL_ALPHA)
|
|
152
127
|
);
|
|
153
128
|
|
package/std/encoding/hex.yo
CHANGED
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
// { hex_encode, hex_decode } :: import "std/encoding/hex";
|
|
7
7
|
//
|
|
8
8
|
// s := hex_encode(data); // "deadbeef"
|
|
9
|
-
// b := hex_decode("deadbeef")
|
|
9
|
+
// b := hex_decode("deadbeef");
|
|
10
10
|
|
|
11
11
|
open import "../string";
|
|
12
12
|
{ ArrayList } :: import "../collections/array_list";
|
|
13
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
14
|
+
{ ToString } :: import "../fmt";
|
|
13
15
|
|
|
14
16
|
// ============================================================================
|
|
15
17
|
// Error type
|
|
@@ -20,6 +22,17 @@ EncodingError :: enum(
|
|
|
20
22
|
OddLength
|
|
21
23
|
);
|
|
22
24
|
|
|
25
|
+
impl(EncodingError, ToString(
|
|
26
|
+
to_string : (self ->
|
|
27
|
+
match(self,
|
|
28
|
+
.InvalidChar(ch) => `encoding error: invalid character ${ch}`,
|
|
29
|
+
.OddLength => `encoding error: odd length`
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
));
|
|
33
|
+
|
|
34
|
+
impl(EncodingError, Error());
|
|
35
|
+
|
|
23
36
|
export EncodingError;
|
|
24
37
|
|
|
25
38
|
// ============================================================================
|
|
@@ -52,41 +65,31 @@ export hex_encode;
|
|
|
52
65
|
// Decoding
|
|
53
66
|
// ============================================================================
|
|
54
67
|
|
|
55
|
-
_hex_nibble :: (fn(c: u8) ->
|
|
68
|
+
_hex_nibble :: (fn(c: u8, using(exn : Exception)) -> u8)(
|
|
56
69
|
cond(
|
|
57
|
-
((c >= u8(48)) && (c <= u8(57))) =>
|
|
58
|
-
((c >= u8(97)) && (c <= u8(102))) =>
|
|
59
|
-
((c >= u8(65)) && (c <= u8(70))) =>
|
|
60
|
-
true => .
|
|
70
|
+
((c >= u8(48)) && (c <= u8(57))) => (c - u8(48)), // '0'-'9'
|
|
71
|
+
((c >= u8(97)) && (c <= u8(102))) => ((c - u8(97)) + u8(10)), // 'a'-'f'
|
|
72
|
+
((c >= u8(65)) && (c <= u8(70))) => ((c - u8(65)) + u8(10)), // 'A'-'F'
|
|
73
|
+
true => exn.throw(dyn EncodingError.InvalidChar(c))
|
|
61
74
|
)
|
|
62
75
|
);
|
|
63
76
|
|
|
64
77
|
// Decode a hexadecimal string into bytes.
|
|
65
|
-
hex_decode :: (fn(s: str) ->
|
|
78
|
+
hex_decode :: (fn(s: str, using(exn : Exception)) -> ArrayList(u8))({
|
|
66
79
|
cond(
|
|
67
80
|
(((s.len() % usize(2)) != usize(0))) => {
|
|
68
|
-
|
|
81
|
+
exn.throw(dyn EncodingError.OddLength);
|
|
69
82
|
},
|
|
70
83
|
true => ()
|
|
71
84
|
);
|
|
72
85
|
out := ArrayList(u8).with_capacity((s.len() / usize(2)));
|
|
73
86
|
i := usize(0);
|
|
74
87
|
while (i < s.len()), (i = (i + usize(2))), {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
.Err(e) => { return .Err(e); },
|
|
79
|
-
.Ok(hi) => {
|
|
80
|
-
match(lo_r,
|
|
81
|
-
.Err(e) => { return .Err(e); },
|
|
82
|
-
.Ok(lo) => {
|
|
83
|
-
out.push(((hi << u8(4)) | lo));
|
|
84
|
-
}
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
);
|
|
88
|
+
hi := _hex_nibble(s.bytes(i));
|
|
89
|
+
lo := _hex_nibble(s.bytes((i + usize(1))));
|
|
90
|
+
out.push(((hi << u8(4)) | lo));
|
|
88
91
|
};
|
|
89
|
-
|
|
92
|
+
out
|
|
90
93
|
});
|
|
91
94
|
|
|
92
95
|
export hex_decode;
|
package/std/encoding/json.yo
CHANGED
|
@@ -4,13 +4,17 @@
|
|
|
4
4
|
//
|
|
5
5
|
// Example:
|
|
6
6
|
// { json_parse, json_stringify, JsonValue } :: import "std/encoding/json";
|
|
7
|
+
// { Exception } :: import "std/error";
|
|
7
8
|
//
|
|
8
|
-
//
|
|
9
|
+
// given(exn) := Exception(throw : ((err) -> { escape (); }));
|
|
10
|
+
// v := json_parse(`{"x": 1}`);
|
|
9
11
|
// println(json_stringify(v));
|
|
10
12
|
|
|
11
13
|
open import "../string";
|
|
12
14
|
{ ArrayList } :: import "../collections/array_list";
|
|
13
15
|
{ snprintf } :: import "../libc/stdio";
|
|
16
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
17
|
+
{ ToString } :: import "../fmt";
|
|
14
18
|
|
|
15
19
|
// ============================================================================
|
|
16
20
|
// JsonError
|
|
@@ -25,6 +29,21 @@ JsonError :: enum(
|
|
|
25
29
|
Other(msg: String)
|
|
26
30
|
);
|
|
27
31
|
|
|
32
|
+
impl(JsonError, ToString(
|
|
33
|
+
to_string : (self ->
|
|
34
|
+
match(self,
|
|
35
|
+
.UnexpectedChar(ch, pos) => `unexpected character at position ${pos}`,
|
|
36
|
+
.UnexpectedEnd => `unexpected end of input`,
|
|
37
|
+
.InvalidNumber => `invalid number`,
|
|
38
|
+
.InvalidEscape => `invalid escape sequence`,
|
|
39
|
+
.InvalidUnicode => `invalid unicode`,
|
|
40
|
+
.Other(msg) => `JSON error: ${msg}`
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
));
|
|
44
|
+
|
|
45
|
+
impl(JsonError, Error());
|
|
46
|
+
|
|
28
47
|
export JsonError;
|
|
29
48
|
|
|
30
49
|
// ============================================================================
|
|
@@ -449,9 +468,12 @@ _parse_value :: (fn(p: _Parser) -> Result(JsonValue, JsonError))({
|
|
|
449
468
|
// Public API
|
|
450
469
|
// ============================================================================
|
|
451
470
|
|
|
452
|
-
json_parse :: (fn(s: str) ->
|
|
471
|
+
json_parse :: (fn(s: str, using(exn : Exception)) -> JsonValue)({
|
|
453
472
|
p := _Parser.new(s);
|
|
454
|
-
_parse_value(p)
|
|
473
|
+
match(_parse_value(p),
|
|
474
|
+
.Ok(v) => v,
|
|
475
|
+
.Err(e) => exn.throw(dyn e)
|
|
476
|
+
)
|
|
455
477
|
});
|
|
456
478
|
|
|
457
479
|
export json_parse;
|
package/std/encoding/utf16.yo
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
// { utf8_to_utf16, utf16_to_utf8 } :: import "std/encoding/utf16";
|
|
7
7
|
//
|
|
8
8
|
// words := utf8_to_utf16("hello");
|
|
9
|
-
// s := utf16_to_utf8(words)
|
|
9
|
+
// s := utf16_to_utf8(words);
|
|
10
10
|
|
|
11
11
|
open import "../string";
|
|
12
12
|
{ ArrayList } :: import "../collections/array_list";
|
|
13
13
|
{ EncodingError } :: import "./hex";
|
|
14
|
+
{ Error, AnyError, Exception } :: import "../error";
|
|
14
15
|
|
|
15
16
|
// ============================================================================
|
|
16
17
|
// UTF-8 → UTF-16
|
|
@@ -63,7 +64,7 @@ export utf8_to_utf16;
|
|
|
63
64
|
// UTF-16 → UTF-8
|
|
64
65
|
// ============================================================================
|
|
65
66
|
|
|
66
|
-
utf16_to_utf8 :: (fn(data: ArrayList(u16)) ->
|
|
67
|
+
utf16_to_utf8 :: (fn(data: ArrayList(u16), using(exn : Exception)) -> String)({
|
|
67
68
|
out := ArrayList(u8).new();
|
|
68
69
|
i := usize(0);
|
|
69
70
|
while (i < data.len()), {
|
|
@@ -73,14 +74,14 @@ utf16_to_utf8 :: (fn(data: ArrayList(u16)) -> Result(String, EncodingError))({
|
|
|
73
74
|
((w >= u32(0xD800)) && (w <= u32(0xDBFF))) => {
|
|
74
75
|
cond(
|
|
75
76
|
((i + usize(1)) >= data.len()) => {
|
|
76
|
-
|
|
77
|
+
exn.throw(dyn EncodingError.InvalidChar(u8(0)));
|
|
77
78
|
},
|
|
78
79
|
true => ()
|
|
79
80
|
);
|
|
80
81
|
w2 := u32(data.get((i + usize(1))).unwrap());
|
|
81
82
|
cond(
|
|
82
83
|
((w2 < u32(0xDC00)) || (w2 > u32(0xDFFF))) => {
|
|
83
|
-
|
|
84
|
+
exn.throw(dyn EncodingError.InvalidChar(u8(0)));
|
|
84
85
|
},
|
|
85
86
|
true => ()
|
|
86
87
|
);
|
|
@@ -109,7 +110,7 @@ utf16_to_utf8 :: (fn(data: ArrayList(u16)) -> Result(String, EncodingError))({
|
|
|
109
110
|
}
|
|
110
111
|
);
|
|
111
112
|
};
|
|
112
|
-
|
|
113
|
+
String.from_bytes(out)
|
|
113
114
|
});
|
|
114
115
|
|
|
115
116
|
export utf16_to_utf8;
|
package/std/error.yo
CHANGED
|
@@ -2,33 +2,49 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Provides a standard Error trait for typed error propagation.
|
|
4
4
|
// All error types in the standard library should implement this trait.
|
|
5
|
-
//
|
|
6
|
-
// Example:
|
|
7
|
-
// { Error } :: import "std/error";
|
|
8
|
-
//
|
|
9
|
-
// MyError :: enum(
|
|
10
|
-
// NotFound(path: String),
|
|
11
|
-
// PermissionDenied
|
|
12
|
-
// );
|
|
13
|
-
// impl(MyError, Error(
|
|
14
|
-
// message : (self -> {
|
|
15
|
-
// return match(self,
|
|
16
|
-
// .NotFound(path) => `file not found: ${path}`,
|
|
17
|
-
// .PermissionDenied => String.from("permission denied")
|
|
18
|
-
// );
|
|
19
|
-
// })
|
|
20
|
-
// ));
|
|
21
|
-
|
|
22
5
|
open import "./string";
|
|
6
|
+
open import "./fmt";
|
|
23
7
|
|
|
24
8
|
// ============================================================================
|
|
25
9
|
// Error trait
|
|
26
10
|
// ============================================================================
|
|
27
11
|
|
|
28
|
-
Error :: (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
)
|
|
32
|
-
;
|
|
12
|
+
Error :: trait(
|
|
13
|
+
(source : (fn(self: *(Self)) -> Option(Dyn(SelfTrait)))) ?= ((self) -> .None),
|
|
14
|
+
|
|
15
|
+
where(Self <: ToString)
|
|
16
|
+
);
|
|
17
|
+
export Error;
|
|
18
|
+
|
|
19
|
+
AnyError :: Dyn(Error);
|
|
20
|
+
export AnyError;
|
|
21
|
+
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Error implementations for standard types
|
|
24
|
+
// ============================================================================
|
|
25
|
+
|
|
26
|
+
impl(String, Error());
|
|
27
|
+
|
|
28
|
+
/// === Exception ===
|
|
29
|
+
// This is a non-resumable exception handling.
|
|
30
|
+
//
|
|
31
|
+
// Example (function that may throw):
|
|
32
|
+
//
|
|
33
|
+
// safe_div :: (fn(x: i32, y: i32, using(exn : Exception)) -> i32)(
|
|
34
|
+
// cond(
|
|
35
|
+
// (y == i32(0)) => exn.throw(dyn `division by zero`)),
|
|
36
|
+
// true => (x / y)
|
|
37
|
+
// )
|
|
38
|
+
// );
|
|
39
|
+
Exception :: module(
|
|
40
|
+
throw : (fn(forall(ResumeType : Type), error : AnyError) -> ResumeType)
|
|
41
|
+
);
|
|
42
|
+
export Exception;
|
|
33
43
|
|
|
34
|
-
|
|
44
|
+
|
|
45
|
+
ResumableException :: (fn(comptime(ResumeType) : Type) -> comptime(Module))(
|
|
46
|
+
module(
|
|
47
|
+
throw : (fn(error : AnyError) -> ResumeType)
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
export ResumableException;
|