flan/test/syntax/handwritten/chain-mixed.fln

77 lines
1.8 KiB
Plaintext

;;;; A comparison chain that mixes < with <=, or > with >=, is the and of its
;;;; neighbouring tests, evaluated as a < b < c is. Every operand below comes
;;;; through mark, which prints its tag, so each tag line is a transcript:
;;;; each operand runs exactly once, in source order, even after a false test.
once calls = 0
fn mark(tag: str, v: i32) -> i32
calls += 1
print(tag)
v
fn line(b: bool) -> ()
print(" -> ")
println(b)
; A name is read where it stands, before a call to its right changes it.
once level = 0
fn raise() -> i32
level = 10
5
fn dyn-mark(tag, v)
print(tag)
v
fn in-grid(r: i32, rows: i32) -> bool = 0 <= r < rows
fn dyn-between(lo, x, hi) = lo <= x < hi
fn main() -> i32
print(in-grid(0, 3))
print(" ")
print(in-grid(2, 3))
print(" ")
print(in-grid(3, 3))
print(" ")
print(in-grid(-1, 3))
println("")
let a = 1
let b = 2
let c = 2
let d = 5
print(a < b <= c < d)
print(" ")
print(a < b <= c < 2)
print(" ")
print(d >= c > 1)
print(" ")
print(d >= c > 2)
println("")
; A middle operand that is a call runs once although two tests name it.
line(mark("a", 1) < mark("b", 2) <= mark("c", 2))
line(mark("a", 1) < mark("b", 2) <= mark("c", 1))
; The first test is false, and every operand still runs.
line(mark("a", 3) < mark("b", 2) <= mark("c", 5))
line(mark("a", 1) <= mark("b", 2) < mark("c", 3) <= mark("d", 3))
line(mark("a", 9) >= mark("b", 5) > mark("c", 7) >= mark("d", 0))
println(calls)
; The same over dyn operands.
print(dyn-between(0, 0, 3))
print(" ")
print(dyn-between(0, 3, 3))
print(" ")
print(dyn-between(1.5, 2, 2.5))
println("")
line(dyn-mark("p", 1) < dyn-mark("q", 2) <= dyn-mark("r", 2))
line(dyn-mark("p", 5) < dyn-mark("q", 2) <= dyn-mark("r", 9))
print(level < raise() <= 7)
level = 0
print(" ")
println(<(level, raise(), 7))
0