wcc,ww: @test under separate compilation (M4 E1, #79)
Make `ww test --sep` work the Hare +test way: the -T synth test-main emits a qualified test.run, and the test package is injected as an ordinary separately-compiled dependency instead of splicing lib/test source into a flat unit. Additive — combined stays the default and 910/997 are untouched (their migration is M4 E2). - compiler synth (both stages): the -T main emits N_DOT test.run plus a synthetic N_USE "test"; cmd/wcc/check.c + selfhost/cmd/wcc/check.ww. - driver (both stages): build_one_sep gains is_test, injects the test package as a root dep, and passes -T to the root; do_test --sep routes a single-file test through the sep producer; cmd/ww/main.c + selfhost/cmd/ww/main.ww. - 989_septest_run gate: ww test --sep on both stages, run-exit + cs==ww byte-id of the sep .s, non-vacuous. The synth's test.run is left ty_err by the checker in both regimes (lib/test's run is scope-keyed under "" not "test"; cgen emits the correct CALL via run's //ww:module test directive) — wwstage tolerates it like cstage (rule-10). The genuine fix, module-keying run under sep so the call type-resolves, is #80. w6c_ww/wwdump_ww/ww_ww move (their embedded source changed); w6a_ww/w6l_ww and the combined codegen output are unchanged.
This commit is contained in:
@@ -14229,6 +14229,22 @@ fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = {
|
||||
// (ref/harec/src/check.c:1566-1581).
|
||||
if (ms != nil && (ms.skind == syntax.skind.SK_USE || ms.use_alias != 0i32)) {
|
||||
s = syntax.scopelookupinmodule(c.cur, modkeyfor(c, callee.lhs.str), nm);
|
||||
// Module-qualified callee whose leaf isn't scope-keyed
|
||||
// under its module: align to cstage, which stamps ty_err
|
||||
// here and lets cgen emit the call (cmd/wcc/check.c:1834-
|
||||
// 1843; rule-10). The -T synth's `test.run` hits this in
|
||||
// BOTH combined and sep (Q2-confirmed): lib/test's `run` is
|
||||
// scope-keyed under "" not "test" — the directive-for-cgen
|
||||
// vs declmod-for-scope keying split, the module-qualified
|
||||
// arm of #27. cgen still emits the correct CALL test.run
|
||||
// from run's `//ww:module test` directive. Load-bearing
|
||||
// until #80 module-keys run under sep so the synth call
|
||||
// type-resolves; NOT an M4-transient.
|
||||
if (s == nil) {
|
||||
e.type_ = c.tc.tyerr: *void;
|
||||
callee.type_ = c.tc.tyerr: *void; // N_DOT node itself (asserttyped checks it)
|
||||
return nil;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (s != nil) { if (s.skind == syntax.skind.SK_FN) { if (s.decl != nil) {
|
||||
@@ -17275,13 +17291,34 @@ export fn checkfile(c: *checker, file: *syntax.node) void = {
|
||||
let arg: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc);
|
||||
arg.str = "__wwtests";
|
||||
let call: *syntax.node = syntax.newnode(syntax.nkind.N_CALL, pf, pl, pc);
|
||||
let cid: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc);
|
||||
cid.str = "run";
|
||||
call.lhs = cid;
|
||||
// QUALIFIED test.run (N_DOT base ident `test`, member `run`):
|
||||
// the sep producer sees lib/test as a real imported package,
|
||||
// so the call must carry the module qualifier; the combined
|
||||
// path tags auto-bundled lib/test `//ww:module test` too, so
|
||||
// it resolves+mangles identically (test.run). Cstage twin:
|
||||
// cmd/wcc/check.c synth. The base ident binds through the
|
||||
// synth N_USE below.
|
||||
let dot: *syntax.node = syntax.newnode(syntax.nkind.N_DOT, pf, pl, pc);
|
||||
let did: *syntax.node = syntax.newnode(syntax.nkind.N_IDENT, pf, pl, pc);
|
||||
did.str = "test";
|
||||
dot.lhs = did;
|
||||
dot.str = "run";
|
||||
call.lhs = dot;
|
||||
call.list = arg;
|
||||
let ret: *syntax.node = syntax.newnode(syntax.nkind.N_RETURN, pf, pl, pc);
|
||||
ret.lhs = call;
|
||||
body.list = ret;
|
||||
// synth `use test;` so the N_DOT base binds as a module
|
||||
// qualifier (SK_USE) and usepathfor maps `test` to its path.
|
||||
// Mirror installdecl's N_USE SK_USE install. Appended to
|
||||
// file.list below; emits no asm.
|
||||
let usenode: *syntax.node = syntax.newnode(syntax.nkind.N_USE, pf, pl, pc);
|
||||
usenode.str = "test";
|
||||
usenode.usepath = "test";
|
||||
syntax.scopedefine(c.top, "test", syntax.skind.SK_USE, nil, usenode);
|
||||
let ul: *syntax.node = file.list;
|
||||
if (ul == nil) { file.list = usenode; }
|
||||
else { for (ul.next != nil) { ul = ul.next; }; ul.next = usenode; };
|
||||
};
|
||||
let m: *syntax.node = syntax.newnode(syntax.nkind.N_FNDECL, pf, pl, pc);
|
||||
m.str = "main";
|
||||
|
||||
Reference in New Issue
Block a user