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