@shd101wyy/yo 0.1.25 → 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.
Files changed (194) hide show
  1. package/.github/skills/yo-async-effects/SKILL.md +4 -4
  2. package/.github/skills/yo-async-effects/async-effects-recipes.md +40 -40
  3. package/.github/skills/yo-core-patterns/SKILL.md +1 -1
  4. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +30 -26
  5. package/.github/skills/yo-project-workflow/SKILL.md +6 -3
  6. package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +34 -11
  7. package/.github/skills/yo-syntax/SKILL.md +7 -6
  8. package/.github/skills/yo-syntax/syntax-cheatsheet.md +78 -60
  9. package/.github/skills/yo-wasm-integration/wasm-integration-cheatsheet.md +3 -3
  10. package/README.md +10 -8
  11. package/out/cjs/index.cjs +583 -567
  12. package/out/cjs/yo-cli.cjs +664 -632
  13. package/out/cjs/yo-lsp.cjs +510 -485
  14. package/out/esm/index.mjs +538 -522
  15. package/out/types/src/codegen/codegen-c.d.ts +2 -2
  16. package/out/types/src/codegen/functions/collection.d.ts +2 -2
  17. package/out/types/src/codegen/functions/context.d.ts +3 -2
  18. package/out/types/src/codegen/types/collection.d.ts +2 -2
  19. package/out/types/src/codegen/utils/index.d.ts +3 -1
  20. package/out/types/src/doc/builder.d.ts +2 -2
  21. package/out/types/src/evaluator/calls/closure-type.d.ts +2 -2
  22. package/out/types/src/evaluator/calls/record-type.d.ts +11 -0
  23. package/out/types/src/evaluator/context.d.ts +8 -9
  24. package/out/types/src/evaluator/index.d.ts +3 -3
  25. package/out/types/src/evaluator/types/record.d.ts +14 -0
  26. package/out/types/src/evaluator/types/validation.d.ts +2 -2
  27. package/out/types/src/evaluator/values/anonymous-module.d.ts +5 -5
  28. package/out/types/src/evaluator/values/impl.d.ts +1 -1
  29. package/out/types/src/expr.d.ts +1 -4
  30. package/out/types/src/formatter.d.ts +11 -0
  31. package/out/types/src/function-value.d.ts +1 -1
  32. package/out/types/src/lsp/document-manager.d.ts +1 -1
  33. package/out/types/src/lsp/formatting.d.ts +2 -0
  34. package/out/types/src/module-manager.d.ts +3 -3
  35. package/out/types/src/tests/formatter.test.d.ts +1 -0
  36. package/out/types/src/types/creators.d.ts +3 -4
  37. package/out/types/src/types/definitions.d.ts +8 -19
  38. package/out/types/src/types/guards.d.ts +3 -3
  39. package/out/types/src/types/tags.d.ts +0 -1
  40. package/out/types/src/types/utils.d.ts +1 -1
  41. package/out/types/src/value-tag.d.ts +0 -1
  42. package/out/types/src/value.d.ts +6 -13
  43. package/out/types/tsconfig.tsbuildinfo +1 -1
  44. package/package.json +1 -1
  45. package/std/alg/hash.yo +13 -21
  46. package/std/allocator.yo +25 -40
  47. package/std/async.yo +3 -7
  48. package/std/build.yo +105 -151
  49. package/std/cli/arg_parser.yo +184 -169
  50. package/std/collections/array_list.yo +350 -314
  51. package/std/collections/btree_map.yo +142 -131
  52. package/std/collections/deque.yo +132 -128
  53. package/std/collections/hash_map.yo +542 -566
  54. package/std/collections/hash_set.yo +623 -687
  55. package/std/collections/linked_list.yo +275 -293
  56. package/std/collections/ordered_map.yo +113 -85
  57. package/std/collections/priority_queue.yo +73 -73
  58. package/std/crypto/md5.yo +191 -95
  59. package/std/crypto/random.yo +56 -64
  60. package/std/crypto/sha256.yo +151 -107
  61. package/std/encoding/base64.yo +87 -81
  62. package/std/encoding/hex.yo +43 -50
  63. package/std/encoding/html.yo +56 -81
  64. package/std/encoding/html_char_utils.yo +7 -13
  65. package/std/encoding/html_entities.yo +2248 -2253
  66. package/std/encoding/json.yo +316 -224
  67. package/std/encoding/punycode.yo +86 -116
  68. package/std/encoding/toml.yo +67 -66
  69. package/std/encoding/utf16.yo +37 -44
  70. package/std/env.yo +62 -91
  71. package/std/error.yo +12 -20
  72. package/std/fmt/display.yo +5 -9
  73. package/std/fmt/index.yo +8 -14
  74. package/std/fmt/to_string.yo +330 -315
  75. package/std/fmt/writer.yo +58 -87
  76. package/std/fs/dir.yo +83 -102
  77. package/std/fs/file.yo +147 -180
  78. package/std/fs/metadata.yo +45 -78
  79. package/std/fs/temp.yo +55 -65
  80. package/std/fs/types.yo +27 -40
  81. package/std/fs/walker.yo +53 -68
  82. package/std/gc.yo +5 -8
  83. package/std/glob.yo +30 -43
  84. package/std/http/client.yo +107 -120
  85. package/std/http/http.yo +106 -96
  86. package/std/http/index.yo +4 -6
  87. package/std/imm/list.yo +88 -93
  88. package/std/imm/map.yo +528 -464
  89. package/std/imm/set.yo +52 -57
  90. package/std/imm/sorted_map.yo +340 -286
  91. package/std/imm/sorted_set.yo +57 -63
  92. package/std/imm/string.yo +404 -345
  93. package/std/imm/vec.yo +173 -181
  94. package/std/io/reader.yo +3 -6
  95. package/std/io/writer.yo +4 -8
  96. package/std/libc/assert.yo +5 -9
  97. package/std/libc/ctype.yo +32 -22
  98. package/std/libc/dirent.yo +26 -25
  99. package/std/libc/errno.yo +164 -90
  100. package/std/libc/fcntl.yo +52 -45
  101. package/std/libc/float.yo +66 -44
  102. package/std/libc/limits.yo +42 -33
  103. package/std/libc/math.yo +53 -82
  104. package/std/libc/signal.yo +72 -47
  105. package/std/libc/stdatomic.yo +217 -188
  106. package/std/libc/stdint.yo +5 -29
  107. package/std/libc/stdio.yo +5 -29
  108. package/std/libc/stdlib.yo +32 -39
  109. package/std/libc/string.yo +5 -23
  110. package/std/libc/sys/stat.yo +58 -56
  111. package/std/libc/time.yo +5 -19
  112. package/std/libc/unistd.yo +5 -20
  113. package/std/libc/wctype.yo +6 -9
  114. package/std/libc/windows.yo +26 -30
  115. package/std/log.yo +41 -55
  116. package/std/net/addr.yo +102 -97
  117. package/std/net/dns.yo +27 -28
  118. package/std/net/errors.yo +50 -49
  119. package/std/net/tcp.yo +113 -124
  120. package/std/net/udp.yo +55 -66
  121. package/std/os/env.yo +35 -33
  122. package/std/os/signal.yo +15 -25
  123. package/std/path.yo +276 -311
  124. package/std/prelude.yo +6316 -4333
  125. package/std/process/command.yo +87 -103
  126. package/std/process/index.yo +12 -31
  127. package/std/regex/compiler.yo +196 -95
  128. package/std/regex/flags.yo +58 -39
  129. package/std/regex/index.yo +157 -173
  130. package/std/regex/match.yo +20 -31
  131. package/std/regex/node.yo +134 -152
  132. package/std/regex/parser.yo +283 -259
  133. package/std/regex/unicode.yo +172 -202
  134. package/std/regex/vm.yo +155 -171
  135. package/std/string/index.yo +5 -7
  136. package/std/string/rune.yo +45 -55
  137. package/std/string/string.yo +937 -964
  138. package/std/string/string_builder.yo +94 -104
  139. package/std/string/unicode.yo +46 -64
  140. package/std/sync/channel.yo +72 -73
  141. package/std/sync/cond.yo +31 -36
  142. package/std/sync/mutex.yo +30 -32
  143. package/std/sync/once.yo +13 -16
  144. package/std/sync/rwlock.yo +26 -31
  145. package/std/sync/waitgroup.yo +20 -25
  146. package/std/sys/advise.yo +16 -24
  147. package/std/sys/bufio/buf_reader.yo +77 -93
  148. package/std/sys/bufio/buf_writer.yo +52 -65
  149. package/std/sys/clock.yo +4 -9
  150. package/std/sys/constants.yo +77 -61
  151. package/std/sys/copy.yo +4 -10
  152. package/std/sys/dir.yo +26 -43
  153. package/std/sys/dns.yo +41 -61
  154. package/std/sys/errors.yo +95 -103
  155. package/std/sys/events.yo +45 -57
  156. package/std/sys/externs.yo +319 -267
  157. package/std/sys/fallocate.yo +7 -11
  158. package/std/sys/fcntl.yo +14 -22
  159. package/std/sys/file.yo +26 -40
  160. package/std/sys/future.yo +5 -8
  161. package/std/sys/iov.yo +12 -25
  162. package/std/sys/lock.yo +12 -13
  163. package/std/sys/mmap.yo +38 -43
  164. package/std/sys/path.yo +3 -8
  165. package/std/sys/perm.yo +7 -21
  166. package/std/sys/pipe.yo +5 -12
  167. package/std/sys/process.yo +23 -29
  168. package/std/sys/seek.yo +10 -12
  169. package/std/sys/signal.yo +7 -13
  170. package/std/sys/signals.yo +52 -35
  171. package/std/sys/socket.yo +63 -58
  172. package/std/sys/socketpair.yo +3 -6
  173. package/std/sys/sockinfo.yo +11 -20
  174. package/std/sys/statfs.yo +11 -34
  175. package/std/sys/statx.yo +25 -52
  176. package/std/sys/sysinfo.yo +15 -20
  177. package/std/sys/tcp.yo +62 -92
  178. package/std/sys/temp.yo +5 -9
  179. package/std/sys/time.yo +5 -15
  180. package/std/sys/timer.yo +6 -11
  181. package/std/sys/tty.yo +10 -18
  182. package/std/sys/udp.yo +22 -39
  183. package/std/sys/umask.yo +3 -6
  184. package/std/sys/unix.yo +33 -52
  185. package/std/testing/bench.yo +49 -52
  186. package/std/thread.yo +10 -15
  187. package/std/time/datetime.yo +105 -89
  188. package/std/time/duration.yo +43 -56
  189. package/std/time/instant.yo +13 -18
  190. package/std/time/sleep.yo +5 -9
  191. package/std/url/index.yo +184 -209
  192. package/std/worker.yo +6 -10
  193. package/out/types/src/evaluator/calls/module-type.d.ts +0 -11
  194. package/out/types/src/evaluator/types/module.d.ts +0 -19
package/std/sys/unix.yo CHANGED
@@ -3,132 +3,113 @@
3
3
  //! Provides Unix domain socket wrappers around the low-level C runtime externs.
4
4
  //! Reuses the socket ops (bind/listen/accept/connect/send/recv/close) from the
5
5
  //! generic socket externs. Uses `sockaddr_un` helpers to build address buffers.
6
-
7
- { GlobalAllocator } :: import "../allocator.yo";
6
+ { GlobalAllocator } :: import("../allocator.yo");
8
7
  { malloc, free } :: GlobalAllocator;
9
- { IOFuture } :: import "./future.yo";
10
- {
11
- __yo_async_socket_start, __yo_async_bind_start,
12
- __yo_async_listen_start, __yo_async_accept_start,
13
- __yo_async_connect_start, __yo_async_send_start,
14
- __yo_async_recv_start, __yo_async_close_start,
15
- __yo_sockaddr_un_set_path,
16
- __yo_sockaddr_un_get_path, __yo_sockaddr_set_family
17
- } :: import "./externs.yo";
18
- {
19
- AF_UNIX, SOCK_STREAM, SOCK_DGRAM,
20
- sockaddr_un_size
21
- } :: import "./socket.yo";
22
-
8
+ { IOFuture } :: import("./future.yo");
9
+ { __yo_async_socket_start, __yo_async_bind_start, __yo_async_listen_start, __yo_async_accept_start, __yo_async_connect_start, __yo_async_send_start, __yo_async_recv_start, __yo_async_close_start, __yo_sockaddr_un_set_path, __yo_sockaddr_un_get_path, __yo_sockaddr_set_family } :: import("./externs.yo");
10
+ { AF_UNIX, SOCK_STREAM, SOCK_DGRAM, sockaddr_un_size } :: import("./socket.yo");
23
11
  // ============================================================================
24
12
  // UnixAddr - sockaddr_un buffer with pointer and length
25
13
  // ============================================================================
26
-
27
14
  UnixAddr :: struct(
28
15
  buf : ?*(u8),
29
16
  len : u32
30
17
  );
31
- export UnixAddr;
32
-
18
+ export(UnixAddr);
33
19
  // ============================================================================
34
20
  // Core Unix Socket Operations (return IOFuture, use with await)
35
21
  // ============================================================================
36
-
37
22
  // Create a Unix domain socket (SOCK_STREAM).
38
23
  // Returns fd on success, -errno on failure.
39
24
  socket_stream :: (fn() -> IOFuture)(
40
25
  __yo_async_socket_start(AF_UNIX, SOCK_STREAM, i32(0))
41
26
  );
42
-
43
27
  // Create a Unix domain socket (SOCK_DGRAM).
44
28
  // Returns fd on success, -errno on failure.
45
29
  socket_dgram :: (fn() -> IOFuture)(
46
30
  __yo_async_socket_start(AF_UNIX, SOCK_DGRAM, i32(0))
47
31
  );
48
-
49
32
  // Bind a socket to a local Unix address.
50
33
  // Returns 0 on success, -errno on failure.
51
- bind :: (fn(sockfd: i32, addr: *(u8), addrlen: u32) -> IOFuture)(
34
+ bind :: (fn(sockfd : i32, addr : *(u8), addrlen : u32) -> IOFuture)(
52
35
  __yo_async_bind_start(sockfd, addr, addrlen)
53
36
  );
54
-
55
37
  // Listen for incoming connections on a Unix socket.
56
38
  // Returns 0 on success, -errno on failure.
57
- listen :: (fn(sockfd: i32, backlog: i32) -> IOFuture)(
39
+ listen :: (fn(sockfd : i32, backlog : i32) -> IOFuture)(
58
40
  __yo_async_listen_start(sockfd, backlog)
59
41
  );
60
-
61
42
  // Accept an incoming connection.
62
43
  // Returns fd on success, -errno on failure.
63
- accept :: (fn(sockfd: i32, addr: *(u8), addrlen: *(u32)) -> IOFuture)(
44
+ accept :: (fn(sockfd : i32, addr : *(u8), addrlen : *(u32)) -> IOFuture)(
64
45
  __yo_async_accept_start(sockfd, addr, addrlen)
65
46
  );
66
-
67
47
  // Connect to a Unix socket address.
68
48
  // Returns 0 on success, -errno on failure.
69
- connect :: (fn(sockfd: i32, addr: *(u8), addrlen: u32) -> IOFuture)(
49
+ connect :: (fn(sockfd : i32, addr : *(u8), addrlen : u32) -> IOFuture)(
70
50
  __yo_async_connect_start(sockfd, addr, addrlen)
71
51
  );
72
-
73
52
  // Send data on a connected Unix socket.
74
53
  // Returns number of bytes sent on success, -errno on failure.
75
- send :: (fn(sockfd: i32, buf: *(u8), len: usize, flags: i32) -> IOFuture)(
54
+ send :: (fn(sockfd : i32, buf : *(u8), len : usize, flags : i32) -> IOFuture)(
76
55
  __yo_async_send_start(sockfd, buf, len, flags)
77
56
  );
78
-
79
57
  // Receive data from a connected Unix socket.
80
58
  // Returns number of bytes received on success, -errno on failure.
81
- recv :: (fn(sockfd: i32, buf: *(u8), len: usize, flags: i32) -> IOFuture)(
59
+ recv :: (fn(sockfd : i32, buf : *(u8), len : usize, flags : i32) -> IOFuture)(
82
60
  __yo_async_recv_start(sockfd, buf, len, flags)
83
61
  );
84
-
85
62
  // Close a Unix socket file descriptor.
86
63
  // Returns 0 on success, -errno on failure.
87
- close :: (fn(fd: i32) -> IOFuture)(
64
+ close :: (fn(fd : i32) -> IOFuture)(
88
65
  __yo_async_close_start(fd)
89
66
  );
90
-
91
67
  // ============================================================================
92
68
  // Unix Socket Address Helpers
93
69
  // ============================================================================
94
-
95
70
  // Create a sockaddr_un from a filesystem path.
96
71
  // The path must be a null-terminated C string.
97
72
  // Returns a UnixAddr with allocated buffer. Caller must free the buffer.
98
- make_sockaddr_un :: (fn(path: *(u8)) -> UnixAddr)({
73
+ make_sockaddr_un :: (fn(path : *(u8)) -> UnixAddr)({
99
74
  size := sockaddr_un_size();
100
75
  cond(
101
76
  (size == usize(0)) => UnixAddr(.None, u32(0)),
102
77
  true => {
103
78
  buf := *(u8)(malloc(size).unwrap());
104
79
  i := usize(0);
105
- while runtime((i < size)), {
80
+ while(runtime(i < size), {
106
81
  (buf &+ i).* = u8(0);
107
82
  i = (i + usize(1));
108
- };
83
+ });
109
84
  __yo_sockaddr_set_family(buf, u16(AF_UNIX));
110
85
  __yo_sockaddr_un_set_path(buf, path);
111
86
  UnixAddr(.Some(buf), u32(size))
112
87
  }
113
88
  )
114
89
  });
115
-
116
90
  // Extract the path from a sockaddr_un buffer.
117
- get_path :: (fn(addr_buf: *(u8)) -> *(u8))(
91
+ get_path :: (fn(addr_buf : *(u8)) -> *(u8))(
118
92
  __yo_sockaddr_un_get_path(addr_buf)
119
93
  );
120
-
121
94
  // Free a UnixAddr buffer.
122
- free_addr :: (fn(addr: UnixAddr) -> unit)(
123
- match(addr.buf,
95
+ free_addr :: (fn(addr : UnixAddr) -> unit)(
96
+ match(
97
+ addr.buf,
124
98
  .Some(p) => free(.Some(*(void)(p))),
125
99
  .None => ()
126
100
  )
127
101
  );
128
-
129
- export
130
- socket_stream, socket_dgram,
131
- bind, listen, accept, connect,
132
- send, recv, close,
133
- make_sockaddr_un, get_path, free_addr
134
- ;
102
+ export(
103
+ socket_stream,
104
+ socket_dgram,
105
+ bind,
106
+ listen,
107
+ accept,
108
+ connect,
109
+ send,
110
+ recv,
111
+ close,
112
+ make_sockaddr_un,
113
+ get_path,
114
+ free_addr
115
+ );
@@ -11,100 +11,97 @@
11
11
  //! result := bench(`sort`, u64(1000), () => { /* work */ });
12
12
  //! println(result.to_string());
13
13
  //! ```
14
-
15
- open import "../string";
16
- { ToString } :: import "../fmt";
17
- { snprintf } :: import "../libc/stdio";
18
- { Instant } :: import "../time/instant";
19
-
14
+ open(import("../string"));
15
+ { ToString } :: import("../fmt");
16
+ { snprintf } :: import("../libc/stdio");
17
+ { Instant } :: import("../time/instant");
20
18
  // ============================================================================
21
19
  // BenchResult
22
20
  // ============================================================================
23
-
24
21
  /// Timing statistics returned by `bench`.
25
22
  BenchResult :: struct(
26
23
  /// Benchmark name.
27
- name : String,
24
+ name : String,
28
25
  /// Total number of iterations executed.
29
26
  iterations : u64,
30
27
  /// Total elapsed nanoseconds across all iterations.
31
- total_ns : i64,
28
+ total_ns : i64,
32
29
  /// Average nanoseconds per iteration.
33
- avg_ns : i64,
30
+ avg_ns : i64,
34
31
  /// Minimum nanoseconds for a single iteration.
35
- min_ns : i64,
32
+ min_ns : i64,
36
33
  /// Maximum nanoseconds for a single iteration.
37
- max_ns : i64
34
+ max_ns : i64
38
35
  );
39
-
40
- _i64_to_string :: (fn(v: i64) -> String)({
36
+ _i64_to_string :: (fn(v : i64) -> String)({
41
37
  buf := Array(u8, usize(32)).fill(u8(0));
42
38
  buf_ptr := &(buf(usize(0)));
43
39
  snprintf(*(char)(buf_ptr), usize(32), "%lld", v);
44
40
  String.from_cstr(buf_ptr).unwrap()
45
41
  });
46
-
47
- _u64_to_string :: (fn(v: u64) -> String)({
42
+ _u64_to_string :: (fn(v : u64) -> String)({
48
43
  buf := Array(u8, usize(32)).fill(u8(0));
49
44
  buf_ptr := &(buf(usize(0)));
50
45
  snprintf(*(char)(buf_ptr), usize(32), "%llu", v);
51
46
  String.from_cstr(buf_ptr).unwrap()
52
47
  });
53
-
54
- impl(BenchResult, ToString(
55
- to_string : (fn(self: *(Self)) -> String)({
56
- prefix := String.from("bench '");
57
- part1 := prefix.concat(self.name);
58
- part2 := part1.concat(String.from("': iters="));
59
- part3 := part2.concat(_u64_to_string(self.iterations));
60
- part4 := part3.concat(String.from(" avg_ns="));
61
- part5 := part4.concat(_i64_to_string(self.avg_ns));
62
- part6 := part5.concat(String.from(" min="));
63
- part7 := part6.concat(_i64_to_string(self.min_ns));
64
- part8 := part7.concat(String.from(" max="));
65
- part8.concat(_i64_to_string(self.max_ns))
66
- })
67
- ));
68
-
69
- export BenchResult;
70
-
48
+ impl(
49
+ BenchResult,
50
+ ToString(
51
+ to_string : (fn(self : *(Self)) -> String)({
52
+ prefix := String.from("bench '");
53
+ part1 := prefix.concat(self.name);
54
+ part2 := part1.concat(String.from("': iters="));
55
+ part3 := part2.concat(_u64_to_string(self.iterations));
56
+ part4 := part3.concat(String.from(" avg_ns="));
57
+ part5 := part4.concat(_i64_to_string(self.avg_ns));
58
+ part6 := part5.concat(String.from(" min="));
59
+ part7 := part6.concat(_i64_to_string(self.min_ns));
60
+ part8 := part7.concat(String.from(" max="));
61
+ part8.concat(_i64_to_string(self.max_ns))
62
+ })
63
+ )
64
+ );
65
+ export(BenchResult);
71
66
  // ============================================================================
72
67
  // bench
73
68
  // ============================================================================
74
-
75
69
  /// Run `body` for `iterations` times and return timing statistics.
76
- bench :: (fn(name: String, iterations: u64, body: Impl(Fn() -> unit)) -> BenchResult)({
70
+ bench :: (fn(name : String, iterations : u64, body : Impl(Fn() -> unit)) -> BenchResult)({
77
71
  total_ns := i64(0);
78
- min_ns := i64(9223372036854775807); // i64::MAX
79
- max_ns := i64(0);
80
- i := u64(0);
81
- while (i < iterations), (i = (i + u64(1))), {
72
+ min_ns := i64(9223372036854775807); // i64::MAX
73
+ max_ns := i64(0);
74
+ i := u64(0);
75
+ while(i < iterations, i = (i + u64(1)), {
82
76
  t_start := Instant.now();
83
77
  body();
84
- t_end := Instant.now();
78
+ t_end := Instant.now();
85
79
  elapsed := t_end.duration_since(t_start).as_nanos();
86
80
  total_ns = (total_ns + elapsed);
87
81
  cond(
88
- (elapsed < min_ns) => { min_ns = elapsed; },
82
+ (elapsed < min_ns) => {
83
+ min_ns = elapsed;
84
+ },
89
85
  true => ()
90
86
  );
91
87
  cond(
92
- (elapsed > max_ns) => { max_ns = elapsed; },
88
+ (elapsed > max_ns) => {
89
+ max_ns = elapsed;
90
+ },
93
91
  true => ()
94
92
  );
95
- };
93
+ });
96
94
  avg_ns := cond(
97
95
  (iterations > u64(0)) => (total_ns / i64(iterations)),
98
96
  true => i64(0)
99
97
  );
100
98
  BenchResult(
101
- name: name,
102
- iterations: iterations,
103
- total_ns: total_ns,
104
- avg_ns: avg_ns,
105
- min_ns: min_ns,
106
- max_ns: max_ns
99
+ name : name,
100
+ iterations : iterations,
101
+ total_ns : total_ns,
102
+ avg_ns : avg_ns,
103
+ min_ns : min_ns,
104
+ max_ns : max_ns
107
105
  )
108
106
  });
109
-
110
- export bench;
107
+ export(bench);
package/std/thread.yo CHANGED
@@ -1,47 +1,42 @@
1
1
  //! OS thread creation and management with per-thread IO event loops.
2
-
3
- extern "Yo",
2
+ extern(
3
+ "Yo",
4
4
  __yo_thread_get_hardware_threads : (fn() -> usize),
5
5
  __yo_get_thread_id : (fn() -> usize),
6
6
  __yo_get_cpu_id : (fn() -> i32)
7
- ;
8
-
9
- extern "Yo",
7
+ );
8
+ extern(
9
+ "Yo",
10
10
  __yo_thread_t : Type,
11
11
  __yo_thread_spawn : (fn(cb : Impl(Fn(using(io : IO)) -> unit, Send)) -> __yo_thread_t),
12
12
  __yo_thread_join : (fn(t : __yo_thread_t) -> unit)
13
- ;
14
-
13
+ );
15
14
  /// OS thread handle. Each spawned thread gets its own IO event loop.
16
15
  Thread :: struct(
17
16
  handle : __yo_thread_t
18
17
  );
19
- impl(Thread,
18
+ impl(
19
+ Thread,
20
20
  /// Spawn a new OS thread running the given closure.
21
21
  /// The closure receives its own per-thread IO event loop.
22
22
  spawn : (fn(cb : Impl(Fn(using(io : IO)) -> unit, Send)) -> Self)({
23
23
  raw := __yo_thread_spawn(cb);
24
24
  Self(raw)
25
25
  }),
26
-
27
26
  /// Block the current thread until this thread completes.
28
27
  join : (fn(self : *(Self)) -> unit)(
29
28
  __yo_thread_join(self.handle)
30
29
  )
31
30
  );
32
-
33
31
  /// Get the number of hardware threads (CPU cores) available.
34
32
  get_hardware_threads :: __yo_thread_get_hardware_threads;
35
-
36
33
  /// Get the current OS thread ID.
37
34
  get_thread_id :: __yo_get_thread_id;
38
-
39
35
  /// Get the current CPU core ID.
40
36
  get_cpu_id :: __yo_get_cpu_id;
41
-
42
- export
37
+ export(
43
38
  get_hardware_threads,
44
39
  get_thread_id,
45
40
  get_cpu_id,
46
41
  Thread
47
- ;
42
+ );
@@ -8,41 +8,45 @@
8
8
  //! now := DateTime.now_utc();
9
9
  //! println(now.to_string()); // "2026-02-26T17:41:24Z"
10
10
  //! ```
11
-
12
- { String } :: import "../string";
13
- { ToString } :: import "../fmt";
14
- { CLOCK_REALTIME, clock_gettime } :: import "../sys/clock";
15
- { snprintf } :: import "../libc/stdio";
16
-
11
+ { String } :: import("../string");
12
+ { ToString } :: import("../fmt");
13
+ { CLOCK_REALTIME, clock_gettime } :: import("../sys/clock");
14
+ { snprintf } :: import("../libc/stdio");
17
15
  /// Calendar date and time with nanosecond precision.
18
16
  /// Values are in UTC unless `utc_offset_secs` is non-zero.
19
17
  DateTime :: struct(
20
- year : i32,
21
- month : u8,
22
- day : u8,
23
- hour : u8,
24
- minute : u8,
25
- second : u8,
26
- nanosecond : u32,
18
+ year : i32,
19
+ month : u8,
20
+ day : u8,
21
+ hour : u8,
22
+ minute : u8,
23
+ second : u8,
24
+ nanosecond : u32,
27
25
  utc_offset_secs : i32
28
26
  );
29
-
30
27
  // Days per month lookup (non-leap year)
31
28
  _DAYS_IN_MONTH :: Array(u8, usize(12))(
32
- u8(31), u8(28), u8(31), u8(30), u8(31), u8(30),
33
- u8(31), u8(31), u8(30), u8(31), u8(30), u8(31)
29
+ u8(31),
30
+ u8(28),
31
+ u8(31),
32
+ u8(30),
33
+ u8(31),
34
+ u8(30),
35
+ u8(31),
36
+ u8(31),
37
+ u8(30),
38
+ u8(31),
39
+ u8(30),
40
+ u8(31)
34
41
  );
35
-
36
- _is_leap_year :: (fn(y: i32) -> bool)(
37
- (((y % i32(4)) == i32(0)) && (((y % i32(100)) != i32(0)) || ((y % i32(400)) == i32(0))))
42
+ _is_leap_year :: (fn(y : i32) -> bool)(
43
+ ((y % i32(4)) == i32(0)) && (((y % i32(100)) != i32(0)) || ((y % i32(400)) == i32(0)))
38
44
  );
39
-
40
45
  // Convert a Unix timestamp (seconds since 1970-01-01 UTC) into date/time fields.
41
- _from_unix_secs :: (fn(secs: i64, nanos: i64) -> DateTime)({
46
+ _from_unix_secs :: (fn(secs : i64, nanos : i64) -> DateTime)({
42
47
  // Adjust epoch: number of days since Unix epoch
43
48
  days := (secs / i64(86400));
44
- rem := (secs % i64(86400));
45
-
49
+ rem := (secs % i64(86400));
46
50
  // Normalise negative remainders
47
51
  rem_adj := cond(
48
52
  (rem < i64(0)) => (rem + i64(86400)),
@@ -52,68 +56,62 @@ _from_unix_secs :: (fn(secs: i64, nanos: i64) -> DateTime)({
52
56
  (rem < i64(0)) => (days - i64(1)),
53
57
  true => days
54
58
  );
55
-
56
- hour := u8((rem_adj / i64(3600)));
57
- min_r := (rem_adj % i64(3600));
58
- minute := u8((min_r / i64(60)));
59
- second := u8((min_r % i64(60)));
60
-
59
+ hour := u8(rem_adj / i64(3600));
60
+ min_r := (rem_adj % i64(3600));
61
+ minute := u8(min_r / i64(60));
62
+ second := u8(min_r % i64(60));
61
63
  // Gregorian calendar computation starting from 1970-01-01
62
64
  // Using the algorithm from days since epoch → year/month/day
63
65
  z := (days_adj + i64(719468));
64
66
  era := cond(
65
67
  (z >= i64(0)) => (z / i64(146097)),
66
- true => (((z - i64(146096)) / i64(146097)))
68
+ true => ((z - i64(146096)) / i64(146097))
67
69
  );
68
- doe := (z - (era * i64(146097)));
69
- yoe := (((doe - (doe / i64(1460))) + (doe / i64(36524))) - (doe / i64(146096)));
70
- yoe = (yoe / i64(365));
71
- y := (yoe + (era * i64(400)));
72
- doy := (doe - (((i64(365) * yoe) + (yoe / i64(4))) - (yoe / i64(100))));
73
- mp := (((i64(5) * doy) + i64(2)) / i64(153));
74
- d := (doy - (((i64(153) * mp) + i64(2)) / i64(5)));
75
- m := cond(
70
+ doe := (z - (era * i64(146097)));
71
+ yoe := (((doe - (doe / i64(1460))) + (doe / i64(36524))) - (doe / i64(146096)));
72
+ yoe = (yoe / i64(365));
73
+ y := (yoe + (era * i64(400)));
74
+ doy := (doe - (((i64(365) * yoe) + (yoe / i64(4))) - (yoe / i64(100))));
75
+ mp := (((i64(5) * doy) + i64(2)) / i64(153));
76
+ d := (doy - (((i64(153) * mp) + i64(2)) / i64(5)));
77
+ m := cond(
76
78
  (mp < i64(10)) => (mp + i64(3)),
77
79
  true => (mp - i64(9))
78
80
  );
79
- y2 := cond(
81
+ y2 := cond(
80
82
  (m <= i64(2)) => (y + i64(1)),
81
83
  true => y
82
84
  );
83
-
84
85
  DateTime(
85
- year: i32(y2),
86
- month: u8(m),
87
- day: u8((d + i64(1))),
88
- hour: hour,
89
- minute: minute,
90
- second: second,
91
- nanosecond: u32(nanos),
92
- utc_offset_secs: i32(0)
86
+ year : i32(y2),
87
+ month : u8(m),
88
+ day : u8(d + i64(1)),
89
+ hour : hour,
90
+ minute : minute,
91
+ second : second,
92
+ nanosecond : u32(nanos),
93
+ utc_offset_secs : i32(0)
93
94
  )
94
95
  });
95
-
96
- impl(DateTime,
96
+ impl(
97
+ DateTime,
97
98
  // Current UTC date/time.
98
99
  now_utc : (fn() -> Self)({
99
- sec := i64(0);
100
+ sec := i64(0);
100
101
  nsec := i64(0);
101
- clock_gettime(CLOCK_REALTIME, (&sec), (&nsec));
102
+ clock_gettime(CLOCK_REALTIME, &(sec), &(nsec));
102
103
  _from_unix_secs(sec, nsec)
103
104
  }),
104
-
105
105
  // Current local date/time (UTC offset not resolved; same as now_utc for now).
106
106
  now : (fn() -> Self)(
107
107
  DateTime.now_utc()
108
108
  ),
109
-
110
109
  // Construct from a Unix timestamp.
111
- from_unix : (fn(secs: i64, nanos: i64) -> Self)(
110
+ from_unix : (fn(secs : i64, nanos : i64) -> Self)(
112
111
  _from_unix_secs(secs, nanos)
113
112
  ),
114
-
115
113
  // Convert back to a Unix timestamp (seconds since epoch).
116
- to_unix : (fn(self: *(Self)) -> i64)({
114
+ to_unix : (fn(self : *(Self)) -> i64)({
117
115
  // Compute days since epoch using the inverse Gregorian algorithm
118
116
  y := i64(self.year);
119
117
  m := i64(self.month);
@@ -124,10 +122,10 @@ impl(DateTime,
124
122
  );
125
123
  era := cond(
126
124
  (y2 >= i64(0)) => (y2 / i64(400)),
127
- true => (((y2 - i64(399)) / i64(400)))
125
+ true => ((y2 - i64(399)) / i64(400))
128
126
  );
129
127
  yoe := (y2 - (era * i64(400)));
130
- mp := cond(
128
+ mp := cond(
131
129
  (m > i64(2)) => (m - i64(3)),
132
130
  true => (m + i64(9))
133
131
  );
@@ -135,43 +133,52 @@ impl(DateTime,
135
133
  doe := ((((yoe * i64(365)) + (yoe / i64(4))) - (yoe / i64(100))) + doy);
136
134
  days := (((era * i64(146097)) + doe) - i64(719468));
137
135
  time_secs := (((i64(self.hour) * i64(3600)) + (i64(self.minute) * i64(60))) + i64(self.second));
138
- ((days * i64(86400)) + time_secs)
136
+ (days * i64(86400)) + time_secs
139
137
  }),
140
-
141
138
  // True if this year is a leap year.
142
- is_leap_year : (fn(self: *(Self)) -> bool)(
139
+ is_leap_year : (fn(self : *(Self)) -> bool)(
143
140
  _is_leap_year(self.year)
144
141
  ),
145
-
146
142
  // Day of week: 0 = Monday, 6 = Sunday (ISO 8601).
147
- day_of_week : (fn(self: *(Self)) -> u8)({
143
+ day_of_week : (fn(self : *(Self)) -> u8)({
148
144
  // Tomohiko Sakamoto's algorithm
149
145
  t := Array(i32, usize(12))(
150
- i32(0), i32(3), i32(2), i32(5), i32(0), i32(3),
151
- i32(5), i32(1), i32(4), i32(6), i32(2), i32(4)
146
+ i32(0),
147
+ i32(3),
148
+ i32(2),
149
+ i32(5),
150
+ i32(0),
151
+ i32(3),
152
+ i32(5),
153
+ i32(1),
154
+ i32(4),
155
+ i32(6),
156
+ i32(2),
157
+ i32(4)
152
158
  );
153
159
  y := cond(
154
160
  (i32(self.month) < i32(3)) => (self.year - i32(1)),
155
161
  true => self.year
156
162
  );
157
- sum := (((((y + (y / i32(4))) - (y / i32(100))) + (y / i32(400))) + t(usize((i32(self.month) - i32(1))))) + i32(self.day));
163
+ sum := (((((y + (y / i32(4))) - (y / i32(100))) + (y / i32(400))) + t(usize(i32(self.month) - i32(1)))) + i32(self.day));
158
164
  dow := (sum % i32(7));
159
165
  // Convert: 0=Sun → remap to 0=Mon
160
- u8(cond(
161
- (dow == i32(0)) => i32(6),
162
- true => (dow - i32(1))
163
- ))
166
+ u8(
167
+ cond(
168
+ (dow == i32(0)) => i32(6),
169
+ true => (dow - i32(1))
170
+ )
171
+ )
164
172
  }),
165
-
166
173
  // Day of year (1-based).
167
- day_of_year : (fn(self: *(Self)) -> u16)({
174
+ day_of_year : (fn(self : *(Self)) -> u16)({
168
175
  m := i32(self.month);
169
176
  d := i32(self.day);
170
177
  // Sum days in preceding months
171
178
  days := d;
172
179
  i := i32(1);
173
- while (i < m), (i = (i + i32(1))), {
174
- idx := usize((i - i32(1)));
180
+ while(i < m, i = (i + i32(1)), {
181
+ idx := usize(i - i32(1));
175
182
  days = (days + i32(_DAYS_IN_MONTH(idx)));
176
183
  // Add leap day after Feb in a leap year
177
184
  cond(
@@ -180,20 +187,29 @@ impl(DateTime,
180
187
  },
181
188
  true => ()
182
189
  );
183
- };
190
+ });
184
191
  u16(days)
185
192
  })
186
193
  );
187
-
188
- impl(DateTime, ToString(
189
- to_string : (fn(self: *(Self)) -> String)({
190
- buf := Array(u8, usize(32)).fill(u8(0));
191
- buf_ptr := &(buf(usize(0)));
192
- snprintf(*(char)(buf_ptr), usize(32), "%04d-%02u-%02uT%02u:%02u:%02uZ",
193
- self.year, self.month, self.day,
194
- self.hour, self.minute, self.second);
195
- String.from_cstr(buf_ptr).unwrap()
196
- })
197
- ));
198
-
199
- export DateTime;
194
+ impl(
195
+ DateTime,
196
+ ToString(
197
+ to_string : (fn(self : *(Self)) -> String)({
198
+ buf := Array(u8, usize(32)).fill(u8(0));
199
+ buf_ptr := &(buf(usize(0)));
200
+ snprintf(
201
+ *(char)(buf_ptr),
202
+ usize(32),
203
+ "%04d-%02u-%02uT%02u:%02u:%02uZ",
204
+ self.year,
205
+ self.month,
206
+ self.day,
207
+ self.hour,
208
+ self.minute,
209
+ self.second
210
+ );
211
+ String.from_cstr(buf_ptr).unwrap()
212
+ })
213
+ )
214
+ );
215
+ export(DateTime);