(module main)

(struct NumericRecord
  (wide i64)
  (ratio f64))

(fn make_record ((wide i64) (ratio f64)) -> NumericRecord
  (NumericRecord (wide wide) (ratio ratio)))

(fn literal_record () -> NumericRecord
  (NumericRecord (wide 2147483648i64) (ratio 3.5)))

(fn echo_record ((record NumericRecord)) -> NumericRecord
  record)

(fn local_record ((wide i64) (ratio f64)) -> NumericRecord
  (let record NumericRecord (make_record wide ratio))
  (echo_record record))

(fn record_wide ((record NumericRecord)) -> i64
  (. record wide))

(fn record_ratio ((record NumericRecord)) -> f64
  (. record ratio))

(fn wide_total ((record NumericRecord)) -> i64
  (+ (. record wide) 10i64))

(fn ratio_total ((record NumericRecord)) -> f64
  (+ (. record ratio) 1.5))

(fn wide_in_range ((record NumericRecord)) -> bool
  (if (> (. record wide) 2147483640i64)
    (< (. record wide) 2147483660i64)
    false))

(fn ratio_in_range ((record NumericRecord)) -> bool
  (if (> (. record ratio) 3.0)
    (< (. record ratio) 4.0)
    false))

(fn wide_text ((record NumericRecord)) -> string
  (std.num.i64_to_string (. record wide)))

(fn ratio_text ((record NumericRecord)) -> string
  (std.num.f64_to_string (. record ratio)))

(test "numeric struct i64 field access"
  (= (record_wide (literal_record)) 2147483648i64))

(test "numeric struct f64 field access"
  (= (record_ratio (literal_record)) 3.5))

(test "numeric struct i64 arithmetic after access"
  (= (wide_total (literal_record)) 2147483658i64))

(test "numeric struct f64 arithmetic after access"
  (= (ratio_total (literal_record)) 5.0))

(test "numeric struct i64 comparison after access"
  (wide_in_range (literal_record)))

(test "numeric struct f64 comparison after access"
  (ratio_in_range (literal_record)))

(test "numeric struct local param return call flow"
  (= (wide_total (local_record 2147483648i64 3.5)) 2147483658i64))

(test "numeric struct i64 format after access"
  (= (wide_text (literal_record)) "2147483648"))

(test "numeric struct f64 format after access"
  (= (ratio_text (literal_record)) "3.5"))

(fn main () -> i32
  (std.io.print_i64 (record_wide (literal_record)))
  (std.io.print_f64 (record_ratio (literal_record)))
  (if (wide_in_range (local_record 2147483648i64 3.5))
    (if (ratio_in_range (local_record 2147483648i64 3.5))
      0
      1)
    1))
