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)))))