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:
@@ -3175,16 +3175,40 @@ check_file(Checker *c, Node *file)
|
||||
scope_define_in_module(c->cur, tab->str, NULL, SK_VAR,
|
||||
tt, tab);
|
||||
|
||||
/* return run(__wwtests); */
|
||||
/* return test.run(__wwtests);
|
||||
* QUALIFIED, not bare `run`: under the sep producer
|
||||
* lib/test is a real imported package, so the call must
|
||||
* carry the `test` module qualifier (N_DOT base ident
|
||||
* `test`, member `run`). The combined path tags the
|
||||
* auto-bundled lib/test `//ww:module test` too, so the
|
||||
* qualified form resolves+mangles identically there
|
||||
* (test.run either way) — byte-neutral. The base ident
|
||||
* resolves through a synthetic N_USE injected below. */
|
||||
Node *arg = newnode(c->a, N_IDENT, fp);
|
||||
arg->str = "__wwtests";
|
||||
Node *call = newnode(c->a, N_CALL, fp);
|
||||
call->lhs = newnode(c->a, N_IDENT, fp);
|
||||
call->lhs->str = "run";
|
||||
Node *dot = newnode(c->a, N_DOT, fp);
|
||||
dot->lhs = newnode(c->a, N_IDENT, fp);
|
||||
dot->lhs->str = "test";
|
||||
dot->str = "run";
|
||||
call->lhs = dot;
|
||||
call->list = arg;
|
||||
Node *ret = newnode(c->a, N_RETURN, fp);
|
||||
ret->lhs = call;
|
||||
body->list = ret;
|
||||
/* synth `use test;` so the N_DOT base ident binds as a
|
||||
* module qualifier (SK_USE) and use_path maps `test` to
|
||||
* its import path. Mirror the typedecl-pass N_USE install
|
||||
* (check.c:2892). Appended to file->list below; emits no
|
||||
* asm (cgen keys off module-tagged decls). */
|
||||
Node *usenode = newnode(c->a, N_USE, fp);
|
||||
usenode->str = "test";
|
||||
usenode->strlen = 4;
|
||||
usenode->usepath = "test";
|
||||
scope_define(c->cur, "test", SK_USE, NULL, usenode);
|
||||
Node *ul = file->list;
|
||||
if (ul == NULL) file->list = usenode;
|
||||
else { while (ul->next) ul = ul->next; ul->next = usenode; }
|
||||
}
|
||||
|
||||
Node *m = newnode(c->a, N_FNDECL, fp);
|
||||
|
||||
Reference in New Issue
Block a user