Function: byte-compile-form
byte-compile-form is a byte-compiled function defined in
bytecomp.el.gz.
Signature
(byte-compile-form FORM &optional FOR-EFFECT)
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/bytecomp.el.gz
;; This is the recursive entry point for compiling each subform of an
;; expression.
;; If for-effect is non-nil, byte-compile-form will output a byte-discard
;; before terminating (ie no value will be left on the stack).
;; A byte-compile handler may, when byte-compile--for-effect is non-nil, choose
;; output code which does not leave a value on the stack, and then set
;; byte-compile--for-effect to nil (to prevent byte-compile-form from
;; outputting the byte-discard).
;; If a handler wants to call another handler, it should do so via
;; byte-compile-form, or take extreme care to handle byte-compile--for-effect
;; correctly. (Use byte-compile-form-do-effect to reset the
;; byte-compile--for-effect flag too.)
;;
(defun byte-compile-form (form &optional for-effect)
(let ((byte-compile--for-effect for-effect))
(push form byte-compile-form-stack)
(cond
((not (consp form))
(cond ((or (not (symbolp form)) (macroexp--const-symbol-p form))
(byte-compile-constant form))
((and byte-compile--for-effect byte-compile-delete-errors)
(setq byte-compile--for-effect nil))
(t (byte-compile-variable-ref form))))
((symbolp (car form))
(let* ((fn (car form))
(handler (get fn 'byte-compile))
(interactive-only
(or (get fn 'interactive-only)
(memq fn byte-compile-interactive-only-functions))))
(when (memq fn '(set symbol-value run-hooks ;; add-to-list
add-hook remove-hook run-hook-with-args
run-hook-with-args-until-success
run-hook-with-args-until-failure))
(pcase (cdr form)
(`(',var . ,_)
(when (memq var byte-compile-lexical-variables)
(byte-compile-report-error
(format-message "%s cannot use lexical var `%s'" fn var))))))
;; Warn about using obsolete hooks.
(if (memq fn '(add-hook remove-hook))
(let ((hook (car-safe (cdr form))))
(if (eq (car-safe hook) 'quote)
(byte-compile-check-variable (cadr hook) nil))))
(when (and (byte-compile-warning-enabled-p 'suspicious)
(macroexp--const-symbol-p fn))
(byte-compile-warn-x fn "`%s' called as a function" fn))
(when (and (byte-compile-warning-enabled-p 'interactive-only fn)
interactive-only)
(byte-compile-warn-x fn "`%s' is for interactive use only%s"
fn
(cond ((stringp interactive-only)
(format "; %s"
(substitute-command-keys
interactive-only)))
((and (symbolp 'interactive-only)
(not (eq interactive-only t)))
(format-message "; use `%s' instead."
interactive-only))
(t "."))))
(if (eq (car-safe (symbol-function (car form))) 'macro)
(byte-compile-report-error
(format "`%s' defined after use in %S (missing `require' of a library file?)"
(car form) form)))
(if (and handler
;; Make sure that function exists.
(and (functionp handler)
;; Ignore obsolete byte-compile function used by former
;; CL code to handle compiler macros (we do it
;; differently now).
(not (eq handler 'cl-byte-compile-compiler-macro))))
(funcall handler form)
(byte-compile-normal-call form))))
((and (byte-code-function-p (car form))
(memq byte-optimize '(t lap)))
(byte-compile-unfold-bcf form))
((and (eq (car-safe (car form)) 'lambda)
;; if the form comes out the same way it went in, that's
;; because it was malformed, and we couldn't unfold it.
(not (eq form (setq form (macroexp--unfold-lambda form)))))
(byte-compile-form form byte-compile--for-effect)
(setq byte-compile--for-effect nil))
((byte-compile-normal-call form)))
(if byte-compile--for-effect
(byte-compile-discard))
(pop byte-compile-form-stack)))