value if/loop follow-ups

This commit is contained in:
2026-06-27 23:24:36 +02:00
parent 61293a23e7
commit 3e54c6f9ad
4 changed files with 282 additions and 26 deletions
+52
View File
@@ -130,6 +130,50 @@ loop_while :: func() i32 {
return 2
}
# --- value if/loop follow-ups (milestone 20.6) -------------------------------
# A branch may exit on every path (here `return`) instead of yielding; the slot
# read after the `if` is only reached on the yielding path.
vif_return :: func(sel i32) i32 {
r :: if (sel == 0) {
yield 10
} else {
return 55 # exits the function instead of yielding
}
return r + 1 # only when sel == 0: 10 + 1 = 11
}
# unwrap-`if` as a value source: present -> transform, absent -> default.
vif_unwrap :: func(opt ?i32) i32 {
r :: if opt |v| {
yield v * 2
} else {
yield 99
}
return r
}
# The simple "unwrap or fallback" case is just `orelse` (already a plain expression).
orelse_value :: func(opt ?i32) i32 {
r :: opt orelse 7
return r
}
# Untyped value loop where `none` is yielded (in a labeled yield) before any
# concrete value: the element type still resolves to ?<i> from `yield :blk i`.
loop_none_first :: func() i32 {
r :: for 0..10 |i| blk: {
if (i > 100) yield :blk none
if (i * i > 40) yield :blk i # first concrete yield: i == 7
yield none
}
if r |found| {
if (found == 7) return 0
return 1
}
return 2
}
main :: func() i32 {
if (basic() != 42) return 101
if (typed() != 100) return 102
@@ -149,5 +193,13 @@ main :: func() i32 {
if (loop_none() != 0) return 114
if (loop_while() != 0) return 115
if (vif_return(0) != 11) return 116
if (vif_return(1) != 55) return 117
if (vif_unwrap(21) != 42) return 118
if (vif_unwrap(none) != 99) return 119
if (orelse_value(5) != 5) return 120
if (orelse_value(none) != 7) return 121
if (loop_none_first() != 0) return 122
return 42
}