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;
|
let nm: str;
|
||||||
nm.ptr = nil; nm.len = 0;
|
nm.ptr = nil; nm.len = 0;
|
||||||
if (callee.kind == nkind.N_IDENT) { nm = callee.str; };
|
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;
|
let nm: str;
|
||||||
nm.ptr = nil; nm.len = 0;
|
nm.ptr = nil; nm.len = 0;
|
||||||
if (callee.kind == nkind.N_IDENT) { nm = callee.str; };
|
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;
|
let nm: str;
|
||||||
nm.ptr = nil; nm.len = 0;
|
nm.ptr = nil; nm.len = 0;
|
||||||
if (callee.kind == nkind.N_IDENT) { nm = callee.str; };
|
if (callee.kind == nkind.N_IDENT) { nm = callee.str; };
|
||||||
|
|||||||
Reference in New Issue
Block a user