; Iter 16b.2 — LetRec captures of fn-params (path-1 safe subset).
; `sum_below(n)` returns the sum of integers from 1 up to but not
; including n. The recursive helper `loop` captures the upper
; bound `n` from `sum_below`'s param list and recurses on its own
; counter `i`. The 16b.2 desugar pass lifts `loop` to a synthetic
; top-level fn `loop$lr_0(i: Int, n: Int) -> Int` (capture appended)
; and rewrites every `(app loop ARGS)` to `(app loop$lr_0 ARGS n)`.
;
; Expected stdout (one per line): 0 (sum below 1), 10 (1+2+3+4),
; 45 (1+2+...+9).

(module local_rec_capture

  (fn sum_below
    (doc "Sum 1 + 2 + ... + (n-1). Helper captures n from the enclosing scope.")
    (type (fn-type (params (own (con Int))) (ret (own (con Int)))))
    (params n)
    (body
      (let-rec loop
        (params i)
        (type (fn-type (params (own (con Int))) (ret (own (con Int)))))
        (body
          (if (app ge i n)
            0
            (app + i (app loop (app + i 1)))))
        (in (app loop 1)))))

  (fn main
    (doc "Drive sum_below at 1, 5, 10. Expected (per line): 0, 10, 45.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (seq (seq (app print (app sum_below 1)) (do io/print_str "\n"))
      (seq (seq (app print (app sum_below 5)) (do io/print_str "\n"))
           (seq (app print (app sum_below 10)) (do io/print_str "\n")))))))
