labeled block statements
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user