Files
ww/selfhost/cmd/wcc/sym.ww
Hojun-Cho 2c33228b7e 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.
2026-05-11 13:49:27 +09:00

114 lines
2.6 KiB
Plaintext

// selfhost/cmd/wcc/sym.ww — port of cmd/wcc/sym.c.
//
// Per-scope hashtable, chained to the parent. Lookup walks up.
// Plan 9 / Hare flavoured. Duplicate definitions in the same scope
// return nil; the caller flags the error.
use mem;
use typ;
use ast;
// Symbol kinds — must stay numerically aligned with cmd/wcc/ww.h Skind.
def SK_NONE: i32 = 0;
def SK_VAR: i32 = 1;
def SK_PARAM: i32 = 2;
def SK_DEF: i32 = 3;
def SK_TYPE: i32 = 4;
def SK_FN: i32 = 5;
def SK_USE: i32 = 6;
def SK_FIELD: i32 = 7;
type sym = struct {
name: str,
skind: i32,
type_: *tinfo,
decl: *node,
exported: i32,
snext: *sym, // iteration order
hashnext: *sym, // hash bucket chain
scope: *scope,
};
def NBUCKETS: i32 = 16;
type scope = struct {
parent: *scope,
first: *sym,
last: *sym,
buckets: **sym, // length = NBUCKETS
nbuckets: i32,
a: *arena,
};
// FNV-1a 64 — same hash the C side uses, so bucket distribution is
// identical when both walk a scope in declaration order.
fn hashstr(s: str) u64 = {
let h: u64 = 14695981039346656037u64;
let i: i32 = 0;
for (i < s.len) {
let c: u8 = s[i];
h = h ^ (c: u64);
h = h * 1099511628211u64;
i += 1;
};
return h;
};
export fn newscope(a: *arena, parent: *scope) *scope = {
let s: *scope = amalloc(a, 64u64): *scope;
s.parent = parent;
s.a = a;
s.nbuckets = NBUCKETS;
s.buckets = amalloc(a, (NBUCKETS: u64) * 8u64): **sym;
return s;
};
export fn streq(a: str, b: str) bool = {
if (a.len != b.len) { return false; };
let i: i32 = 0;
for (i < a.len) {
if (a[i] != b[i]) { return false; };
i += 1;
};
return true;
};
export fn scope_lookup_local(s: *scope, name: str) *sym = {
if (s == nil) { return nil; };
let h: u64 = hashstr(name);
let bi: i32 = (h % (s.nbuckets: u64)): i32;
let b: *sym = s.buckets[bi];
for (b != nil) {
let bn: str = b.name;
if (streq(bn, name)) { return b; };
b = b.hashnext;
};
return nil;
};
export fn scope_lookup(s: *scope, name: str) *sym = {
for (s != nil) {
let r: *sym = scope_lookup_local(s, name);
if (r != nil) { return r; };
s = s.parent;
};
return nil;
};
export fn scope_define(s: *scope, name: str, k: i32, t: *tinfo, decl: *node) *sym = {
if (scope_lookup_local(s, name) != nil) { return nil; };
let sy: *sym = amalloc(s.a, 80u64): *sym;
sy.name = name;
sy.skind = k;
sy.type_ = t;
sy.decl = decl;
sy.scope = s;
let h: u64 = hashstr(name);
let bi: i32 = (h % (s.nbuckets: u64)): i32;
sy.hashnext = s.buckets[bi];
s.buckets[bi] = sy;
if (s.first == nil) { s.first = sy; } else { s.last.snext = sy; };
s.last = sy;
return sy;
};