Function: macroexp--unfold-lambda
macroexp--unfold-lambda is a byte-compiled function defined in
macroexp.el.gz.
Signature
(macroexp--unfold-lambda FORM &optional NAME)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/macroexp.el.gz
(defun macroexp--unfold-lambda (form &optional name)
(or name (setq name "anonymous lambda"))
(pcase form
((or `(funcall (function ,lambda) . ,actuals) `(,lambda . ,actuals))
(let* ((formals (nth 1 lambda))
(body (cdr (macroexp-parse-body (cddr lambda))))
optionalp restp
(dynboundarg nil)
bindings)
;; FIXME: The checks below do not belong in an optimization phase.
(while formals
(if (macroexp--dynamic-variable-p (car formals))
(setq dynboundarg t))
(cond ((eq (car formals) '&optional)
;; ok, I'll let this slide because funcall_lambda() does...
;; (if optionalp (error "Multiple &optional keywords in %s" name))
(if restp (error "&optional found after &rest in %s" name))
(if (null (cdr formals))
(error "Nothing after &optional in %s" name))
(setq optionalp t))
((eq (car formals) '&rest)
;; ...but it is by no stretch of the imagination a reasonable
;; thing that funcall_lambda() allows (&rest x y) and
;; (&rest x &optional y) in formalss.
(if (null (cdr formals))
(error "Nothing after &rest in %s" name))
(if (cdr (cdr formals))
(error "Multiple vars after &rest in %s" name))
(setq restp t))
(restp
(setq bindings (cons (list (car formals)
(and actuals (cons 'list actuals)))
bindings)
actuals nil))
((and (not optionalp) (null actuals))
(setq formals nil actuals 'too-few))
(t
(setq bindings (cons (list (car formals) (car actuals))
bindings)
actuals (cdr actuals))))
(setq formals (cdr formals)))
(cond
(actuals
(macroexp-warn-and-return
(format-message
(if (eq actuals 'too-few)
"attempt to open-code `%s' with too few arguments"
"attempt to open-code `%s' with too many arguments")
name)
form nil nil formals))
;; In lexical-binding mode, let and functions don't bind vars in
;; the same way (let obey special-variable-p, but functions
;; don't). So if one of the vars is declared as dynamically scoped, we
;; can't just convert the call to `let'.
;; FIXME: We should α-rename the affected args and then use `let'.
(dynboundarg form)
(bindings `(let ,(nreverse bindings) . ,body))
(t (macroexp-progn body)))))
(_ (error "Not an unfoldable form: %S" form))))