wcc+w6c+w6c_ww: delete() builtin — single-element slice removal (part of #35)
Hare's delete(xs[i]) (ref/harec/src/check.c:1981-2027): checker accepts an N_INDEX over a slice-typed base, stamps void; loud-rejects the range form delete(xs[i..j]) (stays filed on #35 — regex fold-2b's consumers are all single-element), non-index operands, array bases, wrong arity. Lowering (both stages, converged byte-identical by construction): ascending word-copy loop shifts [i+1..len) down one esz stride, then hdr.len -= 1; cap unchanged. The move is a same-type whole-stride byte copy — src and dst are elements of the SAME slice, so no boxing exists for any element kind; one loop serves scalar/narrow/str/struct/tagged. esz off the STAMPED base type (#34/#48 discipline). Base shapes: local slice ident (LEAQ) and deref-of-local ptr-to-slice (MOVQ — the fold-2b delete_thread shape); others rule-7 loud-stop. test/804: 38 fixtures — first/middle/last/to-empty, esz 1/4/8/24/56 (MOVB/MOVL tails + 7-qword tagged), cap-unchanged, (*threads)[i], 4 checker reject rows; every accept row cs==ww asm byte-id.
This commit is contained in:
@@ -97,12 +97,14 @@ fn seedprimitives(c: *checker) void = {
|
||||
scopedefine(c.top, "nomem", skind.SK_TYPE, nil, nomemdecl);
|
||||
// `nil`, `true`, `false` are keywords — handled at the lex/parser
|
||||
// level, no symbol needed.
|
||||
// `len`, `alloc`, `free`, `append` are pseudo-builtins; scopedefine
|
||||
// them so their use sites resolve. The actual semantics live in cgen.
|
||||
// `len`, `alloc`, `free`, `append`, `delete` are pseudo-builtins;
|
||||
// scopedefine them so their use sites resolve. The actual semantics
|
||||
// live in cgen.
|
||||
scopedefine(c.top, "len", skind.SK_FN, nil, nil);
|
||||
scopedefine(c.top, "alloc", skind.SK_FN, nil, nil);
|
||||
scopedefine(c.top, "free", skind.SK_FN, nil, nil);
|
||||
scopedefine(c.top, "append", skind.SK_FN, nil, nil);
|
||||
scopedefine(c.top, "delete", skind.SK_FN, nil, nil);
|
||||
// #42: typed builtins folded to integer literals at check time —
|
||||
// `size(T)` / `align(T)` (arg is a type-expression planted by the
|
||||
// parser at lib/ww/parse/expr.ww:254-267) and `offset(e.f)` (arg is
|
||||
@@ -2562,6 +2564,44 @@ 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() deferred). 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).
|
||||
if (streq(callee.str, "delete")) {
|
||||
let d: *node = e.list;
|
||||
if (d == nil || d.next != nil) {
|
||||
cerr("delete: takes exactly one argument\n");
|
||||
c.errs += 1;
|
||||
};
|
||||
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");
|
||||
c.errs += 1;
|
||||
} else {
|
||||
if (d.kind != nkind.N_INDEX) {
|
||||
cerr("delete: operand must be an indexing expression xs[i]\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;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
let tn: *node = mktname(c, "void");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
};
|
||||
let nm: str;
|
||||
nm.ptr = nil; nm.len = 0;
|
||||
|
||||
Reference in New Issue
Block a user