ww: implement package initialization

This commit is contained in:
2026-08-14 19:02:35 +09:00
parent 72e890d5aa
commit c6bec0914d
24 changed files with 5279 additions and 1009 deletions

View File

@@ -75,7 +75,7 @@ export type stream = struct {
//
// Returns the stream BY VALUE; the caller passes `&b.vt` to the io
// dispatchers. Mirrors ref/hare/bufio/stream.ha:69.
export fn init(src: io.stream, rbuf: []u8, wbuf: []u8) stream = {
export fn newstream(src: io.stream, rbuf: []u8, wbuf: []u8) stream = {
let r: stream;
r.vt.reader = (&bread): *io.reader;
r.vt.writer = (&bwrite): *io.writer;

View File

@@ -10,7 +10,7 @@ package random;
export type random = u64;
// Mirrors Hare's random::init.
export fn init(seed: u64) random = { return seed: random; };
export fn fromseed(seed: u64) random = { return seed: random; };
// SplitMix64, per Hare's random::next.
export fn next(r: *random) u64 = {

View File

@@ -131,9 +131,17 @@ export type node = struct {
usepath: str, // N_USE: canonical vendor-expanded identity
usealias: str, // N_USE: explicit file-local alias, or empty
usepkgname: str,// N_USE: imported declared package name
useblank: i32, // N_USE: `_` spelling; no source binding
pkgname: str, // declared package name; independent of canonical nmod
sourceid: i32, // lexical source-file scope in an owner/export unit
used: i32, // N_USE: checker observed this file-local binding
initfn: i32, // special source `fn init`, absent from scope/API
initsynthetic: i32,// compiler-owned variable helper/package task
runtimeinit: i32,// module let lowered through an init helper
initorder: u64,// 1-based variable or init-function order
linksym: str, // raw compiler-private assembler symbol
refdecl: *node,// checker-resolved value declaration
initmark: u64,// checker-private initializer dependency walk mark
imported: i32, // M1 #22: decl reached via `//ww:module <path>` import
// boundary (vs root/primary); gates root-only bare main
};
@@ -142,7 +150,7 @@ export fn newnode(k: nkind, file: str, line: i32, col: i32) *node = {
// fval cast-init: 990's wwdump TK_FLOAT diff requires this file
// to tokenise identically through C and ww (lex.ww:382 has the
// same workaround for the cstage %g-formats vs ww-skips divergence).
let n: *node = alloc(node{kind=k, file=file, line=line, col=col, op=tkind.TK_NONE, str="", uval=0u64, fval=0: f64, lhs=nil, rhs=nil, cond=nil, body=nil, els=nil, list=nil, next=nil, attr=nil, exported=0, packed=0, type_=nil, tsuffix="", nmod="", usesource="", usepath="", usealias="", usepkgname="", pkgname="", sourceid=0, used=0, imported=0})!;
let n: *node = alloc(node{kind=k, file=file, line=line, col=col, op=tkind.TK_NONE, str="", uval=0u64, fval=0: f64, lhs=nil, rhs=nil, cond=nil, body=nil, els=nil, list=nil, next=nil, attr=nil, exported=0, packed=0, type_=nil, tsuffix="", nmod="", usesource="", usepath="", usealias="", usepkgname="", useblank=0, pkgname="", sourceid=0, used=0, initfn=0, initsynthetic=0, runtimeinit=0, initorder=0u64, linksym="", refdecl=nil, initmark=0u64, imported=0})!;
return n;
};

View File

@@ -16,8 +16,7 @@ fn parseuse(p: *parser) *node = {
let alias: str;
let first: str;
if (p.curkind == tkind.TK_UNDER) {
errmsg(p, "blank import alias _ is not implemented");
alias = "_";
n.useblank = 1;
advance(p);
expectident(p, &first);
} else {
@@ -34,7 +33,10 @@ fn parseuse(p: *parser) *node = {
expectident(p, &leaf);
path = strings.concat(path, ".", leaf);
};
if (alias.len > 0) { n.str = alias; } else { n.str = leaf; };
if (n.useblank != 0) {
let empty: str;
n.str = empty;
} else { if (alias.len > 0) { n.str = alias; } else { n.str = leaf; }; };
n.usesource = path;
n.usepath = path;
n.usealias = alias;
@@ -68,14 +70,16 @@ fn parsedef(p: *parser, exported: i32) *node = {
};
fn parselet(p: *parser, exported: i32) *node = {
let pf: str = p.curfile;
let pl: i32 = p.curline;
let pc: i32 = p.curcol;
// Accept `let` or `const`. Const-bound bindings are marked via
// n.op = tkind.TK_CONST so the checker can reject reassignment.
let is_const: i32 = 0;
if (p.curkind == tkind.TK_CONST) { is_const = 1; };
advance(p);
// The declaration position is the binding identifier, matching the C
// parser and the source anchor used by package-initialization diagnostics.
let pf: str = p.curfile;
let pl: i32 = p.curline;
let pc: i32 = p.curcol;
let n: *node = newnode(nkind.N_LET, pf, pl, pc);
n.nmod = p.curmod;
let id: str;