selfhost/cmd/wcc: N_CALL intercepts for len/append/free (A.6.2.1b)
Three Hare pseudo-builtins (len/append/free) were resolving via the generic N_CALL path and leaving e.type_ nil, blocking #15's post- checker assertion. Add inline intercepts in exprtype that stamp e.type_ to mktname("i32")/mktname("void") and return the same tnode, matching the cstage shape at cmd/wcc/check.c:896-1011 (rule 10 stage byte-id). No shadow guard: cstage's len/append/free intercepts have none either, and L85-88 seeds the names into c.top so a same-module decl dup- silences. No arg-walk: resolvewalk descends children before dispatching the parent N_CALL (check.ww:404-417), so args are stamped before the intercept fires. insert/delete deferred — not implemented in either stage. The cstage divergence from harec (len → i32 not size; append → void not tagged) pre-dates this task; #19 (dedicated AST kinds) is the Hare-faithful path. Behavior is transitively covered by the 990-997 byte-id corpus (append used in progs 16, 19, 20); the stamp side gates on #15.
This commit is contained in:
@@ -8663,6 +8663,32 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// len(x) / append(s,...) / free(p) — Hare pseudo-builtins.
|
||||
// Mirror cstage cmd/wcc/check.c:896-1011 (rule 10 requires
|
||||
// stage byte-id; both stages stamp the same shape). No shadow
|
||||
// guard: cstage's len/append/free intercepts have none either
|
||||
// (check.c:901/962/1005), and the names are seeded into c.top
|
||||
// at L85-88 so a user same-module decl dup-silences. Harec
|
||||
// models these as dedicated AST kinds — EXPR_LEN at
|
||||
// ref/harec/src/check.c:2630 (result `&builtin_type_size`),
|
||||
// EXPR_APPEND at :745 (result `(nomem | void)`), EXPR_FREE at
|
||||
// :2443 (result `&builtin_type_void`). The cstage divergence
|
||||
// (len → i32 not size, append → void not tagged) pre-dates
|
||||
// this task; #19 (Drew's δ — dedicated AST kinds) is the
|
||||
// Hare-faithful path. This is the intercept-shim minimum to
|
||||
// unblock #15 (A.6.2.1e assertion enable).
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
if (streq(callee.str, "len")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(callee.str, "append") || streq(callee.str, "free")) {
|
||||
let tn: *node = mktname(c, "void");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
};
|
||||
let nm: str;
|
||||
nm.ptr = nil; nm.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) { nm = callee.str; };
|
||||
|
||||
@@ -1699,6 +1699,32 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// len(x) / append(s,...) / free(p) — Hare pseudo-builtins.
|
||||
// Mirror cstage cmd/wcc/check.c:896-1011 (rule 10 requires
|
||||
// stage byte-id; both stages stamp the same shape). No shadow
|
||||
// guard: cstage's len/append/free intercepts have none either
|
||||
// (check.c:901/962/1005), and the names are seeded into c.top
|
||||
// at L85-88 so a user same-module decl dup-silences. Harec
|
||||
// models these as dedicated AST kinds — EXPR_LEN at
|
||||
// ref/harec/src/check.c:2630 (result `&builtin_type_size`),
|
||||
// EXPR_APPEND at :745 (result `(nomem | void)`), EXPR_FREE at
|
||||
// :2443 (result `&builtin_type_void`). The cstage divergence
|
||||
// (len → i32 not size, append → void not tagged) pre-dates
|
||||
// this task; #19 (Drew's δ — dedicated AST kinds) is the
|
||||
// Hare-faithful path. This is the intercept-shim minimum to
|
||||
// unblock #15 (A.6.2.1e assertion enable).
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
if (streq(callee.str, "len")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(callee.str, "append") || streq(callee.str, "free")) {
|
||||
let tn: *node = mktname(c, "void");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
};
|
||||
let nm: str;
|
||||
nm.ptr = nil; nm.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) { nm = callee.str; };
|
||||
|
||||
@@ -8663,6 +8663,32 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// len(x) / append(s,...) / free(p) — Hare pseudo-builtins.
|
||||
// Mirror cstage cmd/wcc/check.c:896-1011 (rule 10 requires
|
||||
// stage byte-id; both stages stamp the same shape). No shadow
|
||||
// guard: cstage's len/append/free intercepts have none either
|
||||
// (check.c:901/962/1005), and the names are seeded into c.top
|
||||
// at L85-88 so a user same-module decl dup-silences. Harec
|
||||
// models these as dedicated AST kinds — EXPR_LEN at
|
||||
// ref/harec/src/check.c:2630 (result `&builtin_type_size`),
|
||||
// EXPR_APPEND at :745 (result `(nomem | void)`), EXPR_FREE at
|
||||
// :2443 (result `&builtin_type_void`). The cstage divergence
|
||||
// (len → i32 not size, append → void not tagged) pre-dates
|
||||
// this task; #19 (Drew's δ — dedicated AST kinds) is the
|
||||
// Hare-faithful path. This is the intercept-shim minimum to
|
||||
// unblock #15 (A.6.2.1e assertion enable).
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
if (streq(callee.str, "len")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(callee.str, "append") || streq(callee.str, "free")) {
|
||||
let tn: *node = mktname(c, "void");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
};
|
||||
let nm: str;
|
||||
nm.ptr = nil; nm.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) { nm = callee.str; };
|
||||
|
||||
Reference in New Issue
Block a user