;; search test helpers — convert forced haskell values to plain SX and run
;; programs built on top of search/src. Reuses hk-test / counters from
;; lib/haskell/testlib.sx (preloaded by the conformance config).

;; Recursively turn a forced HK value into plain SX:
;;   cons-list  -> SX list,  Tuple -> SX list,  leaves unchanged.
(define
  search-hk->sx
  (fn
    (v)
    (cond
      ((and (list? v) (not (empty? v)) (= (first v) "[]")) (list))
      ((and (list? v) (not (empty? v)) (= (first v) ":"))
        (cons
          (search-hk->sx (nth v 1))
          (search-hk->sx (nth v 2))))
      ((and (list? v) (not (empty? v)) (= (first v) "Tuple"))
        (map search-hk->sx (rest v)))
      (:else v))))

;; Evaluate `extra` (extra top-level Haskell bindings) on top of search/src
;; and return binding `name` as plain SX.
(define
  search-eval
  (fn
    (extra name)
    (search-hk->sx
      (hk-deep-force
        (get (hk-eval-program (hk-core (str search/src extra))) name)))))

(define
  search-join
  (fn
    (sep xs)
    (cond
      ((empty? xs) "")
      ((empty? (rest xs)) (first xs))
      (:else (str (first xs) sep (search-join sep (rest xs)))))))

;; Batch many haskell expressions into ONE program evaluation (amortizes the
;; cost of parsing/binding search/src — important under heavy CPU load).
;; `setup` is extra top-level Haskell; `exprs` is a list of expression strings
;; whose results form a single haskell list. Returns the SX list of results.
(define
  search-batch
  (fn
    (setup exprs)
    (search-eval
      (str setup "\nresult = [" (search-join ", " exprs) "]\n")
      "result")))
