Files
ww/CLAUDE.md

15 lines
5.4 KiB
Markdown

1. This is a project for ww programming language
2. ww is a programming language aiming for Hare + CSP, no GC
3. cmd/ is the C bootstrap toolchain (wcc frontend lib, w6c/w6a/w6l per-arch, ww driver); selfhost/ is the ww reimplementation
4. All C code must strictly align with plan 9 coding style
5. lib/ is the standard library; follow Hare APIs (signatures, layout, error idioms) — consult ref/hare/ before designing new modules. Package declaration form is Go-style explicit `package foo;` and imports use `import foo;` (executables declare `package main;`) per language design (rob-pike + plan-9 sensibility); lib/ API surface still mirrors Hare.
6. ref/hare and ref/plan9front are read-only references — consult before inventing data shapes or syntax. Carve-out: the ww compiler frontend is ONE package `lib/ww/syntax/` (tok+lex+ast+sym+typ+parse), a deliberate Go-over-Hare departure modelled on Go's `cmd/compile/internal/syntax` rather than ref/hare/hare's `{ast,lex,parse}` split. Rationale: the split's only payoff is third-party reuse (an IDE wanting `ast` without the parser), which ww has zero of — its frontend is consumed by exactly one client, the `wcc` backend. Consolidating dissolves the cross-package export sprawl (a fn over an unexported sibling type re-triggers sep-build's check_exported_type). Rule 6/12 still bind the internal data shapes (AST kinds, token model, lexer/parser state mirror ref/hare/hare); only the module DECOMPOSITION collapses. The surviving export surface is `syntax`'s public API consumed by `wcc` (a small Hare-faithful set). Ref: USER-approved #74; spec .ai/rob-frontend-reorg.md (rob, drew2 fidelity-confirmed).
7. No workarounds. If a bug forces a workaround, STOP and report with a precise repro. Document any retained divergence at the site with a pointer to the filed task. Never silent.
8. Comments are WHY-only. Never narrate WHAT the code does — names carry the WHAT. Comment only non-obvious WHY: a constraint, a divergence from a reference, a citation to a filed task.
9. Hare-fidelity over convenience. No ad-hoc extensions, renames, or convenience wrappers in lib/. Cite ref/hare/<module>/<file> for every signature ported. Carve-out: the Hare `_unsafe` suffix convention is dropped wholesale (ww is C/Plan-9-lineage, an unmanaged systems language — no GC, no "safe" baseline to be unsafe relative to). bytes→str is a pure reinterpret (`strings.frombytes`, renamed from Hare's `fromutf8_unsafe`); validation is opt-in via `utf8.validate(b)?` at the IO source, never wrapped per-construction. Rationale: ref/hare/strings/utf8.ha:10,22 — the suffix flags Hare's managed-bytes-safety axis, which ww doesn't have. The honest name (`frombytes`) reserves `fromutf8` for a future true validating helper. Carve-out: lib/ tests use Go's external-test-package idiom (`package <mod>_test;` + `import <mod>;`), a sanctioned Go-over-Hare departure — ww hard-rejects self-import (full Go), and Hare's same-package `@test` colocation now has a ww analogue: in-package white-box `@test` files (`package <mod>;`, colocated) are sanctioned alongside the external black-box `package <mod>_test;` split — Go's `foo`/`foo_test` model — now that the non-T `@test` drop landed (#6, harec check.c:3941, 08a76cf; #5 closed). Rule 5/9 binds lib/ *API* surface, not test-authoring style. Ref: Go `foo_test` convention; task #16. Carve-out: `.len`, `.cap`, and `len(x)` remain `i32`, although slice/str header words are 8 bytes and Go returns `int`. This is a deliberate stability exception: ww numeric types do not implicitly interoperate, and the 2026-08-09 strict migration probe found at least 970 new mismatches across 189 paths (575 sites in 57 production lib/internal/selfhost paths). Representation remains word-sized; the checker types `&slice.len`, `&slice.cap`, `&str.len`, and `&str.cap` as `*i64` so indirect writes cover the full header word. Revisit only as a dedicated, independently pinned language migration.
10. Symmetric stages. cstage and wwstage MUST emit byte-identical asm for the same input. When inference power differs, align the richer side DOWN to the leaner side, not the other way.
11. Split commits when they bundle unrelated concerns. Bisect-cleanliness is the default. Multi-fix commits need a body paragraph explaining why they couldn't split.
12. Simple data, simple algorithms. Sea-of-stars style. Mirror Hare's structural choices over clever alternatives.
13. Authoritative size and layout helpers. Route compiler size and layout computations through resolved type metadata or canonical helpers (tinfo.size / Type.size / ty_*->size / size(T) / primtypesize / tyslicesize). Keep unavoidable external ABI and serialized-format constants localized and explain the contract they encode.
14. Test targets. `make test` is the small developer gate: five in-process compiler units plus one compile-only C/WW compiler-fixture smoke case. `make test-compiler` owns the complete declarative compiler corpus and residual artifact/integration carriers; `make test-package`, `make test-lang`, and `make test-library` own package and in-language behavior. `make test-commit` composes those ordinary behavior suites but excludes byte identity, fixed-point/bootstrap, and platform gates. Run those explicitly with `make test-byteid`, `make test-bootstrap`, and `make test-platform`; `make test-all` is the exhaustive composition. Compiler-fixture subprocess coordination defaults to `JOBS=1`. There is no last-green cache or shell scheduler. A small-target result never proves bootstrap or byte identity.