53 lines
1.1 KiB
Plaintext
53 lines
1.1 KiB
Plaintext
# Milestone 20: `yield` and value blocks.
|
|
#
|
|
# A `{ ... }` on the right of a declaration or assignment is a value block: its
|
|
# final `yield <expr>` supplies the value (the block analogue of `return`). The
|
|
# yielded value is captured before the block's defers run. Each section returns a
|
|
# distinct code on failure; success falls through to 42.
|
|
|
|
# Untyped `::`: the local's type is the yield's natural type.
|
|
basic :: func() i32 {
|
|
x :: {
|
|
a :: 20
|
|
b :: 22
|
|
yield a + b
|
|
}
|
|
return x
|
|
}
|
|
|
|
# Typed `T =`: the yield coerces to the annotation.
|
|
typed :: func() i64 {
|
|
x i64 = {
|
|
yield 100
|
|
}
|
|
return x
|
|
}
|
|
|
|
# The yielded value is captured before defers run: the defer mutates a block
|
|
# local, but the captured value is unchanged.
|
|
spill :: func() i32 {
|
|
v :: {
|
|
n i32 = 5
|
|
defer n = 999
|
|
yield n
|
|
}
|
|
return v # 5, not 999
|
|
}
|
|
|
|
# Reassignment into an existing mutable local.
|
|
reassign :: func() i32 {
|
|
r i32 = 0
|
|
r = {
|
|
yield 7
|
|
}
|
|
return r
|
|
}
|
|
|
|
main :: func() i32 {
|
|
if (basic() != 42) return 101
|
|
if (typed() != 100) return 102
|
|
if (spill() != 5) return 103
|
|
if (reassign() != 7) return 104
|
|
return 42
|
|
}
|