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