kittine-compiler
The hand-written lexer, recursive-descent parser and code generator. A plain CLI: lex, parse, emit Rust. No syn crate, no intermediate AST magic — output stays readable enough to diff by eye.
Ecosystem
The hand-written lexer, recursive-descent parser and code generator. A plain CLI: lex, parse, emit Rust. No syn crate, no intermediate AST magic — output stays readable enough to diff by eye.
Hooks Vite's transform pipeline: compiles the touched .kitty file, runs cargo build --target wasm32-unknown-unknown, then wasm-bindgen --target web — all on save, with incremental rebuilds.
An alternative to the Vite pipeline for server-rendered pages: the identical compiler output, run through cargo-leptos and Axum instead, for real pre-rendered HTML and fast first paint.
TextMate-grammar syntax highlighting for .kitty files. No language server yet — that's next, not pretended to already exist.
litter (structs) and breed (enums) declare real Rust types; pounce> pattern-matches a breed value; claw/bare .. for .. are a real trait system, with one type parameter per struct/enum optionally bounded by one. See it next to the generated Rust on the Rust & Leptos page.
97 tests covering every language construct through full codegen, plus real integration tests that compile multi-file Kittine programs end to end via the actual CLI, not mocks.
fmt is a real formatter: it reparses its own output and refuses to write unless the AST matches the original exactly, and it won't touch a file with // comments (the lexer discards them, so there's nothing to preserve) unless told to. lint catches unused imports, params and hold bindings, plus duplicate field/variant/param names that would fail cargo build once generated — caught before it gets there.
kittine.toml/kittine.lock plus kittine-compiler add/install/publish, backed by a real hosted registry with no server of its own — just an index/[name].json per package on kittine-registry, with tarballs as GitHub Release assets. install sha256-verifies every download. Exact-version dependencies only for now — no semver ranges, no transitive resolution yet.
A litter/breed name, optionally []-suffixed, is a real prop/purr param or return type — DocEntry[] entries is a real Vec<DocEntry>. A closure literal, |param| expr, lowers to a real Rust closure — the missing piece a real .filter()/.map() needs. And pounce> now works as an expression too, not just a statement — return (pounce> result Ok(v) >> v Err(e) >> 0) unwraps a Result-shaped value and returns it in one step. See it live: the language reference page's search box is real, data-backed filtering built from exactly these three features.