wcc+w6c+w6c_ww: delete() range form delete(xs[lo:hi]) (fold-5a P2)

Hare's delete also takes a slicing place (harec check.c:1981-2027
EXPR_SLICE; Hare spells it delete(xs[i..j])): remove [lo, hi) — shift
[hi..len) down count = hi-lo strides, len -= count, cap unchanged; lo
defaults 0, hi defaults len, so delete(xs[:]) clears the slice with
storage retained. Checker accepts N_SLICE next to N_INDEX (object must
chase to a slice, harec :2024); the old range-unimplemented reject and
its #35 cite drop.

Lowering (both stages, converged byte-identical by construction) is the
single-element arm's same-slice whole-stride word-copy loop with a
DYNAMIC src offset (count*esz via a src register) instead of the
constant one-stride. Base shapes: local slice ident, deref-of-local,
plus NEW indexed local-slice base xs[g][lo:hi] — the fold-5a consumer
shape (regex.ha:333 delete(jump_idxs[group_level][..]); outer stride
off the type table). Bounds stay implicit, inheriting the documented
single-element posture (no index checks anywhere in cgen). Operands
evaluate left-to-right, exactly once, before the shift (harec order);
only the header ADDRESS is taken before operand eval, so a bound
expression's writes through the slice land before the copy.

test/809: 64 fixtures — full/explicit/re-clear/head/mid/tail/empty
a:a/end-boundary len:len/explicit 0:0 on a never-appended (nil-ptr)
slice, single-vs-range equivalence, cap preservation, esz 1/2/4/8/16/24
copy tails against the dynamic src, operand order-of-eval (lo/hi CALLs
fire once each, in order) + aliasing-visibility pins, the EXACT
[][]size regex consumer shape, deref base, 2 reject rows w/ diagnostic
text; every accept row cs==ww asm byte-id. test/804: reject_range row
retired (form now accepted), reject_nonindex text follows the widened
message.
This commit is contained in:
2026-06-04 23:18:38 +09:00
parent 60e61315bc
commit 1bcf2726cf
9 changed files with 1505 additions and 98 deletions

View File

@@ -2675,13 +2675,15 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
e.type_ = tinfofornode(c, tn): *void;
return tn;
};
// delete(xs[i]) — single-element slice removal, the
// delete-half of #35 (insert() is the twin arm below). Mirrors
// cstage cmd/wcc/check.c's delete arm. harec
// ref/harec/src/check.c:1981-2027 also accepts the
// range form delete(xs[i..j]) (EXPR_SLICE) —
// loud-rejected here, filed on #35 (regex fold-2b's
// consumers are all single-element).
// delete(xs[i]) / delete(xs[lo:hi]) — slice removal,
// the delete-half of #35 (insert() is the twin arm
// below). Mirrors cstage cmd/wcc/check.c's delete
// arm. harec ref/harec/src/check.c:1981-2027 accepts
// both an indexing place (EXPR_ACCESS/ACCESS_INDEX)
// and a slicing place (EXPR_SLICE — Hare spells it
// delete(xs[i..j])); either way the OBJECT must be a
// slice. The range form is the fold-5a prereq P2
// (regex.ha:333 delete(jump_idxs[group_level][..])).
if (streq(callee.str, "delete")) {
let d: *node = e.list;
if (d == nil || d.next != nil) {
@@ -2690,22 +2692,20 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
};
if (d != nil) {
exprtype(c, d, nil);
if (d.kind == nkind.N_SLICE) {
cerr("delete: range form delete(xs[i..j]) unimplemented (task #35)\n");
// harec check.c:2016's reject; wording
// adapted to ww's delete: prefix.
if (d.kind != nkind.N_INDEX && d.kind != nkind.N_SLICE) {
cerr("delete: operand must be an indexing or slicing expression\n");
c.errs += 1;
} else {
if (d.kind != nkind.N_INDEX) {
cerr("delete: operand must be an indexing expression xs[i]\n");
let basetn: *node = exprtype(c, d.lhs, nil);
let u: *node = resolvealias(c, unwrapbang(basetn));
// harec check.c:2024 wording; a
// fixed-size [N]T base and a str
// base land here.
if (u == nil || u.kind != nkind.N_TSLICE) {
cerr("delete must operate on a slice\n");
c.errs += 1;
} else {
let basetn: *node = exprtype(c, d.lhs, nil);
let u: *node = resolvealias(c, unwrapbang(basetn));
// harec check.c:2024 wording; a
// fixed-size [N]T base lands here.
if (u == nil || u.kind != nkind.N_TSLICE) {
cerr("delete must operate on a slice\n");
c.errs += 1;
};
};
};
};