ww: import toolchain — C bootstrap + ww-side self-host (phases 0-10)

C bootstrap (phases 0-9):
  cmd/wwc, cmd/6c, cmd/6a, cmd/6l, cmd/ww, rt, lib/*.

ww-side self-host (phase 10):
  selfhost/cmd/wwc — ww-cgen frontend; bootstrap fixed point.
  selfhost/cmd/6a  — assembler; byte-identical to C 6a (test 991).
  selfhost/cmd/6l  — linker w/ archive (.a) support; byte-identical
                     to C 6l (test 992).
  selfhost/cmd/ww  — driver (build/run/version); byte-identical to
                     C ww (test 993).

make test: 15/15. make bootstrap: ww2.s == ww3.s, ww2.o == ww3.o,
ww2 == ww3 byte-identical, with the full ww-tooled chain.
This commit is contained in:
2026-05-11 02:17:47 +09:00
parent 4c8fc59ca1
commit 1657bdeda3
106 changed files with 35654 additions and 15 deletions

View File

@@ -54,16 +54,23 @@ This file is the contract for the work. Read PLAN.md for the schedule.
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.
7. **No generics, no interfaces, no tagged unions, no closures, no
lambdas.** Five forms of bloat we refuse. Polymorphism, when
genuinely needed, is a struct of function pointers plus a
`ctx: *void` (Plan 9 `Bio`, Hare `io::stream`). All functions are
declared at file scope; function values are pointers to those
named functions. No capturing. No anonymous function literals.
The compiler does no virtual dispatch; users build vtables
explicitly when they want them. If a function needs to work on
multiple types, write it multiple times, or operate on `[]u8`
and let the caller cast.
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`,
Hare `io::stream`). All functions are declared at file scope;
function values are pointers to those named functions. No
capturing. No anonymous function literals. The compiler does no
virtual dispatch; users build vtables explicitly when they want
them. If a function needs to work on multiple types, write it
multiple times, or operate on `[]u8` and let the caller cast.
**Tagged unions are allowed**, but only as the Hare-style error
idiom: `(T | error)` (and a few sentinel kin like `nomem`).
Pattern-matched with `match`. Propagated with postfix `?`. Asserted
with postfix `!`. They are not an open extension point — no enum
methods, no virtual dispatch through the tag, no nesting beyond
what the error idiom needs. If you find yourself reaching for a
discriminated record, use a struct with a tag field instead.
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
@@ -176,9 +183,20 @@ Lexical rules:
## Errors
Plan 9 model. An error is a string. Empty means OK. Hare uses
tagged unions for errors; we don't have unions, so we drop down
to the plainer Plan 9 thing.
Two idioms, picked by the API author:
1. **Plan 9 model.** An error is a string. Empty means OK. Functions
that can fail return `(T, error)`. Use this when there are only one
or two error sources and the caller usually wants to format the
message and move on.
2. **Hare tagged-union model.** A function returns `(T | E1 | E2 | ...)`.
Callers `match` on it, or propagate with postfix `?`, or assert
non-error with `!`. Use this when errors are structured (have
payload) or when a caller routinely wants to handle one specific
error kind.
Both are first-class. Pick whichever fits; do not mix in a single
return type.
```
type error = str;
@@ -365,8 +383,10 @@ for toolchain organization and compiler internals.
- A package manager. Modules are directories. Vendoring is `cp -r`.
- A formatter beyond `wwfmt` (one canonical style, no options).
- A language server in phase 0. Plain editors are fine.
- Generics, interfaces, tagged unions, closures, lambdas. Ever.
See hard rule #7.
- Generics, interfaces, closures, lambdas. Ever. See hard rule #7.
Tagged unions are allowed but ONLY for the Hare-style error idiom
(`(T | error)` + `match` + `?` + `!`). No general-purpose enums or
open extension points.
- An async/await coloring. CSP is the concurrency story; a function
is a function.
@@ -383,3 +403,8 @@ When making changes:
- If a design question is non-obvious, propose two options before
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`,
`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.