(module main)

(fn make_i32_values ((base i32)) -> (array i32 3)
  (array i32 base (+ base 1) (+ base 2)))

(fn make_i64_values ((base i64)) -> (array i64 3)
  (array i64 base (+ base 1i64) (+ base 2i64)))

(fn make_f64_values ((base f64)) -> (array f64 3)
  (array f64 base (+ base 1.0) (+ base 2.0)))

(fn make_flags ((first bool)) -> (array bool 3)
  (array bool first false true))

(fn i32_at ((values (array i32 3)) (i i32)) -> i32
  (index values i))

(fn i64_at ((values (array i64 3)) (i i32)) -> i64
  (index values i))

(fn f64_at ((values (array f64 3)) (i i32)) -> f64
  (index values i))

(fn bool_at ((values (array bool 3)) (i i32)) -> bool
  (index values i))

(fn i64_local_array_flow ((i i32)) -> i64
  (let values (array i64 3) (make_i64_values 40i64))
  (i64_at values i))

(fn f64_parameter_local_copy ((values (array f64 3)) (i i32)) -> f64
  (let copy (array f64 3) values)
  (index copy i))

(fn echo_flags ((values (array bool 3))) -> (array bool 3)
  values)

(fn bool_call_return_index ((i i32)) -> bool
  (index (make_flags true) i))

(test "i32 array parameter value flow"
  (= (i32_at (make_i32_values 7) 0) 7))

(test "i64 array local call value flow"
  (= (i64_local_array_flow 2) 42i64))

(test "f64 array parameter local copy"
  (= (f64_parameter_local_copy (make_f64_values 4.0) 1) 5.0))

(test "bool array dynamic index"
  (bool_at (make_flags true) 2))

(test "bool array return call value flow"
  (index (echo_flags (make_flags false)) 2))

(fn main () -> i32
  (if (bool_call_return_index 0)
    0
    1))
