ww: rename toolchain to w-prefix + hare-style build/run/test driver
Plan 9-style w-prefix on the per-arch tools, disambiguating from the
real Plan 9 6c/6a/6l in ref/plan9front/:
cmd/wwc/ → cmd/wcc/ libwwc.a → libwcc.a
cmd/6{c,a,l} → cmd/w6{c,a,l} binary names too
test/wwc/ → test/wcc/ 6 test files w/ w6 prefix
selfhost/cmd mirror in lockstep
bootstrap/amd64/{w6c,w6a,w6l} snapshot binaries (gitignored)
WW_6{C,A,L} → WW_W6{C,A,L} env-var overrides
Plan 9 source-tree refs ("Plan 9 6c shape", ref/plan9front/, etc.)
preserved. Hare-style driver, both C and ww sides:
ww test [path] discover *_test.ww in a directory module, run
each; single-file mode for `ww test foo.ww`
Module-by-name `ww build foo` resolves to foo.ww or foo/foo.ww
via search path (cwd : -I dirs : $WW_LIB)
Default-to-cwd `ww build` / `ww test` build the cwd module
Run pass-through `ww run path arg1 arg2` reaches the program
lib/os: getcwd (79) and getdents64 (217) syscalls power `.` resolution
and directory enumeration on the ww side.
Makefile: wwstage tool deps now include lib/os/os.ww (+ lib/strconv
for wwdump_ww) so lib/* edits force their rebuild instead of leaving
stale binaries — surfaced when test 995 first failed against a stale
w6c_ww built before the lib/os additions.
Test 993 byte-identical parity gate (C-side ww vs ww-side ww_ww on a
build corpus) stays green; all 19 tests pass.
This commit is contained in:
44
CLAUDE.md
44
CLAUDE.md
@@ -13,17 +13,17 @@ This file is the contract for the work. Read PLAN.md for the schedule.
|
||||
- Toolchain: Plan 9-organized. One library + one binary per role
|
||||
per target architecture. Plan 9 uses a single digit per arch
|
||||
(8=386, 6=amd64, 5=arm, 7=arm64, 9=power); we adopt that.
|
||||
- `cmd/wwc/` — frontend library (lex, parse, check). Builds
|
||||
`libwwc.a`. Not a binary.
|
||||
- `cmd/6c/` — amd64 compiler. Reads `.ww`, writes `.s`
|
||||
- `cmd/wcc/` — frontend library (lex, parse, check). Builds
|
||||
`libwcc.a`. Not a binary.
|
||||
- `cmd/w6c/` — amd64 compiler. Reads `.ww`, writes `.s`
|
||||
(Plan 9 amd64 asm).
|
||||
- `cmd/6a/` — amd64 assembler. Reads `.s`, writes `.o`
|
||||
- `cmd/w6a/` — amd64 assembler. Reads `.s`, writes `.o`
|
||||
(ELF, for C interop).
|
||||
- `cmd/6l/` — amd64 linker. Reads `.o` and `.a`, writes a
|
||||
- `cmd/w6l/` — amd64 linker. Reads `.o` and `.a`, writes a
|
||||
static ELF binary.
|
||||
- `cmd/ww/` — user-facing driver (Hare's `hare(1)` /
|
||||
Plan 9's `cc(1)` analogue). Orchestrates `6c → 6a → 6l`.
|
||||
Adding a new target later means a new triple (e.g. `7c`/`7a`/`7l`
|
||||
Plan 9's `cc(1)` analogue). Orchestrates `w6c → w6a → w6l`.
|
||||
Adding a new target later means a new triple (e.g. `w7c`/`w7a`/`w7l`
|
||||
for arm64). The frontend library `wwc` is shared.
|
||||
|
||||
## Hard rules (do not violate)
|
||||
@@ -48,12 +48,12 @@ This file is the contract for the work. Read PLAN.md for the schedule.
|
||||
`extern "c"` marker is needed.
|
||||
6. **Plan 9 toolchain. No LLVM, no QBE, no external IR.** We do not
|
||||
invent a portable SSA IR. We follow Plan 9: the per-target
|
||||
compiler (`6c` for amd64) reads `.ww` and writes Plan 9-style
|
||||
target assembly (`.s`); the per-target assembler (`6a`) writes
|
||||
ELF objects; the per-target linker (`6l`) produces a static
|
||||
compiler (`w6c` for amd64) reads `.ww` and writes Plan 9-style
|
||||
target assembly (`.s`); the per-target assembler (`w6a`) writes
|
||||
ELF objects; the per-target linker (`w6l`) produces a static
|
||||
binary. Each tool uses Plan 9 cc's in-memory `Prog`/`Adr`
|
||||
shapes — read `ref/plan9front/sys/src/cmd/cc/`, `cmd/6c/`,
|
||||
`cmd/6a/`, `cmd/6l/` before writing your own.
|
||||
shapes — read `ref/plan9front/sys/src/cmd/cc/`, `cmd/w6c/`,
|
||||
`cmd/w6a/`, `cmd/w6l/` before writing your own.
|
||||
7. **No generics, no interfaces, no closures, no lambdas.** Four forms
|
||||
of bloat we refuse. Polymorphism, when genuinely needed, is a
|
||||
struct of function pointers plus a `ctx: *void` (Plan 9 `Bio`,
|
||||
@@ -74,7 +74,7 @@ This file is the contract for the work. Read PLAN.md for the schedule.
|
||||
8. **Tests run after every change.** `make test` is the truth. A
|
||||
change without a green `make test` is not a change.
|
||||
9. **Prototype in C, then self-host.** The C bootstrap toolchain
|
||||
(`libwwc`, `6c`, `6a`, `6l`, `ww`) is throwaway scaffolding.
|
||||
(`libwcc`, `w6c`, `w6a`, `w6l`, `ww`) is throwaway scaffolding.
|
||||
Its job is to compile enough of `ww` to compile the ww
|
||||
reimplementations of itself. Do not over-engineer the C side.
|
||||
|
||||
@@ -300,7 +300,7 @@ ergonomics live in a sibling pure-`ww` package.
|
||||
POSIX `make`, no autotools, no cmake.
|
||||
|
||||
```
|
||||
make # builds libwwc, 6c, 6a, 6l, ww, stdlib
|
||||
make # builds libwcc, w6c, w6a, w6l, ww, stdlib
|
||||
make test # runs all tests (toolchain + stdlib)
|
||||
make install # installs to $PREFIX (default /usr/local)
|
||||
make clean
|
||||
@@ -312,11 +312,11 @@ Target layout under `out/`:
|
||||
out/
|
||||
bin/
|
||||
ww user-facing driver
|
||||
6c amd64 compiler
|
||||
6a amd64 assembler
|
||||
6l amd64 linker
|
||||
w6c amd64 compiler
|
||||
w6a amd64 assembler
|
||||
w6l amd64 linker
|
||||
lib/
|
||||
libwwc.a frontend library (linked into 6c)
|
||||
libwcc.a frontend library (linked into w6c)
|
||||
libwwrt.a runtime archive (linked into final binaries)
|
||||
<pkg>.a precompiled stdlib modules
|
||||
obj/... intermediate .s, .o per package
|
||||
@@ -329,7 +329,7 @@ ELF. Dynamic is `ww build -shared` or per-library `-l`.
|
||||
|
||||
Three tiers, all driven by `make test`:
|
||||
|
||||
1. **Compiler unit tests** (`test/wwc/`): C, table-driven. Lex, parse,
|
||||
1. **Compiler unit tests** (`test/wcc/`): C, table-driven. Lex, parse,
|
||||
typecheck, IR-gen, codegen each have their own table.
|
||||
2. **Language tests** (`test/lang/*.ww`): each file is a single ww
|
||||
program with a comment header declaring expected exit code and
|
||||
@@ -355,7 +355,7 @@ Every change must:
|
||||
|
||||
Applied to this project:
|
||||
|
||||
- `6c` is a single-pass-ish recursive-descent parser into a typed
|
||||
- `w6c` is a single-pass-ish recursive-descent parser into a typed
|
||||
AST, walked into a `Prog` list, then printed as text. No parser
|
||||
generator, no LLVM, no SSA pass pipeline.
|
||||
- Optimizer is intentionally absent at first. Constant fold + dead
|
||||
@@ -370,7 +370,7 @@ Applied to this project:
|
||||
- `ref/hare/` — the Hare distribution. Read for syntax, FFI
|
||||
(`@symbol`), stdlib layout, type names, error idioms.
|
||||
- `ref/plan9front/` — 9front. Read `sys/src/cmd/cc/` (the shared
|
||||
frontend library), `sys/src/cmd/8c/` and `sys/src/cmd/6c/` (per-
|
||||
frontend library), `sys/src/cmd/8c/` and `sys/src/cmd/w6c/` (per-
|
||||
target compilers), `sys/src/cmd/8a/` (assembler), `sys/src/cmd/8l/`
|
||||
(linker) for toolchain organization, `Prog`/`Adr` data shapes,
|
||||
mkfile style, and naming.
|
||||
@@ -404,7 +404,7 @@ When making changes:
|
||||
writing code.
|
||||
- Keep diffs small. One concern per change.
|
||||
- Commits: Plan 9 style. Subject is one short lowercase line,
|
||||
prefixed with the affected area: `6c: fix const fold for i64`,
|
||||
prefixed with the affected area: `w6c: fix const fold for i64`,
|
||||
`lib/fmt: handle %v for slices`, `cc: typo`. Body only when the
|
||||
why is not obvious from the diff. No `Co-Authored-By` trailer,
|
||||
no "Generated with" footer, no emoji.
|
||||
|
||||
Reference in New Issue
Block a user