@shd101wyy/yo 0.1.26 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/.github/skills/yo-async-effects/SKILL.md +4 -4
  2. package/.github/skills/yo-async-effects/async-effects-recipes.md +34 -34
  3. package/.github/skills/yo-core-patterns/SKILL.md +1 -1
  4. package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +26 -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 +73 -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 +456 -438
  12. package/out/cjs/yo-cli.cjs +576 -543
  13. package/out/cjs/yo-lsp.cjs +559 -532
  14. package/out/esm/index.mjs +281 -263
  15. package/out/types/src/formatter.d.ts +11 -0
  16. package/out/types/src/lsp/formatting.d.ts +2 -0
  17. package/out/types/src/tests/formatter.test.d.ts +1 -0
  18. package/out/types/tsconfig.tsbuildinfo +1 -1
  19. package/package.json +1 -1
  20. package/std/alg/hash.yo +13 -21
  21. package/std/allocator.yo +25 -40
  22. package/std/async.yo +3 -7
  23. package/std/build.yo +105 -151
  24. package/std/cli/arg_parser.yo +184 -169
  25. package/std/collections/array_list.yo +350 -314
  26. package/std/collections/btree_map.yo +142 -131
  27. package/std/collections/deque.yo +132 -128
  28. package/std/collections/hash_map.yo +542 -566
  29. package/std/collections/hash_set.yo +623 -687
  30. package/std/collections/linked_list.yo +275 -293
  31. package/std/collections/ordered_map.yo +113 -85
  32. package/std/collections/priority_queue.yo +73 -73
  33. package/std/crypto/md5.yo +191 -95
  34. package/std/crypto/random.yo +56 -64
  35. package/std/crypto/sha256.yo +151 -107
  36. package/std/encoding/base64.yo +87 -81
  37. package/std/encoding/hex.yo +43 -50
  38. package/std/encoding/html.yo +56 -81
  39. package/std/encoding/html_char_utils.yo +7 -13
  40. package/std/encoding/html_entities.yo +2248 -2253
  41. package/std/encoding/json.yo +316 -224
  42. package/std/encoding/punycode.yo +86 -116
  43. package/std/encoding/toml.yo +67 -66
  44. package/std/encoding/utf16.yo +37 -44
  45. package/std/env.yo +62 -91
  46. package/std/error.yo +7 -15
  47. package/std/fmt/display.yo +5 -9
  48. package/std/fmt/index.yo +8 -14
  49. package/std/fmt/to_string.yo +330 -315
  50. package/std/fmt/writer.yo +58 -87
  51. package/std/fs/dir.yo +83 -102
  52. package/std/fs/file.yo +147 -180
  53. package/std/fs/metadata.yo +45 -78
  54. package/std/fs/temp.yo +55 -65
  55. package/std/fs/types.yo +27 -40
  56. package/std/fs/walker.yo +53 -68
  57. package/std/gc.yo +5 -8
  58. package/std/glob.yo +30 -43
  59. package/std/http/client.yo +107 -120
  60. package/std/http/http.yo +106 -96
  61. package/std/http/index.yo +4 -6
  62. package/std/imm/list.yo +88 -93
  63. package/std/imm/map.yo +528 -464
  64. package/std/imm/set.yo +52 -57
  65. package/std/imm/sorted_map.yo +340 -286
  66. package/std/imm/sorted_set.yo +57 -63
  67. package/std/imm/string.yo +404 -345
  68. package/std/imm/vec.yo +173 -181
  69. package/std/io/reader.yo +3 -6
  70. package/std/io/writer.yo +4 -8
  71. package/std/libc/assert.yo +5 -9
  72. package/std/libc/ctype.yo +32 -22
  73. package/std/libc/dirent.yo +26 -25
  74. package/std/libc/errno.yo +164 -90
  75. package/std/libc/fcntl.yo +52 -45
  76. package/std/libc/float.yo +66 -44
  77. package/std/libc/limits.yo +42 -33
  78. package/std/libc/math.yo +53 -82
  79. package/std/libc/signal.yo +72 -47
  80. package/std/libc/stdatomic.yo +217 -188
  81. package/std/libc/stdint.yo +5 -29
  82. package/std/libc/stdio.yo +5 -29
  83. package/std/libc/stdlib.yo +32 -39
  84. package/std/libc/string.yo +5 -23
  85. package/std/libc/sys/stat.yo +58 -56
  86. package/std/libc/time.yo +5 -19
  87. package/std/libc/unistd.yo +5 -20
  88. package/std/libc/wctype.yo +6 -9
  89. package/std/libc/windows.yo +26 -30
  90. package/std/log.yo +41 -55
  91. package/std/net/addr.yo +102 -97
  92. package/std/net/dns.yo +27 -28
  93. package/std/net/errors.yo +50 -49
  94. package/std/net/tcp.yo +113 -124
  95. package/std/net/udp.yo +55 -66
  96. package/std/os/env.yo +35 -33
  97. package/std/os/signal.yo +15 -25
  98. package/std/path.yo +276 -311
  99. package/std/prelude.yo +6304 -4315
  100. package/std/process/command.yo +87 -103
  101. package/std/process/index.yo +12 -31
  102. package/std/regex/compiler.yo +196 -95
  103. package/std/regex/flags.yo +58 -39
  104. package/std/regex/index.yo +157 -173
  105. package/std/regex/match.yo +20 -31
  106. package/std/regex/node.yo +134 -152
  107. package/std/regex/parser.yo +283 -259
  108. package/std/regex/unicode.yo +172 -202
  109. package/std/regex/vm.yo +155 -171
  110. package/std/string/index.yo +5 -7
  111. package/std/string/rune.yo +45 -55
  112. package/std/string/string.yo +937 -964
  113. package/std/string/string_builder.yo +94 -104
  114. package/std/string/unicode.yo +46 -64
  115. package/std/sync/channel.yo +72 -73
  116. package/std/sync/cond.yo +31 -36
  117. package/std/sync/mutex.yo +30 -32
  118. package/std/sync/once.yo +13 -16
  119. package/std/sync/rwlock.yo +26 -31
  120. package/std/sync/waitgroup.yo +20 -25
  121. package/std/sys/advise.yo +16 -24
  122. package/std/sys/bufio/buf_reader.yo +77 -93
  123. package/std/sys/bufio/buf_writer.yo +52 -65
  124. package/std/sys/clock.yo +4 -9
  125. package/std/sys/constants.yo +77 -61
  126. package/std/sys/copy.yo +4 -10
  127. package/std/sys/dir.yo +26 -43
  128. package/std/sys/dns.yo +41 -61
  129. package/std/sys/errors.yo +95 -103
  130. package/std/sys/events.yo +45 -57
  131. package/std/sys/externs.yo +319 -267
  132. package/std/sys/fallocate.yo +7 -11
  133. package/std/sys/fcntl.yo +14 -22
  134. package/std/sys/file.yo +26 -40
  135. package/std/sys/future.yo +5 -8
  136. package/std/sys/iov.yo +12 -25
  137. package/std/sys/lock.yo +12 -13
  138. package/std/sys/mmap.yo +38 -43
  139. package/std/sys/path.yo +3 -8
  140. package/std/sys/perm.yo +7 -21
  141. package/std/sys/pipe.yo +5 -12
  142. package/std/sys/process.yo +23 -29
  143. package/std/sys/seek.yo +10 -12
  144. package/std/sys/signal.yo +7 -13
  145. package/std/sys/signals.yo +52 -35
  146. package/std/sys/socket.yo +63 -58
  147. package/std/sys/socketpair.yo +3 -6
  148. package/std/sys/sockinfo.yo +11 -20
  149. package/std/sys/statfs.yo +11 -34
  150. package/std/sys/statx.yo +25 -52
  151. package/std/sys/sysinfo.yo +15 -20
  152. package/std/sys/tcp.yo +62 -92
  153. package/std/sys/temp.yo +5 -9
  154. package/std/sys/time.yo +5 -15
  155. package/std/sys/timer.yo +6 -11
  156. package/std/sys/tty.yo +10 -18
  157. package/std/sys/udp.yo +22 -39
  158. package/std/sys/umask.yo +3 -6
  159. package/std/sys/unix.yo +33 -52
  160. package/std/testing/bench.yo +49 -52
  161. package/std/thread.yo +10 -15
  162. package/std/time/datetime.yo +105 -89
  163. package/std/time/duration.yo +43 -56
  164. package/std/time/instant.yo +13 -18
  165. package/std/time/sleep.yo +5 -9
  166. package/std/url/index.yo +184 -209
  167. package/std/worker.yo +6 -10
@@ -18,60 +18,63 @@
18
18
  //! assert((val.unwrap() == i32(42)), "received value");
19
19
  //! t.join();
20
20
  //! ```
21
-
22
- { GlobalAllocator } :: import "../allocator";
21
+ { GlobalAllocator } :: import("../allocator");
23
22
  { malloc, free } :: GlobalAllocator;
24
- { Mutex } :: import "./mutex";
25
- { Cond } :: import "./cond";
26
-
23
+ { Mutex } :: import("./mutex");
24
+ { Cond } :: import("./cond");
27
25
  /// Thread-safe bounded channel for passing values between threads.
28
26
  /// Uses atomic reference counting — implements `Send` and can be
29
27
  /// safely shared across threads without `Arc` wrapping.
30
28
  /// T must implement `Send` to ensure values are safe to transfer between threads.
31
- Channel :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))
32
- atomic object(
33
- _data : *(T),
34
- _head : usize,
35
- _len : usize,
36
- _capacity : usize,
37
- _mutex : Mutex,
38
- _not_empty : Cond,
39
- _not_full : Cond,
40
- _closed : bool
29
+ Channel :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
30
+ atomic(
31
+ object(
32
+ _data : *(T),
33
+ _head : usize,
34
+ _len : usize,
35
+ _capacity : usize,
36
+ _mutex : Mutex,
37
+ _not_empty : Cond,
38
+ _not_full : Cond,
39
+ _closed : bool
40
+ )
41
41
  )
42
- ;
43
-
44
- impl(forall(T : Type), Channel(T), where(T <: Send),
42
+ );
43
+ impl(
44
+ forall(T : Type),
45
+ Channel(T),
46
+ where(T <: Send),
45
47
  /// Create a bounded channel with the given capacity.
46
48
  /// Capacity must be > 0.
47
- new : (fn(capacity: usize) -> Self)({
48
- assert((capacity > usize(0)), "Channel.new: capacity must be > 0");
49
- (ptr : *(T)) = *(T)(malloc((capacity * sizeof(T))).unwrap());
50
- return Self(
51
- _data: ptr,
52
- _head: usize(0),
53
- _len: usize(0),
54
- _capacity: capacity,
55
- _mutex: Mutex.new(),
56
- _not_empty: Cond.new(),
57
- _not_full: Cond.new(),
58
- _closed: false
49
+ new : (fn(capacity : usize) -> Self)({
50
+ assert(capacity > usize(0), "Channel.new: capacity must be > 0");
51
+ (ptr : *(T)) = *(T)(malloc(capacity * sizeof(T)).unwrap());
52
+ return(
53
+ Self(
54
+ _data : ptr,
55
+ _head : usize(0),
56
+ _len : usize(0),
57
+ _capacity : capacity,
58
+ _mutex : Mutex.new(),
59
+ _not_empty : Cond.new(),
60
+ _not_full : Cond.new(),
61
+ _closed : false
62
+ )
59
63
  );
60
64
  }),
61
-
62
65
  /// Send a value into the channel.
63
66
  /// Blocks if the channel is full until space becomes available.
64
67
  /// Returns .Ok(()) on success, .Err(()) if the channel is closed.
65
- send : (fn(self: Self, value: T) -> Result(unit, unit))({
68
+ send : (fn(self : Self, value : T) -> Result(unit, unit))({
66
69
  self._mutex.lock();
67
70
  // Wait while buffer is full and channel is not closed
68
- while runtime(((self._len >= self._capacity) && (!(self._closed)))), {
71
+ while(runtime((self._len >= self._capacity) && (!(self._closed))), {
69
72
  self._not_full.wait(self._mutex);
70
- };
73
+ });
71
74
  cond(
72
75
  self._closed => {
73
76
  self._mutex.unlock();
74
- return .Err(());
77
+ return(.Err(()));
75
78
  },
76
79
  true => ()
77
80
  );
@@ -81,22 +84,21 @@ impl(forall(T : Type), Channel(T), where(T <: Send),
81
84
  self._len = (self._len + usize(1));
82
85
  self._not_empty.signal();
83
86
  self._mutex.unlock();
84
- return .Ok(());
87
+ return(.Ok(()));
85
88
  }),
86
-
87
89
  /// Receive a value from the channel.
88
90
  /// Blocks if the channel is empty until a value is available.
89
91
  /// Returns .Some(value) on success, .None if the channel is closed and empty.
90
- recv : (fn(self: Self) -> ?T)({
92
+ recv : (fn(self : Self) -> ?(T))({
91
93
  self._mutex.lock();
92
94
  // Wait while buffer is empty and channel is not closed
93
- while runtime(((self._len == usize(0)) && (!(self._closed)))), {
95
+ while(runtime((self._len == usize(0)) && (!(self._closed))), {
94
96
  self._not_empty.wait(self._mutex);
95
- };
97
+ });
96
98
  cond(
97
99
  (self._len == usize(0)) => {
98
100
  self._mutex.unlock();
99
- return .None;
101
+ return(.None);
100
102
  },
101
103
  true => ()
102
104
  );
@@ -108,17 +110,16 @@ impl(forall(T : Type), Channel(T), where(T <: Send),
108
110
  self._len = (self._len - usize(1));
109
111
  self._not_full.signal();
110
112
  self._mutex.unlock();
111
- return .Some(val);
113
+ return(.Some(val));
112
114
  }),
113
-
114
115
  /// Try to send a value without blocking.
115
116
  /// Returns .Ok(()) if sent, .Err(()) if full or closed.
116
- try_send : (fn(self: Self, value: T) -> Result(unit, unit))({
117
+ try_send : (fn(self : Self, value : T) -> Result(unit, unit))({
117
118
  self._mutex.lock();
118
119
  cond(
119
120
  (self._closed || (self._len >= self._capacity)) => {
120
121
  self._mutex.unlock();
121
- return .Err(());
122
+ return(.Err(()));
122
123
  },
123
124
  true => ()
124
125
  );
@@ -127,17 +128,16 @@ impl(forall(T : Type), Channel(T), where(T <: Send),
127
128
  self._len = (self._len + usize(1));
128
129
  self._not_empty.signal();
129
130
  self._mutex.unlock();
130
- return .Ok(());
131
+ return(.Ok(()));
131
132
  }),
132
-
133
133
  /// Try to receive a value without blocking.
134
134
  /// Returns .Some(value) if available, .None if empty.
135
- try_recv : (fn(self: Self) -> ?T)({
135
+ try_recv : (fn(self : Self) -> ?(T))({
136
136
  self._mutex.lock();
137
137
  cond(
138
138
  (self._len == usize(0)) => {
139
139
  self._mutex.unlock();
140
- return .None;
140
+ return(.None);
141
141
  },
142
142
  true => ()
143
143
  );
@@ -148,47 +148,46 @@ impl(forall(T : Type), Channel(T), where(T <: Send),
148
148
  self._len = (self._len - usize(1));
149
149
  self._not_full.signal();
150
150
  self._mutex.unlock();
151
- return .Some(val);
151
+ return(.Some(val));
152
152
  }),
153
-
154
153
  /// Close the channel. No more values can be sent.
155
154
  /// Pending recv() calls will return .None once the buffer is drained.
156
155
  /// Pending send() calls will return .Err(()).
157
- close : (fn(self: Self) -> unit)({
156
+ close : (fn(self : Self) -> unit)({
158
157
  self._mutex.lock();
159
158
  self._closed = true;
160
159
  self._not_empty.broadcast();
161
160
  self._not_full.broadcast();
162
161
  self._mutex.unlock();
163
162
  }),
164
-
165
163
  /// Check if the channel is closed.
166
- is_closed : (fn(self: Self) -> bool)(
164
+ is_closed : (fn(self : Self) -> bool)(
167
165
  self._closed
168
166
  ),
169
-
170
167
  /// Return the number of values currently buffered.
171
- len : (fn(self: Self) -> usize)(
168
+ len : (fn(self : Self) -> usize)(
172
169
  self._len
173
170
  ),
174
-
175
171
  /// Check if the channel buffer is empty.
176
- is_empty : (fn(self: Self) -> bool)(
177
- (self._len == usize(0))
172
+ is_empty : (fn(self : Self) -> bool)(
173
+ self._len == usize(0)
178
174
  )
179
175
  );
180
-
181
176
  // Dispose: drop remaining elements and free the buffer
182
- impl(forall(T : Type), Channel(T), where(T <: Send), Dispose(
183
- dispose : (fn(self: Self) -> unit)({
184
- (i : usize) = usize(0);
185
- while runtime((i < self._len)), {
186
- (idx : usize) = ((self._head + i) % self._capacity);
187
- unsafe.drop((self._data &+ idx).*);
188
- i = (i + usize(1));
189
- };
190
- free(.Some(*(void)(self._data)));
191
- })
192
- ));
193
-
194
- export Channel;
177
+ impl(
178
+ forall(T : Type),
179
+ Channel(T),
180
+ where(T <: Send),
181
+ Dispose(
182
+ dispose : (fn(self : Self) -> unit)({
183
+ (i : usize) = usize(0);
184
+ while(runtime(i < self._len), {
185
+ (idx : usize) = ((self._head + i) % self._capacity);
186
+ unsafe.drop((self._data &+ idx).*);
187
+ i = (i + usize(1));
188
+ });
189
+ free(.Some(*(void)(self._data)));
190
+ })
191
+ )
192
+ );
193
+ export(Channel);
package/std/sync/cond.yo CHANGED
@@ -1,74 +1,69 @@
1
1
  //! Condition variable for thread synchronization.
2
-
3
- { __YO_THREAD_SYNC_TYPE, mutex_t, Mutex } :: import "./mutex";
4
-
5
- extern "Yo",
2
+ { __YO_THREAD_SYNC_TYPE, mutex_t, Mutex } :: import("./mutex");
3
+ extern(
4
+ "Yo",
6
5
  __YO_COND_TYPE : Type,
7
6
  __yo_cond_create : (fn() -> __YO_COND_TYPE),
8
7
  __yo_cond_wait : (fn(cv : *(__YO_COND_TYPE), mutex : *(__YO_THREAD_SYNC_TYPE)) -> unit),
9
8
  __yo_cond_signal : (fn(cv : *(__YO_COND_TYPE)) -> unit),
10
9
  __yo_cond_broadcast : (fn(cv : *(__YO_COND_TYPE)) -> unit),
11
10
  __yo_cond_destroy : (fn(cv : *(__YO_COND_TYPE)) -> unit)
12
- ;
13
-
11
+ );
14
12
  impl(__YO_COND_TYPE, Send());
15
13
  impl(__YO_COND_TYPE, Acyclic());
16
-
17
14
  /// Low-level condition variable (manual lifetime via `destroy`).
18
15
  cond_t :: newtype(
19
16
  cv : __YO_COND_TYPE
20
17
  );
21
- impl(cond_t,
18
+ impl(
19
+ cond_t,
22
20
  new : (fn() -> Self)({
23
- return Self(__yo_cond_create());
21
+ return(Self(__yo_cond_create()));
24
22
  }),
25
-
26
23
  wait : (fn(self : *(Self), mutex : *(mutex_t)) -> unit)({
27
- return __yo_cond_wait(&(self.cv), &(mutex.mutex));
24
+ return(__yo_cond_wait(&(self.cv), &(mutex.mutex)));
28
25
  }),
29
-
30
26
  signal : (fn(self : *(Self)) -> unit)({
31
- return __yo_cond_signal(&(self.cv));
27
+ return(__yo_cond_signal(&(self.cv)));
32
28
  }),
33
-
34
29
  broadcast : (fn(self : *(Self)) -> unit)({
35
- return __yo_cond_broadcast(&(self.cv));
30
+ return(__yo_cond_broadcast(&(self.cv)));
36
31
  }),
37
-
38
32
  destroy : (fn(self : *(Self)) -> unit)({
39
- return __yo_cond_destroy(&(self.cv));
33
+ return(__yo_cond_destroy(&(self.cv)));
40
34
  })
41
35
  );
42
-
43
36
  /// Reference-counted condition variable with automatic cleanup via `Dispose`.
44
37
  /// Uses atomic reference counting for safe cross-thread sharing.
45
- Cond :: atomic object(
46
- cv : __YO_COND_TYPE
38
+ Cond :: atomic(
39
+ object(
40
+ cv : __YO_COND_TYPE
41
+ )
47
42
  );
48
- impl(Cond,
43
+ impl(
44
+ Cond,
49
45
  new : (fn() -> Self)({
50
- return Self(__yo_cond_create());
46
+ return(Self(__yo_cond_create()));
51
47
  }),
52
-
53
48
  wait : (fn(self : Self, mutex : Mutex) -> unit)({
54
- return __yo_cond_wait(&(self.cv), &(mutex.mutex));
49
+ return(__yo_cond_wait(&(self.cv), &(mutex.mutex)));
55
50
  }),
56
-
57
51
  signal : (fn(self : Self) -> unit)({
58
- return __yo_cond_signal(&(self.cv));
52
+ return(__yo_cond_signal(&(self.cv)));
59
53
  }),
60
-
61
54
  broadcast : (fn(self : Self) -> unit)({
62
- return __yo_cond_broadcast(&(self.cv));
55
+ return(__yo_cond_broadcast(&(self.cv)));
63
56
  })
64
57
  );
65
- impl(Cond, Dispose(
66
- dispose : (fn(self : Self) -> unit)({
67
- return __yo_cond_destroy(&(self.cv));
68
- })
69
- ));
70
-
71
- export
58
+ impl(
59
+ Cond,
60
+ Dispose(
61
+ dispose : (fn(self : Self) -> unit)({
62
+ return(__yo_cond_destroy(&(self.cv)));
63
+ })
64
+ )
65
+ );
66
+ export(
72
67
  cond_t,
73
68
  Cond
74
- ;
69
+ );
package/std/sync/mutex.yo CHANGED
@@ -1,64 +1,62 @@
1
1
  //! Mutual exclusion lock primitives.
2
-
3
- extern "Yo",
2
+ extern(
3
+ "Yo",
4
4
  __YO_THREAD_SYNC_TYPE : Type,
5
5
  __yo_mutex_create : (fn() -> __YO_THREAD_SYNC_TYPE),
6
6
  __yo_mutex_lock : (fn(mutex : *(__YO_THREAD_SYNC_TYPE)) -> unit),
7
7
  __yo_mutex_unlock : (fn(mutex : *(__YO_THREAD_SYNC_TYPE)) -> unit),
8
8
  __yo_mutex_destroy : (fn(mutex : *(__YO_THREAD_SYNC_TYPE)) -> unit)
9
- ;
10
-
9
+ );
11
10
  impl(__YO_THREAD_SYNC_TYPE, Send());
12
11
  impl(__YO_THREAD_SYNC_TYPE, Acyclic());
13
-
14
12
  /// Low-level mutex (manual lifetime via `destroy`).
15
13
  mutex_t :: newtype(
16
14
  mutex : __YO_THREAD_SYNC_TYPE
17
15
  );
18
- impl(mutex_t,
16
+ impl(
17
+ mutex_t,
19
18
  new : (fn() -> Self)({
20
- return Self(__yo_mutex_create());
19
+ return(Self(__yo_mutex_create()));
21
20
  }),
22
-
23
- lock : (fn(self : *(Self))-> unit)({
24
- return __yo_mutex_lock(&(self.mutex));
21
+ lock : (fn(self : *(Self)) -> unit)({
22
+ return(__yo_mutex_lock(&(self.mutex)));
25
23
  }),
26
-
27
24
  unlock : (fn(self : *(Self)) -> unit)({
28
- return __yo_mutex_unlock(&(self.mutex));
25
+ return(__yo_mutex_unlock(&(self.mutex)));
29
26
  }),
30
-
31
27
  destroy : (fn(self : *(Self)) -> unit)({
32
- return __yo_mutex_destroy(&(self.mutex));
28
+ return(__yo_mutex_destroy(&(self.mutex)));
33
29
  })
34
30
  );
35
-
36
31
  /// Reference-counted mutex with automatic cleanup via `Dispose`.
37
32
  /// Uses atomic reference counting for safe cross-thread sharing.
38
- Mutex :: atomic object(
39
- mutex : __YO_THREAD_SYNC_TYPE
33
+ Mutex :: atomic(
34
+ object(
35
+ mutex : __YO_THREAD_SYNC_TYPE
36
+ )
40
37
  );
41
- impl(Mutex,
38
+ impl(
39
+ Mutex,
42
40
  new : (fn() -> Self)({
43
- return Self(__yo_mutex_create());
41
+ return(Self(__yo_mutex_create()));
44
42
  }),
45
-
46
- lock : (fn(self : Self)-> unit)({
47
- return __yo_mutex_lock(&(self.mutex));
43
+ lock : (fn(self : Self) -> unit)({
44
+ return(__yo_mutex_lock(&(self.mutex)));
48
45
  }),
49
-
50
46
  unlock : (fn(self : Self) -> unit)({
51
- return __yo_mutex_unlock(&(self.mutex));
47
+ return(__yo_mutex_unlock(&(self.mutex)));
52
48
  })
53
49
  );
54
- impl(Mutex, Dispose(
55
- dispose : (fn(self : Self) -> unit)({
56
- return __yo_mutex_destroy(&(self.mutex));
57
- })
58
- ));
59
-
60
- export
50
+ impl(
51
+ Mutex,
52
+ Dispose(
53
+ dispose : (fn(self : Self) -> unit)({
54
+ return(__yo_mutex_destroy(&(self.mutex)));
55
+ })
56
+ )
57
+ );
58
+ export(
61
59
  __YO_THREAD_SYNC_TYPE,
62
60
  mutex_t,
63
61
  Mutex
64
- ;
62
+ );
package/std/sync/once.yo CHANGED
@@ -14,31 +14,30 @@
14
14
  //! println("this will NOT run");
15
15
  //! });
16
16
  //! ```
17
-
18
- { Mutex } :: import "./mutex";
19
-
17
+ { Mutex } :: import("./mutex");
20
18
  /// Execute a function exactly once, thread-safely.
21
19
  /// Uses atomic reference counting for safe cross-thread sharing.
22
- Once :: atomic object(
23
- _done : bool,
24
- _mutex : Mutex
20
+ Once :: atomic(
21
+ object(
22
+ _done : bool,
23
+ _mutex : Mutex
24
+ )
25
25
  );
26
-
27
- impl(Once,
26
+ impl(
27
+ Once,
28
28
  // Create a new Once.
29
29
  new : (fn() -> Self)(
30
30
  Self(
31
- _done: false,
32
- _mutex: Mutex.new()
31
+ _done : false,
32
+ _mutex : Mutex.new()
33
33
  )
34
34
  ),
35
-
36
35
  // Execute the function exactly once.
37
36
  // Subsequent calls are no-ops.
38
37
  // Note: The fast-path read of _done is not strictly atomic, but since _done
39
38
  // is only ever set from false to true and the double-check inside the lock
40
39
  // prevents the function from running twice, this is safe in practice.
41
- call : (fn(self: Self, f: Impl(Fn() -> unit)) -> unit)({
40
+ call : (fn(self : Self, f : Impl(Fn() -> unit)) -> unit)({
42
41
  // Fast path: already done
43
42
  cond(
44
43
  self._done => (),
@@ -58,11 +57,9 @@ impl(Once,
58
57
  }
59
58
  );
60
59
  }),
61
-
62
60
  // Check if the function has been called.
63
- is_done : (fn(self: Self) -> bool)(
61
+ is_done : (fn(self : Self) -> bool)(
64
62
  self._done
65
63
  )
66
64
  );
67
-
68
- export Once;
65
+ export(Once);
@@ -16,45 +16,43 @@
16
16
  //! // ... write shared data ...
17
17
  //! lock.write_unlock();
18
18
  //! ```
19
-
20
- { Mutex } :: import "./mutex";
21
- { Cond } :: import "./cond";
22
-
19
+ { Mutex } :: import("./mutex");
20
+ { Cond } :: import("./cond");
23
21
  /// Reader-writer lock built on `Mutex` and `Cond`.
24
22
  /// Uses atomic reference counting for safe cross-thread sharing.
25
- RwLock :: atomic object(
26
- _readers : i32,
27
- _writer : bool,
28
- _mutex : Mutex,
29
- _read_cv : Cond,
30
- _write_cv : Cond
23
+ RwLock :: atomic(
24
+ object(
25
+ _readers : i32,
26
+ _writer : bool,
27
+ _mutex : Mutex,
28
+ _read_cv : Cond,
29
+ _write_cv : Cond
30
+ )
31
31
  );
32
-
33
- impl(RwLock,
32
+ impl(
33
+ RwLock,
34
34
  // Create a new reader-writer lock.
35
35
  new : (fn() -> Self)(
36
36
  Self(
37
- _readers: i32(0),
38
- _writer: false,
39
- _mutex: Mutex.new(),
40
- _read_cv: Cond.new(),
41
- _write_cv: Cond.new()
37
+ _readers : i32(0),
38
+ _writer : false,
39
+ _mutex : Mutex.new(),
40
+ _read_cv : Cond.new(),
41
+ _write_cv : Cond.new()
42
42
  )
43
43
  ),
44
-
45
44
  // Acquire a read lock. Blocks if a writer holds the lock.
46
45
  // Multiple readers can hold the lock simultaneously.
47
- read_lock : (fn(self: Self) -> unit)({
46
+ read_lock : (fn(self : Self) -> unit)({
48
47
  self._mutex.lock();
49
- while runtime(self._writer), {
48
+ while(runtime(self._writer), {
50
49
  self._read_cv.wait(self._mutex);
51
- };
50
+ });
52
51
  self._readers = (self._readers + i32(1));
53
52
  self._mutex.unlock();
54
53
  }),
55
-
56
54
  // Release a read lock.
57
- read_unlock : (fn(self: Self) -> unit)({
55
+ read_unlock : (fn(self : Self) -> unit)({
58
56
  self._mutex.lock();
59
57
  self._readers = (self._readers - i32(1));
60
58
  cond(
@@ -63,19 +61,17 @@ impl(RwLock,
63
61
  );
64
62
  self._mutex.unlock();
65
63
  }),
66
-
67
64
  // Acquire a write lock. Blocks until all readers and writers release.
68
- write_lock : (fn(self: Self) -> unit)({
65
+ write_lock : (fn(self : Self) -> unit)({
69
66
  self._mutex.lock();
70
- while runtime((self._writer || (self._readers > i32(0)))), {
67
+ while(runtime(self._writer || (self._readers > i32(0))), {
71
68
  self._write_cv.wait(self._mutex);
72
- };
69
+ });
73
70
  self._writer = true;
74
71
  self._mutex.unlock();
75
72
  }),
76
-
77
73
  // Release a write lock.
78
- write_unlock : (fn(self: Self) -> unit)({
74
+ write_unlock : (fn(self : Self) -> unit)({
79
75
  self._mutex.lock();
80
76
  self._writer = false;
81
77
  self._read_cv.broadcast();
@@ -83,5 +79,4 @@ impl(RwLock,
83
79
  self._mutex.unlock();
84
80
  })
85
81
  );
86
-
87
- export RwLock;
82
+ export(RwLock);
@@ -18,31 +18,30 @@
18
18
  //! };
19
19
  //! wg.wait(); // blocks until all 3 tasks call done()
20
20
  //! ```
21
-
22
- { Mutex } :: import "./mutex";
23
- { Cond } :: import "./cond";
24
-
21
+ { Mutex } :: import("./mutex");
22
+ { Cond } :: import("./cond");
25
23
  /// Synchronization primitive that blocks until a counter reaches zero.
26
24
  /// Uses atomic reference counting for safe cross-thread sharing.
27
- WaitGroup :: atomic object(
28
- _count : i32,
29
- _mutex : Mutex,
30
- _cv : Cond
25
+ WaitGroup :: atomic(
26
+ object(
27
+ _count : i32,
28
+ _mutex : Mutex,
29
+ _cv : Cond
30
+ )
31
31
  );
32
-
33
- impl(WaitGroup,
32
+ impl(
33
+ WaitGroup,
34
34
  // Create a new WaitGroup with count 0.
35
35
  new : (fn() -> Self)(
36
36
  Self(
37
- _count: i32(0),
38
- _mutex: Mutex.new(),
39
- _cv: Cond.new()
37
+ _count : i32(0),
38
+ _mutex : Mutex.new(),
39
+ _cv : Cond.new()
40
40
  )
41
41
  ),
42
-
43
42
  // Add delta to the counter (can be negative).
44
43
  // If the counter becomes zero, all waiters are woken.
45
- add : (fn(self: Self, delta: i32) -> unit)({
44
+ add : (fn(self : Self, delta : i32) -> unit)({
46
45
  self._mutex.lock();
47
46
  self._count = (self._count + delta);
48
47
  cond(
@@ -54,25 +53,21 @@ impl(WaitGroup,
54
53
  );
55
54
  self._mutex.unlock();
56
55
  }),
57
-
58
56
  // Decrement the counter by one (equivalent to add(-1)).
59
- done : (fn(self: Self) -> unit)(
57
+ done : (fn(self : Self) -> unit)(
60
58
  self.add(i32(-(1)))
61
59
  ),
62
-
63
60
  // Block until the counter reaches zero.
64
- wait : (fn(self: Self) -> unit)({
61
+ wait : (fn(self : Self) -> unit)({
65
62
  self._mutex.lock();
66
- while runtime((self._count > i32(0))), {
63
+ while(runtime(self._count > i32(0)), {
67
64
  self._cv.wait(self._mutex);
68
- };
65
+ });
69
66
  self._mutex.unlock();
70
67
  }),
71
-
72
68
  // Get the current count (for debugging).
73
- count : (fn(self: Self) -> i32)(
69
+ count : (fn(self : Self) -> i32)(
74
70
  self._count
75
71
  )
76
72
  );
77
-
78
- export WaitGroup;
73
+ export(WaitGroup);