Function: cconv-make-interpreted-closure
cconv-make-interpreted-closure is a byte-compiled function defined in
cconv.el.gz.
Signature
(cconv-make-interpreted-closure FUN ENV)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/cconv.el.gz
(defun cconv-make-interpreted-closure (fun env)
(cl-assert (eq (car-safe fun) 'lambda))
(let ((lexvars (delq nil (mapcar #'car-safe env))))
(if (null lexvars)
;; The lexical environment is empty, so there's no need to
;; look for free variables.
`(closure ,env . ,(cdr fun))
;; We could try and cache the result of the macroexpansion and
;; `cconv-fv' analysis. Not sure it's worth the trouble.
(let* ((form `#',fun)
(expanded-form
(let ((lexical-binding t) ;; Tell macros which dialect is in use.
;; Make the macro aware of any defvar declarations in scope.
(macroexp--dynvars
(if macroexp--dynvars
(append env macroexp--dynvars) env)))
(macroexpand-all form macroexpand-all-environment)))
;; Since we macroexpanded the body, we may as well use that.
(expanded-fun-cdr
(pcase expanded-form
(`#'(lambda . ,cdr) cdr)
(_ (cdr fun))))
(dynvars (delq nil (mapcar (lambda (b) (if (symbolp b) b)) env)))
(fvs (cconv-fv expanded-form lexvars dynvars))
(newenv (nconc (mapcar (lambda (fv) (assq fv env)) (car fvs))
(cdr fvs))))
;; Never return a nil env, since nil means to use the dynbind
;; dialect of ELisp.
`(closure ,(or newenv '(t)) . ,expanded-fun-cdr)))))