This library is in flux. APIs may change without notice. Generated from source with koruc 0.1.7 on 11/4/2026.
Tree
import std/treeKoru Standard Library: Tree — owned heap nodes, `.k`-spellable
tree.kz · 4 tors
Koru Standard Library: Tree — owned heap nodes, `.k`-spellable · 48 more lines
~part registry koru_std/tree.registry.kz
Koru Standard Library: the `registry` part of tree.kz. Joined via `~part registry` in tree.kz; merged into the tree module. Node registrations read two places, exactly like proto's own doors: a LIVE `std/tree:node` invocation (declaration still in the tree — the transform may not have visited it yet) and the erased `// proto-node Name: fields` marker it leaves behind. A reader that checks only one ordering-mines the registry; both scans answer "is X a node here". Field CLASSIFICATION is the lane's whole grammar. `name: Type` splits on `?` (optional) and on which registry `Type` lives in: node-registered or the decl's own name → edge scalar / terminal / proto-compound → payload anything else → refusal (caller words it)
~part node koru_std/tree.node.kz
Koru Standard Library: the `node` part of tree.kz. Joined via `~part node` in tree.kz; merged into the tree module. `std/tree:node(Node) { fields }` — the KIND declaration. Registers Node in the shared registry as kind=node, validates the field grammar (payload vs edge by registry kind of the field type), and materializes the host node record. Nothing else emits here — mint/dispose synthesize their own tors lazily at their call sites, so transform order is never a contract.
// Koru Standard Library: the `node` part of tree.kz.
// Joined via `~part node` in tree.kz; merged into the tree module.
//
// `std/tree:node(Node) { fields }` — the KIND declaration. Registers Node in
// the shared registry as kind=node, validates the field grammar (payload vs
// edge by registry kind of the field type), and materializes the host node
// record. Nothing else emits here — mint/dispose synthesize their own tors
// lazily at their call sites, so transform order is never a contract.
~[comptime|transform] pub tor node {
expr: Expression,
source: ?Source,
item: std/compiler:*const Item,
program: std/compiler:*const Program,
allocator: std.mem.Allocator,
reporter: std/compiler:*ErrorReporter
} -> SiteResult~part mint koru_std/tree.mint.kz
Koru Standard Library: the `mint` part of tree.kz. Joined via `~part mint` in tree.kz; merged into the tree module. `std/tree:mint(Node) { item: v, left: l, right: r }` — create one node. The transform validates the arg block against Node's registered fields (required edges and payloads must be spelled; `?` fields may be omitted or null), synthesizes `mint-Node` into the caller's module on first use (dispatch-gap doctrine: the concrete per-type tor is synthesized, the lane verb routes), and rewrites the site to call it. The single-owner law is not a check here — it is the signature: edge params are `?*T<!owned>` / `*T<!owned>`, so an edge arg must be a fresh mint or `null`; re-using an already-bound child is a second consume of an owned binding, which the obligation checker already refuses.
// Koru Standard Library: the `mint` part of tree.kz.
// Joined via `~part mint` in tree.kz; merged into the tree module.
//
// `std/tree:mint(Node) { item: v, left: l, right: r }` — create one node.
// The transform validates the arg block against Node's registered fields
// (required edges and payloads must be spelled; `?` fields may be omitted or
// null), synthesizes `mint-Node` into the caller's module on first use
// (dispatch-gap doctrine: the concrete per-type tor is synthesized, the lane
// verb routes), and rewrites the site to call it.
//
// The single-owner law is not a check here — it is the signature: edge
// params are `?*T<!owned>` / `*T<!owned>`, so an edge arg must be a fresh
// mint or `null`; re-using an already-bound child is a second consume of an
// owned binding, which the obligation checker already refuses.
~[comptime|transform] pub tor mint {
expr: Expression,
source: ?Source,
invocation: *const Invocation,
item: std/compiler:*const Item,
program: std/compiler:*const Program,
reporter: std/compiler:*ErrorReporter,
allocator: std.mem.Allocator
} -> SiteResult~part dispose koru_std/tree.dispose.kz
Koru Standard Library: the `dispose` part of tree.kz. Joined via `~part dispose` in tree.kz; merged into the tree module. `std/tree:dispose(t)` — consume the `owned!` root, recursive free. The transform resolves WHICH node type `t` is (the enclosing tor's param signature, or the in-flow invocation that bound it), synthesizes `dispose-<Node>` + the module-scope `__koru_tree_free_<Node>` walker on first use, and rewrites the site to call it. The obligation checker owns "consumed twice" and "never disposed" — this transform only routes.
// Koru Standard Library: the `dispose` part of tree.kz.
// Joined via `~part dispose` in tree.kz; merged into the tree module.
//
// `std/tree:dispose(t)` — consume the `owned!` root, recursive free. The
// transform resolves WHICH node type `t` is (the enclosing tor's param
// signature, or the in-flow invocation that bound it), synthesizes
// `dispose-<Node>` + the module-scope `__koru_tree_free_<Node>` walker on
// first use, and rewrites the site to call it. The obligation checker owns
// "consumed twice" and "never disposed" — this transform only routes.
~[comptime|transform] pub tor dispose {
expr: Expression,
invocation: *const Invocation,
item: std/compiler:*const Item,
program: std/compiler:*const Program,
reporter: std/compiler:*ErrorReporter,
allocator: std.mem.Allocator
} -> SiteResult~part fold koru_std/tree.fold.kz
Koru Standard Library: the `fold` part of tree.kz. Joined via `~part fold` in tree.kz; merged into the tree module. `std/tree:fold(t) | node n -> <expr> | null -> <expr>` — the catamorphism: a pure, value-returning recursive collapse of an owned tree. Inside `| node n`, a payload field reads as payload and an EDGE field reads as the already-folded child — the field's registry kind flips its meaning in fold position, the same law that makes `node`'s field grammar decide payload vs edge. `| null` is the empty case, required always (a `?` edge reaches it on every leaf; a `?*Node` root reaches it on an absent tree). The transform resolves `t`'s node kind by provenance (dispose's resolveNodeTypeOf — param signature or in-flow producer), rewrites the site's node-arm expression at text level (`n.<payload>` → `n.<f>` on the unwrapped pointer, `n.<edge>` → the recursive fold call), synthesizes `__koru_tree_fold_<Node>_<h> { t: ?*Node<*> } -> T` as an event + |zig proc (`if (t) |n| return <arm>; else return <base>;`), and replaces the site flow with a plain call — the arms are CONSUMED by the rewrite, the `: c` bind and the chain tail survive untouched. fold is the value-side lane verb for the invariant hoist: `build |> fold |> dispose` in a `for ! each` body reads as one invariant prefix — fold reads a hoisted name, returns a value, stays clean by lane contract (the frontend pass classifies it before transforms expand, same door `dispose` walks through as a consume). v1 cuts (loud refusals): single-kind folds only — every edge must reach the same node kind (heterogeneous folds need per-kind arms, undecided); arms are single `-> expr` terminals, not step chains; the node binding may only read declared fields (a bare `n` in the expression refuses).
~[comptime|transform] pub tor fold {
expr: Expression,
invocation: *const Invocation,
item: std/compiler:*const Item,
program: std/compiler:*const Program,
reporter: std/compiler:*ErrorReporter,
allocator: std.mem.Allocator
} -> SiteResult