@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
@@ -17,230 +17,266 @@
17
17
  //! m = m.insert(i32(2), i32(20));
18
18
  //! // keys are always sorted: 1, 2, 3
19
19
  //! ```
20
-
21
- { List } :: import "./list.yo";
22
- { Pair } :: import "./map.yo";
23
-
20
+ { List } :: import("./list.yo");
21
+ { Pair } :: import("./map.yo");
24
22
  /// Color of a red-black tree node.
25
23
  Color :: enum(Red, Black);
26
-
27
24
  /// Internal LLRB tree node — an `atomic object` for thread-safe sharing.
28
- RBNode :: (fn(
29
- comptime(K) : Type,
30
- comptime(V) : Type,
31
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
32
- ) -> comptime(Type))(
33
- atomic object(
34
- _key : K,
35
- _value : V,
36
- _color : Color,
37
- _left : Option(Self),
38
- _right : Option(Self)
25
+ RBNode :: (
26
+ fn(
27
+ comptime(K) : Type,
28
+ comptime(V) : Type,
29
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
30
+ ) -> comptime(Type)
31
+ )(
32
+ atomic(
33
+ object(
34
+ _key : K,
35
+ _value : V,
36
+ _color : Color,
37
+ _left : Option(Self),
38
+ _right : Option(Self)
39
+ )
39
40
  )
40
41
  );
41
-
42
42
  // Manual Acyclic impl — RBNode is self-referential, so auto-derivation skips it.
43
43
  // This is safe because RBNode is immutable: all tree operations create new nodes
44
44
  // and never mutate existing ones, making it impossible to form cycles at runtime.
45
45
  impl(forall(K : Type, V : Type), where(K <: (Eq(K), Ord(K), Send), V <: Send), RBNode(K, V), Acyclic());
46
-
47
46
  /// Persistent immutable sorted map backed by a left-leaning red-black tree.
48
- SortedMap :: (fn(
49
- comptime(K) : Type,
50
- comptime(V) : Type,
51
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
52
- ) -> comptime(Type))(
47
+ SortedMap :: (
48
+ fn(
49
+ comptime(K) : Type,
50
+ comptime(V) : Type,
51
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
52
+ ) -> comptime(Type)
53
+ )(
53
54
  struct(
54
55
  _root : Option(RBNode(K, V)),
55
56
  _len : usize
56
57
  )
57
58
  );
58
-
59
59
  // ---------------------------------------------------------------------------
60
60
  // Helper standalone functions
61
61
  // ---------------------------------------------------------------------------
62
-
63
- _is_red :: (fn(
64
- comptime(K) : Type,
65
- comptime(V) : Type,
66
- node: Option(RBNode(K, V)),
67
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
68
- ) -> bool)(
69
- match(node,
70
- .Some(n) => match(n._color,
62
+ _is_red :: (
63
+ fn(
64
+ comptime(K) : Type,
65
+ comptime(V) : Type,
66
+ node : Option(RBNode(K, V)),
67
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
68
+ ) -> bool
69
+ )(
70
+ match(
71
+ node,
72
+ .Some(n) => match(
73
+ n._color,
71
74
  .Red => true,
72
75
  .Black => false
73
76
  ),
74
77
  .None => false
75
78
  )
76
79
  );
77
-
78
- _new_node :: (fn(
79
- comptime(K) : Type,
80
- comptime(V) : Type,
81
- key: K,
82
- value: V,
83
- color: Color,
84
- left: Option(RBNode(K, V)),
85
- right: Option(RBNode(K, V)),
86
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
87
- ) -> RBNode(K, V))(
80
+ _new_node :: (
81
+ fn(
82
+ comptime(K) : Type,
83
+ comptime(V) : Type,
84
+ key : K,
85
+ value : V,
86
+ color : Color,
87
+ left : Option(RBNode(K, V)),
88
+ right : Option(RBNode(K, V)),
89
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
90
+ ) -> RBNode(K, V)
91
+ )(
88
92
  RBNode(K, V)(
89
- _key: key,
90
- _value: value,
91
- _color: color,
92
- _left: left,
93
- _right: right
93
+ _key : key,
94
+ _value : value,
95
+ _color : color,
96
+ _left : left,
97
+ _right : right
94
98
  )
95
99
  );
96
-
97
100
  /// Rotate left: h.right becomes the new root.
98
- _rotate_left :: (fn(
99
- comptime(K) : Type,
100
- comptime(V) : Type,
101
- h: RBNode(K, V),
102
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
103
- ) -> RBNode(K, V))({
101
+ _rotate_left :: (
102
+ fn(
103
+ comptime(K) : Type,
104
+ comptime(V) : Type,
105
+ h : RBNode(K, V),
106
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
107
+ ) -> RBNode(K, V)
108
+ )({
104
109
  // x = h.right (must be Some)
105
- (x : RBNode(K, V)) = match(h._right,
110
+ (x : RBNode(K, V)) = match(
111
+ h._right,
106
112
  .Some(n) => n,
107
- .None => h // unreachable
113
+ .None => h // unreachable
108
114
  );
109
115
  new_h := _new_node(K, V, h._key, h._value, x._color, h._left, x._left);
110
- _new_node(K, V, x._key, x._value, h._color, .Some(new_h), x._right)
116
+ _new_node(K, V, x._key, x._value, h._color,.Some(new_h), x._right)
111
117
  });
112
-
113
118
  /// Rotate right: h.left becomes the new root.
114
- _rotate_right :: (fn(
115
- comptime(K) : Type,
116
- comptime(V) : Type,
117
- h: RBNode(K, V),
118
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
119
- ) -> RBNode(K, V))({
120
- (x : RBNode(K, V)) = match(h._left,
119
+ _rotate_right :: (
120
+ fn(
121
+ comptime(K) : Type,
122
+ comptime(V) : Type,
123
+ h : RBNode(K, V),
124
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
125
+ ) -> RBNode(K, V)
126
+ )({
127
+ (x : RBNode(K, V)) = match(
128
+ h._left,
121
129
  .Some(n) => n,
122
- .None => h // unreachable
130
+ .None => h // unreachable
123
131
  );
124
132
  new_h := _new_node(K, V, h._key, h._value, x._color, x._right, h._right);
125
- _new_node(K, V, x._key, x._value, h._color, x._left, .Some(new_h))
133
+ _new_node(K, V, x._key, x._value, h._color, x._left,.Some(new_h))
126
134
  });
127
-
128
135
  /// Flip colors of a node and its children.
129
- _flip_colors :: (fn(
130
- comptime(K) : Type,
131
- comptime(V) : Type,
132
- h: RBNode(K, V),
133
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
134
- ) -> RBNode(K, V))({
135
- new_color := match(h._color,
136
+ _flip_colors :: (
137
+ fn(
138
+ comptime(K) : Type,
139
+ comptime(V) : Type,
140
+ h : RBNode(K, V),
141
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
142
+ ) -> RBNode(K, V)
143
+ )({
144
+ new_color := match(
145
+ h._color,
136
146
  .Red => Color.Black,
137
147
  .Black => Color.Red
138
148
  );
139
- (new_left : Option(RBNode(K, V))) = match(h._left,
149
+ (new_left : Option(RBNode(K, V))) = match(
150
+ h._left,
140
151
  .Some(l) => {
141
- lc := match(l._color,
152
+ lc := match(
153
+ l._color,
142
154
  .Red => Color.Black,
143
155
  .Black => Color.Red
144
156
  );
145
- (Option(RBNode(K, V)).Some(_new_node(K, V, l._key, l._value, lc, l._left, l._right)))
157
+ Option(RBNode(K, V)).Some(_new_node(K, V, l._key, l._value, lc, l._left, l._right))
146
158
  },
147
- .None => (Option(RBNode(K, V)).None)
159
+ .None => Option(RBNode(K, V)).None
148
160
  );
149
- (new_right : Option(RBNode(K, V))) = match(h._right,
161
+ (new_right : Option(RBNode(K, V))) = match(
162
+ h._right,
150
163
  .Some(r) => {
151
- rc := match(r._color,
164
+ rc := match(
165
+ r._color,
152
166
  .Red => Color.Black,
153
167
  .Black => Color.Red
154
168
  );
155
- (Option(RBNode(K, V)).Some(_new_node(K, V, r._key, r._value, rc, r._left, r._right)))
169
+ Option(RBNode(K, V)).Some(_new_node(K, V, r._key, r._value, rc, r._left, r._right))
156
170
  },
157
- .None => (Option(RBNode(K, V)).None)
171
+ .None => Option(RBNode(K, V)).None
158
172
  );
159
173
  _new_node(K, V, h._key, h._value, new_color, new_left, new_right)
160
174
  });
161
-
162
175
  /// Fix-up after insertion: enforce LLRB invariants.
163
- _fixup :: (fn(
164
- comptime(K) : Type,
165
- comptime(V) : Type,
166
- h: RBNode(K, V),
167
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
168
- ) -> RBNode(K, V))({
176
+ _fixup :: (
177
+ fn(
178
+ comptime(K) : Type,
179
+ comptime(V) : Type,
180
+ h : RBNode(K, V),
181
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
182
+ ) -> RBNode(K, V)
183
+ )({
169
184
  (node : RBNode(K, V)) = h;
170
185
  // Right-leaning red link → rotate left
171
- if((_is_red(K, V, node._right) && !(_is_red(K, V, node._left))), {
186
+ if(_is_red(K, V, node._right) && !(_is_red(K, V, node._left)), {
172
187
  node = _rotate_left(K, V, node);
173
188
  });
174
189
  // Two consecutive red left links → rotate right
175
190
  left_red := _is_red(K, V, node._left);
176
- left_left_red := match(node._left,
191
+ left_left_red := match(
192
+ node._left,
177
193
  .Some(l) => _is_red(K, V, l._left),
178
194
  .None => false
179
195
  );
180
- if((left_red && left_left_red), {
196
+ if(left_red && left_left_red, {
181
197
  node = _rotate_right(K, V, node);
182
198
  });
183
199
  // Both children red → flip colors
184
- if((_is_red(K, V, node._left) && _is_red(K, V, node._right)), {
200
+ if(_is_red(K, V, node._left) && _is_red(K, V, node._right), {
185
201
  node = _flip_colors(K, V, node);
186
202
  });
187
203
  node
188
204
  });
189
-
190
205
  /// Insert into subtree rooted at node. Returns new subtree root.
191
- _node_insert :: (fn(
192
- comptime(K) : Type,
193
- comptime(V) : Type,
194
- node: Option(RBNode(K, V)),
195
- key: K,
196
- value: V,
197
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
198
- ) -> RBNode(K, V))(
199
- match(node,
200
- .None => _new_node(K, V, key, value, .Red, .None, .None),
206
+ _node_insert :: (
207
+ fn(
208
+ comptime(K) : Type,
209
+ comptime(V) : Type,
210
+ node : Option(RBNode(K, V)),
211
+ key : K,
212
+ value : V,
213
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
214
+ ) -> RBNode(K, V)
215
+ )(
216
+ match(
217
+ node,
218
+ .None => _new_node(K, V, key, value,.Red,.None,.None),
201
219
  .Some(h) => {
202
220
  (n : RBNode(K, V)) = cond(
203
221
  (key < h._key) =>
204
- _new_node(K, V, h._key, h._value, h._color,
205
- .Some(recur(K, V, h._left, key, value)), h._right),
222
+ _new_node(
223
+ K,
224
+ V,
225
+ h._key,
226
+ h._value,
227
+ h._color,
228
+ .Some(recur(K, V, h._left, key, value)),
229
+ h._right
230
+ ),
206
231
  (key == h._key) =>
207
232
  _new_node(K, V, h._key, value, h._color, h._left, h._right),
208
233
  true =>
209
- _new_node(K, V, h._key, h._value, h._color,
210
- h._left, .Some(recur(K, V, h._right, key, value)))
234
+ _new_node(
235
+ K,
236
+ V,
237
+ h._key,
238
+ h._value,
239
+ h._color,
240
+ h._left,
241
+ .Some(recur(K, V, h._right, key, value))
242
+ )
211
243
  );
212
244
  _fixup(K, V, n)
213
245
  }
214
246
  )
215
247
  );
216
-
217
248
  /// Get value associated with key from subtree.
218
- _node_get :: (fn(
219
- comptime(K) : Type,
220
- comptime(V) : Type,
221
- node: Option(RBNode(K, V)),
222
- key: K,
223
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
224
- ) -> Option(V))(
225
- match(node,
226
- .None => .None,
249
+ _node_get :: (
250
+ fn(
251
+ comptime(K) : Type,
252
+ comptime(V) : Type,
253
+ node : Option(RBNode(K, V)),
254
+ key : K,
255
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
256
+ ) -> Option(V)
257
+ )(
258
+ match(
259
+ node,
260
+ .None =>.None,
227
261
  .Some(h) => cond(
228
262
  (key < h._key) => recur(K, V, h._left, key),
229
- (key == h._key) => .Some(h._value),
263
+ (key == h._key) =>.Some(h._value),
230
264
  true => recur(K, V, h._right, key)
231
265
  )
232
266
  )
233
267
  );
234
-
235
268
  /// Check if key exists in subtree.
236
- _node_contains :: (fn(
237
- comptime(K) : Type,
238
- comptime(V) : Type,
239
- node: Option(RBNode(K, V)),
240
- key: K,
241
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
242
- ) -> bool)(
243
- match(node,
269
+ _node_contains :: (
270
+ fn(
271
+ comptime(K) : Type,
272
+ comptime(V) : Type,
273
+ node : Option(RBNode(K, V)),
274
+ key : K,
275
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
276
+ ) -> bool
277
+ )(
278
+ match(
279
+ node,
244
280
  .None => false,
245
281
  .Some(h) => cond(
246
282
  (key < h._key) => recur(K, V, h._left, key),
@@ -249,27 +285,29 @@ _node_contains :: (fn(
249
285
  )
250
286
  )
251
287
  );
252
-
253
288
  // ---------------------------------------------------------------------------
254
289
  // Remove helpers for LLRB delete
255
290
  // ---------------------------------------------------------------------------
256
-
257
291
  /// Move red left: used during delete-min
258
- _move_red_left :: (fn(
259
- comptime(K) : Type,
260
- comptime(V) : Type,
261
- h: RBNode(K, V),
262
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
263
- ) -> RBNode(K, V))({
292
+ _move_red_left :: (
293
+ fn(
294
+ comptime(K) : Type,
295
+ comptime(V) : Type,
296
+ h : RBNode(K, V),
297
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
298
+ ) -> RBNode(K, V)
299
+ )({
264
300
  (node : RBNode(K, V)) = _flip_colors(K, V, h);
265
- right_left_red := match(node._right,
301
+ right_left_red := match(
302
+ node._right,
266
303
  .Some(r) => _is_red(K, V, r._left),
267
304
  .None => false
268
305
  );
269
306
  if(right_left_red, {
270
- (new_right : Option(RBNode(K, V))) = match(node._right,
307
+ (new_right : Option(RBNode(K, V))) = match(
308
+ node._right,
271
309
  .Some(r) => Option(RBNode(K, V)).Some(_rotate_right(K, V, r)),
272
- .None => (Option(RBNode(K, V)).None)
310
+ .None => Option(RBNode(K, V)).None
273
311
  );
274
312
  node = _new_node(K, V, node._key, node._value, node._color, node._left, new_right);
275
313
  node = _rotate_left(K, V, node);
@@ -277,16 +315,18 @@ _move_red_left :: (fn(
277
315
  });
278
316
  node
279
317
  });
280
-
281
318
  /// Move red right: used during delete
282
- _move_red_right :: (fn(
283
- comptime(K) : Type,
284
- comptime(V) : Type,
285
- h: RBNode(K, V),
286
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
287
- ) -> RBNode(K, V))({
319
+ _move_red_right :: (
320
+ fn(
321
+ comptime(K) : Type,
322
+ comptime(V) : Type,
323
+ h : RBNode(K, V),
324
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
325
+ ) -> RBNode(K, V)
326
+ )({
288
327
  (node : RBNode(K, V)) = _flip_colors(K, V, h);
289
- left_left_red := match(node._left,
328
+ left_left_red := match(
329
+ node._left,
290
330
  .Some(l) => _is_red(K, V, l._left),
291
331
  .None => false
292
332
  );
@@ -296,73 +336,85 @@ _move_red_right :: (fn(
296
336
  });
297
337
  node
298
338
  });
299
-
300
339
  /// Find the minimum node in a subtree.
301
- _node_min :: (fn(
302
- comptime(K) : Type,
303
- comptime(V) : Type,
304
- h: RBNode(K, V),
305
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
306
- ) -> RBNode(K, V))(
307
- match(h._left,
340
+ _node_min :: (
341
+ fn(
342
+ comptime(K) : Type,
343
+ comptime(V) : Type,
344
+ h : RBNode(K, V),
345
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
346
+ ) -> RBNode(K, V)
347
+ )(
348
+ match(
349
+ h._left,
308
350
  .Some(l) => recur(K, V, l),
309
351
  .None => h
310
352
  )
311
353
  );
312
-
313
354
  /// Delete the minimum node from subtree.
314
- _delete_min :: (fn(
315
- comptime(K) : Type,
316
- comptime(V) : Type,
317
- h: RBNode(K, V),
318
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
319
- ) -> Option(RBNode(K, V)))(
320
- match(h._left,
321
- .None => .None,
355
+ _delete_min :: (
356
+ fn(
357
+ comptime(K) : Type,
358
+ comptime(V) : Type,
359
+ h : RBNode(K, V),
360
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
361
+ ) -> Option(RBNode(K, V))
362
+ )(
363
+ match(
364
+ h._left,
365
+ .None =>.None,
322
366
  .Some(l) => {
323
367
  (node : RBNode(K, V)) = h;
324
- if((!(_is_red(K, V, .Some(l))) && !(_is_red(K, V, l._left))), {
368
+ if(!(_is_red(K, V,.Some(l))) && !(_is_red(K, V, l._left)), {
325
369
  node = _move_red_left(K, V, node);
326
370
  });
327
- new_left := match(node._left,
371
+ new_left := match(
372
+ node._left,
328
373
  .Some(nl) => recur(K, V, nl),
329
- .None => (Option(RBNode(K, V)).None)
374
+ .None => Option(RBNode(K, V)).None
330
375
  );
331
- .Some(_fixup(K, V,
332
- _new_node(K, V, node._key, node._value, node._color, new_left, node._right)
333
- ))
376
+ .Some(
377
+ _fixup(
378
+ K,
379
+ V,
380
+ _new_node(K, V, node._key, node._value, node._color, new_left, node._right)
381
+ )
382
+ )
334
383
  }
335
384
  )
336
385
  );
337
-
338
386
  /// Remove key from subtree. Returns new subtree (or None if empty).
339
- _node_remove :: (fn(
340
- comptime(K) : Type,
341
- comptime(V) : Type,
342
- h: RBNode(K, V),
343
- key: K,
344
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
345
- ) -> Option(RBNode(K, V)))({
387
+ _node_remove :: (
388
+ fn(
389
+ comptime(K) : Type,
390
+ comptime(V) : Type,
391
+ h : RBNode(K, V),
392
+ key : K,
393
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
394
+ ) -> Option(RBNode(K, V))
395
+ )({
346
396
  (node : RBNode(K, V)) = h;
347
-
348
- if((key < node._key), {
397
+ if(key < node._key, {
349
398
  // Go left
350
- has_left := match(node._left,
399
+ has_left := match(
400
+ node._left,
351
401
  .Some(_) => true,
352
402
  .None => false
353
403
  );
354
404
  if(has_left, {
355
405
  left_red := _is_red(K, V, node._left);
356
- left_left_red := match(node._left,
406
+ left_left_red := match(
407
+ node._left,
357
408
  .Some(l) => _is_red(K, V, l._left),
358
409
  .None => false
359
410
  );
360
- if((!(left_red) && !(left_left_red)), {
411
+ if(!(left_red) && !(left_left_red), {
361
412
  node = _move_red_left(K, V, node);
362
413
  });
363
- new_left := match(node._left,
414
+ new_left := match(
415
+ node._left,
364
416
  .Some(nl) => recur(K, V, nl, key),
365
- .None => (Option(RBNode(K, V)).None)
417
+ .None => Option(RBNode(K, V)).None
366
418
  );
367
419
  node = _new_node(K, V, node._key, node._value, node._color, new_left, node._right);
368
420
  });
@@ -372,67 +424,69 @@ _node_remove :: (fn(
372
424
  if(_is_red(K, V, node._left), {
373
425
  node = _rotate_right(K, V, node);
374
426
  });
375
-
376
427
  // If equal and no right child, delete this node
377
428
  is_eq := (key == node._key);
378
- has_right := match(node._right,
429
+ has_right := match(
430
+ node._right,
379
431
  .Some(_) => true,
380
432
  .None => false
381
433
  );
382
- if((is_eq && !(has_right)), {
383
- return .None;
434
+ if(is_eq && !(has_right), {
435
+ return(.None);
384
436
  });
385
-
386
437
  // Ensure right child is not a 2-node
387
438
  if(has_right, {
388
439
  right_red := _is_red(K, V, node._right);
389
- right_left_red := match(node._right,
440
+ right_left_red := match(
441
+ node._right,
390
442
  .Some(r) => _is_red(K, V, r._left),
391
443
  .None => false
392
444
  );
393
- if((!(right_red) && !(right_left_red)), {
445
+ if(!(right_red) && !(right_left_red), {
394
446
  node = _move_red_right(K, V, node);
395
447
  });
396
448
  });
397
-
398
449
  is_eq2 := (key == node._key);
399
450
  if(is_eq2, {
400
451
  // Replace with successor (min of right subtree)
401
- succ := match(node._right,
452
+ succ := match(
453
+ node._right,
402
454
  .Some(r) => _node_min(K, V, r),
403
- .None => node // unreachable
455
+ .None => node // unreachable
404
456
  );
405
- new_right := match(node._right,
457
+ new_right := match(
458
+ node._right,
406
459
  .Some(r) => _delete_min(K, V, r),
407
- .None => (Option(RBNode(K, V)).None)
460
+ .None => Option(RBNode(K, V)).None
408
461
  );
409
462
  node = _new_node(K, V, succ._key, succ._value, node._color, node._left, new_right);
410
463
  }, {
411
464
  // Go right
412
- new_right := match(node._right,
465
+ new_right := match(
466
+ node._right,
413
467
  .Some(r) => recur(K, V, r, key),
414
- .None => (Option(RBNode(K, V)).None)
468
+ .None => Option(RBNode(K, V)).None
415
469
  );
416
470
  node = _new_node(K, V, node._key, node._value, node._color, node._left, new_right);
417
471
  });
418
-
419
472
  .Some(_fixup(K, V, node))
420
473
  })
421
474
  });
422
-
423
475
  // ---------------------------------------------------------------------------
424
476
  // In-order traversal helpers
425
477
  // ---------------------------------------------------------------------------
426
-
427
478
  /// Collect keys in-order into a List.
428
- _collect_keys :: (fn(
429
- comptime(K) : Type,
430
- comptime(V) : Type,
431
- node: Option(RBNode(K, V)),
432
- acc: List(K),
433
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
434
- ) -> List(K))(
435
- match(node,
479
+ _collect_keys :: (
480
+ fn(
481
+ comptime(K) : Type,
482
+ comptime(V) : Type,
483
+ node : Option(RBNode(K, V)),
484
+ acc : List(K),
485
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
486
+ ) -> List(K)
487
+ )(
488
+ match(
489
+ node,
436
490
  .None => acc,
437
491
  .Some(h) => {
438
492
  right_acc := recur(K, V, h._right, acc);
@@ -441,16 +495,18 @@ _collect_keys :: (fn(
441
495
  }
442
496
  )
443
497
  );
444
-
445
498
  /// Collect values in key-order into a List.
446
- _collect_values :: (fn(
447
- comptime(K) : Type,
448
- comptime(V) : Type,
449
- node: Option(RBNode(K, V)),
450
- acc: List(V),
451
- where(K <: (Eq(K), Ord(K), Send), V <: Send)
452
- ) -> List(V))(
453
- match(node,
499
+ _collect_values :: (
500
+ fn(
501
+ comptime(K) : Type,
502
+ comptime(V) : Type,
503
+ node : Option(RBNode(K, V)),
504
+ acc : List(V),
505
+ where(K <: (Eq(K), Ord(K), Send), V <: Send)
506
+ ) -> List(V)
507
+ )(
508
+ match(
509
+ node,
454
510
  .None => acc,
455
511
  .Some(h) => {
456
512
  right_acc := recur(K, V, h._right, acc);
@@ -459,85 +515,83 @@ _collect_values :: (fn(
459
515
  }
460
516
  )
461
517
  );
462
-
463
518
  // ---------------------------------------------------------------------------
464
519
  // SortedMap impl
465
520
  // ---------------------------------------------------------------------------
466
-
467
- impl(forall(K : Type, V : Type), where(K <: (Eq(K), Ord(K), Send), V <: Send), SortedMap(K, V),
521
+ impl(
522
+ forall(K : Type, V : Type),
523
+ where(K <: (Eq(K), Ord(K), Send), V <: Send),
524
+ SortedMap(K, V),
468
525
  /// Create an empty sorted map.
469
526
  new : (fn() -> Self)(
470
- Self(_root: .None, _len: usize(0))
527
+ Self(_root :.None, _len : usize(0))
471
528
  ),
472
-
473
529
  /// Number of entries.
474
- len : (fn(self: Self) -> usize)(self._len),
475
-
530
+ len : (fn(self : Self) -> usize)(self._len),
476
531
  /// Check if the map is empty.
477
- is_empty : (fn(self: Self) -> bool)((self._len == usize(0))),
478
-
532
+ is_empty : (fn(self : Self) -> bool)(self._len == usize(0)),
479
533
  /// Look up a value by key.
480
- get : (fn(self: Self, key: K) -> Option(V))(
534
+ get : (fn(self : Self, key : K) -> Option(V))(
481
535
  _node_get(K, V, self._root, key)
482
536
  ),
483
-
484
537
  /// Check if a key exists.
485
- contains_key : (fn(self: Self, key: K) -> bool)(
538
+ contains_key : (fn(self : Self, key : K) -> bool)(
486
539
  _node_contains(K, V, self._root, key)
487
540
  ),
488
-
489
541
  /// Return a new map with the key-value pair inserted (or updated).
490
- insert : (fn(self: Self, key: K, value: V) -> Self)({
542
+ insert : (fn(self : Self, key : K, value : V) -> Self)({
491
543
  existed := _node_contains(K, V, self._root, key);
492
544
  new_root := _node_insert(K, V, self._root, key, value);
493
545
  // Root is always black
494
- black_root := _new_node(K, V, new_root._key, new_root._value, .Black, new_root._left, new_root._right);
546
+ black_root := _new_node(K, V, new_root._key, new_root._value,.Black, new_root._left, new_root._right);
495
547
  new_len := cond(
496
548
  existed => self._len,
497
549
  true => (self._len + usize(1))
498
550
  );
499
- Self(_root: .Some(black_root), _len: new_len)
551
+ Self(_root :.Some(black_root), _len : new_len)
500
552
  }),
501
-
502
553
  /// Return a new map with the key removed.
503
- remove : (fn(self: Self, key: K) -> Self)(
504
- match(self._root,
554
+ remove : (fn(self : Self, key : K) -> Self)(
555
+ match(
556
+ self._root,
505
557
  .None => self,
506
558
  .Some(root) => {
507
- existed := _node_contains(K, V, .Some(root), key);
559
+ existed := _node_contains(K, V,.Some(root), key);
508
560
  if(!(existed), {
509
- return self;
561
+ return(self);
510
562
  });
511
563
  result := _node_remove(K, V, root, key);
512
- (new_root : Option(RBNode(K, V))) = match(result,
513
- .Some(n) => Option(RBNode(K, V)).Some(_new_node(K, V, n._key, n._value, .Black, n._left, n._right)),
514
- .None => (Option(RBNode(K, V)).None)
564
+ (new_root : Option(RBNode(K, V))) = match(
565
+ result,
566
+ .Some(n) => Option(RBNode(K, V)).Some(_new_node(K, V, n._key, n._value,.Black, n._left, n._right)),
567
+ .None => Option(RBNode(K, V)).None
515
568
  );
516
- Self(_root: new_root, _len: (self._len - usize(1)))
569
+ Self(_root : new_root, _len : (self._len - usize(1)))
517
570
  }
518
571
  )
519
572
  ),
520
-
521
573
  /// Get the minimum key in the map.
522
- min_key : (fn(self: Self) -> Option(K))(
523
- match(self._root,
524
- .None => .None,
574
+ min_key : (fn(self : Self) -> Option(K))(
575
+ match(
576
+ self._root,
577
+ .None =>.None,
525
578
  .Some(root) => {
526
579
  m := _node_min(K, V, root);
527
580
  .Some(m._key)
528
581
  }
529
582
  )
530
583
  ),
531
-
532
584
  /// Get the maximum key by going right.
533
- max_key : (fn(self: Self) -> Option(K))(
534
- match(self._root,
535
- .None => .None,
585
+ max_key : (fn(self : Self) -> Option(K))(
586
+ match(
587
+ self._root,
588
+ .None =>.None,
536
589
  .Some(root) => {
537
590
  (cur : RBNode(K, V)) = root;
538
591
  (done : bool) = false;
539
- while runtime(!(done)), {
540
- match(cur._right,
592
+ while(runtime(!(done)), {
593
+ match(
594
+ cur._right,
541
595
  .Some(r) => {
542
596
  cur = r;
543
597
  },
@@ -545,51 +599,51 @@ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Ord(K), Send), V <: Send), S
545
599
  done = true;
546
600
  }
547
601
  );
548
- };
602
+ });
549
603
  .Some(cur._key)
550
604
  }
551
605
  )
552
606
  ),
553
-
554
607
  /// Return in-order list of keys.
555
- keys : (fn(self: Self) -> List(K))(
608
+ keys : (fn(self : Self) -> List(K))(
556
609
  _collect_keys(K, V, self._root, List(K).new())
557
610
  ),
558
-
559
611
  /// Return list of values in key order.
560
- values : (fn(self: Self) -> List(V))(
612
+ values : (fn(self : Self) -> List(V))(
561
613
  _collect_values(K, V, self._root, List(V).new())
562
614
  ),
563
-
564
615
  /// Create a sorted map from a slice of key-value pairs.
565
- from_entries : (fn(pairs: Slice(Pair(K, V))) -> Self)({
616
+ from_entries : (fn(pairs : Slice(Pair(K, V))) -> Self)({
566
617
  (result : Self) = Self.new();
567
618
  i := usize(0);
568
619
  plen := pairs.len();
569
- while (i < plen), (i = (i + usize(1))), {
620
+ while(i < plen, i = (i + usize(1)), {
570
621
  p := (pairs.ptr() &+ i).*;
571
622
  result = result.insert(p.key, p.value);
572
- };
623
+ });
573
624
  result
574
625
  })
575
626
  );
576
-
577
- impl(forall(K : Type, V : Type), where(K <: (Eq(K), Ord(K), Send), V <: (Eq(V), Send)), SortedMap(K, V), Eq(SortedMap(K, V))(
578
- (==) : (fn(lhs: Self, rhs: Self) -> bool)({
579
- if((lhs._len != rhs._len), {
580
- return false;
581
- });
582
- if(((lhs._len == usize(0)) && (rhs._len == usize(0))), {
583
- return true;
584
- });
585
- lhs_keys := lhs.keys();
586
- lhs_vals := lhs.values();
587
- rhs_keys := rhs.keys();
588
- rhs_vals := rhs.values();
589
- ((lhs_keys == rhs_keys) && (lhs_vals == rhs_vals))
590
- })
591
- ));
592
-
593
- export SortedMap;
594
- export RBNode;
595
- export Color;
627
+ impl(
628
+ forall(K : Type, V : Type),
629
+ where(K <: (Eq(K), Ord(K), Send), V <: (Eq(V), Send)),
630
+ SortedMap(K, V),
631
+ Eq(SortedMap(K, V))(
632
+ (==) : (fn(lhs : Self, rhs : Self) -> bool)({
633
+ if(lhs._len != rhs._len, {
634
+ return(false);
635
+ });
636
+ if((lhs._len == usize(0)) && (rhs._len == usize(0)), {
637
+ return(true);
638
+ });
639
+ lhs_keys := lhs.keys();
640
+ lhs_vals := lhs.values();
641
+ rhs_keys := rhs.keys();
642
+ rhs_vals := rhs.values();
643
+ (lhs_keys == rhs_keys) && (lhs_vals == rhs_vals)
644
+ })
645
+ )
646
+ );
647
+ export(SortedMap);
648
+ export(RBNode);
649
+ export(Color);