Function: cconv-fv

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

Signature

(cconv-fv FORM LEXVARS DYNVARS)

Documentation

Return the free variables used in FORM.

FORM is usually a function #'(lambda ...), but may be any valid form. LEXVARS is a list of symbols, each of which is lexically bound in FORM's context. DYNVARS is a list of symbols, each of which is dynamically bound in FORM's context. Returns a cons (LEXV . DYNV), the car and cdr being lists of the lexically and dynamically bound symbols 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 free variables used in FORM.
FORM is usually a function #\\='(lambda ...), but may be any valid
form.  LEXVARS is a list of symbols, each of which is lexically
bound in FORM's context.  DYNVARS is a list of symbols, each of
which is dynamically bound in FORM's context.
Returns a cons (LEXV . DYNV), the car and cdr being lists of the
lexically and dynamically bound symbols 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)))))