Function: cconv-fv

cconv-fv is a byte-compiled function defined in cconv.el.gz.

Signature

(cconv-fv FORM LEXVARS DYNVARS)

Documentation

Return the list of free variables in FORM.

LEXVARS is the list of statically scoped vars in the context and DYNVARS is the list of dynamically scoped vars in the context. Returns a pair (LEXV . DYNV) of those vars actually used by FORM.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/cconv.el.gz
(defun cconv-fv (form lexvars dynvars)
  "Return the list of free variables in FORM.
LEXVARS is the list of statically scoped vars in the context
and DYNVARS is the list of dynamically scoped vars in the context.
Returns a pair (LEXV . DYNV) of those vars actually used by FORM."
  (let* ((fun
          ;; Wrap FORM into a function because the analysis code we
          ;; have only computes freevars for functions.
          ;; In practice FORM is always already of the form
          ;; #'(lambda ...), so optimize for this case.
          (if (and (eq 'function (car-safe form))
                   (eq 'lambda (car-safe (cadr form)))
                   ;; To get correct results, FUN needs to be a "simple lambda"
                   ;; without nested forms that aren't part of the body.  :-(
                   (not (assq 'interactive (cadr form)))
                   (not (assq ':documentation (cadr form))))
              form
            `#'(lambda () ,form)))
         (analysis-env (mapcar (lambda (v) (list v nil nil nil nil)) lexvars))
         (cconv--dynbound-variables dynvars)
         (byte-compile-lexical-variables nil)
         (cconv--dynbindings nil)
         (cconv-freevars-alist '())
	 (cconv-var-classification '()))
    (let* ((body (cddr (cadr fun))))
      ;; Analyze form - fill these variables with new information.
      (cconv-analyze-form fun analysis-env)
      (setq cconv-freevars-alist (nreverse cconv-freevars-alist))
      (unless (equal (if (eq :documentation (car-safe (car body)))
                            (cdr body) body)
                     (caar cconv-freevars-alist))
        (message "BOOH!\n%S\n%S"
                 body (caar cconv-freevars-alist)))
      (cl-assert (equal (if (eq :documentation (car-safe (car body)))
                            (cdr body) body)
                        (caar cconv-freevars-alist)))
      (let ((fvs (nreverse (cdar cconv-freevars-alist)))
            (dyns (delq nil (mapcar (lambda (var) (car (memq var dynvars)))
                                    (delete-dups cconv--dynbindings)))))
        (cons fvs dyns)))))