Function: rx--expand-template
rx--expand-template is a byte-compiled function defined in rx.el.gz.
Signature
(rx--expand-template OP VALUES ARGLIST TEMPLATE)
Documentation
Return TEMPLATE with variables in ARGLIST replaced with VALUES.
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/rx.el.gz
;; FIXME: Consider adding extensions in Lisp macro style, where
;; arguments are passed unevaluated to code that returns the rx form
;; to use. Example:
;;
;; (rx-let ((radix-digit (radix)
;; :lisp (list 'any (cons ?0 (+ ?0 (eval radix) -1)))))
;; (rx (radix-digit (+ 5 3))))
;; =>
;; "[0-7]"
;;
;; While this would permit more powerful extensions, it's unclear just
;; how often they would be used in practice. Let's wait until there is
;; demand for it.
;; FIXME: An alternative binding syntax would be
;;
;; (NAME RXs...)
;; and
;; ((NAME ARGS...) RXs...)
;;
;; which would have two minor advantages: multiple RXs with implicit
;; `seq' in the definition, and the arglist is no longer an optional
;; element in the middle of the list. On the other hand, it's less
;; like traditional lisp arglist constructs (defun, defmacro).
;; Since it's a Scheme-like syntax, &rest parameters could be done using
;; dotted lists:
;; (rx-let (((name arg1 arg2 . rest) ...definition...)) ...)
(defun rx--expand-template (op values arglist template)
"Return TEMPLATE with variables in ARGLIST replaced with VALUES."
(let ((bindings nil)
(value-tail values)
(formals arglist))
(while formals
(pcase (car formals)
('&rest
(unless (cdr formals)
(error
"Expanding rx def `%s': missing &rest parameter name" op))
(push (cons (cadr formals) value-tail) bindings)
(setq formals nil)
(setq value-tail nil))
(name
(unless value-tail
(error
"Expanding rx def `%s': too few arguments (got %d, need %s%d)"
op (length values)
(if (memq '&rest arglist) "at least " "")
(- (length arglist) (length (memq '&rest arglist)))))
(push (cons name (list (car value-tail))) bindings)
(setq value-tail (cdr value-tail))))
(setq formals (cdr formals)))
(when value-tail
(error
"Expanding rx def `%s': too many arguments (got %d, need %d)"
op (length values) (length arglist)))
(let ((subst (rx--substitute bindings template)))
(if (and subst (not (cdr subst)))
(car subst)
(error "Expanding rx def `%s': must result in a single value" op)))))