syntax+w6c: multi-type match patterns in wwstage (align up to cstage)

`case T1 | T2 =>` (binding-less; cstage parse.c:635-650 chains extra
types through cs->list, bindings stay single-type by design). Three
wwstage layers, no AST change (node.list already exists):
- parser (expr.ww): pipe loop after the non-let arm's first
  parsetype;
- checker (check.ww): resolvewalk N_MCASE now walks n.list so each
  alt gets its type_ stamp (exhaustiveness/casecovers were already
  alt-aware, built ahead of the parser);
- cgen (cgenexpr.ww): the single-pattern want-computation moves
  VERBATIM into matcharmwant; a cs.list arm emits CMPQ/JE per alt
  funneling into one match_body label, mirroring cgen.c:11118-11141
  incl. label mint order and the tag<0 clamp. Nullable arms keep
  ignoring alts (both stages).

Graduates the held e2e row (pin 1732/1158/3464); byte-identical on
the repro and the single-pattern control.
This commit is contained in:
2026-08-08 17:15:41 +09:00
parent bbdd8bede6
commit 184afa3243
5 changed files with 120 additions and 37 deletions

View File

@@ -0,0 +1,27 @@
//ww:run-exit 18
// Migrated from 700_e2e row 72.
package main;
fn pick(n: i64) (i64 | i32 | u32) = {
if (n < 0) { return 1: i32; };
if (n == 0) { return 2: u32; };
return n;
};
fn main() i32 = {
let r1: (i64 | i32 | u32) = pick(0);
let r2: (i64 | i32 | u32) = pick(-1);
let r3: (i64 | i32 | u32) = pick(7);
let acc: i32 = 0;
match (r1) {
case let v: i64 => acc += 100;
case i32 | u32 => acc += 1;
};
match (r2) {
case let v: i64 => acc += 100;
case i32 | u32 => acc += 10;
};
match (r3) {
case let v: i64 => acc += v: i32;
case i32 | u32 => acc += 100;
};
return acc;
};