;; Tests for let-match — CEK special form and bytecode compiler desugaring
;; let-match destructures a dict: (let-match {:key var} expr body...)

(deftest "let-match destructures dict"
  (let-match {:name n :age a} (dict :name "alice" :age 30)
    (assert= n "alice")
    (assert= a 30)))

(deftest "let-match inside let"
  (let ((data (dict :status "ok" :value 42)))
    (let-match {:status s :value v} data
      (assert= s "ok")
      (assert= v 42))))

(deftest "let-match missing key gives nil"
  (let-match {:present p :missing m} (dict :present "yes")
    (assert= p "yes")
    (assert= m nil)))

(deftest "let-match body evaluates all expressions"
  (let ((result nil))
    (let-match {:a a} (dict :a 1)
      (set! result a)
      (assert= result 1))))

;; In function body — tests bytecode compiler desugaring path
(define lm-add (fn (d) (let-match {:x x :y y} d (+ x y))))

(deftest "let-match in compiled function"
  (assert= (lm-add (dict :x 3 :y 7)) 10))

(define lm-format (fn (input) (let-match {:type t :value v} input (str t ":" v))))

(deftest "let-match variant 2 in compiled function"
  (assert= (lm-format (dict :type "num" :value 5)) "num:5"))

;; Nested let-match
(deftest "nested let-match"
  (let-match {:outer o} (dict :outer (dict :inner 99))
    (let-match {:inner i} o
      (assert= i 99))))

;; let-match with computed expression
(deftest "let-match with function call as expr"
  (let-match {:a a :b b} (dict :a (+ 1 2) :b (* 3 4))
    (assert= a 3)
    (assert= b 12)))
