labeled block statements

This commit is contained in:
2026-06-28 09:07:09 +02:00
parent eaa66511a0
commit 3007910526
5 changed files with 181 additions and 21 deletions
+44
View File
@@ -240,6 +240,45 @@ break_outer :: func() i32 {
return count # 5
}
# A labeled block *statement* (not a value source): `break :blk` exits it early.
stmt_block :: func(early i32) i32 {
x i32 = 0
blk: {
x = 1
if (early == 1) break :blk
x = 2
}
return x # early == 1 -> 1, else 2
}
# `break :search` escapes a nested loop and the block in one jump; the block's
# defer still runs on the way out.
stmt_block_escape :: func() i32 {
hits i32 = 0
search: {
defer hits += 1000
for 0..10 |i| {
hits += 1
if (i == 3) break :search
}
hits += 100 # skipped by break :search
}
return hits # 4 + 1000 (defer) = 1004
}
# Item B: a `none` yielded before a concrete `yield :blk` that references a block local.
lblock_local :: func() i32 {
r :: blk: {
val :: 9
if (false) yield :blk none
yield :blk val
}
if r |v| {
return v
}
return -1
}
main :: func() i32 {
if (basic() != 42) return 101
if (typed() != 100) return 102
@@ -276,5 +315,10 @@ main :: func() i32 {
if (yield_outer(99) != -1) return 129
if (break_outer() != 5) return 130
if (stmt_block(1) != 1) return 131
if (stmt_block(0) != 2) return 132
if (stmt_block_escape() != 1004) return 133
if (lblock_local() != 9) return 134
return 42
}