Files

92 lines
2.0 KiB
Plaintext

# Milestone 5: conditional optional unwrapping, guards, and multi-unwrap.
observe func(counter @mut i32, value ?i32) ?i32 {
counter^ = counter^ + 1
return value
}
main func() i32 {
total i32 := 0
# present optional scalar -> binds v to the unwrapped value
a ?i32 := 40
if a |v| {
total = total + v # 40
} else {
total = total + 99
}
# null -> else branch taken; the binding is not in scope there
b ?i32 := null
if b |v| {
total = total + v
} else {
total = total + 2 # 42
}
# optional pointer present -> binds q to a non-null @i32; deref proves it
n i32 := 0
p ?@i32 := &n
if p |q| {
total = total + q^ # +0
}
# optional pointer null -> skipped
z ?@i32 := null
if z |_| {
total = total + 1000
}
# guarded multi-unwrap exposes every capture to the guard and then-block
age ?i32 := 2
if a and age |value, years : value + years == 42| {
total = total
} else {
total = total + 100
}
# parenthesized chains and three-value unwraps are equivalent
bonus ?i32 := 0
if (a and age and bonus) |value, years, extra : value + years + extra == 42| {
total = total
} else {
total = total + 100
}
# false guards use the else branch, or simply fall through without one
if a |value : value == 0| {
total = total + 100
} else {
total = total
}
if a |value : value == 0| {
total = total + 100
}
# a failed unwrap prevents later expressions from being evaluated
calls i32 := 0
if b and observe(&calls, age) |missing, observed| {
total = total + missing + observed
}
if calls != 0 {
total = total + 100
}
# short-circuiting also applies after an earlier successful unwrap
if a and b and observe(&calls, age) |value, missing, observed| {
total = total + value + missing + observed
}
if calls != 0 {
total = total + 100
}
# optional pointers participate in multi-unwrap and guards
if a and p |value, q : value == 40 and q^ == 0| {
total = total
} else {
total = total + 100
}
return total # expect exit code 42
}