Update FSF's address.
[bpt/emacs.git] / lisp / emacs-lisp / bytecomp.el
index 22592eb..d602eae 100644 (file)
@@ -1,6 +1,6 @@
 ;;; bytecomp.el --- compilation of Lisp code into byte code.
 
-;;; Copyright (C) 1985, 1986, 1987, 1992, 1994 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1992, 1994 Free Software Foundation, Inc.
 
 ;; Author: Jamie Zawinski <jwz@lucid.com>
 ;;     Hallvard Furuseth <hbf@ulrik.uio.no>
@@ -25,8 +25,9 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
 
 ;;; Commentary:
 
 
 ;;; Code:
 
-;;; ========================================================================
-;;; Entry points:
-;;;    byte-recompile-directory, byte-compile-file,
-;;;     batch-byte-compile, batch-byte-recompile-directory,
-;;;    byte-compile, compile-defun,
-;;;    display-call-tree
-;;; (byte-compile-buffer and byte-compile-and-load-file were turned off
-;;;  because they are not terribly useful and get in the way of completion.)
-
-;;; This version of the byte compiler has the following improvements:
-;;;  + optimization of compiled code:
-;;;    - removal of unreachable code;
-;;;    - removal of calls to side-effectless functions whose return-value
-;;;      is unused;
-;;;    - compile-time evaluation of safe constant forms, such as (consp nil)
-;;;      and (ash 1 6);
-;;;    - open-coding of literal lambdas;
-;;;    - peephole optimization of emitted code;
-;;;    - trivial functions are left uncompiled for speed.
-;;;  + support for inline functions;
-;;;  + compile-time evaluation of arbitrary expressions;
-;;;  + compile-time warning messages for:
-;;;    - functions being redefined with incompatible arglists;
-;;;    - functions being redefined as macros, or vice-versa;
-;;;    - functions or macros defined multiple times in the same file;
-;;;    - functions being called with the incorrect number of arguments;
-;;;    - functions being called which are not defined globally, in the 
-;;;      file, or as autoloads;
-;;;    - assignment and reference of undeclared free variables;
-;;;    - various syntax errors;
-;;;  + correct compilation of nested defuns, defmacros, defvars and defsubsts;
-;;;  + correct compilation of top-level uses of macros;
-;;;  + the ability to generate a histogram of functions called.
-
-;;; User customization variables:
-;;;
-;;; byte-compile-verbose       Whether to report the function currently being
-;;;                            compiled in the minibuffer;
-;;; byte-optimize              Whether to do optimizations; this may be 
-;;;                            t, nil, 'source, or 'byte;
-;;; byte-optimize-log          Whether to report (in excruciating detail) 
-;;;                            exactly which optimizations have been made.
-;;;                            This may be t, nil, 'source, or 'byte;
-;;; byte-compile-error-on-warn Whether to stop compilation when a warning is
-;;;                            produced;
-;;; byte-compile-delete-errors Whether the optimizer may delete calls or
-;;;                            variable references that are side-effect-free
-;;;                            except that they may return an error.
-;;; byte-compile-generate-call-tree    Whether to generate a histogram of
-;;;                            function calls.  This can be useful for 
-;;;                            finding unused functions, as well as simple
-;;;                            performance metering.
-;;; byte-compile-warnings      List of warnings to issue, or t.  May contain
-;;;                            'free-vars (references to variables not in the
-;;;                                        current lexical scope)
-;;;                            'unresolved (calls to unknown functions)
-;;;                            'callargs  (lambda calls with args that don't
-;;;                                        match the lambda's definition)
-;;;                            'redefine  (function cell redefined from
-;;;                                        a macro to a lambda or vice versa,
-;;;                                        or redefined to take other args)
-;;;                            'obsolete  (obsolete variables and functions)
-;;; byte-compile-compatibility Whether the compiler should
-;;;                            generate .elc files which can be loaded into
-;;;                            generic emacs 18.
-;;; emacs-lisp-file-regexp     Regexp for the extension of source-files;
-;;;                            see also the function byte-compile-dest-file.
-
-;;; New Features:
-;;;
-;;;  o The form `defsubst' is just like `defun', except that the function
-;;;    generated will be open-coded in compiled code which uses it.  This
-;;;    means that no function call will be generated, it will simply be
-;;;    spliced in.  Lisp functions calls are very slow, so this can be a
-;;;    big win.
-;;;
-;;;    You can generally accomplish the same thing with `defmacro', but in
-;;;    that case, the defined procedure can't be used as an argument to
-;;;    mapcar, etc.
-;;;
-;;;  o You can also open-code one particular call to a function without
-;;;    open-coding all calls.  Use the 'inline' form to do this, like so:
-;;;
-;;;            (inline (foo 1 2 3))    ;; `foo' will be open-coded
-;;;    or...
-;;;            (inline                 ;;  `foo' and `baz' will be 
-;;;             (foo 1 2 3 (bar 5))    ;; open-coded, but `bar' will not.
-;;;             (baz 0))
-;;;
-;;;  o It is possible to open-code a function in the same file it is defined
-;;;    in without having to load that file before compiling it.  the
-;;;    byte-compiler has been modified to remember function definitions in
-;;;    the compilation environment in the same way that it remembers macro
-;;;    definitions.
-;;;
-;;;  o  Forms like ((lambda ...) ...) are open-coded.
-;;;
-;;;  o  The form `eval-when-compile' is like progn, except that the body
-;;;     is evaluated at compile-time.  When it appears at top-level, this
-;;;     is analogous to the Common Lisp idiom (eval-when (compile) ...).
-;;;     When it does not appear at top-level, it is similar to the
-;;;     Common Lisp #. reader macro (but not in interpreted code).
-;;;
-;;;  o  The form `eval-and-compile' is similar to eval-when-compile, but
-;;;    the whole form is evalled both at compile-time and at run-time.
-;;;
-;;;  o  The command compile-defun is analogous to eval-defun.
-;;;
-;;;  o  If you run byte-compile-file on a filename which is visited in a 
-;;;     buffer, and that buffer is modified, you are asked whether you want
-;;;     to save the buffer before compiling.
-;;;
-;;;  o  byte-compiled files now start with the string `;ELC'.
-;;;     Some versions of `file' can be customized to recognize that.
+;; ========================================================================
+;; Entry points:
+;;     byte-recompile-directory, byte-compile-file,
+;;     batch-byte-compile, batch-byte-recompile-directory,
+;;     byte-compile, compile-defun,
+;;     display-call-tree
+;; (byte-compile-buffer and byte-compile-and-load-file were turned off
+;;  because they are not terribly useful and get in the way of completion.)
+
+;; This version of the byte compiler has the following improvements:
+;;  + optimization of compiled code:
+;;    - removal of unreachable code;
+;;    - removal of calls to side-effectless functions whose return-value
+;;      is unused;
+;;    - compile-time evaluation of safe constant forms, such as (consp nil)
+;;      and (ash 1 6);
+;;    - open-coding of literal lambdas;
+;;    - peephole optimization of emitted code;
+;;    - trivial functions are left uncompiled for speed.
+;;  + support for inline functions;
+;;  + compile-time evaluation of arbitrary expressions;
+;;  + compile-time warning messages for:
+;;    - functions being redefined with incompatible arglists;
+;;    - functions being redefined as macros, or vice-versa;
+;;    - functions or macros defined multiple times in the same file;
+;;    - functions being called with the incorrect number of arguments;
+;;    - functions being called which are not defined globally, in the 
+;;      file, or as autoloads;
+;;    - assignment and reference of undeclared free variables;
+;;    - various syntax errors;
+;;  + correct compilation of nested defuns, defmacros, defvars and defsubsts;
+;;  + correct compilation of top-level uses of macros;
+;;  + the ability to generate a histogram of functions called.
+
+;; User customization variables:
+;;
+;; byte-compile-verbose        Whether to report the function currently being
+;;                             compiled in the minibuffer;
+;; byte-optimize               Whether to do optimizations; this may be 
+;;                             t, nil, 'source, or 'byte;
+;; byte-optimize-log           Whether to report (in excruciating detail) 
+;;                             exactly which optimizations have been made.
+;;                             This may be t, nil, 'source, or 'byte;
+;; byte-compile-error-on-warn  Whether to stop compilation when a warning is
+;;                             produced;
+;; byte-compile-delete-errors  Whether the optimizer may delete calls or
+;;                             variable references that are side-effect-free
+;;                             except that they may return an error.
+;; byte-compile-generate-call-tree     Whether to generate a histogram of
+;;                             function calls.  This can be useful for 
+;;                             finding unused functions, as well as simple
+;;                             performance metering.
+;; byte-compile-warnings       List of warnings to issue, or t.  May contain
+;;                             'free-vars (references to variables not in the
+;;                                         current lexical scope)
+;;                             'unresolved (calls to unknown functions)
+;;                             'callargs  (lambda calls with args that don't
+;;                                         match the lambda's definition)
+;;                             'redefine  (function cell redefined from
+;;                                         a macro to a lambda or vice versa,
+;;                                         or redefined to take other args)
+;;                             'obsolete  (obsolete variables and functions)
+;; byte-compile-compatibility  Whether the compiler should
+;;                             generate .elc files which can be loaded into
+;;                             generic emacs 18.
+;; emacs-lisp-file-regexp      Regexp for the extension of source-files;
+;;                             see also the function byte-compile-dest-file.
+
+;; New Features:
+;;
+;;  o  The form `defsubst' is just like `defun', except that the function
+;;     generated will be open-coded in compiled code which uses it.  This
+;;     means that no function call will be generated, it will simply be
+;;     spliced in.  Lisp functions calls are very slow, so this can be a
+;;     big win.
+;;
+;;     You can generally accomplish the same thing with `defmacro', but in
+;;     that case, the defined procedure can't be used as an argument to
+;;     mapcar, etc.
+;;
+;;  o  You can also open-code one particular call to a function without
+;;     open-coding all calls.  Use the 'inline' form to do this, like so:
+;;
+;;             (inline (foo 1 2 3))    ;; `foo' will be open-coded
+;;     or...
+;;             (inline                 ;;  `foo' and `baz' will be 
+;;              (foo 1 2 3 (bar 5))    ;; open-coded, but `bar' will not.
+;;              (baz 0))
+;;
+;;  o  It is possible to open-code a function in the same file it is defined
+;;     in without having to load that file before compiling it.  the
+;;     byte-compiler has been modified to remember function definitions in
+;;     the compilation environment in the same way that it remembers macro
+;;     definitions.
+;;
+;;  o  Forms like ((lambda ...) ...) are open-coded.
+;;
+;;  o  The form `eval-when-compile' is like progn, except that the body
+;;     is evaluated at compile-time.  When it appears at top-level, this
+;;     is analogous to the Common Lisp idiom (eval-when (compile) ...).
+;;     When it does not appear at top-level, it is similar to the
+;;     Common Lisp #. reader macro (but not in interpreted code).
+;;
+;;  o  The form `eval-and-compile' is similar to eval-when-compile, but
+;;     the whole form is evalled both at compile-time and at run-time.
+;;
+;;  o  The command compile-defun is analogous to eval-defun.
+;;
+;;  o  If you run byte-compile-file on a filename which is visited in a 
+;;     buffer, and that buffer is modified, you are asked whether you want
+;;     to save the buffer before compiling.
+;;
+;;  o  byte-compiled files now start with the string `;ELC'.
+;;     Some versions of `file' can be customized to recognize that.
 
 (require 'backquote)
 
@@ -938,7 +939,7 @@ otherwise pop it")
 (defun byte-compile-arglist-signatures-congruent-p (old new)
   (not (or
         (> (car new) (car old))  ; requires more args now
-        (and (null (cdr old))    ; tooks rest-args, doesn't any more
+        (and (null (cdr old))    ; took rest-args, doesn't any more
              (cdr new))
         (and (cdr new) (cdr old) ; can't take as many args now
              (< (cdr new) (cdr old)))
@@ -1122,7 +1123,14 @@ otherwise pop it")
 
 \f
 ;;;###autoload
-(defun byte-recompile-directory (directory &optional arg)
+(defun byte-force-recompile (directory)
+  "Recompile every `.el' file in DIRECTORY that already has a `.elc' file.
+Files in subdirectories of DIRECTORY are processed also."
+  (interactive "DByte force recompile (directory): ")
+  (byte-recompile-directory directory nil t))
+
+;;;###autoload
+(defun byte-recompile-directory (directory &optional arg force)
   "Recompile every `.el' file in DIRECTORY that needs recompilation.
 This is if a `.elc' file exists but is older than the `.el' file.
 Files in subdirectories of DIRECTORY are processed also.
@@ -1132,7 +1140,10 @@ But a prefix argument (optional second arg) means ask user,
 for each such `.el' file, whether to compile it.  Prefix argument 0 means
 don't ask and compile the file anyway.
 
-A nonzero prefix argument also means ask about each subdirectory."
+A nonzero prefix argument also means ask about each subdirectory.
+
+If the third argument FORCE is non-nil,
+recompile every `.el' file that already has a `.elc' file."
   (interactive "DByte recompile directory: \nP")
   (if arg
       (setq arg (prefix-numeric-value arg)))
@@ -1155,16 +1166,20 @@ A nonzero prefix argument also means ask about each subdirectory."
           (if (and (not (member (car files) '("." ".." "RCS" "CVS")))
                    (file-directory-p source)
                    (not (file-symlink-p source)))
+              ;; This file is a subdirectory.  Handle them differently.
               (if (or (null arg)
                       (eq 0 arg)
                       (y-or-n-p (concat "Check " source "? ")))
                   (setq directories
                         (nconc directories (list source))))
+            ;; It is an ordinary file.  Decide whether to compile it.
             (if (and (string-match emacs-lisp-file-regexp source)
                      (not (auto-save-file-name-p source))
                      (setq dest (byte-compile-dest-file source))
                      (if (file-exists-p dest)
-                         (file-newer-than-file-p source dest)
+                         ;; File was already compiled.
+                         (or force (file-newer-than-file-p source dest))
+                       ;; No compiled file exists yet.
                        (and arg
                             (or (eq 0 arg)
                                 (y-or-n-p (concat "Compile " source "? "))))))
@@ -1322,6 +1337,7 @@ With argument, insert value in current buffer after the form."
        (float-output-format nil)
        (case-fold-search nil)
        (print-length nil)
+       (print-level nil)
        ;; Simulate entry to byte-compile-top-level
        (byte-compile-constants nil)
        (byte-compile-variables nil)
@@ -1366,7 +1382,7 @@ With argument, insert value in current buffer after the form."
        ;; Compile pending forms at end of file.
        (byte-compile-flush-pending)
        (byte-compile-warn-about-unresolved-functions)
-       ;; SHould we always do this?  When calling multiple files, it
+       ;; Should we always do this?  When calling multiple files, it
        ;; would be useful to delay this warning until all have
        ;; been compiled.
        (setq byte-compile-unresolved-functions nil))))
@@ -1471,6 +1487,7 @@ list that represents a doc string reference.
         ;; Insert the doc string, and make it a comment with #@LENGTH.
         (and (>= (nth 1 info) 0)
              dynamic-docstrings
+             (not byte-compile-compatibility)
              (progn
                ;; Make the doc string start at beginning of line
                ;; for make-docfile's sake.
@@ -1890,9 +1907,16 @@ If FORM is a lambda or a macro, byte-compile it as a function."
                  ;; If the interactive spec is a call to `list',
                  ;; don't compile it, because `call-interactively'
                  ;; looks at the args of `list'.
-                 (or (eq (car-safe (nth 1 int)) 'list)
-                     (setq int (list 'interactive
-                                     (byte-compile-top-level (nth 1 int))))))
+                 (let ((form (nth 1 int)))
+                   (while (or (eq (car-safe form) 'let)
+                              (eq (car-safe form) 'let*)
+                              (eq (car-safe form) 'save-excursion))
+                     (while (consp (cdr form))
+                       (setq form (cdr form)))
+                     (setq form (car form)))
+                   (or (eq (car-safe form) 'list)
+                       (setq int (list 'interactive
+                                       (byte-compile-top-level (nth 1 int)))))))
                 ((cdr int)
                  (byte-compile-warn "malformed interactive spec: %s"
                                     (prin1-to-string int))))))
@@ -2403,13 +2427,18 @@ If FORM is a lambda or a macro, byte-compile it as a function."
 
 
 ;; Compile a function that accepts one or more args and is right-associative.
+;; We do it by left-associativity so that the operations
+;; are done in the same order as in interpreted code.
 (defun byte-compile-associative (form)
   (if (cdr form)
-      (let ((opcode (get (car form) 'byte-opcode)))
-       ;; To compile all the args first may enable some optimizations.
-       (mapcar 'byte-compile-form (setq form (cdr form)))
-       (while (setq form (cdr form))
-         (byte-compile-out opcode 0)))
+      (let ((opcode (get (car form) 'byte-opcode))
+           (args (copy-sequence (cdr form))))
+       (byte-compile-form (car args))
+       (setq args (cdr args))
+       (while args
+         (byte-compile-form (car args))
+         (byte-compile-out opcode 0)
+         (setq args (cdr args))))
     (byte-compile-constant (eval form))))
 
 \f