@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.
- package/README.md +43 -1
- package/out/cjs/index.cjs +581 -601
- package/out/cjs/yo-cli.cjs +739 -733
- package/out/cjs/yo-lsp.cjs +11615 -0
- package/out/esm/index.mjs +530 -550
- package/out/types/src/cache.d.ts +2 -0
- package/out/types/src/codegen/exprs/return.d.ts +1 -1
- package/out/types/src/codegen/types/generation.d.ts +0 -2
- package/out/types/src/codegen/utils/index.d.ts +2 -8
- package/out/types/src/doc/extractor.d.ts +4 -0
- package/out/types/src/evaluator/builtins/rc-fns.d.ts +0 -5
- package/out/types/src/evaluator/context.d.ts +7 -3
- package/out/types/src/evaluator/trait-checking.d.ts +2 -0
- package/out/types/src/evaluator/types/object.d.ts +2 -1
- package/out/types/src/evaluator/types/struct.d.ts +2 -1
- package/out/types/src/evaluator/types/utils.d.ts +3 -8
- package/out/types/src/evaluator/values/impl.d.ts +9 -1
- package/out/types/src/expr.d.ts +1 -2
- package/out/types/src/function-value.d.ts +1 -0
- package/out/types/src/lsp/completion.d.ts +3 -0
- package/out/types/src/lsp/definition.d.ts +3 -0
- package/out/types/src/lsp/diagnostics.d.ts +6 -0
- package/out/types/src/lsp/document-manager.d.ts +31 -0
- package/out/types/src/lsp/folding.d.ts +3 -0
- package/out/types/src/lsp/hover.d.ts +3 -0
- package/out/types/src/lsp/inlay-hints.d.ts +3 -0
- package/out/types/src/lsp/references.d.ts +3 -0
- package/out/types/src/lsp/rename.d.ts +16 -0
- package/out/types/src/lsp/server.d.ts +1 -0
- package/out/types/src/lsp/signature-help.d.ts +3 -0
- package/out/types/src/lsp/symbols.d.ts +3 -0
- package/out/types/src/lsp/utils.d.ts +11 -0
- package/out/types/src/tests/lsp.test.d.ts +1 -0
- package/out/types/src/tests/version.test.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +2 -3
- package/out/types/src/types/definitions.d.ts +3 -6
- package/out/types/src/types/guards.d.ts +5 -2
- package/out/types/src/types/tags.d.ts +0 -1
- package/out/types/src/version-cache.d.ts +7 -0
- package/out/types/src/version.d.ts +5 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -1
- package/scripts/build-site.ts +32 -15
- package/scripts/check-liburing.js +2 -2
- package/std/imm/list.yo +254 -0
- package/std/imm/map.yo +917 -0
- package/std/imm/set.yo +179 -0
- package/std/imm/sorted_map.yo +595 -0
- package/std/imm/sorted_set.yo +202 -0
- package/std/imm/string.yo +667 -0
- package/std/imm/vec.yo +456 -0
- package/std/prelude.yo +22 -5
- package/std/sync/channel.yo +92 -44
- package/std/sync/cond.yo +5 -1
- package/std/sync/mutex.yo +5 -1
- package/std/sync/once.yo +2 -1
- package/std/sync/rwlock.yo +2 -1
- package/std/sync/waitgroup.yo +2 -1
- package/out/types/src/codegen/exprs/arc.d.ts +0 -5
- 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.
|
|
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",
|
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"markdown_yo": "0.0.4",
|
|
51
|
+
"vscode-languageserver": "^9.0.1",
|
|
52
|
+
"vscode-languageserver-textdocument": "^1.0.12",
|
|
51
53
|
"yargs": "^17.7.2"
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
package/scripts/build-site.ts
CHANGED
|
@@ -20,18 +20,19 @@ import * as fs from "fs";
|
|
|
20
20
|
import * as path from "path";
|
|
21
21
|
import { createRenderer } from "markdown_yo";
|
|
22
22
|
import type { MarkdownRenderer } from "markdown_yo";
|
|
23
|
-
import {
|
|
23
|
+
import { execFileSync } from "child_process";
|
|
24
24
|
|
|
25
25
|
const ROOT = path.resolve(import.meta.dir, "..");
|
|
26
26
|
const GITHUB_REPO = "https://github.com/shd101wyy/Yo";
|
|
27
27
|
|
|
28
28
|
// Detect the latest release tag for stable links.
|
|
29
29
|
// Falls back to "main" if no tags exist or git fails.
|
|
30
|
-
function getLatestTag(): string {
|
|
30
|
+
export function getLatestTag(rootDir: string = ROOT): string {
|
|
31
31
|
try {
|
|
32
|
-
const result =
|
|
33
|
-
cwd:
|
|
32
|
+
const result = execFileSync("git", ["describe", "--tags", "--abbrev=0"], {
|
|
33
|
+
cwd: rootDir,
|
|
34
34
|
encoding: "utf-8",
|
|
35
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
35
36
|
timeout: 5000,
|
|
36
37
|
}).trim();
|
|
37
38
|
return result || "main";
|
|
@@ -43,6 +44,16 @@ function getLatestTag(): string {
|
|
|
43
44
|
const GITHUB_REF = getLatestTag();
|
|
44
45
|
const GITHUB_BLOB = `${GITHUB_REPO}/blob/${GITHUB_REF}`;
|
|
45
46
|
|
|
47
|
+
export function getStdDocCommand(rootDir: string = ROOT): {
|
|
48
|
+
command: string;
|
|
49
|
+
args: string[];
|
|
50
|
+
} {
|
|
51
|
+
return {
|
|
52
|
+
command: "node",
|
|
53
|
+
args: [path.join(rootDir, "out", "cjs", "yo-cli.cjs"), "doc", "std/"],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
46
57
|
// ── Parse args ───────────────────────────────────────────────────────
|
|
47
58
|
|
|
48
59
|
let outputDir = path.join(ROOT, "site");
|
|
@@ -399,7 +410,7 @@ function injectHomeLinks(stdDir: string): void {
|
|
|
399
410
|
|
|
400
411
|
// ── Main ─────────────────────────────────────────────────────────────
|
|
401
412
|
|
|
402
|
-
async function main(): Promise<void> {
|
|
413
|
+
export async function main(): Promise<void> {
|
|
403
414
|
console.log("Building documentation site...");
|
|
404
415
|
console.log(` Output: ${outputDir}`);
|
|
405
416
|
|
|
@@ -449,12 +460,16 @@ async function main(): Promise<void> {
|
|
|
449
460
|
const stdOutputDir = path.join(outputDir, "std");
|
|
450
461
|
|
|
451
462
|
try {
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
463
|
+
const stdDocCommand = getStdDocCommand();
|
|
464
|
+
execFileSync(
|
|
465
|
+
stdDocCommand.command,
|
|
466
|
+
[...stdDocCommand.args, "--output", stdOutputDir],
|
|
467
|
+
{
|
|
468
|
+
cwd: ROOT,
|
|
469
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
470
|
+
timeout: 600_000,
|
|
471
|
+
}
|
|
472
|
+
);
|
|
458
473
|
console.log(" ✓ Standard library docs generated");
|
|
459
474
|
} catch (err) {
|
|
460
475
|
console.error(
|
|
@@ -492,7 +507,9 @@ function getTotalSize(dir: string): number {
|
|
|
492
507
|
return Math.round(total / 1024);
|
|
493
508
|
}
|
|
494
509
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
510
|
+
if (import.meta.main) {
|
|
511
|
+
main().catch((err) => {
|
|
512
|
+
console.error("Fatal error:", err);
|
|
513
|
+
process.exit(1);
|
|
514
|
+
});
|
|
515
|
+
}
|
|
@@ -9,9 +9,9 @@ const fs = require("fs");
|
|
|
9
9
|
function checkLiburing() {
|
|
10
10
|
const platform = os.platform();
|
|
11
11
|
|
|
12
|
-
// Only check on Linux
|
|
12
|
+
// Only check on Linux. Other platforms don't use io_uring, so keep postinstall
|
|
13
|
+
// quiet instead of printing a Linux-specific note.
|
|
13
14
|
if (platform !== "linux") {
|
|
14
|
-
console.log("ℹ️ Async I/O with io_uring is only supported on Linux.");
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
17
|
|
package/std/imm/list.yo
ADDED
|
@@ -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
|
+
;
|