@shd101wyy/yo 0.1.15 → 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 (38) hide show
  1. package/README.md +3 -0
  2. package/out/cjs/index.cjs +541 -561
  3. package/out/cjs/yo-cli.cjs +644 -664
  4. package/out/cjs/yo-lsp.cjs +585 -605
  5. package/out/esm/index.mjs +527 -547
  6. package/out/types/src/codegen/exprs/return.d.ts +1 -1
  7. package/out/types/src/codegen/types/generation.d.ts +0 -2
  8. package/out/types/src/codegen/utils/index.d.ts +2 -8
  9. package/out/types/src/evaluator/builtins/rc-fns.d.ts +0 -5
  10. package/out/types/src/evaluator/context.d.ts +7 -3
  11. package/out/types/src/evaluator/trait-checking.d.ts +2 -0
  12. package/out/types/src/evaluator/types/object.d.ts +2 -1
  13. package/out/types/src/evaluator/types/struct.d.ts +2 -1
  14. package/out/types/src/evaluator/types/utils.d.ts +3 -8
  15. package/out/types/src/expr.d.ts +1 -2
  16. package/out/types/src/function-value.d.ts +1 -0
  17. package/out/types/src/types/creators.d.ts +2 -3
  18. package/out/types/src/types/definitions.d.ts +1 -6
  19. package/out/types/src/types/guards.d.ts +5 -2
  20. package/out/types/src/types/tags.d.ts +0 -1
  21. package/out/types/tsconfig.tsbuildinfo +1 -1
  22. package/package.json +1 -1
  23. package/std/imm/list.yo +254 -0
  24. package/std/imm/map.yo +917 -0
  25. package/std/imm/set.yo +179 -0
  26. package/std/imm/sorted_map.yo +595 -0
  27. package/std/imm/sorted_set.yo +202 -0
  28. package/std/imm/string.yo +667 -0
  29. package/std/imm/vec.yo +456 -0
  30. package/std/prelude.yo +22 -5
  31. package/std/sync/channel.yo +92 -44
  32. package/std/sync/cond.yo +5 -1
  33. package/std/sync/mutex.yo +5 -1
  34. package/std/sync/once.yo +2 -1
  35. package/std/sync/rwlock.yo +2 -1
  36. package/std/sync/waitgroup.yo +2 -1
  37. package/out/types/src/codegen/exprs/arc.d.ts +0 -5
  38. package/out/types/src/evaluator/calls/arc.d.ts +0 -15
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shd101wyy/yo",
3
3
  "displayName": "Yo",
4
- "version": "0.1.15",
4
+ "version": "0.1.16",
5
5
  "main": "./out/cjs/index.cjs",
6
6
  "module": "./out/esm/index.mjs",
7
7
  "types": "./out/types/src/index.d.ts",
@@ -0,0 +1,254 @@
1
+ //! Persistent immutable singly-linked list with O(1) prepend, head, and tail.
2
+ //!
3
+ //! `List(T)` is a cons list backed by `atomic object` nodes for thread-safe
4
+ //! structural sharing. Multiple lists can share tails with no copying.
5
+ //!
6
+ //! All elements must implement `Send` to guarantee thread safety.
7
+ //!
8
+ //! # Examples
9
+ //!
10
+ //! ```rust
11
+ //! { List } :: import "std/imm/list";
12
+ //!
13
+ //! xs := List(i32).new();
14
+ //! xs = xs.prepend(i32(3)).prepend(i32(2)).prepend(i32(1));
15
+ //! assert((xs.head().unwrap() == i32(1)), "head is 1");
16
+ //! assert((xs.len() == usize(3)), "length is 3");
17
+ //! ```
18
+
19
+ { GlobalAllocator } :: import "../allocator.yo";
20
+ { malloc, free } :: GlobalAllocator;
21
+ { memcpy } :: import "../libc/string.yo";
22
+
23
+ /// Internal cons cell — atomic object for thread-safe structural sharing.
24
+ ListNode :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
25
+ atomic object(
26
+ _value : T,
27
+ _next : Option(Self)
28
+ )
29
+ );
30
+
31
+ // Manual Acyclic impl — ListNode is self-referential, so auto-derivation skips it.
32
+ // This is safe because ListNode is immutable: all operations create new nodes and never
33
+ // mutate existing ones, making it impossible to form cycles at runtime.
34
+ impl(forall(T : Type), where(T <: Send), ListNode(T), Acyclic());
35
+
36
+ /// Persistent immutable singly-linked list.
37
+ ///
38
+ /// A value-type wrapper around an optional chain of `ListNode` atomic objects.
39
+ /// Cheap to copy (just a pointer + length). All "modification" operations
40
+ /// return a new `List` that shares structure with the original.
41
+ List :: (fn(comptime(T) : Type, where(T <: Send)) -> comptime(Type))(
42
+ struct(
43
+ _head : Option(ListNode(T)),
44
+ _len : usize
45
+ )
46
+ );
47
+
48
+ impl(forall(T : Type), where(T <: Send), List(T),
49
+ /// Create an empty list.
50
+ new : (fn() -> Self)(
51
+ Self(_head: .None, _len: usize(0))
52
+ ),
53
+
54
+ /// Return the number of elements.
55
+ len : (fn(self : Self) -> usize)(
56
+ self._len
57
+ ),
58
+
59
+ /// Return `true` if the list is empty.
60
+ is_empty : (fn(self : Self) -> bool)(
61
+ (self._len == usize(0))
62
+ ),
63
+
64
+ /// Return a new list with `value` at the front. O(1).
65
+ prepend : (fn(self : Self, value : T) -> Self)(
66
+ Self(
67
+ _head: .Some(ListNode(T)(_value: value, _next: self._head)),
68
+ _len: (self._len + usize(1))
69
+ )
70
+ ),
71
+
72
+ /// Return the first element, or `.None` if empty. O(1).
73
+ head : (fn(self : Self) -> Option(T))(
74
+ match(self._head,
75
+ .Some(node) => .Some(node._value),
76
+ .None => .None
77
+ )
78
+ ),
79
+
80
+ /// Return a new list without the first element. O(1).
81
+ /// Returns an empty list if already empty.
82
+ tail : (fn(self : Self) -> Self)(
83
+ match(self._head,
84
+ .Some(node) => Self(_head: node._next, _len: (self._len - usize(1))),
85
+ .None => self
86
+ )
87
+ ),
88
+
89
+ /// Access element at `index`. O(n).
90
+ /// Returns `.None` if index is out of bounds.
91
+ get : (fn(self : Self, index : usize) -> Option(T))({
92
+ if((index >= self._len), {
93
+ return .None;
94
+ });
95
+ (current : Option(ListNode(T))) = self._head;
96
+ (i : usize) = usize(0);
97
+ while runtime(true), {
98
+ match(current,
99
+ .Some(node) => {
100
+ if((i == index), {
101
+ return .Some(node._value);
102
+ });
103
+ current = node._next;
104
+ i = (i + usize(1));
105
+ },
106
+ .None => {
107
+ return .None;
108
+ }
109
+ );
110
+ };
111
+ .None
112
+ }),
113
+
114
+ /// Return a new list with elements in reverse order. O(n).
115
+ reverse : (fn(self : Self) -> Self)({
116
+ (result : Self) = Self.new();
117
+ (current : Option(ListNode(T))) = self._head;
118
+ while runtime(current.is_some()), {
119
+ (node : ListNode(T)) = current.unwrap();
120
+ result = result.prepend(node._value);
121
+ current = node._next;
122
+ };
123
+ result
124
+ }),
125
+
126
+ /// Concatenate two lists. O(n) where n = self.len().
127
+ /// The resulting list contains all elements of `self` followed by `other`.
128
+ concat : (fn(self : Self, other : Self) -> Self)({
129
+ reversed := self.reverse();
130
+ (result : Self) = other;
131
+ (current : Option(ListNode(T))) = reversed._head;
132
+ while runtime(current.is_some()), {
133
+ (node : ListNode(T)) = current.unwrap();
134
+ result = result.prepend(node._value);
135
+ current = node._next;
136
+ };
137
+ result
138
+ }),
139
+
140
+ /// Apply a function to each element, producing a new list. O(n).
141
+ map : (fn(forall(U : Type), self : Self, f : Impl(Fn(a : T) -> U), where(U <: Send)) -> List(U))({
142
+ (result : List(U)) = List(U).new();
143
+ (current : Option(ListNode(T))) = self._head;
144
+ while runtime(current.is_some()), {
145
+ (node : ListNode(T)) = current.unwrap();
146
+ result = result.prepend(f(node._value));
147
+ current = node._next;
148
+ };
149
+ result.reverse()
150
+ }),
151
+
152
+ /// Keep only elements satisfying the predicate. O(n).
153
+ filter : (fn(self : Self, f : Impl(Fn(a : T) -> bool)) -> Self)({
154
+ (result : Self) = Self.new();
155
+ (current : Option(ListNode(T))) = self._head;
156
+ while runtime(current.is_some()), {
157
+ (node : ListNode(T)) = current.unwrap();
158
+ if(f(node._value), {
159
+ result = result.prepend(node._value);
160
+ });
161
+ current = node._next;
162
+ };
163
+ result.reverse()
164
+ }),
165
+
166
+ /// Left fold over the list. O(n).
167
+ fold : (fn(forall(U : Type), self : Self, init : U, f : Impl(Fn(acc : U, item : T) -> U)) -> U)({
168
+ (acc : U) = init;
169
+ (current : Option(ListNode(T))) = self._head;
170
+ while runtime(current.is_some()), {
171
+ (node : ListNode(T)) = current.unwrap();
172
+ acc = f(acc, node._value);
173
+ current = node._next;
174
+ };
175
+ acc
176
+ }),
177
+
178
+ /// Execute a function for each element. O(n).
179
+ for_each : (fn(self : Self, f : Impl(Fn(a : T) -> unit)) -> unit)({
180
+ (current : Option(ListNode(T))) = self._head;
181
+ while runtime(current.is_some()), {
182
+ (node : ListNode(T)) = current.unwrap();
183
+ f(node._value);
184
+ current = node._next;
185
+ };
186
+ }),
187
+
188
+ /// Check if the list contains a value. O(n).
189
+ /// Requires T to implement Eq.
190
+ contains : (fn(self : Self, value : T, where(T <: Eq(T))) -> bool)({
191
+ (current : Option(ListNode(T))) = self._head;
192
+ while runtime(true), {
193
+ match(current,
194
+ .Some(node) => {
195
+ if((node._value == value), {
196
+ return true;
197
+ });
198
+ current = node._next;
199
+ },
200
+ .None => {
201
+ return false;
202
+ }
203
+ );
204
+ };
205
+ false
206
+ }),
207
+
208
+ /// Build a list from a slice. O(n).
209
+ from_slice : (fn(s : Slice(T)) -> Self)({
210
+ (result : Self) = Self.new();
211
+ (i : usize) = s.len();
212
+ while ((i > usize(0))), {
213
+ i = (i - usize(1));
214
+ result = result.prepend(s(i));
215
+ };
216
+ result
217
+ })
218
+ );
219
+
220
+ /// Equality: two lists are equal if they have the same length and elements.
221
+ impl(forall(T : Type), where(T <: (Send, Eq(T))), List(T), Eq(List(T))(
222
+ (==) : (fn(lhs : Self, rhs : Self) -> bool)({
223
+ if((lhs._len != rhs._len), {
224
+ return false;
225
+ });
226
+ (l : Option(ListNode(T))) = lhs._head;
227
+ (r : Option(ListNode(T))) = rhs._head;
228
+ while runtime(true), {
229
+ match(l,
230
+ .Some(ln) => match(r,
231
+ .Some(rn) => {
232
+ if((ln._value != rn._value), {
233
+ return false;
234
+ });
235
+ l = ln._next;
236
+ r = rn._next;
237
+ },
238
+ .None => {
239
+ return false;
240
+ }
241
+ ),
242
+ .None => {
243
+ return true;
244
+ }
245
+ );
246
+ };
247
+ true
248
+ })
249
+ ));
250
+
251
+ export
252
+ List,
253
+ ListNode
254
+ ;