@shd101wyy/yo 0.1.32 → 0.1.33
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/.github/skills/yo-async-effects/async-effects-recipes.md +2 -2
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +25 -1
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +4 -1
- package/out/cjs/index.cjs +580 -507
- package/out/cjs/yo-cli.cjs +643 -570
- package/out/cjs/yo-lsp.cjs +651 -578
- package/out/esm/index.mjs +411 -338
- package/out/types/src/codegen/functions/context.d.ts +1 -0
- package/out/types/src/evaluator/types/flowability.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/collections/hash_map.yo +51 -14
- package/std/prelude.yo +4 -0
|
@@ -160,13 +160,13 @@ process_dir :: (fn(root: Path, ctx : WalkCtx) -> Impl(Future(unit, WalkCtx)))(
|
|
|
160
160
|
stack := ArrayList(Path).new();
|
|
161
161
|
{ stack.push(root); };
|
|
162
162
|
|
|
163
|
-
while(
|
|
163
|
+
while(stack.len() > usize(0), {
|
|
164
164
|
cur := match(stack.pop(), .Some(p) => p, .None => return());
|
|
165
165
|
entries := ctx.io.await(read_dir(cur, ctx.io), ctx.io);
|
|
166
166
|
// process `entries`, push subdirectories to `stack`
|
|
167
167
|
n := entries.len();
|
|
168
168
|
i := usize(0);
|
|
169
|
-
while(
|
|
169
|
+
while(i < n, {
|
|
170
170
|
match(entries.get(i),
|
|
171
171
|
.None => (),
|
|
172
172
|
.Some(e) => {
|
|
@@ -78,6 +78,30 @@ text := match(parsed,
|
|
|
78
78
|
- Prefer combinators for straight-line transforms: `map`, `and_then`, `map_err`, `or_else`
|
|
79
79
|
- Switch to `match(...)` when branches need different logic or side effects
|
|
80
80
|
|
|
81
|
+
### Match destructuring: prefer curly `{field}`, avoid positional `_` padding
|
|
82
|
+
|
|
83
|
+
For a variant with **2+ fields**, destructure by **name** with curly braces —
|
|
84
|
+
name only the fields the arm uses. Do NOT count positions and pad with `_`.
|
|
85
|
+
|
|
86
|
+
```rust
|
|
87
|
+
// ✅ Curly — names only what you need; order-free; partial matches OK.
|
|
88
|
+
// Robust: adding a field to the variant later doesn't shift anything.
|
|
89
|
+
match(v,
|
|
90
|
+
.FuncVal({ func_id }) => use(func_id), // bind field `func_id`
|
|
91
|
+
.Struct({ id, name: n }) => use2(id, n), // rename via `field: alias`
|
|
92
|
+
.EnumT({ id }) => use3(id), // ignore the other 6 fields
|
|
93
|
+
_ => ()
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
// ❌ Avoid — positional with many `_`; brittle and unreadable:
|
|
97
|
+
// .FuncVal(_, _, _, _, _, _, _, _, func_id) => … // count the 8 _'s!
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`{a}` = bind field `a`; `{a: x}` = rename to `x`; `{a: _}` = assert-exists-ignore.
|
|
101
|
+
Empty `{}` and bare `{_}` are rejected. Spec: `tests/match_curly.test.yo`.
|
|
102
|
+
(Full rules: `.github/instructions/yo-syntax.instructions.md` § Match
|
|
103
|
+
destructuring forms.)
|
|
104
|
+
|
|
81
105
|
## Collections
|
|
82
106
|
|
|
83
107
|
```rust
|
|
@@ -303,7 +327,7 @@ node_eq :: (fn(a : Node, b : Node) -> bool)(
|
|
|
303
327
|
true => {
|
|
304
328
|
(i : usize) = usize(0);
|
|
305
329
|
(ok : bool) = true;
|
|
306
|
-
while(
|
|
330
|
+
while(((i < acs.len()) && ok), {
|
|
307
331
|
match(acs.get(i),
|
|
308
332
|
.Some(ac) => match(bcs.get(i),
|
|
309
333
|
.Some(bc) => { ok = recur(ac, bc); },
|
|
@@ -134,6 +134,7 @@ masked := ((A | B) | C);
|
|
|
134
134
|
- **Audit public stdlib safety with `./yo-cli public-safe-report [path]`.** Flags every top-level public `fn(...)` whose params or return type expose `*(T)` outside an `extern(...)` block. Skips FFI-by-construction directories (`libc/`, `linux/`, `darwin/`, `cuda/`, `sys/`, `sync/`) and names that signal raw-pointer use by contract (`*_cstr`, `*_ptr`, `*_raw`, `raw_*`, `from_raw_parts`, `as_ptr`, `argv`, `argc`). Currently reports 0 findings on `./std` and `./yo-self`; keep it that way when adding new APIs.
|
|
135
135
|
- **Extern "c" call sites require `unsafe(...)` even in pragma'd files.** `unsafe(memcpy(dst, src, n))`, `unsafe(strlen(s))`, etc. The pragma authorizes DECLARING the FFI symbol via `extern(...)` / `c_include(...)`; the wrap is the per-call audit marker so `yo unsafe-report` lines up with UB-capable lines. `asm(...)` and `extern(...)` / `c_include(...)` declarations themselves do NOT need a wrap (the keyword / declaration syntax is its own marker). See `plans/EXTERN_UNSAFE_WRAP.md`.
|
|
136
136
|
- **Slice-flowability rule:** a function returning a slice-bearing type (`Slice(T)`, `str`, a struct wrapping a Slice, ...) must root the returned value in caller-owned storage (a `ref`-bound parameter, any non-`ref` parameter, a `comptime`/literal source, or a flowable projection chain). `(fn() -> Option(Slice(i32)))({ arr := ArrayList(i32).new(); arr.as_slice() })` is rejected; `(fn(ref(arr) : ArrayList(i32)) -> Option(Slice(i32)))(arr.as_slice())` is accepted. See `plans/SLICE_FLOWABILITY.md`.
|
|
137
|
+
- **Return-slot modifier placement: on the LABEL, not the type.** In a _labeled_ return slot, a `ref`/`comptime` modifier attaches to the label, mirroring the parameter convention (`ref(name) : T`). Valid: `-> ref(T)` and `-> comptime(T)` (unlabeled — modifier on the sole type), `-> (ref(name) : T)`, `-> (comptime(name) : T)`. **Rejected:** `-> (name : ref(T))`, `-> (name : comptime(T))` (modifier on the type when labeled), and `-> (ref(name) : ref(T))` (double-ref — "pick one"). Enforced at function-type eval in `src/evaluator/types/function.ts` (and the yo-self port).
|
|
137
138
|
- **Signed-integer overflow is defined (wrap-around).** Yo passes `-fwrapv` to clang/gcc/zig by default so `x + i32(1)` on `i32(MAX)` wraps to `i32(MIN)` instead of UB. Opt-out: `--cflags='-fno-wrapv'`.
|
|
138
139
|
- **`// SAFETY:` comment convention.** Every non-obvious `unsafe(...)` site in stdlib should have a `// SAFETY:` comment in the previous ~8 lines explaining the contract. `yo unsafe-report` picks them up and shows them inline under each finding.
|
|
139
140
|
- **User-facing memory-safety guide:** `docs/en-US/MEMORY_SAFETY.md` (English) and `docs/zh-CN/MEMORY_SAFETY.md` (Chinese). Refer users there instead of `plans/MEMORY_SAFETY.md` (which is the design document — not shipped via npm).
|
|
@@ -524,7 +525,9 @@ divide :: (fn(x : i32, y : i32, requires(y != i32(0)), ensures(result == (x / y)
|
|
|
524
525
|
increment :: (fn(ref(n) : i32, ensures(n == (old(n) + i32(1)))) -> unit)({ n = (n + i32(1)); });
|
|
525
526
|
|
|
526
527
|
// invariant(...) must be the FIRST statement of a while body.
|
|
527
|
-
|
|
528
|
+
// NOTE: do NOT wrap the condition in runtime(...) — while conditions are
|
|
529
|
+
// runtime by default, so `while(runtime(i < n), …)` is redundant; use `while(i < n, …)`.
|
|
530
|
+
while(i < n, {
|
|
528
531
|
invariant(i <= n, acc >= i32(0));
|
|
529
532
|
i = (i + i32(1)); acc = (acc + i);
|
|
530
533
|
});
|