feat: multi-stmt match arms and block-as-expression

Blocks can yield a value: last expression statement is the result.
Match arms accept block bodies, so multi-statement arms work:

  match n {
    1 => { let a = 10; a + 1 },
    _ => 0
  }

Bootstrap: lowerBlock(asExpr) lifts the trailing skExpr. Selfhost: parse
{...} as ekBlock, emit __blk_N yield temps (retTypeKind -2), and treat
only non-empty strValue as match/block yield. Nested enum/struct pattern
bindings recurse in both compilers.

Example: match_block.bux. Selfhost-loop remains binary-identical.
This commit is contained in:
2026-07-18 01:24:48 +03:00
parent e3ca724bfa
commit f9185c96b2
8 changed files with 337 additions and 98 deletions
+8
View File
@@ -661,6 +661,14 @@ func parserParsePrimary(p: *Parser) -> *Expr {
return parserParseClosure(p);
}
// Block expression { stmts; value }
if kind == tkLBrace {
let e: *Expr = parserMakeExpr(ekBlock, line, col);
e.boolValue = false;
e.refBlock = parserParseBlock(p);
return e;
}
// unsafe { ... } — unsafe block expression
if kind == tkUnsafe {
discard parserAdvance(p);