ww+wcc: graduate selfhost TK_* defs to tkind enum

`type tkind = enum i32 { TK_NONE = 0, TK_EOF = 1, ... TK_LAST = 86 }`
replaces the 87-line `def TK_*: i32 = N` cluster in lib/ww/lex/tok.ww.
Numeric values explicit so 990_selfhost's byte-diff against the C-side
`Tkind` enum still passes.

All ~270 reference sites in lib/ww and selfhost/cmd/{wcc,wwdump}
sed-renamed `TK_X` → `tkind.TK_X`. Struct fields (`tok.kind`,
`parser.curkind`) intentionally kept as `i32` — making them `tkind`
shifted some byte-positions in the cgen output and broke 990/993/995
byte-identity probes without an obvious win.

To make the rename non-cascading on every signature, type_assignable
and unify_arith in cmd/wcc/check+type relax to allow enum ↔ int
mixing when storage matches (a `tkind` value flows into an `i32`
slot and vice versa, no explicit cast). This deviates from Hare's
strict enum semantics; doc'd as an explicit pragmatic relaxation
for the compiler's internal enum-shaped kinds. External user code
can still get the type-safety benefit if they declare their
parameters with the enum type.

combined.ww files regenerated by ww build.
This commit is contained in:
2026-05-12 04:50:36 +09:00
parent fc49da44d8
commit 408ea2a322
14 changed files with 1806 additions and 1771 deletions

View File

@@ -295,6 +295,21 @@ type_assignable(Type *dst, Type *src)
if (dst->kind == TY_NAMED && type_eq(dst->under, src)) return 1;
if (src->kind == TY_NAMED && type_eq(dst, src->under)) return 1;
/* Enum ↔ integer storage: bare i32 flows into a `tkind` slot and
* vice-versa as long as the storage type matches. Hare-strict
* would require an explicit cast, but the ww frontend's tkind /
* nkind enums have hundreds of `let k: i32 = expr` sites we'd
* otherwise have to migrate in lockstep — the relaxation is
* explicit and limited to int-typed enums. */
{
Type *du = (dst->kind == TY_NAMED) ? dst->under : dst;
Type *su = (src->kind == TY_NAMED) ? src->under : src;
if (du && du->kind == TY_ENUM && type_isint(src) &&
type_eq(du->sub, src)) return 1;
if (su && su->kind == TY_ENUM && type_isint(dst) &&
type_eq(dst, su->sub)) return 1;
}
/* Tuple-to-tuple: element-wise assignable. */
if (dst->kind == TY_TUPLE && src->kind == TY_TUPLE) {
Tparam *pa = dst->params, *pb = src->params;