93 lines
2.5 KiB
Plaintext
93 lines
2.5 KiB
Plaintext
;; e as g inside an and chain (decision 136): g is bound for the rest of the
|
|
;; chain and for the block, and not in the else, an elif or after the block.
|
|
;; e? as g is the same test.
|
|
|
|
struct Grain
|
|
color-idx: i32
|
|
|
|
let calls: i32 = 0
|
|
|
|
fn get-cell(grid: [4 i32], i: i32) -> Grain?
|
|
calls += 1
|
|
if i < 0 or i >= 4
|
|
return None
|
|
Some(Grain{.color-idx grid[i]})
|
|
|
|
fn is-empty-cell(g: Grain) -> bool
|
|
g.color-idx < 0
|
|
|
|
fn tick(n: i32) -> i32
|
|
calls += 1
|
|
print(n, "")
|
|
n
|
|
|
|
fn half(n: i32) -> i32?
|
|
calls += 1
|
|
if n % 2 == 0 then Some(n / 2) else None
|
|
|
|
fn classify(grid: [4 i32], i: i32) -> str
|
|
if get-cell(grid, i) as g and is-empty-cell(g)
|
|
"empty"
|
|
elif get-cell(grid, i) as g and g.color-idx > 1
|
|
"big"
|
|
elif half(i) as h and h > 0
|
|
"half"
|
|
else
|
|
"other"
|
|
|
|
fn main()
|
|
let grid = [1, -1, 2, -3]
|
|
;; A block if, with an else that does not see g.
|
|
let g = 100
|
|
if get-cell(grid, 1) as g and is-empty-cell(g)
|
|
println("empty", g.color-idx)
|
|
if get-cell(grid, 0) as g and is-empty-cell(g)
|
|
println("empty", g.color-idx)
|
|
else
|
|
println("else sees the outer g", g)
|
|
println("after", g)
|
|
;; A kept when gives a Grain?.
|
|
let left = when get-cell(grid, 3) as g and is-empty-cell(g) then g
|
|
println(left!.color-idx)
|
|
let none: Grain? = when get-cell(grid, 0)? as g and is-empty-cell(g) then g
|
|
println(none?)
|
|
;; Two bindings, and a test over both.
|
|
let a: i32? = Some(3)
|
|
let b: i32? = Some(5)
|
|
if a as x and b as y and x < y
|
|
println(x, y)
|
|
if a as x and b as y and x > y
|
|
println(x, y)
|
|
else
|
|
println("not less")
|
|
;; One line, in a let.
|
|
let v = if half(8) as h and h > 3 then h * 10 else -1
|
|
let w = if half(6) as h and h > 3 then h * 10 else -1
|
|
println(v, w)
|
|
;; An elif chain.
|
|
println(classify(grid, 1), classify(grid, 2), classify(grid, 0), classify(grid, 4), classify(grid, 5))
|
|
;; Each value is found once, left to right, and a failed test stops the chain.
|
|
calls = 0
|
|
if tick(1) > 0 and half(tick(2)) as h and tick(3) + h > 0
|
|
println("ran", h)
|
|
println(calls)
|
|
calls = 0
|
|
if tick(1) > 0 and half(tick(3)) as h and tick(5) + h > 0
|
|
println("ran", h)
|
|
else
|
|
println("stopped")
|
|
println(calls)
|
|
;; x? narrows beside as in one chain.
|
|
let n: i32? = Some(40)
|
|
if n? and half(n) as h and n + h > 50
|
|
println(n + h)
|
|
if half(6) as h and n? and n + h > 40
|
|
println(n + h)
|
|
;; while: pop while the next cell is empty.
|
|
let i = 1
|
|
let seen = 0
|
|
while get-cell(grid, i) as c and is-empty-cell(c)
|
|
seen += c.color-idx
|
|
i += 2
|
|
println(seen, i)
|