Files
dimgigov f9185c96b2 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.
2026-07-18 01:24:48 +03:00

82 lines
1.6 KiB
Plaintext

// Multi-stmt match arms (block bodies) + block-as-expression
import Std::Io::{PrintLine, PrintInt};
import Std::Test::{Test_AssertEqInt, Test_Pass};
struct Point {
x: int,
y: int,
}
enum Option {
Some(int),
None
}
func Classify(n: int) -> int {
match n {
1 => {
let a: int = 10;
a + 1
},
2 => {
PrintLine("two");
let b: int = 20;
b * 2
},
_ => 0
}
}
func Main() -> int {
Test_AssertEqInt(Classify(1), 11);
Test_AssertEqInt(Classify(2), 40);
Test_AssertEqInt(Classify(9), 0);
// Block as expression outside match
let r: int = {
let x: int = 5;
let y: int = 6;
x + y
};
Test_AssertEqInt(r, 11);
// Tuple pattern + block body
let t: (int, int) = (3, 4);
let u: int = match t {
(a, b) => {
let prod: int = a * b;
prod
},
_ => 0
};
Test_AssertEqInt(u, 12);
// Struct pattern + block body
let p: Point = Point { x: 2, y: 5 };
let z: int = match p {
Point { x: px, y: py } => {
let sum: int = px + py;
sum
},
_ => -1
};
Test_AssertEqInt(z, 7);
// Enum payload + block
let opt: Option = Option { tag: Option_Some };
opt.data.Some_0 = 7;
let v: int = match opt {
Option::Some(n) => {
let doubled: int = n + n;
doubled
},
Option::None => 0
};
Test_AssertEqInt(v, 14);
PrintInt(Classify(2));
PrintLine("");
Test_Pass("match_block");
return 0;
}