@shd101wyy/yo 0.0.23 → 0.0.25

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 (97) hide show
  1. package/out/cjs/index.cjs +560 -520
  2. package/out/cjs/yo-cli.cjs +598 -558
  3. package/out/esm/index.mjs +551 -511
  4. package/out/types/src/codegen/exprs/arc.d.ts +5 -0
  5. package/out/types/src/codegen/types/generation.d.ts +2 -0
  6. package/out/types/src/codegen/utils/index.d.ts +8 -1
  7. package/out/types/src/evaluator/builtins/rc-fns.d.ts +5 -0
  8. package/out/types/src/evaluator/calls/arc.d.ts +15 -0
  9. package/out/types/src/evaluator/calls/trait-type.d.ts +8 -1
  10. package/out/types/src/evaluator/context.d.ts +11 -1
  11. package/out/types/src/evaluator/types/utils.d.ts +8 -3
  12. package/out/types/src/evaluator/utils/closure.d.ts +7 -1
  13. package/out/types/src/evaluator/values/impl.d.ts +8 -0
  14. package/out/types/src/expr.d.ts +6 -0
  15. package/out/types/src/test-runner.d.ts +2 -0
  16. package/out/types/src/types/creators.d.ts +2 -1
  17. package/out/types/src/types/definitions.d.ts +10 -0
  18. package/out/types/src/types/guards.d.ts +2 -1
  19. package/out/types/src/types/tags.d.ts +1 -0
  20. package/out/types/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +1 -1
  22. package/std/collections/array_list.yo +80 -10
  23. package/std/collections/btree_map.yo +120 -2
  24. package/std/collections/deque.yo +98 -6
  25. package/std/collections/hash_map.yo +137 -1
  26. package/std/collections/hash_set.yo +85 -1
  27. package/std/collections/linked_list.yo +61 -1
  28. package/std/collections/priority_queue.yo +70 -1
  29. package/std/crypto/md5.yo +4 -4
  30. package/std/crypto/random.yo +3 -3
  31. package/std/crypto/sha256.yo +8 -7
  32. package/std/encoding/base64.yo +6 -6
  33. package/std/encoding/hex.yo +27 -22
  34. package/std/encoding/json.yo +185 -186
  35. package/std/encoding/utf16.yo +2 -2
  36. package/std/fmt/display.yo +1 -1
  37. package/std/fmt/writer.yo +2 -4
  38. package/std/fs/dir.yo +5 -5
  39. package/std/fs/file.yo +21 -13
  40. package/std/fs/metadata.yo +4 -4
  41. package/std/fs/temp.yo +3 -3
  42. package/std/fs/types.yo +1 -1
  43. package/std/fs/walker.yo +1 -1
  44. package/std/net/addr.yo +2 -2
  45. package/std/net/dns.yo +21 -20
  46. package/std/net/errors.yo +1 -1
  47. package/std/net/tcp.yo +134 -100
  48. package/std/net/udp.yo +51 -42
  49. package/std/os/env.yo +21 -23
  50. package/std/os/signal.yo +10 -9
  51. package/std/prelude.yo +158 -22
  52. package/std/string/string.yo +99 -1
  53. package/std/sync/once.yo +1 -1
  54. package/std/{io → sys}/advise.yo +1 -1
  55. package/std/sys/bufio/buf_reader.yo +300 -0
  56. package/std/sys/bufio/buf_writer.yo +168 -0
  57. package/std/{io → sys}/clock.yo +1 -1
  58. package/std/{io → sys}/constants.yo +1 -1
  59. package/std/{io → sys}/copy.yo +1 -1
  60. package/std/{io → sys}/dir.yo +6 -6
  61. package/std/{io → sys}/dns.yo +3 -3
  62. package/std/{io → sys}/errors.yo +1 -1
  63. package/std/{io → sys}/events.yo +1 -1
  64. package/std/{io → sys}/externs.yo +1 -1
  65. package/std/{io → sys}/fallocate.yo +1 -1
  66. package/std/{io → sys}/fcntl.yo +1 -1
  67. package/std/{io → sys}/file.yo +1 -1
  68. package/std/{io → sys}/future.yo +1 -1
  69. package/std/{io → sys}/iov.yo +1 -1
  70. package/std/{io → sys}/lock.yo +1 -1
  71. package/std/{io → sys}/mmap.yo +1 -1
  72. package/std/{io → sys}/path.yo +1 -1
  73. package/std/{io → sys}/perm.yo +3 -3
  74. package/std/{io → sys}/pipe.yo +1 -1
  75. package/std/{io → sys}/process.yo +1 -1
  76. package/std/{io → sys}/seek.yo +1 -1
  77. package/std/{io → sys}/signal.yo +1 -1
  78. package/std/{io → sys}/signals.yo +1 -1
  79. package/std/{io → sys}/socket.yo +1 -1
  80. package/std/{io → sys}/socketpair.yo +1 -1
  81. package/std/{io → sys}/sockinfo.yo +1 -1
  82. package/std/{io → sys}/statfs.yo +2 -2
  83. package/std/{io → sys}/statx.yo +1 -1
  84. package/std/{io → sys}/sysinfo.yo +1 -1
  85. package/std/{io → sys}/tcp.yo +3 -3
  86. package/std/{io → sys}/temp.yo +1 -1
  87. package/std/{io → sys}/time.yo +2 -2
  88. package/std/{io → sys}/timer.yo +1 -1
  89. package/std/{io → sys}/tty.yo +1 -1
  90. package/std/{io → sys}/udp.yo +4 -4
  91. package/std/{io → sys}/umask.yo +1 -1
  92. package/std/{io → sys}/unix.yo +1 -1
  93. package/std/time/datetime.yo +18 -23
  94. package/std/time/instant.yo +13 -11
  95. package/std/url/url.yo +533 -0
  96. package/std/math/functions.yo +0 -74
  97. package/std/math/random.yo +0 -94
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shd101wyy/yo",
3
3
  "displayName": "Yo",
4
- "version": "0.0.23",
4
+ "version": "0.0.25",
5
5
  "main": "./out/cjs/index.cjs",
6
6
  "module": "./out/esm/index.mjs",
7
7
  "types": "./out/types/src/index.d.ts",
@@ -54,16 +54,16 @@ impl(forall(T : Type), ArrayList(T),
54
54
 
55
55
  /**
56
56
  * Get a slice view of the ArrayList
57
- * Returns a fat pointer [T] with data pointer and length
57
+ * Returns a fat pointer Slice(T) with data pointer and length
58
58
  * This allows passing ArrayList to functions expecting slices
59
+ * Returns .None for an empty ArrayList with no allocated buffer
59
60
  */
60
- // as_slice :: (fn(self: Self) -> [T])({
61
- // ptr := match(self._ptr,
62
- // .Some(p) => p,
63
- // .None => (*(T))(*(void)(usize(0))) // NULL for empty list
64
- // );
65
- // return [T](ptr, self._length);
66
- // }),
61
+ as_slice : (fn(self: Self) -> Option(Slice(T)))(
62
+ match(self._ptr,
63
+ .Some(p) => .Some(Slice(T).from_raw_parts(p, self._length)),
64
+ .None => .None
65
+ )
66
+ ),
67
67
 
68
68
  /** * Directly set the length of the ArrayList
69
69
  * UNSAFE: This does not initialize new elements or free removed elements
@@ -400,7 +400,7 @@ impl(forall(T : Type), ArrayList(T),
400
400
  while(i < slice_length, i = (i + usize(1)), {
401
401
  src := (src_ptr &+ (start + i));
402
402
  dst := (dst_ptr &+ i);
403
- dst.* = src.*;
403
+ consume(dst.* = src.*);
404
404
  });
405
405
 
406
406
  // Set the length of the new list
@@ -441,7 +441,77 @@ impl(forall(T : Type), ArrayList(T), Dispose(
441
441
  })
442
442
  ));
443
443
 
444
+ // === Iterator support ===
445
+
446
+ /**
447
+ * Value iterator for ArrayList - yields elements by value (T)
448
+ * Used by into_iter() / IntoIterator trait
449
+ */
450
+ ArrayListIter :: (fn(comptime(T) : Type) -> comptime(Type))(
451
+ struct(
452
+ _list : ArrayList(T),
453
+ _index : usize
454
+ )
455
+ );
456
+
457
+ impl(forall(T : Type), ArrayListIter(T), Iterator(
458
+ Item : T,
459
+ next : (fn(self : *(Self)) -> Option(T))(
460
+ cond(
461
+ (self._index >= self._list._length) => .None,
462
+ true => {
463
+ value := self._list.get(self._index);
464
+ self._index = (self._index + usize(1));
465
+ value
466
+ }
467
+ )
468
+ )
469
+ ));
470
+
471
+ impl(forall(T : Type), ArrayList(T),
472
+ into_iter : (fn(self : Self) -> ArrayListIter(T))(
473
+ ArrayListIter(T)(_list: self, _index: usize(0))
474
+ )
475
+ );
476
+
477
+ /**
478
+ * Pointer iterator for ArrayList - yields pointers to elements (*(T))
479
+ * Used by iter() method
480
+ */
481
+ ArrayListIterPtr :: (fn(comptime(T) : Type) -> comptime(Type))(
482
+ struct(
483
+ _list : ArrayList(T),
484
+ _index : usize
485
+ )
486
+ );
487
+
488
+ impl(forall(T : Type), ArrayListIterPtr(T), Iterator(
489
+ Item : *(T),
490
+ next : (fn(self : *(Self)) -> Option(*(T)))(
491
+ cond(
492
+ (self._index >= self._list._length) => .None,
493
+ true =>
494
+ match(self._list._ptr,
495
+ .Some(ptr) => {
496
+ element_ptr := (ptr &+ self._index);
497
+ self._index = (self._index + usize(1));
498
+ .Some(element_ptr)
499
+ },
500
+ .None => .None
501
+ )
502
+ )
503
+ )
504
+ ));
505
+
506
+ impl(forall(T : Type), ArrayList(T),
507
+ iter : (fn(self : *(Self)) -> ArrayListIterPtr(T))(
508
+ ArrayListIterPtr(T)(_list: self.*, _index: usize(0))
509
+ )
510
+ );
511
+
444
512
  export
445
513
  ArrayList,
446
- ArrayListError
514
+ ArrayListError,
515
+ ArrayListIter,
516
+ ArrayListIterPtr
447
517
  ;
@@ -130,8 +130,126 @@ impl(forall(K : Type, V : Type), BTreeMap(K, V),
130
130
  true => .Some(self._entries.get((self._entries.len() - usize(1))).unwrap())
131
131
  )
132
132
  )
133
+ );
134
+
135
+ /**
136
+ * Value iterator for BTreeMap - yields BTreeEntry(K, V) in sorted key order
137
+ */
138
+ BTreeMapIter :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
139
+ struct(
140
+ _entries : ArrayList(BTreeEntry(K, V)),
141
+ _index : usize
142
+ )
143
+ );
144
+
145
+ impl(forall(K : Type, V : Type), BTreeMapIter(K, V), Iterator(
146
+ Item : BTreeEntry(K, V),
147
+ next : (fn(self : *(Self)) -> Option(BTreeEntry(K, V)))(
148
+ cond(
149
+ (self._index >= self._entries.len()) => .None,
150
+ true => {
151
+ entry := self._entries.get(self._index).unwrap();
152
+ self._index = (self._index + usize(1));
153
+ .Some(entry)
154
+ }
155
+ )
156
+ )
157
+ ));
158
+
159
+ impl(forall(K : Type, V : Type), BTreeMap(K, V),
160
+ into_iter : (fn(self : Self) -> BTreeMapIter(K, V))(
161
+ BTreeMapIter(K, V)(_entries: self._entries, _index: usize(0))
162
+ )
163
+ );
164
+
165
+ /**
166
+ * Pointer iterator for BTreeMap - yields pointers to BTreeEntry(K, V) in sorted key order
167
+ */
168
+ BTreeMapIterPtr :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
169
+ struct(
170
+ _entries : ArrayList(BTreeEntry(K, V)),
171
+ _index : usize
172
+ )
173
+ );
133
174
 
134
- // TODO: Add iteration via Iterator trait once supported.
175
+ impl(forall(K : Type, V : Type), BTreeMapIterPtr(K, V), Iterator(
176
+ Item : *(BTreeEntry(K, V)),
177
+ next : (fn(self : *(Self)) -> Option(*(BTreeEntry(K, V))))(
178
+ cond(
179
+ (self._index >= self._entries.len()) => .None,
180
+ true =>
181
+ match(self._entries._ptr,
182
+ .Some(ptr) => {
183
+ element_ptr := (ptr &+ self._index);
184
+ self._index = (self._index + usize(1));
185
+ .Some(element_ptr)
186
+ },
187
+ .None => .None
188
+ )
189
+ )
190
+ )
191
+ ));
192
+
193
+ impl(forall(K : Type, V : Type), BTreeMap(K, V),
194
+ iter : (fn(self : *(Self)) -> BTreeMapIterPtr(K, V))(
195
+ BTreeMapIterPtr(K, V)(_entries: self.*._entries, _index: usize(0))
196
+ )
197
+ );
198
+
199
+ /**
200
+ * Keys iterator - wraps BTreeMapIter and yields only keys in sorted order
201
+ */
202
+ BTreeMapKeys :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
203
+ struct(
204
+ _inner : BTreeMapIter(K, V)
205
+ )
206
+ );
207
+
208
+ impl(forall(K : Type, V : Type), BTreeMapKeys(K, V), Iterator(
209
+ Item : K,
210
+ next : (fn(self : *(Self)) -> Option(K))(
211
+ match(self._inner.next(),
212
+ .None => .None,
213
+ .Some(entry) => .Some(entry.key)
214
+ )
215
+ )
216
+ ));
217
+
218
+ impl(forall(K : Type, V : Type), BTreeMap(K, V),
219
+ keys : (fn(self : Self) -> BTreeMapKeys(K, V))(
220
+ BTreeMapKeys(K, V)(_inner: BTreeMapIter(K, V)(_entries: self._entries, _index: usize(0)))
221
+ )
222
+ );
223
+
224
+ /**
225
+ * Values iterator - wraps BTreeMapIter and yields only values in sorted key order
226
+ */
227
+ BTreeMapValues :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
228
+ struct(
229
+ _inner : BTreeMapIter(K, V)
230
+ )
231
+ );
232
+
233
+ impl(forall(K : Type, V : Type), BTreeMapValues(K, V), Iterator(
234
+ Item : V,
235
+ next : (fn(self : *(Self)) -> Option(V))(
236
+ match(self._inner.next(),
237
+ .None => .None,
238
+ .Some(entry) => .Some(entry.value)
239
+ )
240
+ )
241
+ ));
242
+
243
+ impl(forall(K : Type, V : Type), BTreeMap(K, V),
244
+ values : (fn(self : Self) -> BTreeMapValues(K, V))(
245
+ BTreeMapValues(K, V)(_inner: BTreeMapIter(K, V)(_entries: self._entries, _index: usize(0)))
246
+ )
135
247
  );
136
248
 
137
- export BTreeMap;
249
+ export
250
+ BTreeMap,
251
+ BTreeMapIter,
252
+ BTreeMapIterPtr,
253
+ BTreeMapKeys,
254
+ BTreeMapValues
255
+ ;
@@ -57,8 +57,21 @@ impl(forall(T : Type), Deque(T),
57
57
  while (i < self._len), (i = (i + usize(1))), {
58
58
  idx := ((self._head + i) % self._capacity);
59
59
  buf := self._buf.unwrap();
60
- (new_buf &+ i).* = (buf &+ idx).*;
60
+ consume((new_buf &+ i).* = (buf &+ idx).*);
61
61
  };
62
+ // Drop old elements for RC types before freeing old buffer
63
+ // (the copy above duped each element, so old slots still hold references)
64
+ cond(
65
+ Type.contains_rc_type(T) => {
66
+ j := usize(0);
67
+ while (j < self._len), (j = (j + usize(1))), {
68
+ old_idx := ((self._head + j) % self._capacity);
69
+ old_buf := self._buf.unwrap();
70
+ unsafe.drop((old_buf &+ old_idx).*);
71
+ };
72
+ },
73
+ true => ()
74
+ );
62
75
  match(self._buf,
63
76
  .Some(p) => free(.Some(*(void)(p))),
64
77
  .None => ()
@@ -76,7 +89,7 @@ impl(forall(T : Type), Deque(T),
76
89
  true => ()
77
90
  );
78
91
  buf := self._buf.unwrap();
79
- (buf &+ self._tail).* = val;
92
+ consume((buf &+ self._tail).* = val);
80
93
  self._tail = ((self._tail + usize(1)) % self._capacity);
81
94
  self._len = (self._len + usize(1));
82
95
  }),
@@ -92,7 +105,7 @@ impl(forall(T : Type), Deque(T),
92
105
  true => (self._head - usize(1))
93
106
  );
94
107
  buf := self._buf.unwrap();
95
- (buf &+ self._head).* = val;
108
+ consume((buf &+ self._head).* = val);
96
109
  self._len = (self._len + usize(1));
97
110
  }),
98
111
 
@@ -102,7 +115,9 @@ impl(forall(T : Type), Deque(T),
102
115
  (self._len == usize(0)) => .None,
103
116
  true => {
104
117
  buf := self._buf.unwrap();
105
- val := (buf &+ self._head).*;
118
+ element_ptr := (buf &+ self._head);
119
+ val := element_ptr.*;
120
+ unsafe.drop(element_ptr.*);
106
121
  self._head = ((self._head + usize(1)) % self._capacity);
107
122
  self._len = (self._len - usize(1));
108
123
  .Some(val)
@@ -120,7 +135,9 @@ impl(forall(T : Type), Deque(T),
120
135
  true => (self._tail - usize(1))
121
136
  );
122
137
  buf := self._buf.unwrap();
123
- val := (buf &+ self._tail).*;
138
+ element_ptr := (buf &+ self._tail);
139
+ val := element_ptr.*;
140
+ unsafe.drop(element_ptr.*);
124
141
  self._len = (self._len - usize(1));
125
142
  .Some(val)
126
143
  }
@@ -162,4 +179,79 @@ impl(forall(T : Type), Deque(T), Dispose(
162
179
  })
163
180
  ));
164
181
 
165
- export Deque;
182
+ /**
183
+ * Value iterator for Deque - yields elements by value (T)
184
+ * Traverses the circular buffer in logical order.
185
+ */
186
+ DequeIter :: (fn(comptime(T) : Type) -> comptime(Type))(
187
+ struct(
188
+ _deque : Deque(T),
189
+ _pos : usize,
190
+ _remaining : usize
191
+ )
192
+ );
193
+
194
+ impl(forall(T : Type), DequeIter(T), Iterator(
195
+ Item : T,
196
+ next : (fn(self : *(Self)) -> Option(T))(
197
+ cond(
198
+ (self._remaining == usize(0)) => .None,
199
+ true => {
200
+ idx := ((self._deque._head + self._pos) % self._deque._capacity);
201
+ buf := self._deque._buf.unwrap();
202
+ value := (buf &+ idx).*;
203
+ self._pos = (self._pos + usize(1));
204
+ self._remaining = (self._remaining - usize(1));
205
+ .Some(value)
206
+ }
207
+ )
208
+ )
209
+ ));
210
+
211
+ impl(forall(T : Type), Deque(T),
212
+ into_iter : (fn(self : Self) -> DequeIter(T))(
213
+ DequeIter(T)(_deque: self, _pos: usize(0), _remaining: self._len)
214
+ )
215
+ );
216
+
217
+ /**
218
+ * Pointer iterator for Deque - yields pointers to elements (*(T))
219
+ * Yields pointers into the circular buffer. Pointers are valid as long as
220
+ * the deque is not modified during iteration.
221
+ */
222
+ DequeIterPtr :: (fn(comptime(T) : Type) -> comptime(Type))(
223
+ struct(
224
+ _deque : Deque(T),
225
+ _pos : usize,
226
+ _remaining : usize
227
+ )
228
+ );
229
+
230
+ impl(forall(T : Type), DequeIterPtr(T), Iterator(
231
+ Item : *(T),
232
+ next : (fn(self : *(Self)) -> Option(*(T)))(
233
+ cond(
234
+ (self._remaining == usize(0)) => .None,
235
+ true => {
236
+ idx := ((self._deque._head + self._pos) % self._deque._capacity);
237
+ buf := self._deque._buf.unwrap();
238
+ element_ptr := (buf &+ idx);
239
+ self._pos = (self._pos + usize(1));
240
+ self._remaining = (self._remaining - usize(1));
241
+ .Some(element_ptr)
242
+ }
243
+ )
244
+ )
245
+ ));
246
+
247
+ impl(forall(T : Type), Deque(T),
248
+ iter : (fn(self : *(Self)) -> DequeIterPtr(T))(
249
+ DequeIterPtr(T)(_deque: self.*, _pos: usize(0), _remaining: self.*._len)
250
+ )
251
+ );
252
+
253
+ export
254
+ Deque,
255
+ DequeIter,
256
+ DequeIterPtr
257
+ ;
@@ -565,8 +565,144 @@ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMap(K, V),
565
565
  })
566
566
  ));
567
567
 
568
+ /**
569
+ * Value iterator for HashMap - yields Bucket(K, V) by value
570
+ * Scans ctrl bytes to find occupied slots.
571
+ */
572
+ HashMapIter :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
573
+ struct(
574
+ _map : HashMap(K, V),
575
+ _index : usize
576
+ )
577
+ );
578
+
579
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMapIter(K, V), Iterator(
580
+ Item : Bucket(K, V),
581
+ next : (fn(self : *(Self)) -> Option(Bucket(K, V)))(
582
+ cond(
583
+ (self._map.capacity == usize(0)) => .None,
584
+ true => {
585
+ ctrl_ptr := self._map.ctrl.unwrap();
586
+ data_ptr := self._map.data.unwrap();
587
+ result := Option(Bucket(K, V)).None;
588
+ while ((self._index < self._map.capacity) && result.is_none()), (self._index = (self._index + usize(1))), {
589
+ ctrl_byte := (ctrl_ptr &+ self._index).*;
590
+ cond(
591
+ ((ctrl_byte != CTRL_EMPTY) && (ctrl_byte != CTRL_DELETED)) => {
592
+ result = .Some((data_ptr &+ self._index).*);
593
+ },
594
+ true => ()
595
+ );
596
+ };
597
+ result
598
+ }
599
+ )
600
+ )
601
+ ));
602
+
603
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMap(K, V),
604
+ into_iter : (fn(self : Self) -> HashMapIter(K, V))(
605
+ HashMapIter(K, V)(_map: self, _index: usize(0))
606
+ )
607
+ );
608
+
609
+ /**
610
+ * Pointer iterator for HashMap - yields pointers to Bucket(K, V)
611
+ * Pointers are valid as long as the map is not modified during iteration.
612
+ */
613
+ HashMapIterPtr :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
614
+ struct(
615
+ _map : HashMap(K, V),
616
+ _index : usize
617
+ )
618
+ );
619
+
620
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMapIterPtr(K, V), Iterator(
621
+ Item : *(Bucket(K, V)),
622
+ next : (fn(self : *(Self)) -> Option(*(Bucket(K, V))))(
623
+ cond(
624
+ (self._map.capacity == usize(0)) => .None,
625
+ true => {
626
+ ctrl_ptr := self._map.ctrl.unwrap();
627
+ data_ptr := self._map.data.unwrap();
628
+ result := Option(*(Bucket(K, V))).None;
629
+ while ((self._index < self._map.capacity) && result.is_none()), (self._index = (self._index + usize(1))), {
630
+ ctrl_byte := (ctrl_ptr &+ self._index).*;
631
+ cond(
632
+ ((ctrl_byte != CTRL_EMPTY) && (ctrl_byte != CTRL_DELETED)) => {
633
+ result = .Some((data_ptr &+ self._index));
634
+ },
635
+ true => ()
636
+ );
637
+ };
638
+ result
639
+ }
640
+ )
641
+ )
642
+ ));
643
+
644
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMap(K, V),
645
+ iter : (fn(self : *(Self)) -> HashMapIterPtr(K, V))(
646
+ HashMapIterPtr(K, V)(_map: self.*, _index: usize(0))
647
+ )
648
+ );
649
+
650
+ /**
651
+ * Keys iterator - wraps HashMapIter and yields only the keys
652
+ */
653
+ HashMapKeys :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
654
+ struct(
655
+ _inner : HashMapIter(K, V)
656
+ )
657
+ );
658
+
659
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMapKeys(K, V), Iterator(
660
+ Item : K,
661
+ next : (fn(self : *(Self)) -> Option(K))(
662
+ match(self._inner.next(),
663
+ .None => .None,
664
+ .Some(bucket) => .Some(bucket.key)
665
+ )
666
+ )
667
+ ));
668
+
669
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMap(K, V),
670
+ keys : (fn(self : Self) -> HashMapKeys(K, V))(
671
+ HashMapKeys(K, V)(_inner: HashMapIter(K, V)(_map: self, _index: usize(0)))
672
+ )
673
+ );
674
+
675
+ /**
676
+ * Values iterator - wraps HashMapIter and yields only the values
677
+ */
678
+ HashMapValues :: (fn(comptime(K) : Type, comptime(V) : Type) -> comptime(Type))(
679
+ struct(
680
+ _inner : HashMapIter(K, V)
681
+ )
682
+ );
683
+
684
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMapValues(K, V), Iterator(
685
+ Item : V,
686
+ next : (fn(self : *(Self)) -> Option(V))(
687
+ match(self._inner.next(),
688
+ .None => .None,
689
+ .Some(bucket) => .Some(bucket.value)
690
+ )
691
+ )
692
+ ));
693
+
694
+ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), HashMap(K, V),
695
+ values : (fn(self : Self) -> HashMapValues(K, V))(
696
+ HashMapValues(K, V)(_inner: HashMapIter(K, V)(_map: self, _index: usize(0)))
697
+ )
698
+ );
699
+
568
700
  export
569
701
  HashMap,
570
702
  HashMapError,
571
- Bucket
703
+ Bucket,
704
+ HashMapIter,
705
+ HashMapIterPtr,
706
+ HashMapKeys,
707
+ HashMapValues
572
708
  ;
@@ -781,7 +781,91 @@ impl(forall(T : Type), where(T <: (Eq(T), Hash)), HashSet(T), Dispose(
781
781
  )
782
782
  ));
783
783
 
784
+ /**
785
+ * Value iterator for HashSet - yields elements by value (T)
786
+ * Scans ctrl bytes to find occupied slots.
787
+ */
788
+ HashSetIter :: (fn(comptime(T) : Type) -> comptime(Type))(
789
+ struct(
790
+ _set : HashSet(T),
791
+ _index : usize
792
+ )
793
+ );
794
+
795
+ impl(forall(T : Type), where(T <: (Eq(T), Hash)), HashSetIter(T), Iterator(
796
+ Item : T,
797
+ next : (fn(self : *(Self)) -> Option(T))(
798
+ cond(
799
+ (self._set.capacity == usize(0)) => .None,
800
+ true => {
801
+ ctrl_ptr := self._set.ctrl.unwrap();
802
+ data_ptr := self._set.data.unwrap();
803
+ result := Option(T).None;
804
+ while ((self._index < self._set.capacity) && result.is_none()), (self._index = (self._index + usize(1))), {
805
+ ctrl_byte := (ctrl_ptr &+ self._index).*;
806
+ cond(
807
+ ((ctrl_byte != CTRL_EMPTY) && (ctrl_byte != CTRL_DELETED)) => {
808
+ result = .Some((data_ptr &+ self._index).*);
809
+ },
810
+ true => ()
811
+ );
812
+ };
813
+ result
814
+ }
815
+ )
816
+ )
817
+ ));
818
+
819
+ impl(forall(T : Type), where(T <: (Eq(T), Hash)), HashSet(T),
820
+ into_iter : (fn(self : Self) -> HashSetIter(T))(
821
+ HashSetIter(T)(_set: self, _index: usize(0))
822
+ )
823
+ );
824
+
825
+ /**
826
+ * Pointer iterator for HashSet - yields pointers to elements (*(T))
827
+ * Pointers are valid as long as the set is not modified during iteration.
828
+ */
829
+ HashSetIterPtr :: (fn(comptime(T) : Type) -> comptime(Type))(
830
+ struct(
831
+ _set : HashSet(T),
832
+ _index : usize
833
+ )
834
+ );
835
+
836
+ impl(forall(T : Type), where(T <: (Eq(T), Hash)), HashSetIterPtr(T), Iterator(
837
+ Item : *(T),
838
+ next : (fn(self : *(Self)) -> Option(*(T)))(
839
+ cond(
840
+ (self._set.capacity == usize(0)) => .None,
841
+ true => {
842
+ ctrl_ptr := self._set.ctrl.unwrap();
843
+ data_ptr := self._set.data.unwrap();
844
+ result := Option(*(T)).None;
845
+ while ((self._index < self._set.capacity) && result.is_none()), (self._index = (self._index + usize(1))), {
846
+ ctrl_byte := (ctrl_ptr &+ self._index).*;
847
+ cond(
848
+ ((ctrl_byte != CTRL_EMPTY) && (ctrl_byte != CTRL_DELETED)) => {
849
+ result = .Some((data_ptr &+ self._index));
850
+ },
851
+ true => ()
852
+ );
853
+ };
854
+ result
855
+ }
856
+ )
857
+ )
858
+ ));
859
+
860
+ impl(forall(T : Type), where(T <: (Eq(T), Hash)), HashSet(T),
861
+ iter : (fn(self : *(Self)) -> HashSetIterPtr(T))(
862
+ HashSetIterPtr(T)(_set: self.*, _index: usize(0))
863
+ )
864
+ );
865
+
784
866
  export
785
867
  HashSet,
786
- HashSetError
868
+ HashSetError,
869
+ HashSetIter,
870
+ HashSetIterPtr
787
871
  ;
@@ -438,8 +438,68 @@ impl(forall(T : Type), LinkedList(T), Dispose(
438
438
  )
439
439
  ));
440
440
 
441
+ /**
442
+ * Value iterator for LinkedList - yields elements by value (T)
443
+ * Traverses the linked list following node.next pointers.
444
+ */
445
+ LinkedListIter :: (fn(comptime(T) : Type) -> comptime(Type))(
446
+ struct(
447
+ _current : Option(Node(T))
448
+ )
449
+ );
450
+
451
+ impl(forall(T : Type), LinkedListIter(T), Iterator(
452
+ Item : T,
453
+ next : (fn(self : *(Self)) -> Option(T))(
454
+ match(self._current,
455
+ .None => .None,
456
+ .Some(node) => {
457
+ self._current = node.next;
458
+ .Some(node.value)
459
+ }
460
+ )
461
+ )
462
+ ));
463
+
464
+ impl(forall(T : Type), LinkedList(T),
465
+ into_iter : (fn(self : Self) -> LinkedListIter(T))(
466
+ LinkedListIter(T)(_current: self.head)
467
+ )
468
+ );
469
+
470
+ /**
471
+ * Pointer iterator for LinkedList - yields pointers to elements (*(T))
472
+ * Yields &(node.value) for each node. Pointers are valid as long as
473
+ * the list is not modified during iteration.
474
+ */
475
+ LinkedListIterPtr :: (fn(comptime(T) : Type) -> comptime(Type))(
476
+ struct(
477
+ _current : Option(Node(T))
478
+ )
479
+ );
480
+
481
+ impl(forall(T : Type), LinkedListIterPtr(T), Iterator(
482
+ Item : *(T),
483
+ next : (fn(self : *(Self)) -> Option(*(T)))(
484
+ match(self._current,
485
+ .None => .None,
486
+ .Some(node) => {
487
+ self._current = node.next;
488
+ .Some(&(node.value))
489
+ }
490
+ )
491
+ )
492
+ ));
493
+
494
+ impl(forall(T : Type), LinkedList(T),
495
+ iter : (fn(self : *(Self)) -> LinkedListIterPtr(T))(
496
+ LinkedListIterPtr(T)(_current: self.*.head)
497
+ )
498
+ );
441
499
 
442
500
  export
443
501
  LinkedList,
444
- LinkedListError
502
+ LinkedListError,
503
+ LinkedListIter,
504
+ LinkedListIterPtr
445
505
  ;