@shd101wyy/yo 0.0.26 → 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.
Files changed (38) hide show
  1. package/README.md +6 -6
  2. package/out/cjs/index.cjs +558 -553
  3. package/out/cjs/yo-cli.cjs +479 -474
  4. package/out/esm/index.mjs +432 -427
  5. package/out/types/src/codegen/async/state-machine.d.ts +1 -1
  6. package/out/types/src/codegen/exprs/await.d.ts +1 -0
  7. package/out/types/src/codegen/exprs/return.d.ts +1 -0
  8. package/out/types/src/codegen/exprs/while.d.ts +1 -1
  9. package/out/types/src/codegen/functions/context.d.ts +6 -18
  10. package/out/types/src/codegen/functions/declarations.d.ts +10 -2
  11. package/out/types/src/evaluator/async/await-analysis.d.ts +1 -0
  12. package/out/types/src/evaluator/context.d.ts +1 -0
  13. package/out/types/src/expr.d.ts +1 -0
  14. package/out/types/src/function-value.d.ts +1 -0
  15. package/out/types/src/types/creators.d.ts +2 -1
  16. package/out/types/src/types/definitions.d.ts +2 -1
  17. package/out/types/tsconfig.tsbuildinfo +1 -1
  18. package/package.json +1 -1
  19. package/std/crypto/random.yo +25 -13
  20. package/std/encoding/base64.yo +24 -49
  21. package/std/encoding/hex.yo +25 -22
  22. package/std/encoding/json.yo +25 -3
  23. package/std/encoding/utf16.yo +6 -5
  24. package/std/fs/dir.yo +106 -103
  25. package/std/fs/file.yo +122 -158
  26. package/std/fs/metadata.yo +23 -22
  27. package/std/fs/temp.yo +41 -47
  28. package/std/fs/walker.yo +48 -55
  29. package/std/net/addr.yo +8 -7
  30. package/std/net/dns.yo +27 -33
  31. package/std/net/errors.yo +13 -8
  32. package/std/net/tcp.yo +92 -113
  33. package/std/net/udp.yo +50 -54
  34. package/std/os/signal.yo +13 -8
  35. package/std/prelude.yo +23 -2
  36. package/std/sys/errors.yo +45 -33
  37. package/std/url/url.yo +19 -32
  38. package/out/types/src/codegen/effects/effect-state-machine.d.ts +0 -34
package/std/net/tcp.yo CHANGED
@@ -1,21 +1,22 @@
1
1
  // std/net/tcp.yo - High-level TCP types
2
2
  //
3
3
  // Wraps std/sys/tcp with typed TcpListener and TcpStream objects.
4
+ // Uses the Exception effect for error handling.
4
5
  //
5
6
  // Example:
6
7
  // { TcpListener, TcpStream } :: import "std/net/tcp";
7
8
  // { SocketAddr, IpAddr } :: import "std/net/addr";
9
+ // { Exception } :: import "std/error";
8
10
  //
9
11
  // main :: (fn(using(io : IO)) -> unit)({
12
+ // given(exn) := Exception(throw : ((err) -> {
13
+ // println(err.message());
14
+ // escape ();
15
+ // }));
10
16
  // addr := SocketAddr.new(IpAddr.any_v4(), u16(8080));
11
17
  // listener := io.await(TcpListener.bind(addr));
12
- // match(listener,
13
- // .Ok(l) => {
14
- // stream := io.await(l.accept());
15
- // // ...
16
- // },
17
- // .Err(e) => println(e.to_string())
18
- // );
18
+ // stream := io.await(listener.accept());
19
+ // // ...
19
20
  // });
20
21
 
21
22
  { GlobalAllocator } :: import "../allocator";
@@ -26,6 +27,7 @@ open import "../fmt";
26
27
  { NetError } :: import "./errors";
27
28
  { IOError } :: import "../sys/errors";
28
29
  { IpAddr, SocketAddr } :: import "./addr";
30
+ { Error, AnyError, Exception } :: import "../error";
29
31
  IO_tcp :: import "../sys/tcp";
30
32
  {
31
33
  AF_INET, AF_INET6, SOCK_STREAM,
@@ -53,6 +55,10 @@ _make_sockaddr :: (fn(addr: SocketAddr) -> IO_tcp.SockAddr)(
53
55
  )
54
56
  );
55
57
 
58
+ _throw_io :: (fn(errno_val: i32, using(exn : Exception)) -> unit)(
59
+ exn.throw(dyn NetError.from_io(IOError.from_errno(errno_val)))
60
+ );
61
+
56
62
  // ============================================================================
57
63
  // TcpStream (declared before TcpListener so accept can reference it)
58
64
  // ============================================================================
@@ -75,21 +81,15 @@ TcpListener :: object(
75
81
 
76
82
  impl(TcpListener,
77
83
  // Bind to a socket address and start listening.
78
- bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(TcpListener, NetError), IO)))(
79
- io.async((using(io : IO)) => {
84
+ bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(TcpListener, IO, Exception)))(
85
+ io.async((using(io : IO, exn : Exception)) => {
80
86
  domain := cond(
81
87
  addr.ip.is_v4() => AF_INET,
82
88
  true => AF_INET6
83
89
  );
84
90
  // Create socket
85
- fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
86
- cond(
87
- (fd < i32(0)) => {
88
- (ret : Result(TcpListener, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - fd))));
89
- return ret;
90
- },
91
- true => ()
92
- );
91
+ raw_fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
92
+ fd := NetError.check(raw_fd);
93
93
  // Set SO_REUSEADDR
94
94
  reuse_val := i32(1);
95
95
  reuse_ptr := &reuse_val;
@@ -101,8 +101,7 @@ impl(TcpListener,
101
101
  cond(
102
102
  (bind_result < i32(0)) => {
103
103
  io.await(IO_tcp.close(fd));
104
- (ret : Result(TcpListener, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - bind_result))));
105
- return ret;
104
+ _throw_io((i32(0) - bind_result));
106
105
  },
107
106
  true => ()
108
107
  );
@@ -111,21 +110,18 @@ impl(TcpListener,
111
110
  cond(
112
111
  (listen_result < i32(0)) => {
113
112
  io.await(IO_tcp.close(fd));
114
- (ret : Result(TcpListener, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - listen_result))));
115
- return ret;
113
+ _throw_io((i32(0) - listen_result));
116
114
  },
117
115
  true => ()
118
116
  );
119
- (ret : Result(TcpListener, NetError)) = .Ok(TcpListener(_fd: fd, _local_addr: addr, _is_closed: false));
120
- return ret;
117
+ return TcpListener(_fd: fd, _local_addr: addr, _is_closed: false);
121
118
  })
122
119
  ),
123
120
 
124
121
  // Accept an incoming connection.
125
- // Returns a new TcpStream for the accepted connection.
126
- accept : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(TcpStream, NetError), IO)))({
122
+ accept : (fn(self: Self, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))({
127
123
  fd := self._fd;
128
- io.async((using(io : IO)) => {
124
+ io.async((using(io : IO, exn : Exception)) => {
129
125
  // Allocate space for the peer address
130
126
  addr_buf := *(u8)(malloc(usize(128)).unwrap());
131
127
  addr_len := *(u32)(malloc(usize(4)).unwrap());
@@ -135,8 +131,7 @@ impl(TcpListener,
135
131
  (client_fd < i32(0)) => {
136
132
  free(.Some(*(void)(addr_buf)));
137
133
  free(.Some(*(void)(addr_len)));
138
- (ret : Result(TcpStream, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - client_fd))));
139
- return ret;
134
+ _throw_io((i32(0) - client_fd));
140
135
  },
141
136
  true => ()
142
137
  );
@@ -145,12 +140,11 @@ impl(TcpListener,
145
140
  free(.Some(*(void)(addr_buf)));
146
141
  free(.Some(*(void)(addr_len)));
147
142
  peer_addr := SocketAddr.new(IpAddr.any_v4(), peer_port);
148
- (ret : Result(TcpStream, NetError)) = .Ok(TcpStream(
143
+ return TcpStream(
149
144
  _fd: client_fd,
150
145
  _peer_addr: peer_addr,
151
146
  _is_closed: false
152
- ));
153
- return ret;
147
+ );
154
148
  })
155
149
  }),
156
150
 
@@ -160,21 +154,20 @@ impl(TcpListener,
160
154
  ),
161
155
 
162
156
  // Close the listener.
163
- close : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
157
+ close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
164
158
  fd := self._fd;
165
- io.async((using(io : IO)) => {
166
- (ret : Result(unit, NetError)) = cond(
167
- self._is_closed => .Ok(()),
159
+ io.async((using(io : IO, exn : Exception)) => {
160
+ cond(
161
+ self._is_closed => (),
168
162
  true => {
169
- result := io.await(IO_tcp.close(fd));
163
+ r := io.await(IO_tcp.close(fd));
170
164
  self._is_closed = true;
171
165
  cond(
172
- (result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
173
- true => .Ok(())
174
- )
166
+ (r < i32(0)) => { _throw_io((i32(0) - r)); },
167
+ true => ()
168
+ );
175
169
  }
176
170
  );
177
- ret
178
171
  })
179
172
  }),
180
173
 
@@ -205,148 +198,136 @@ export TcpListener;
205
198
 
206
199
  impl(TcpStream,
207
200
  // Connect to a remote address.
208
- connect : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(TcpStream, NetError), IO)))(
209
- io.async((using(io : IO)) => {
201
+ connect : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(TcpStream, IO, Exception)))(
202
+ io.async((using(io : IO, exn : Exception)) => {
210
203
  domain := cond(
211
204
  addr.ip.is_v4() => AF_INET,
212
205
  true => AF_INET6
213
206
  );
214
- fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
215
- cond(
216
- (fd < i32(0)) => {
217
- (ret : Result(TcpStream, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - fd))));
218
- return ret;
219
- },
220
- true => ()
221
- );
207
+ raw_fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
208
+ fd := NetError.check(raw_fd);
222
209
  saddr := _make_sockaddr(addr);
223
210
  conn_result := io.await(IO_tcp.connect(fd, saddr.buf, saddr.len));
224
211
  IO_tcp.free_sockaddr(saddr);
225
212
  cond(
226
213
  (conn_result < i32(0)) => {
227
214
  io.await(IO_tcp.close(fd));
228
- (ret : Result(TcpStream, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - conn_result))));
229
- return ret;
215
+ _throw_io((i32(0) - conn_result));
230
216
  },
231
217
  true => ()
232
218
  );
233
- (ret : Result(TcpStream, NetError)) = .Ok(TcpStream(
219
+ return TcpStream(
234
220
  _fd: fd,
235
221
  _peer_addr: addr,
236
222
  _is_closed: false
237
- ));
238
- return ret;
223
+ );
239
224
  })
240
225
  ),
241
226
 
242
227
  // Read bytes from the stream.
243
228
  // Returns the number of bytes read (0 means peer closed).
244
- read : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
229
+ read : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
245
230
  fd := self._fd;
246
- io.async((using(io : IO)) => {
247
- result := io.await(IO_tcp.recv(fd, buf, size, i32(0)));
248
- NetError.from_result(result)
231
+ io.async((using(io : IO, exn : Exception)) => {
232
+ r := io.await(IO_tcp.recv(fd, buf, size, i32(0)));
233
+ NetError.check(r)
249
234
  })
250
235
  }),
251
236
 
252
237
  // Write a str to the stream.
253
238
  // Returns the number of bytes written.
254
- write_str : (fn(self: Self, data: str, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
239
+ write_str : (fn(self: Self, data: str, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
255
240
  fd := self._fd;
256
241
  s := String.from(data);
257
242
  s_bytes := s.as_bytes();
258
- io.async((using(io : IO)) => {
259
- result := io.await(IO_tcp.send(fd, s_bytes.ptr().unwrap(), s_bytes.len(), i32(0)));
260
- NetError.from_result(result)
243
+ io.async((using(io : IO, exn : Exception)) => {
244
+ r := io.await(IO_tcp.send(fd, s_bytes.ptr().unwrap(), s_bytes.len(), i32(0)));
245
+ NetError.check(r)
261
246
  })
262
247
  }),
263
248
 
264
249
  // Write a String to the stream.
265
250
  // Returns the number of bytes written.
266
- write : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
251
+ write_string : (fn(self: Self, data: String, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
267
252
  fd := self._fd;
268
253
  data_bytes := data.as_bytes();
269
- io.async((using(io : IO)) => {
270
- result := io.await(IO_tcp.send(fd, data_bytes.ptr().unwrap(), data_bytes.len(), i32(0)));
271
- NetError.from_result(result)
254
+ io.async((using(io : IO, exn : Exception)) => {
255
+ r := io.await(IO_tcp.send(fd, data_bytes.ptr().unwrap(), data_bytes.len(), i32(0)));
256
+ NetError.check(r)
272
257
  })
273
258
  }),
274
259
 
275
260
  // Write bytes to the stream.
276
261
  // Returns the number of bytes written.
277
- write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
262
+ write_bytes : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
278
263
  fd := self._fd;
279
- io.async((using(io : IO)) => {
280
- result := io.await(IO_tcp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
281
- NetError.from_result(result)
264
+ io.async((using(io : IO, exn : Exception)) => {
265
+ r := io.await(IO_tcp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
266
+ NetError.check(r)
282
267
  })
283
268
  }),
284
269
 
285
270
  // Read all available data into a byte list.
286
- read_all : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(ArrayList(u8), NetError), IO)))({
271
+ read_all : (fn(self: Self, using(io : IO)) -> Impl(Future(ArrayList(u8), IO, Exception)))({
287
272
  fd := self._fd;
288
- io.async((using(io : IO)) => {
273
+ io.async((using(io : IO, exn : Exception)) => {
289
274
  buf_size := usize(4096);
290
275
  buf := *(u8)(malloc(buf_size).unwrap());
291
- result := ArrayList(u8).new();
292
- while runtime(true), {
276
+ acc := ArrayList(u8).new();
277
+ done := false;
278
+ while runtime(!(done)), {
293
279
  n := io.await(IO_tcp.recv(fd, buf, buf_size, i32(0)));
294
280
  cond(
295
281
  (n < i32(0)) => {
296
282
  free(.Some(*(void)(buf)));
297
- (ret : Result(ArrayList(u8), NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - n))));
298
- return ret;
283
+ done = true;
284
+ _throw_io((i32(0) - n));
299
285
  },
300
286
  (n == i32(0)) => {
301
- free(.Some(*(void)(buf)));
302
- (ret : Result(ArrayList(u8), NetError)) = .Ok(result);
303
- return ret;
287
+ done = true;
304
288
  },
305
289
  true => {
306
290
  i := usize(0);
307
291
  while runtime((i < usize(n))), {
308
- result.push((buf &+ i).*);
292
+ acc.push((buf &+ i).*);
309
293
  i = (i + usize(1));
310
294
  };
311
295
  }
312
296
  );
313
297
  };
314
298
  free(.Some(*(void)(buf)));
315
- (ret : Result(ArrayList(u8), NetError)) = .Ok(result);
316
- return ret;
299
+ return acc;
317
300
  })
318
301
  }),
319
302
 
320
303
  // Shut down the connection.
321
304
  // how: 0 = read, 1 = write, 2 = both
322
- shutdown : (fn(self: Self, how: i32, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
305
+ shutdown : (fn(self: Self, how: i32, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
323
306
  fd := self._fd;
324
- io.async((using(io : IO)) => {
325
- result := io.await(IO_tcp.shutdown(fd, how));
326
- (ret : Result(unit, NetError)) = cond(
327
- (result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
328
- true => .Ok(())
307
+ io.async((using(io : IO, exn : Exception)) => {
308
+ r := io.await(IO_tcp.shutdown(fd, how));
309
+ cond(
310
+ (r < i32(0)) => { _throw_io((i32(0) - r)); },
311
+ true => ()
329
312
  );
330
- ret
331
313
  })
332
314
  }),
333
315
 
334
316
  // Close the stream.
335
- close : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
317
+ close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
336
318
  fd := self._fd;
337
- io.async((using(io : IO)) => {
338
- (ret : Result(unit, NetError)) = cond(
339
- self._is_closed => .Ok(()),
319
+ io.async((using(io : IO, exn : Exception)) => {
320
+ cond(
321
+ self._is_closed => (),
340
322
  true => {
341
- result := io.await(IO_tcp.close(fd));
323
+ r := io.await(IO_tcp.close(fd));
342
324
  self._is_closed = true;
343
325
  cond(
344
- (result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
345
- true => .Ok(())
346
- )
326
+ (r < i32(0)) => { _throw_io((i32(0) - r)); },
327
+ true => ()
328
+ );
347
329
  }
348
330
  );
349
- ret
350
331
  })
351
332
  }),
352
333
 
@@ -361,32 +342,30 @@ impl(TcpStream,
361
342
  ),
362
343
 
363
344
  // Enable/disable TCP_NODELAY (Nagle's algorithm).
364
- set_nodelay : (fn(self: Self, nodelay: bool, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
345
+ set_nodelay : (fn(self: Self, nodelay: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
365
346
  sock_fd := self._fd;
366
- io.async((using(io : IO)) => {
347
+ io.async((using(io : IO, exn : Exception)) => {
367
348
  val := cond(nodelay => i32(1), true => i32(0));
368
349
  val_ptr := &val;
369
- result := io.await(IO_tcp.setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, *(u8)(val_ptr), u32(4)));
370
- (ret : Result(unit, NetError)) = cond(
371
- (result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
372
- true => .Ok(())
350
+ r := io.await(IO_tcp.setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, *(u8)(val_ptr), u32(4)));
351
+ cond(
352
+ (r < i32(0)) => { _throw_io((i32(0) - r)); },
353
+ true => ()
373
354
  );
374
- ret
375
355
  })
376
356
  }),
377
357
 
378
358
  // Enable/disable SO_KEEPALIVE.
379
- set_keepalive : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
359
+ set_keepalive : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
380
360
  sock_fd := self._fd;
381
- io.async((using(io : IO)) => {
361
+ io.async((using(io : IO, exn : Exception)) => {
382
362
  val := cond(enabled => i32(1), true => i32(0));
383
363
  val_ptr := &val;
384
- result := io.await(IO_tcp.setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, *(u8)(val_ptr), u32(4)));
385
- (ret : Result(unit, NetError)) = cond(
386
- (result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
387
- true => .Ok(())
364
+ r := io.await(IO_tcp.setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, *(u8)(val_ptr), u32(4)));
365
+ cond(
366
+ (r < i32(0)) => { _throw_io((i32(0) - r)); },
367
+ true => ()
388
368
  );
389
- ret
390
369
  })
391
370
  })
392
371
  );
package/std/net/udp.yo CHANGED
@@ -1,20 +1,21 @@
1
1
  // std/net/udp.yo - High-level UDP socket
2
2
  //
3
3
  // Wraps std/sys/udp with typed UdpSocket object.
4
+ // Uses the Exception effect for error handling.
4
5
  //
5
6
  // Example:
6
7
  // { UdpSocket } :: import "std/net/udp";
7
8
  // { SocketAddr, IpAddr } :: import "std/net/addr";
9
+ // { Exception } :: import "std/error";
8
10
  //
9
11
  // main :: (fn(using(io : IO)) -> unit)({
12
+ // given(exn) := Exception(throw : ((err) -> {
13
+ // println(err.message());
14
+ // escape ();
15
+ // }));
10
16
  // addr := SocketAddr.new(IpAddr.loopback_v4(), u16(9999));
11
17
  // sock := io.await(UdpSocket.bind(addr));
12
- // match(sock,
13
- // .Ok(s) => {
14
- // io.await(s.close());
15
- // },
16
- // .Err(e) => println(e.to_string())
17
- // );
18
+ // io.await(sock.close());
18
19
  // });
19
20
 
20
21
  { GlobalAllocator } :: import "../allocator";
@@ -25,6 +26,7 @@ open import "../fmt";
25
26
  { NetError } :: import "./errors";
26
27
  { IOError } :: import "../sys/errors";
27
28
  { IpAddr, SocketAddr } :: import "./addr";
29
+ { Error, AnyError, Exception } :: import "../error";
28
30
  IO_udp :: import "../sys/udp";
29
31
  IO_tcp :: import "../sys/tcp";
30
32
  {
@@ -49,6 +51,10 @@ _make_sockaddr :: (fn(addr: SocketAddr) -> IO_tcp.SockAddr)(
49
51
  )
50
52
  );
51
53
 
54
+ _throw_net_io :: (fn(errno_val: i32, using(exn : Exception)) -> unit)(
55
+ exn.throw(dyn NetError.from_io(IOError.from_errno(errno_val)))
56
+ );
57
+
52
58
  // ============================================================================
53
59
  // UdpSocket
54
60
  // ============================================================================
@@ -61,108 +67,98 @@ UdpSocket :: object(
61
67
 
62
68
  impl(UdpSocket,
63
69
  // Create and bind a UDP socket to the given address.
64
- bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(UdpSocket, NetError), IO)))(
65
- io.async((using(io : IO)) => {
70
+ bind : (fn(addr: SocketAddr, using(io : IO)) -> Impl(Future(UdpSocket, IO, Exception)))(
71
+ io.async((using(io : IO, exn : Exception)) => {
66
72
  domain := cond(
67
73
  addr.ip.is_v4() => AF_INET,
68
74
  true => AF_INET6
69
75
  );
70
- fd := io.await(IO_udp.socket(domain, i32(0)));
71
- cond(
72
- (fd < i32(0)) => {
73
- (ret : Result(UdpSocket, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - fd))));
74
- return ret;
75
- },
76
- true => ()
77
- );
76
+ raw_fd := io.await(IO_udp.socket(domain, i32(0)));
77
+ fd := NetError.check(raw_fd);
78
78
  saddr := _make_sockaddr(addr);
79
- bind_result := io.await(IO_udp.bind(fd, saddr.buf, saddr.len));
79
+ bind_r := io.await(IO_udp.bind(fd, saddr.buf, saddr.len));
80
80
  IO_tcp.free_sockaddr(saddr);
81
81
  cond(
82
- (bind_result < i32(0)) => {
82
+ (bind_r < i32(0)) => {
83
83
  io.await(IO_udp.close(fd));
84
- (ret : Result(UdpSocket, NetError)) = .Err(NetError.from_io(IOError.from_errno((i32(0) - bind_result))));
85
- return ret;
84
+ _throw_net_io((i32(0) - bind_r));
86
85
  },
87
86
  true => ()
88
87
  );
89
- (ret : Result(UdpSocket, NetError)) = .Ok(UdpSocket(_fd: fd, _local_addr: addr, _is_closed: false));
90
- return ret;
88
+ return UdpSocket(_fd: fd, _local_addr: addr, _is_closed: false);
91
89
  })
92
90
  ),
93
91
 
94
92
  // Send a datagram to a specific address.
95
93
  // Returns the number of bytes sent.
96
- send_to : (fn(self: Self, data: ArrayList(u8), addr: SocketAddr, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
94
+ send_to : (fn(self: Self, data: ArrayList(u8), addr: SocketAddr, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
97
95
  fd := self._fd;
98
- io.async((using(io : IO)) => {
96
+ io.async((using(io : IO, exn : Exception)) => {
99
97
  saddr := _make_sockaddr(addr);
100
- result := io.await(IO_udp.sendto(fd, data.ptr().unwrap(), data.len(), i32(0), saddr.buf, saddr.len));
98
+ r := io.await(IO_udp.sendto(fd, data.ptr().unwrap(), data.len(), i32(0), saddr.buf, saddr.len));
101
99
  IO_tcp.free_sockaddr(saddr);
102
- NetError.from_result(result)
100
+ NetError.check(r)
103
101
  })
104
102
  }),
105
103
 
106
104
  // Receive a datagram.
107
105
  // Returns the number of bytes received.
108
- recv : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
106
+ recv : (fn(self: Self, buf: *(u8), size: usize, using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
109
107
  fd := self._fd;
110
- io.async((using(io : IO)) => {
111
- result := io.await(IO_udp.recv(fd, buf, size, i32(0)));
112
- NetError.from_result(result)
108
+ io.async((using(io : IO, exn : Exception)) => {
109
+ r := io.await(IO_udp.recv(fd, buf, size, i32(0)));
110
+ NetError.check(r)
113
111
  })
114
112
  }),
115
113
 
116
114
  // Receive a datagram and get the source address.
117
115
  // Returns the number of bytes received.
118
- recv_from : (fn(self: Self, buf: *(u8), size: usize, src_addr: *(u8), src_addr_len: *(u32), using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
116
+ recv_from : (fn(self: Self, buf: *(u8), size: usize, src_addr: *(u8), src_addr_len: *(u32), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
119
117
  fd := self._fd;
120
- io.async((using(io : IO)) => {
121
- result := io.await(IO_udp.recvfrom(fd, buf, size, i32(0), src_addr, src_addr_len));
122
- NetError.from_result(result)
118
+ io.async((using(io : IO, exn : Exception)) => {
119
+ r := io.await(IO_udp.recvfrom(fd, buf, size, i32(0), src_addr, src_addr_len));
120
+ NetError.check(r)
123
121
  })
124
122
  }),
125
123
 
126
124
  // Send data on a connected socket (after connect()).
127
- send : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(Result(i32, NetError), IO)))({
125
+ send : (fn(self: Self, data: ArrayList(u8), using(io : IO)) -> Impl(Future(i32, IO, Exception)))({
128
126
  fd := self._fd;
129
- io.async((using(io : IO)) => {
130
- result := io.await(IO_udp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
131
- NetError.from_result(result)
127
+ io.async((using(io : IO, exn : Exception)) => {
128
+ r := io.await(IO_udp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
129
+ NetError.check(r)
132
130
  })
133
131
  }),
134
132
 
135
133
  // Close the socket.
136
- close : (fn(self: Self, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
134
+ close : (fn(self: Self, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
137
135
  fd := self._fd;
138
- io.async((using(io : IO)) => {
139
- (ret : Result(unit, NetError)) = cond(
140
- self._is_closed => .Ok(()),
136
+ io.async((using(io : IO, exn : Exception)) => {
137
+ cond(
138
+ self._is_closed => (),
141
139
  true => {
142
- result := io.await(IO_udp.close(fd));
140
+ r := io.await(IO_udp.close(fd));
143
141
  self._is_closed = true;
144
142
  cond(
145
- (result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
146
- true => .Ok(())
147
- )
143
+ (r < i32(0)) => { _throw_net_io((i32(0) - r)); },
144
+ true => ()
145
+ );
148
146
  }
149
147
  );
150
- ret
151
148
  })
152
149
  }),
153
150
 
154
151
  // Enable/disable SO_BROADCAST.
155
- set_broadcast : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(Result(unit, NetError), IO)))({
152
+ set_broadcast : (fn(self: Self, enabled: bool, using(io : IO)) -> Impl(Future(unit, IO, Exception)))({
156
153
  fd := self._fd;
157
- io.async((using(io : IO)) => {
154
+ io.async((using(io : IO, exn : Exception)) => {
158
155
  val := cond(enabled => i32(1), true => i32(0));
159
156
  val_ptr := &val;
160
- result := io.await(IO_udp.setsockopt(fd, SOL_SOCKET, SO_BROADCAST, *(u8)(val_ptr), u32(4)));
161
- (ret : Result(unit, NetError)) = cond(
162
- (result < i32(0)) => .Err(NetError.from_io(IOError.from_errno((i32(0) - result)))),
163
- true => .Ok(())
157
+ r := io.await(IO_udp.setsockopt(fd, SOL_SOCKET, SO_BROADCAST, *(u8)(val_ptr), u32(4)));
158
+ cond(
159
+ (r < i32(0)) => { _throw_net_io((i32(0) - r)); },
160
+ true => ()
164
161
  );
165
- ret
166
162
  })
167
163
  }),
168
164
 
package/std/os/signal.yo CHANGED
@@ -13,6 +13,7 @@
13
13
  on_signal : _on_signal, off_signal : _off_signal, SignalHandler
14
14
  } :: import "../sys/signal";
15
15
  { platform, Platform } :: import "../process";
16
+ { Error, AnyError, Exception } :: import "../error";
16
17
 
17
18
  // ============================================================================
18
19
  // Signal enum
@@ -73,23 +74,27 @@ _signal_num :: (fn(sig: Signal) -> i32)(
73
74
  // ============================================================================
74
75
 
75
76
  // Register a handler for the given signal.
76
- on_signal :: (fn(sig: Signal, handler: SignalHandler) -> Result(unit, IOError))({
77
+ on_signal :: (fn(sig: Signal, handler: SignalHandler, using(exn : Exception)) -> unit)({
77
78
  num := _signal_num(sig);
78
79
  r := _on_signal(num, handler);
79
80
  cond(
80
- (r < i32(0)) => .Err(IOError.from_errno((i32(0) - r))),
81
- true => .Ok(())
82
- )
81
+ (r < i32(0)) => {
82
+ exn.throw(dyn IOError.from_errno((i32(0) - r)));
83
+ },
84
+ true => ()
85
+ );
83
86
  });
84
87
 
85
88
  // Remove the handler for the given signal.
86
- off_signal :: (fn(sig: Signal) -> Result(unit, IOError))({
89
+ off_signal :: (fn(sig: Signal, using(exn : Exception)) -> unit)({
87
90
  num := _signal_num(sig);
88
91
  r := _off_signal(num);
89
92
  cond(
90
- (r < i32(0)) => .Err(IOError.from_errno((i32(0) - r))),
91
- true => .Ok(())
92
- )
93
+ (r < i32(0)) => {
94
+ exn.throw(dyn IOError.from_errno((i32(0) - r)));
95
+ },
96
+ true => ()
97
+ );
93
98
  });
94
99
 
95
100
  export SignalHandler, on_signal, off_signal;