Files
brolang/examples/programs/defer/main.bro
T
2026-06-30 19:38:28 +02:00

83 lines
2.0 KiB
Plaintext

# Milestone 19: `defer` and bare block statements.
#
# `defer <stmt>` runs the statement when the enclosing scope exits, in reverse
# (LIFO) order, on every exit path. A bare `{ ... }` introduces a scope. Each
# section returns a distinct code on failure; success falls through to 42.
# The return value is captured before defers run, so the mutation here does not
# change what is returned (Zig semantics).
spill_check func() i32 {
x i32 = 5
defer x = 999
return x
}
# A function-scope defer runs only at function exit; a `break` runs the loop-body
# defer but NOT the enclosing function-scope defer.
enclosing_defer_check func() i32 {
v i32 = 0
defer v = v + 100
for 0..3 |i| {
defer v = v + 1
if (i == 1) break
}
return v # 0->1 (i=0 fall-through), ->2 (i=1 break); the +100 runs after capture
}
main func() i32 {
# 1. return value captured before defers run.
if (spill_check() != 5) return 101
# 2. LIFO ordering, run at end of each loop iteration.
r i32 = 0
for 0..1 |i| {
defer r = r * 2 + 1 # registered first -> runs last
defer r = r * 2 # registered second -> runs first
_ = i
}
if (r != 1) return 102 # 0 -> (r*2)=0 -> (r*2+1)=1 ; FIFO would give 2
# 3. scoped bare block + scoped defer (defer fires at the closing brace, and
# the block-local is not visible afterwards).
a i32 = 1
{
defer a = 4
c i32 = 3
_ = c
}
if (a != 4) return 103
# 4. `defer { ... }` block: all its statements run (in order) at scope close.
s i32 = 0
{
defer {
s = s + 1
s = s * 10
}
s = 5
}
if (s != 60) return 104 # 5 -> 6 -> 60
# 5. `break` flushes the loop-body defer.
bc i32 = 0
for 0..5 |i| {
defer bc = bc + 1
if (i == 2) break
}
if (bc != 3) return 105 # i=0,1 fall-through + i=2 break
# 6. `continue` flushes the loop-body defer.
cc i32 = 0
for 0..3 |i| {
defer cc = cc + 1
if (i == 1) continue
cc = cc + 10
}
if (cc != 23) return 106 # 10,+1 ; +1 (continue) ; +10,+1
# 7. break does not run an enclosing function-scope defer.
if (enclosing_defer_check() != 2) return 107
return 42
}