; Iter 16c — lit patterns at top level and inside Ctor sub-patterns.
; `classify` matches an Int against three lit arms (0, 1, default).
; `categorize_first` matches a List<Int>: empty -> -1, head==0 -> 0,
; otherwise the head value. The latter exercises Pat-Lit nested
; inside Pat-Ctor's first field. Both shapes are now handled by the
; 16c desugar pass; codegen sees only If/Match-on-Ctor combinations.
;
; Iter 16d update — the chain machinery's terminator is now the
; polymorphic `__unreachable__` builtin (`forall a. a`, lowered to
; LLVM `unreachable`) instead of a `Unit` literal. That removed the
; pre-16d need for a trailing `(case _ 0)` arm in `categorize_first`
; whose only purpose was to dominate the synthetic `Unit`-typed
; terminator. The two ctor arms (`Nil` and `Cons h _`) are
; exhaustive on `IntList`; the chain default is never reached.
;
; Expected stdout (one per line): 100, 200, 999, -1, 0, 7.

(module lit_pat

  (data IntList
    (ctor Nil)
    (ctor Cons (con Int) (con IntList)))

  (fn classify
    (doc "Map 0->100, 1->200, anything else->999.")
    (type (fn-type (params (own (con Int))) (ret (own (con Int)))))
    (params n)
    (body
      (match n
        (case (pat-lit 0) 100)
        (case (pat-lit 1) 200)
        (case _ 999))))

  (fn categorize_first
    (doc "Empty -> -1; first element 0 -> 0; otherwise return the head.")
    (type (fn-type (params (borrow (con IntList))) (ret (own (con Int)))))
    (params xs)
    (body
      (match xs
        (case (pat-ctor Nil) -1)
        (case (pat-ctor Cons (pat-lit 0) _) 0)
        (case (pat-ctor Cons h _) h))))

  (fn main
    (doc "Drive both fns. Expected (per line): 100, 200, 999, -1, 0, 7.")
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (seq (seq (app print (app classify 0)) (do io/print_str "\n"))
      (seq (seq (app print (app classify 1)) (do io/print_str "\n"))
      (seq (seq (app print (app classify 17)) (do io/print_str "\n"))
      (seq (seq (app print (app categorize_first (term-ctor IntList Nil))) (do io/print_str "\n"))
      (seq (seq (app print (app categorize_first (term-ctor IntList Cons 0 (term-ctor IntList Nil)))) (do io/print_str "\n"))
           (seq (app print (app categorize_first (term-ctor IntList Cons 7 (term-ctor IntList Nil)))) (do io/print_str "\n"))))))))))
