#lang racket/base
(require (for-syntax racket/base
                     syntax/stx)
         "match-a-pattern.rkt"
         racket/match)

(provide extract-clauses
         extracted-clauses->fns)

(define-for-syntax extracted-conditions #f)
(define-syntax (extract-clauses stx)
  (syntax-case stx (match-a-pattern)
    [(_ (match-a-pattern #:allow-else p clauses ...))
     (begin
       (set! extracted-conditions
             (cons #'p
                   (filter
                    values
                    (map
                     (λ (clause)
                       (syntax-case clause (else)
                         [[cond #f] #f]
                         [[`(name id pat) if-part]
                          [eq? 'name (syntax-e #'name)]
                          #f] ;; skip this here, want bound variant for pat* - added in pat-unify
                         [[else exp ...] #f] ;; skip the cstr test; that's added elsewhere
                         [[cond not-false ...] #'cond]))
                     (syntax->list #'(clauses ...))))))
       (stx-car (stx-cdr stx)))]))

(define-syntax (extracted-clauses->fns stx)
  (unless extracted-conditions
    (raise-syntax-error #f "no pats extracted"))
  (with-syntax ([(p condition ...) extracted-conditions]
                [(name ...) (map (λ (x) (string->symbol (format "~s" (syntax->datum x))))
                                 (cdr extracted-conditions))])
    #`(list 
       (let ([name (λ (p) (match p [condition #t] [else #f]))])
         name) ...)))
