lib/ww/syntax: export the 16 public types consumed by the wcc backend (#72)

After the frontend consolidated into one syntax package, the wcc backend
imports syntax and calls its exported fns — whose signatures reference
types that were unexported. Producing syntax's .wwi interface re-triggered
check_exported_type ("exported declaration references unexported type"):
the residual of BUG-A at the one surviving syntax->wcc boundary. Export
the 16 types that appear in syntax's wcc-facing public surface (directly
in an exported signature, or via a recursively-referenced exported struct
field): nkind, node, lex, tok, tkind, parser, scope, sym, skind, tinfo,
tykind, tfield, tparam, ttupleelem, tctx, tinfocacheent. The set is
minimal (unexporting any one re-breaks the producer) and complete; pos
stays internal. Pure source change — exporting a type emits no code, so
the bootstrap binaries are byte-identical (verified against a clean base
build); only syntax's .wwi gains the type decls.

Post-frontend-reorg residual (#74). syntax now sep-produces clean both
stages. The separate concern of wcc's currently-unqualified refs to
syntax symbols (#75) is a distinct follow-up. Gate 989_syntaxexport_run.
This commit is contained in:
2026-06-16 20:19:14 +09:00
parent 7a8acfb952
commit 697e413113
10 changed files with 343 additions and 48 deletions

View File

@@ -21,7 +21,7 @@ import strconv;
// explicit and must stay in sync — the 990_selfhost test diffs
// astprint against the C side byte-for-byte. Tail-appended entries
// (TYPETEST onward) preserve every prior N_* value.
type nkind = enum i32 {
export type nkind = enum i32 {
N_NONE = 0,
N_INTLIT = 1,
@@ -115,7 +115,7 @@ type nkind = enum i32 {
// ---- Node -------------------------------------------------------------
type node = struct {
export type node = struct {
kind: nkind,
file: str,
line: i32,

View File

@@ -46,7 +46,7 @@ fn hexval(c: rune) (i32 | void) = {
return;
};
type lex = struct {
export type lex = struct {
file: str,
src: *u8, // raw bytes; not necessarily NUL-terminated
srclen: u64,

View File

@@ -17,7 +17,7 @@ package syntax;
import os;
import strings;
type parser = struct {
export type parser = struct {
l: *lex,
errs: i32,
// nocast: while inside `[...]` we treat ':' as the slice

View File

@@ -7,7 +7,7 @@
package syntax;
// Symbol kinds — must stay numerically aligned with cmd/wcc/ww.h Skind.
type skind = enum i32 {
export type skind = enum i32 {
SK_NONE = 0,
SK_VAR = 1,
SK_PARAM = 2,
@@ -18,7 +18,7 @@ type skind = enum i32 {
SK_FIELD = 7,
};
type sym = struct {
export type sym = struct {
name: str,
skind: skind,
type_: *tinfo,
@@ -43,7 +43,7 @@ type sym = struct {
def NBUCKETS: i32 = 16;
type scope = struct {
export type scope = struct {
parent: *scope,
first: *sym,
last: *sym,

View File

@@ -20,7 +20,7 @@ import strings;
// explicit and must stay in sync — the 990_selfhost test diffs wwdump
// output against the C side, byte for byte.
type tkind = enum i32 {
export type tkind = enum i32 {
TK_NONE = 0,
TK_EOF = 1,
TK_ERR = 2,
@@ -143,7 +143,7 @@ type pos = struct {
col: i32,
};
type tok = struct {
export type tok = struct {
kind: tkind,
file: str, // path of the source the token came from
line: i32,

View File

@@ -18,7 +18,7 @@ import os;
// Mirror of the C `TypeKind` enum in cmd/wcc/ww.h. Numeric values
// are explicit and must stay in sync — the selfhost selfcheck and
// typed-AST printers depend on matching numeric layout.
type tykind = enum i32 {
export type tykind = enum i32 {
TY_NONE = 0,
TY_VOID = 1,
TY_BOOL = 2,
@@ -69,14 +69,14 @@ def SIZE_UNDEFINED: u64 = 18446744073709551615;
// ---- tinfo / tfield / tparam -----------------------------------------
type tfield = struct {
export type tfield = struct {
name: str,
type_: *tinfo,
offset: u64,
tnext: *tfield,
};
type tparam = struct {
export type tparam = struct {
name: str,
type_: *tinfo,
// #61a: per-variant `!T` error mark for TY_TAGGED variants.
@@ -98,13 +98,13 @@ type tparam = struct {
// sea-of-stars mirrors Hare's structural choice; the empty-name idiom
// from #50's TTAGGED-on-tparam would conflate two semantic axes
// (variants can be named; positionals never can).
type ttupleelem = struct {
export type ttupleelem = struct {
type_: *tinfo,
offset: u64,
tnext: *ttupleelem,
};
type tinfo = struct {
export type tinfo = struct {
kind: tykind,
size: u64,
align: u64,
@@ -154,7 +154,7 @@ type tinfo = struct {
// (rule-12): cnext chains WITHIN a bucket; lookup/bind hash then touch
// only one bucket -> O(1) amortized. Identical lookup results (same
// *tinfo for the same node), so emitted asm is byte-identical.
type tinfocacheent = struct {
export type tinfocacheent = struct {
key: *node,
val: *tinfo,
cnext: *tinfocacheent,
@@ -168,7 +168,7 @@ def NBUCKETS_TINFO: u64 = 8192u64;
// ---- tctx — the box of primitive types -------------------------------
type tctx = struct {
export type tctx = struct {
tyvoid: *tinfo,
tybool: *tinfo,
tyrune: *tinfo,