@shd101wyy/yo 0.1.14 → 0.1.16

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 (60) hide show
  1. package/README.md +43 -1
  2. package/out/cjs/index.cjs +581 -601
  3. package/out/cjs/yo-cli.cjs +739 -733
  4. package/out/cjs/yo-lsp.cjs +11615 -0
  5. package/out/esm/index.mjs +530 -550
  6. package/out/types/src/cache.d.ts +2 -0
  7. package/out/types/src/codegen/exprs/return.d.ts +1 -1
  8. package/out/types/src/codegen/types/generation.d.ts +0 -2
  9. package/out/types/src/codegen/utils/index.d.ts +2 -8
  10. package/out/types/src/doc/extractor.d.ts +4 -0
  11. package/out/types/src/evaluator/builtins/rc-fns.d.ts +0 -5
  12. package/out/types/src/evaluator/context.d.ts +7 -3
  13. package/out/types/src/evaluator/trait-checking.d.ts +2 -0
  14. package/out/types/src/evaluator/types/object.d.ts +2 -1
  15. package/out/types/src/evaluator/types/struct.d.ts +2 -1
  16. package/out/types/src/evaluator/types/utils.d.ts +3 -8
  17. package/out/types/src/evaluator/values/impl.d.ts +9 -1
  18. package/out/types/src/expr.d.ts +1 -2
  19. package/out/types/src/function-value.d.ts +1 -0
  20. package/out/types/src/lsp/completion.d.ts +3 -0
  21. package/out/types/src/lsp/definition.d.ts +3 -0
  22. package/out/types/src/lsp/diagnostics.d.ts +6 -0
  23. package/out/types/src/lsp/document-manager.d.ts +31 -0
  24. package/out/types/src/lsp/folding.d.ts +3 -0
  25. package/out/types/src/lsp/hover.d.ts +3 -0
  26. package/out/types/src/lsp/inlay-hints.d.ts +3 -0
  27. package/out/types/src/lsp/references.d.ts +3 -0
  28. package/out/types/src/lsp/rename.d.ts +16 -0
  29. package/out/types/src/lsp/server.d.ts +1 -0
  30. package/out/types/src/lsp/signature-help.d.ts +3 -0
  31. package/out/types/src/lsp/symbols.d.ts +3 -0
  32. package/out/types/src/lsp/utils.d.ts +11 -0
  33. package/out/types/src/tests/lsp.test.d.ts +1 -0
  34. package/out/types/src/tests/version.test.d.ts +1 -0
  35. package/out/types/src/types/creators.d.ts +2 -3
  36. package/out/types/src/types/definitions.d.ts +3 -6
  37. package/out/types/src/types/guards.d.ts +5 -2
  38. package/out/types/src/types/tags.d.ts +0 -1
  39. package/out/types/src/version-cache.d.ts +7 -0
  40. package/out/types/src/version.d.ts +5 -0
  41. package/out/types/tsconfig.tsbuildinfo +1 -1
  42. package/package.json +3 -1
  43. package/scripts/build-site.ts +32 -15
  44. package/scripts/check-liburing.js +2 -2
  45. package/std/imm/list.yo +254 -0
  46. package/std/imm/map.yo +917 -0
  47. package/std/imm/set.yo +179 -0
  48. package/std/imm/sorted_map.yo +595 -0
  49. package/std/imm/sorted_set.yo +202 -0
  50. package/std/imm/string.yo +667 -0
  51. package/std/imm/vec.yo +456 -0
  52. package/std/prelude.yo +22 -5
  53. package/std/sync/channel.yo +92 -44
  54. package/std/sync/cond.yo +5 -1
  55. package/std/sync/mutex.yo +5 -1
  56. package/std/sync/once.yo +2 -1
  57. package/std/sync/rwlock.yo +2 -1
  58. package/std/sync/waitgroup.yo +2 -1
  59. package/out/types/src/codegen/exprs/arc.d.ts +0 -5
  60. package/out/types/src/evaluator/calls/arc.d.ts +0 -15
@@ -0,0 +1,595 @@
1
+ //! Persistent immutable sorted map using a left-leaning red-black tree.
2
+ //!
3
+ //! `SortedMap(K, V)` stores key-value pairs in sorted order by key.
4
+ //! All mutations return new maps, leaving the original unchanged.
5
+ //! Backed by `atomic object` nodes for thread-safe structural sharing.
6
+ //!
7
+ //! Keys must implement `Eq`, `Ord`, and `Send`. Values must implement `Send`.
8
+ //!
9
+ //! # Examples
10
+ //!
11
+ //! ```rust
12
+ //! { SortedMap } :: import "std/imm/sorted_map";
13
+ //!
14
+ //! m := SortedMap(i32, i32).new();
15
+ //! m = m.insert(i32(3), i32(30));
16
+ //! m = m.insert(i32(1), i32(10));
17
+ //! m = m.insert(i32(2), i32(20));
18
+ //! // keys are always sorted: 1, 2, 3
19
+ //! ```
20
+
21
+ { List } :: import "./list.yo";
22
+ { Pair } :: import "./map.yo";
23
+
24
+ /// Color of a red-black tree node.
25
+ Color :: enum(Red, Black);
26
+
27
+ /// 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)
39
+ )
40
+ );
41
+
42
+ // Manual Acyclic impl — RBNode is self-referential, so auto-derivation skips it.
43
+ // This is safe because RBNode is immutable: all tree operations create new nodes
44
+ // and never mutate existing ones, making it impossible to form cycles at runtime.
45
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Ord(K), Send), V <: Send), RBNode(K, V), Acyclic());
46
+
47
+ /// 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))(
53
+ struct(
54
+ _root : Option(RBNode(K, V)),
55
+ _len : usize
56
+ )
57
+ );
58
+
59
+ // ---------------------------------------------------------------------------
60
+ // Helper standalone functions
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,
71
+ .Red => true,
72
+ .Black => false
73
+ ),
74
+ .None => false
75
+ )
76
+ );
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))(
88
+ RBNode(K, V)(
89
+ _key: key,
90
+ _value: value,
91
+ _color: color,
92
+ _left: left,
93
+ _right: right
94
+ )
95
+ );
96
+
97
+ /// 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))({
104
+ // x = h.right (must be Some)
105
+ (x : RBNode(K, V)) = match(h._right,
106
+ .Some(n) => n,
107
+ .None => h // unreachable
108
+ );
109
+ 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)
111
+ });
112
+
113
+ /// 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,
121
+ .Some(n) => n,
122
+ .None => h // unreachable
123
+ );
124
+ 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))
126
+ });
127
+
128
+ /// 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
+ .Red => Color.Black,
137
+ .Black => Color.Red
138
+ );
139
+ (new_left : Option(RBNode(K, V))) = match(h._left,
140
+ .Some(l) => {
141
+ lc := match(l._color,
142
+ .Red => Color.Black,
143
+ .Black => Color.Red
144
+ );
145
+ (Option(RBNode(K, V)).Some(_new_node(K, V, l._key, l._value, lc, l._left, l._right)))
146
+ },
147
+ .None => (Option(RBNode(K, V)).None)
148
+ );
149
+ (new_right : Option(RBNode(K, V))) = match(h._right,
150
+ .Some(r) => {
151
+ rc := match(r._color,
152
+ .Red => Color.Black,
153
+ .Black => Color.Red
154
+ );
155
+ (Option(RBNode(K, V)).Some(_new_node(K, V, r._key, r._value, rc, r._left, r._right)))
156
+ },
157
+ .None => (Option(RBNode(K, V)).None)
158
+ );
159
+ _new_node(K, V, h._key, h._value, new_color, new_left, new_right)
160
+ });
161
+
162
+ /// 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))({
169
+ (node : RBNode(K, V)) = h;
170
+ // Right-leaning red link → rotate left
171
+ if((_is_red(K, V, node._right) && !(_is_red(K, V, node._left))), {
172
+ node = _rotate_left(K, V, node);
173
+ });
174
+ // Two consecutive red left links → rotate right
175
+ left_red := _is_red(K, V, node._left);
176
+ left_left_red := match(node._left,
177
+ .Some(l) => _is_red(K, V, l._left),
178
+ .None => false
179
+ );
180
+ if((left_red && left_left_red), {
181
+ node = _rotate_right(K, V, node);
182
+ });
183
+ // Both children red → flip colors
184
+ if((_is_red(K, V, node._left) && _is_red(K, V, node._right)), {
185
+ node = _flip_colors(K, V, node);
186
+ });
187
+ node
188
+ });
189
+
190
+ /// 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),
201
+ .Some(h) => {
202
+ (n : RBNode(K, V)) = cond(
203
+ (key < h._key) =>
204
+ _new_node(K, V, h._key, h._value, h._color,
205
+ .Some(_node_insert(K, V, h._left, key, value)), h._right),
206
+ (key == h._key) =>
207
+ _new_node(K, V, h._key, value, h._color, h._left, h._right),
208
+ true =>
209
+ _new_node(K, V, h._key, h._value, h._color,
210
+ h._left, .Some(_node_insert(K, V, h._right, key, value)))
211
+ );
212
+ _fixup(K, V, n)
213
+ }
214
+ )
215
+ );
216
+
217
+ /// 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,
227
+ .Some(h) => cond(
228
+ (key < h._key) => _node_get(K, V, h._left, key),
229
+ (key == h._key) => .Some(h._value),
230
+ true => _node_get(K, V, h._right, key)
231
+ )
232
+ )
233
+ );
234
+
235
+ /// 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,
244
+ .None => false,
245
+ .Some(h) => cond(
246
+ (key < h._key) => _node_contains(K, V, h._left, key),
247
+ (key == h._key) => true,
248
+ true => _node_contains(K, V, h._right, key)
249
+ )
250
+ )
251
+ );
252
+
253
+ // ---------------------------------------------------------------------------
254
+ // Remove helpers for LLRB delete
255
+ // ---------------------------------------------------------------------------
256
+
257
+ /// 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))({
264
+ (node : RBNode(K, V)) = _flip_colors(K, V, h);
265
+ right_left_red := match(node._right,
266
+ .Some(r) => _is_red(K, V, r._left),
267
+ .None => false
268
+ );
269
+ if(right_left_red, {
270
+ (new_right : Option(RBNode(K, V))) = match(node._right,
271
+ .Some(r) => Option(RBNode(K, V)).Some(_rotate_right(K, V, r)),
272
+ .None => (Option(RBNode(K, V)).None)
273
+ );
274
+ node = _new_node(K, V, node._key, node._value, node._color, node._left, new_right);
275
+ node = _rotate_left(K, V, node);
276
+ node = _flip_colors(K, V, node);
277
+ });
278
+ node
279
+ });
280
+
281
+ /// 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))({
288
+ (node : RBNode(K, V)) = _flip_colors(K, V, h);
289
+ left_left_red := match(node._left,
290
+ .Some(l) => _is_red(K, V, l._left),
291
+ .None => false
292
+ );
293
+ if(left_left_red, {
294
+ node = _rotate_right(K, V, node);
295
+ node = _flip_colors(K, V, node);
296
+ });
297
+ node
298
+ });
299
+
300
+ /// 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,
308
+ .Some(l) => _node_min(K, V, l),
309
+ .None => h
310
+ )
311
+ );
312
+
313
+ /// 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,
322
+ .Some(l) => {
323
+ (node : RBNode(K, V)) = h;
324
+ if((!(_is_red(K, V, .Some(l))) && !(_is_red(K, V, l._left))), {
325
+ node = _move_red_left(K, V, node);
326
+ });
327
+ new_left := match(node._left,
328
+ .Some(nl) => _delete_min(K, V, nl),
329
+ .None => (Option(RBNode(K, V)).None)
330
+ );
331
+ .Some(_fixup(K, V,
332
+ _new_node(K, V, node._key, node._value, node._color, new_left, node._right)
333
+ ))
334
+ }
335
+ )
336
+ );
337
+
338
+ /// 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)))({
346
+ (node : RBNode(K, V)) = h;
347
+
348
+ if((key < node._key), {
349
+ // Go left
350
+ has_left := match(node._left,
351
+ .Some(_) => true,
352
+ .None => false
353
+ );
354
+ if(has_left, {
355
+ left_red := _is_red(K, V, node._left);
356
+ left_left_red := match(node._left,
357
+ .Some(l) => _is_red(K, V, l._left),
358
+ .None => false
359
+ );
360
+ if((!(left_red) && !(left_left_red)), {
361
+ node = _move_red_left(K, V, node);
362
+ });
363
+ new_left := match(node._left,
364
+ .Some(nl) => _node_remove(K, V, nl, key),
365
+ .None => (Option(RBNode(K, V)).None)
366
+ );
367
+ node = _new_node(K, V, node._key, node._value, node._color, new_left, node._right);
368
+ });
369
+ .Some(_fixup(K, V, node))
370
+ }, {
371
+ // key >= node._key
372
+ if(_is_red(K, V, node._left), {
373
+ node = _rotate_right(K, V, node);
374
+ });
375
+
376
+ // If equal and no right child, delete this node
377
+ is_eq := (key == node._key);
378
+ has_right := match(node._right,
379
+ .Some(_) => true,
380
+ .None => false
381
+ );
382
+ if((is_eq && !(has_right)), {
383
+ return .None;
384
+ });
385
+
386
+ // Ensure right child is not a 2-node
387
+ if(has_right, {
388
+ right_red := _is_red(K, V, node._right);
389
+ right_left_red := match(node._right,
390
+ .Some(r) => _is_red(K, V, r._left),
391
+ .None => false
392
+ );
393
+ if((!(right_red) && !(right_left_red)), {
394
+ node = _move_red_right(K, V, node);
395
+ });
396
+ });
397
+
398
+ is_eq2 := (key == node._key);
399
+ if(is_eq2, {
400
+ // Replace with successor (min of right subtree)
401
+ succ := match(node._right,
402
+ .Some(r) => _node_min(K, V, r),
403
+ .None => node // unreachable
404
+ );
405
+ new_right := match(node._right,
406
+ .Some(r) => _delete_min(K, V, r),
407
+ .None => (Option(RBNode(K, V)).None)
408
+ );
409
+ node = _new_node(K, V, succ._key, succ._value, node._color, node._left, new_right);
410
+ }, {
411
+ // Go right
412
+ new_right := match(node._right,
413
+ .Some(r) => _node_remove(K, V, r, key),
414
+ .None => (Option(RBNode(K, V)).None)
415
+ );
416
+ node = _new_node(K, V, node._key, node._value, node._color, node._left, new_right);
417
+ });
418
+
419
+ .Some(_fixup(K, V, node))
420
+ })
421
+ });
422
+
423
+ // ---------------------------------------------------------------------------
424
+ // In-order traversal helpers
425
+ // ---------------------------------------------------------------------------
426
+
427
+ /// 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,
436
+ .None => acc,
437
+ .Some(h) => {
438
+ right_acc := _collect_keys(K, V, h._right, acc);
439
+ with_key := right_acc.prepend(h._key);
440
+ _collect_keys(K, V, h._left, with_key)
441
+ }
442
+ )
443
+ );
444
+
445
+ /// 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,
454
+ .None => acc,
455
+ .Some(h) => {
456
+ right_acc := _collect_values(K, V, h._right, acc);
457
+ with_val := right_acc.prepend(h._value);
458
+ _collect_values(K, V, h._left, with_val)
459
+ }
460
+ )
461
+ );
462
+
463
+ // ---------------------------------------------------------------------------
464
+ // SortedMap impl
465
+ // ---------------------------------------------------------------------------
466
+
467
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Ord(K), Send), V <: Send), SortedMap(K, V),
468
+ /// Create an empty sorted map.
469
+ new : (fn() -> Self)(
470
+ Self(_root: .None, _len: usize(0))
471
+ ),
472
+
473
+ /// Number of entries.
474
+ len : (fn(self: Self) -> usize)(self._len),
475
+
476
+ /// Check if the map is empty.
477
+ is_empty : (fn(self: Self) -> bool)((self._len == usize(0))),
478
+
479
+ /// Look up a value by key.
480
+ get : (fn(self: Self, key: K) -> Option(V))(
481
+ _node_get(K, V, self._root, key)
482
+ ),
483
+
484
+ /// Check if a key exists.
485
+ contains_key : (fn(self: Self, key: K) -> bool)(
486
+ _node_contains(K, V, self._root, key)
487
+ ),
488
+
489
+ /// Return a new map with the key-value pair inserted (or updated).
490
+ insert : (fn(self: Self, key: K, value: V) -> Self)({
491
+ existed := _node_contains(K, V, self._root, key);
492
+ new_root := _node_insert(K, V, self._root, key, value);
493
+ // Root is always black
494
+ black_root := _new_node(K, V, new_root._key, new_root._value, .Black, new_root._left, new_root._right);
495
+ new_len := cond(
496
+ existed => self._len,
497
+ true => (self._len + usize(1))
498
+ );
499
+ Self(_root: .Some(black_root), _len: new_len)
500
+ }),
501
+
502
+ /// Return a new map with the key removed.
503
+ remove : (fn(self: Self, key: K) -> Self)(
504
+ match(self._root,
505
+ .None => self,
506
+ .Some(root) => {
507
+ existed := _node_contains(K, V, .Some(root), key);
508
+ if(!(existed), {
509
+ return self;
510
+ });
511
+ 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)
515
+ );
516
+ Self(_root: new_root, _len: (self._len - usize(1)))
517
+ }
518
+ )
519
+ ),
520
+
521
+ /// Get the minimum key in the map.
522
+ min_key : (fn(self: Self) -> Option(K))(
523
+ match(self._root,
524
+ .None => .None,
525
+ .Some(root) => {
526
+ m := _node_min(K, V, root);
527
+ .Some(m._key)
528
+ }
529
+ )
530
+ ),
531
+
532
+ /// Get the maximum key by going right.
533
+ max_key : (fn(self: Self) -> Option(K))(
534
+ match(self._root,
535
+ .None => .None,
536
+ .Some(root) => {
537
+ (cur : RBNode(K, V)) = root;
538
+ (done : bool) = false;
539
+ while runtime(!(done)), {
540
+ match(cur._right,
541
+ .Some(r) => {
542
+ cur = r;
543
+ },
544
+ .None => {
545
+ done = true;
546
+ }
547
+ );
548
+ };
549
+ .Some(cur._key)
550
+ }
551
+ )
552
+ ),
553
+
554
+ /// Return in-order list of keys.
555
+ keys : (fn(self: Self) -> List(K))(
556
+ _collect_keys(K, V, self._root, List(K).new())
557
+ ),
558
+
559
+ /// Return list of values in key order.
560
+ values : (fn(self: Self) -> List(V))(
561
+ _collect_values(K, V, self._root, List(V).new())
562
+ ),
563
+
564
+ /// Create a sorted map from a slice of key-value pairs.
565
+ from_entries : (fn(pairs: Slice(Pair(K, V))) -> Self)({
566
+ (result : Self) = Self.new();
567
+ i := usize(0);
568
+ plen := pairs.len();
569
+ while (i < plen), (i = (i + usize(1))), {
570
+ p := (pairs.ptr() &+ i).*;
571
+ result = result.insert(p.key, p.value);
572
+ };
573
+ result
574
+ })
575
+ );
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;