;; @ignore
;; A helper method for the c{plet} macro. Given a list of pairs,
;; (pattern datum), plet-make-bindings transforms it into a pair
;; of "let" bindings s.t.:
;; 1. the car of the pair is a list of p:match invocations
;; bound to named match results. For example:
;; ((@mr0 (p:match '(?a . ?b) p1)) (@mr1 (p:match '(?c . ?d) p2)))
;; 2. the cdr is a list of pattern variable bindings, e.g.:
;; ((a (match-result:get @mr0 'a))
;; (b (match-result:get @mr0 'b))
;; (c (match-result:get @mr1 'c))
;; (d (match-result:get @mr1 'd)))
(define (plet-make-bindings pattern-pairs rename)
(let lp
((i 0)
(pattern-pairs pattern-pairs))
(cond ((null? pattern-pairs) (cons () ()))
(else
(let* ((first-pair (first pattern-pairs))
(pattern (car first-pair))
(datum (cadr first-pair))
(compiled (p:compile pattern))
(mr (rename (string->symbol (string-append "@mr" (number->string i)))))
(vars (matcher:variables compiled))
(bindings (map (lambda (var)
(list var `(match-result:get ,mr (quote ,var))))
vars))
(next-bindings (lp (1+ i) (cdr pattern-pairs))))
(cons (cons `(,mr (p:assert-match ,(list 'quasiquote pattern) ,datum))
(car next-bindings))
(append bindings (cdr next-bindings))))))))