ww: add Hare-style is/as postfix ops on tagged unions

`e is T` returns bool (variant tag == T's index); `e as T` unwraps
to T or exit(1) on mismatch. Postfix, same precedence as `:` cast.
TK_IS / N_TYPETEST / N_TYPEASSERT appended at the tail of their
enums so every prior numeric value stays unchanged — the
990_selfhost wwdump-diff stays byte-clean.

Cgen mirrors the match-case slot-based load (tag at +0, value at
+8/+16), so an N_IDENT tagged-union local works just like a
match scrutinee. Selfhost cgen inlines the slot resolution
because the wwstage cgen drops sign bits on `*i32` output
parameters in this position.

Renames `errors.is` -> `errors.equal` (the only naming collision;
the existing comment already noted it shared shape with
strings.equal/bytes.equal).
This commit is contained in:
2026-05-11 23:21:08 +09:00
parent 8899ce5621
commit dd188ca460
16 changed files with 614 additions and 15 deletions

View File

@@ -670,6 +670,22 @@ parsepostfix(Parser *p, Node *lhs)
lhs = n;
break;
}
case TK_AS:
case TK_IS: {
/* Hare-style:
* e as T — assert lhs is variant T of its tagged
* union; abort if not. Yields T.
* e is T — bool: does lhs currently hold variant T?
* Postfix, same level as `:` cast. */
Tkind k = p->cur.kind;
advance(p);
Node *n = newnode(p->a,
k == TK_AS ? N_TYPEASSERT : N_TYPETEST, pp);
n->lhs = lhs;
n->rhs = parsetype(p);
lhs = n;
break;
}
default:
return lhs;
}