|
|
1.1 root 1: ;; Compilation of Lisp code into byte code.
2: ;; Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc.
3:
4: ;; This file is part of GNU Emacs.
5:
6: ;; GNU Emacs is free software; you can redistribute it and/or modify
7: ;; it under the terms of the GNU General Public License as published by
8: ;; the Free Software Foundation; either version 1, or (at your option)
9: ;; any later version.
10:
11: ;; GNU Emacs is distributed in the hope that it will be useful,
12: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: ;; GNU General Public License for more details.
15:
16: ;; You should have received a copy of the GNU General Public License
17: ;; along with GNU Emacs; see the file COPYING. If not, write to
18: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19:
20: (provide 'byte-compile)
21:
22: (defvar byte-compile-constnum -1
23: "Transfer vector index of last constant allocated.")
24: (defvar byte-compile-constants nil
25: "Alist describing contents to put in transfer vector.
26: Each element is (CONTENTS . INDEX)")
27: (defvar byte-compile-macro-environment nil
28: "Alist of (MACRONAME . DEFINITION) macros defined in the file
29: which is being compiled.")
30: (defvar byte-compile-pc 0
31: "Index in byte string to store next opcode at.")
32: (defvar byte-compile-output nil
33: "Alist describing contents to put in byte code string.
34: Each element is (INDEX . VALUE)")
35: (defvar byte-compile-depth 0
36: "Current depth of execution stack.")
37: (defvar byte-compile-maxdepth 0
38: "Maximum depth of execution stack.")
39:
40: (defconst byte-varref 8
41: "Byte code opcode for variable reference.")
42: (defconst byte-varset 16
43: "Byte code opcode for setting a variable.")
44: (defconst byte-varbind 24
45: "Byte code opcode for binding a variable.")
46: (defconst byte-call 32
47: "Byte code opcode for calling a function.")
48: (defconst byte-unbind 40
49: "Byte code opcode for unbinding special bindings.")
50:
51: (defconst byte-constant 192
52: "Byte code opcode for reference to a constant.")
53: (defconst byte-constant-limit 64
54: "Maximum index usable in byte-constant opcode.")
55:
56: (defconst byte-constant2 129
57: "Byte code opcode for reference to a constant with vector index >= 0100.")
58:
59: (defconst byte-goto 130
60: "Byte code opcode for unconditional jump")
61:
62: (defconst byte-goto-if-nil 131
63: "Byte code opcode for pop value and jump if it's nil.")
64:
65: (defconst byte-goto-if-not-nil 132
66: "Byte code opcode for pop value and jump if it's not nil.")
67:
68: (defconst byte-goto-if-nil-else-pop 133
69: "Byte code opcode for examine top-of-stack, jump and don't pop it if it's nil,
70: otherwise pop it.")
71:
72: (defconst byte-goto-if-not-nil-else-pop 134
73: "Byte code opcode for examine top-of-stack, jump and don't pop it if it's not nil,
74: otherwise pop it.")
75:
76: (defconst byte-return 135
77: "Byte code opcode for pop value and return it from byte code interpreter.")
78:
79: (defconst byte-discard 136
80: "Byte code opcode to discard one value from stack.")
81:
82: (defconst byte-dup 137
83: "Byte code opcode to duplicate the top of the stack.")
84:
85: (defconst byte-save-excursion 138
86: "Byte code opcode to make a binding to record the buffer, point and mark.")
87:
88: (defconst byte-save-window-excursion 139
89: "Byte code opcode to make a binding to record entire window configuration.")
90:
91: (defconst byte-save-restriction 140
92: "Byte code opcode to make a binding to record the current buffer clipping restrictions.")
93:
94: (defconst byte-catch 141
95: "Byte code opcode for catch. Takes, on stack, the tag and an expression for the body.")
96:
97: (defconst byte-unwind-protect 142
98: "Byte code opcode for unwind-protect. Takes, on stack, an expression for the body
99: and an expression for the unwind-action.")
100:
101: (defconst byte-condition-case 143
102: "Byte code opcode for condition-case. Takes, on stack, the variable to bind,
103: an expression for the body, and a list of clauses.")
104:
105: (defconst byte-temp-output-buffer-setup 144
106: "Byte code opcode for entry to with-output-to-temp-buffer.
107: Takes, on stack, the buffer name.
108: Binds standard-output and does some other things.
109: Returns with temp buffer on the stack in place of buffer name.")
110:
111: (defconst byte-temp-output-buffer-show 145
112: "Byte code opcode for exit from with-output-to-temp-buffer.
113: Expects the temp buffer on the stack underneath value to return.
114: Pops them both, then pushes the value back on.
115: Unbinds standard-output and makes the temp buffer visible.")
116:
117: (defconst byte-nth 56)
118: (defconst byte-symbolp 57)
119: (defconst byte-consp 58)
120: (defconst byte-stringp 59)
121: (defconst byte-listp 60)
122: (defconst byte-eq 61)
123: (defconst byte-memq 62)
124: (defconst byte-not 63)
125: (defconst byte-car 64)
126: (defconst byte-cdr 65)
127: (defconst byte-cons 66)
128: (defconst byte-list1 67)
129: (defconst byte-list2 68)
130: (defconst byte-list3 69)
131: (defconst byte-list4 70)
132: (defconst byte-length 71)
133: (defconst byte-aref 72)
134: (defconst byte-aset 73)
135: (defconst byte-symbol-value 74)
136: (defconst byte-symbol-function 75)
137: (defconst byte-set 76)
138: (defconst byte-fset 77)
139: (defconst byte-get 78)
140: (defconst byte-substring 79)
141: (defconst byte-concat2 80)
142: (defconst byte-concat3 81)
143: (defconst byte-concat4 82)
144: (defconst byte-sub1 83)
145: (defconst byte-add1 84)
146: (defconst byte-eqlsign 85)
147: (defconst byte-gtr 86)
148: (defconst byte-lss 87)
149: (defconst byte-leq 88)
150: (defconst byte-geq 89)
151: (defconst byte-diff 90)
152: (defconst byte-negate 91)
153: (defconst byte-plus 92)
154: (defconst byte-max 93)
155: (defconst byte-min 94)
156:
157: (defconst byte-point 96)
158: ;(defconst byte-mark 97) no longer generated -- lisp code shouldn't call this very frequently
159: (defconst byte-goto-char 98)
160: (defconst byte-insert 99)
161: (defconst byte-point-max 100)
162: (defconst byte-point-min 101)
163: (defconst byte-char-after 102)
164: (defconst byte-following-char 103)
165: (defconst byte-preceding-char 104)
166: (defconst byte-current-column 105)
167: (defconst byte-indent-to 106)
168: ;(defconst byte-scan-buffer 107) no longer generated
169: (defconst byte-eolp 108)
170: (defconst byte-eobp 109)
171: (defconst byte-bolp 110)
172: (defconst byte-bobp 111)
173: (defconst byte-current-buffer 112)
174: (defconst byte-set-buffer 113)
175: (defconst byte-read-char 114)
176: ;(defconst byte-set-mark 115) ;obsolete
177: (defconst byte-interactive-p 116)
178:
179: (defun byte-recompile-directory (directory &optional arg)
180: "Recompile every .el file in DIRECTORY that needs recompilation.
181: This is if a .elc file exists but is older than the .el file.
182: If the .elc file does not exist, offer to compile the .el file
183: only if a prefix argument has been specified."
184: (interactive "DByte recompile directory: \nP")
185: (save-some-buffers)
186: (setq directory (expand-file-name directory))
187: (let ((files (directory-files directory nil "\\.el\\'"))
188: (count 0)
189: source dest)
190: (while files
191: (if (and (not (auto-save-file-name-p (car files)))
192: (setq source (expand-file-name (car files) directory))
193: (setq dest (concat (file-name-sans-versions source) "c"))
194: (if (file-exists-p dest)
195: (file-newer-than-file-p source dest)
196: (and arg (y-or-n-p (concat "Compile " source "? ")))))
197: (progn (byte-compile-file source)
198: (setq count (1+ count))))
199: (setq files (cdr files)))
200: (message "Done (Total of %d file%s compiled)"
201: count (if (= count 1) "" "s"))))
202:
203: (defun byte-compile-file (filename)
204: "Compile a file of Lisp code named FILENAME into a file of byte code.
205: The output file's name is made by appending \"c\" to the end of FILENAME."
206: (interactive "fByte compile file: ")
207: ;; Expand now so we get the current buffer's defaults
208: (setq filename (expand-file-name filename))
209: (message "Compiling %s..." filename)
210: (let ((inbuffer (get-buffer-create " *Compiler Input*"))
211: (outbuffer (get-buffer-create " *Compiler Output*"))
212: (byte-compile-macro-environment nil)
213: (case-fold-search nil)
214: sexp)
215: (save-excursion
216: (set-buffer inbuffer)
217: (erase-buffer)
218: (insert-file-contents filename)
219: (goto-char 1)
220: (set-buffer outbuffer)
221: ;; Avoid running hooks; all we really want is the syntax table.
222: (let (emacs-lisp-mode-hook)
223: (emacs-lisp-mode))
224: (erase-buffer)
225: (while (save-excursion
226: (set-buffer inbuffer)
227: (while (progn (skip-chars-forward " \t\n\^l")
228: (looking-at ";"))
229: (forward-line 1))
230: (not (eobp)))
231: (setq sexp (read inbuffer))
232: (print (byte-compile-file-form sexp) outbuffer))
233: (set-buffer outbuffer)
234: (goto-char 1)
235: ;; In each defun or autoload, if there is a doc string,
236: ;; put a backslash-newline at the front of it.
237: (while (search-forward "\n(" nil t)
238: (cond ((looking-at "defun \\|autoload ")
239: (forward-sexp 3)
240: (skip-chars-forward " ")
241: (if (looking-at "\"")
242: (progn (forward-char 1)
243: (insert "\\\n"))))))
244: (goto-char 1)
245: ;; In each defconst or defvar, if there is a doc string
246: ;; and it starts on the same line as the form begins
247: ;; (i.e. if there is no newline in a string in the initial value)
248: ;; then put in backslash-newline at the start of the doc string.
249: (while (search-forward "\n(" nil t)
250: (if (looking-at "defvar \\|defconst ")
251: (let ((this-line (1- (point))))
252: ;;Go to end of initial value expression
253: (if (condition-case ()
254: (progn (forward-sexp 3) t)
255: (error nil))
256: (progn
257: (skip-chars-forward " ")
258: (and (eq this-line
259: (save-excursion (beginning-of-line) (point)))
260: (looking-at "\"")
261: (progn (forward-char 1)
262: (insert "\\\n"))))))))
263: (let ((vms-stmlf-recfm t))
264: (write-region 1 (point-max)
265: (concat (file-name-sans-versions filename) "c")))
266: (kill-buffer (current-buffer))
267: (kill-buffer inbuffer)))
268: t)
269:
270:
271: (defun byte-compile-file-form (form)
272: (cond ((not (listp form))
273: form)
274: ((memq (car form) '(defun defmacro))
275: (let* ((name (car (cdr form)))
276: (tem (assq name byte-compile-macro-environment)))
277: (if (eq (car form) 'defun)
278: (progn
279: (message "Compiling %s (%s)..." filename (nth 1 form))
280: (cond (tem (setcdr tem nil))
281: ((and (fboundp name)
282: (eq (car-safe (symbol-function name)) 'macro))
283: ;; shadow existing macro definition
284: (setq byte-compile-macro-environment
285: (cons (cons name nil)
286: byte-compile-macro-environment))))
287: (prog1 (cons 'defun (byte-compile-lambda (cdr form)))
288: (if (not noninteractive)
289: (message "Compiling %s..." filename))))
290: ;; defmacro
291: (if tem
292: (setcdr tem (cons 'lambda (cdr (cdr form))))
293: (setq byte-compile-macro-environment
294: (cons (cons name (cons 'lambda (cdr (cdr form))))
295: byte-compile-macro-environment)))
296: (cons 'defmacro (byte-compile-lambda (cdr form))))))
297: ((eq (car form) 'require)
298: (eval form)
299: form)
300: (t form)))
301:
302: (defun byte-compile (funname)
303: "Byte-compile the definition of function FUNNAME (a symbol)."
304: (if (and (fboundp funname)
305: (eq (car-safe (symbol-function funname)) 'lambda))
306: (fset funname (byte-compile-lambda (symbol-function funname)))))
307:
308: (defun byte-compile-lambda (fun)
309: (let* ((bodyptr (cdr fun))
310: (int (assq 'interactive (cdr bodyptr)))
311: newbody)
312: ;; Skip doc string.
313: (if (and (cdr (cdr bodyptr)) (stringp (car (cdr bodyptr))))
314: (setq bodyptr (cdr bodyptr)))
315: (setq newbody (list (byte-compile-top-level
316: (cons 'progn (cdr bodyptr)))))
317: (if int
318: (setq newbody (cons (if (or (stringp (car (cdr int)))
319: (null (car (cdr int))))
320: int
321: (list 'interactive
322: (byte-compile-top-level (car (cdr int)))))
323: newbody)))
324: (if (not (eq bodyptr (cdr fun)))
325: (setq newbody (cons (nth 2 fun) newbody)))
326: (cons (car fun) (cons (car (cdr fun)) newbody))))
327:
328: (defun byte-compile-top-level (form)
329: (let ((byte-compile-constants nil)
330: (byte-compile-constnum nil)
331: (byte-compile-pc 0)
332: (byte-compile-depth 0)
333: (byte-compile-maxdepth 0)
334: (byte-compile-output nil)
335: (byte-compile-string nil)
336: (byte-compile-vector nil))
337: (let (vars temp (i -1))
338: (setq temp (byte-compile-find-vars form))
339: (setq form (car temp))
340: (setq vars (nreverse (cdr temp)))
341: (while vars
342: (setq i (1+ i))
343: (setq byte-compile-constants (cons (cons (car vars) i)
344: byte-compile-constants))
345: (setq vars (cdr vars)))
346: (setq byte-compile-constnum i))
347: (byte-compile-form form)
348: (byte-compile-out 'byte-return 0)
349: (setq byte-compile-vector (make-vector (1+ byte-compile-constnum)
350: nil))
351: (while byte-compile-constants
352: (aset byte-compile-vector (cdr (car byte-compile-constants))
353: (car (car byte-compile-constants)))
354: (setq byte-compile-constants (cdr byte-compile-constants)))
355: (setq byte-compile-string (make-string byte-compile-pc 0))
356: (while byte-compile-output
357: (aset byte-compile-string (car (car byte-compile-output))
358: (cdr (car byte-compile-output)))
359: (setq byte-compile-output (cdr byte-compile-output)))
360: (list 'byte-code byte-compile-string
361: byte-compile-vector byte-compile-maxdepth)))
362:
363: ;; Expand all macros in FORM and find all variables it uses.
364: ;; Return a pair (EXPANDEDFORM . VARS)
365: ;; VARS is ordered with the variables encountered earliest
366: ;; at the end.
367: ;; The body and cases of a condition-case, and the body of a catch,
368: ;; are not scanned; variables used in them are not reported,
369: ;; and they are not macroexpanded. This is because they will
370: ;; be compiled separately when encountered during the main
371: ;; compilation pass.
372: (defun byte-compile-find-vars (form)
373: (let ((all-vars nil))
374: (cons (byte-compile-find-vars-1 form)
375: all-vars)))
376:
377: ;; Walk FORM, making sure all variables it uses are in ALL-VARS,
378: ;; and also expanding macros.
379: ;; Return the result of expanding all macros in FORM.
380: ;; This is a copy; FORM itself is not altered.
381: (defun byte-compile-find-vars-1 (form)
382: (cond ((symbolp form)
383: (if (not (memq form all-vars))
384: (setq all-vars (cons form all-vars)))
385: form)
386: ((or (not (consp form)) (eq (car form) 'quote))
387: form)
388: ((memq (car form) '(let let*))
389: (let* ((binds (copy-sequence (car (cdr form))))
390: (body (cdr (cdr form)))
391: (tail binds))
392: (while tail
393: (if (symbolp (car tail))
394: (if (not (memq (car tail) all-vars))
395: (setq all-vars (cons (car tail) all-vars)))
396: (if (consp (car tail))
397: (progn
398: (if (not (memq (car (car tail)) all-vars))
399: (setq all-vars (cons (car (car tail)) all-vars)))
400: (setcar tail
401: (list (car (car tail))
402: (byte-compile-find-vars-1 (car (cdr (car tail)))))))))
403: (setq tail (cdr tail)))
404: (cons (car form)
405: (cons binds
406: (mapcar 'byte-compile-find-vars-1 body)))))
407: ((or (eq (car form) 'function)
408: ;; Because condition-case is compiled by breaking out
409: ;; all its subexpressions and compiling them separately,
410: ;; we regard it here as containing nothing but constants.
411: (eq (car form) 'condition-case))
412: form)
413: ((eq (car form) 'catch)
414: ;; catch is almost like condition case, but we
415: ;; treat its first argument normally.
416: (cons 'catch
417: (cons (byte-compile-find-vars-1 (nth 1 form))
418: (nthcdr 2 form))))
419: ((eq (car form) 'cond)
420: (let* ((clauses (copy-sequence (cdr form)))
421: (tail clauses))
422: (while tail
423: (setcar tail (mapcar 'byte-compile-find-vars-1 (car tail)))
424: (setq tail (cdr tail)))
425: (cons 'cond clauses)))
426: ((not (eq form (setq form (macroexpand form byte-compile-macro-environment))))
427: (byte-compile-find-vars-1 form))
428: ((symbolp (car form))
429: (cons (car form) (mapcar 'byte-compile-find-vars-1 (cdr form))))
430: (t (mapcar 'byte-compile-find-vars-1 form))))
431:
432: ;; This is the recursive entry point for compiling each subform of an expression.
433:
434: ;; Note that handler functions SHOULD NOT increment byte-compile-depth
435: ;; for the values they are returning! That is done on return here.
436: ;; Handlers should make sure that the depth on exit is the same as
437: ;; it was when the handler was called.
438:
439: (defun byte-compile-form (form)
440: (setq form (macroexpand form byte-compile-macro-environment))
441: (cond ((eq form 'nil)
442: (byte-compile-constant form))
443: ((eq form 't)
444: (byte-compile-constant form))
445: ((symbolp form)
446: (byte-compile-variable-ref 'byte-varref form))
447: ((not (consp form))
448: (byte-compile-constant form))
449: ((not (symbolp (car form)))
450: (if (eq (car-safe (car form)) 'lambda)
451: (let ((vars (nth 1 (car form)))
452: (vals (cdr form))
453: result)
454: (while vars
455: (setq result (cons (list (car vars) (car vals)) result))
456: (setq vars (cdr vars) vals (cdr vals)))
457: (byte-compile-form
458: (cons 'let (cons (nreverse result) (cdr (cdr (car form)))))))
459: (byte-compile-normal-call form)))
460: (t
461: (let ((handler (get (car form) 'byte-compile)))
462: (if handler
463: (funcall handler form)
464: (byte-compile-normal-call form)))))
465: (setq byte-compile-maxdepth
466: (max byte-compile-maxdepth
467: (setq byte-compile-depth (1+ byte-compile-depth)))))
468:
469: (defun byte-compile-normal-call (form)
470: (byte-compile-push-constant (car form))
471: (let ((copy (cdr form)))
472: (while copy (byte-compile-form (car copy)) (setq copy (cdr copy))))
473: (byte-compile-out 'byte-call (length (cdr form)))
474: (setq byte-compile-depth (- byte-compile-depth (length (cdr form)))))
475:
476: (defun byte-compile-variable-ref (base-op var)
477: (let ((data (assq var byte-compile-constants)))
478: (if data
479: (byte-compile-out base-op (cdr data))
480: (error (format "Variable %s seen on pass 2 of byte compiler but not pass 1"
481: (prin1-to-string var))))))
482:
483: ;; Use this when the value of a form is a constant,
484: ;; because byte-compile-depth will be incremented accordingly
485: ;; on return to byte-compile-form, so it should not be done by the handler.
486: (defun byte-compile-constant (const)
487: (let ((data (if (stringp const)
488: (assoc const byte-compile-constants)
489: (assq const byte-compile-constants))))
490: (if data
491: (byte-compile-out-const (cdr data))
492: (setq byte-compile-constants
493: (cons (cons const (setq byte-compile-constnum (1+ byte-compile-constnum)))
494: byte-compile-constants))
495: (byte-compile-out-const byte-compile-constnum))))
496:
497: ;; Use this for a constant that is not the value of its containing form.
498: ;; Note that the calling function must explicitly decrement byte-compile-depth
499: ;; (or perhaps call byte-compile-discard to do so)
500: ;; for the word pushed by this function.
501: (defun byte-compile-push-constant (const)
502: (byte-compile-constant const)
503: (setq byte-compile-maxdepth
504: (max byte-compile-maxdepth
505: (setq byte-compile-depth (1+ byte-compile-depth)))))
506:
507: ;; Compile those primitive ordinary functions
508: ;; which have special byte codes just for speed.
509:
510: (put 'point 'byte-compile 'byte-compile-no-args)
511: (put 'point 'byte-opcode 'byte-point)
512:
513: (put 'dot 'byte-compile 'byte-compile-no-args)
514: (put 'dot 'byte-opcode 'byte-point)
515:
516: ;(put 'mark 'byte-compile 'byte-compile-no-args)
517: ;(put 'mark 'byte-opcode 'byte-mark)
518:
519: (put 'point-max 'byte-compile 'byte-compile-no-args)
520: (put 'point-max 'byte-opcode 'byte-point-max)
521:
522: (put 'point-min 'byte-compile 'byte-compile-no-args)
523: (put 'point-min 'byte-opcode 'byte-point-min)
524:
525: (put 'dot-max 'byte-compile 'byte-compile-no-args)
526: (put 'dot-max 'byte-opcode 'byte-point-max)
527:
528: (put 'dot-min 'byte-compile 'byte-compile-no-args)
529: (put 'dot-min 'byte-opcode 'byte-point-min)
530:
531: (put 'following-char 'byte-compile 'byte-compile-no-args)
532: (put 'following-char 'byte-opcode 'byte-following-char)
533:
534: (put 'preceding-char 'byte-compile 'byte-compile-no-args)
535: (put 'preceding-char 'byte-opcode 'byte-preceding-char)
536:
537: (put 'current-column 'byte-compile 'byte-compile-no-args)
538: (put 'current-column 'byte-opcode 'byte-current-column)
539:
540: (put 'eolp 'byte-compile 'byte-compile-no-args)
541: (put 'eolp 'byte-opcode 'byte-eolp)
542:
543: (put 'eobp 'byte-compile 'byte-compile-no-args)
544: (put 'eobp 'byte-opcode 'byte-eobp)
545:
546: (put 'bolp 'byte-compile 'byte-compile-no-args)
547: (put 'bolp 'byte-opcode 'byte-bolp)
548:
549: (put 'bobp 'byte-compile 'byte-compile-no-args)
550: (put 'bobp 'byte-opcode 'byte-bobp)
551:
552: (put 'current-buffer 'byte-compile 'byte-compile-no-args)
553: (put 'current-buffer 'byte-opcode 'byte-current-buffer)
554:
555: (put 'read-char 'byte-compile 'byte-compile-no-args)
556: (put 'read-char 'byte-opcode 'byte-read-char)
557:
558:
559: (put 'symbolp 'byte-compile 'byte-compile-one-arg)
560: (put 'symbolp 'byte-opcode 'byte-symbolp)
561:
562: (put 'consp 'byte-compile 'byte-compile-one-arg)
563: (put 'consp 'byte-opcode 'byte-consp)
564:
565: (put 'stringp 'byte-compile 'byte-compile-one-arg)
566: (put 'stringp 'byte-opcode 'byte-stringp)
567:
568: (put 'listp 'byte-compile 'byte-compile-one-arg)
569: (put 'listp 'byte-opcode 'byte-listp)
570:
571: (put 'not 'byte-compile 'byte-compile-one-arg)
572: (put 'not 'byte-opcode 'byte-not)
573:
574: (put 'null 'byte-compile 'byte-compile-one-arg)
575: (put 'null 'byte-opcode 'byte-not)
576:
577: (put 'car 'byte-compile 'byte-compile-one-arg)
578: (put 'car 'byte-opcode 'byte-car)
579:
580: (put 'cdr 'byte-compile 'byte-compile-one-arg)
581: (put 'cdr 'byte-opcode 'byte-cdr)
582:
583: (put 'length 'byte-compile 'byte-compile-one-arg)
584: (put 'length 'byte-opcode 'byte-length)
585:
586: (put 'symbol-value 'byte-compile 'byte-compile-one-arg)
587: (put 'symbol-value 'byte-opcode 'byte-symbol-value)
588:
589: (put 'symbol-function 'byte-compile 'byte-compile-one-arg)
590: (put 'symbol-function 'byte-opcode 'byte-symbol-function)
591:
592: (put '1+ 'byte-compile 'byte-compile-one-arg)
593: (put '1+ 'byte-opcode 'byte-add1)
594:
595: (put '1- 'byte-compile 'byte-compile-one-arg)
596: (put '1- 'byte-opcode 'byte-sub1)
597:
598: (put 'goto-char 'byte-compile 'byte-compile-one-arg)
599: (put 'goto-char 'byte-opcode 'byte-goto-char)
600:
601: (put 'char-after 'byte-compile 'byte-compile-one-arg)
602: (put 'char-after 'byte-opcode 'byte-char-after)
603:
604: (put 'set-buffer 'byte-compile 'byte-compile-one-arg)
605: (put 'set-buffer 'byte-opcode 'byte-set-buffer)
606:
607: ;set-mark turns out to be too unimportant for its own opcode.
608: ;(put 'set-mark 'byte-compile 'byte-compile-one-arg)
609: ;(put 'set-mark 'byte-opcode 'byte-set-mark)
610:
611:
612: (put 'eq 'byte-compile 'byte-compile-two-args)
613: (put 'eq 'byte-opcode 'byte-eq)
614: (put 'eql 'byte-compile 'byte-compile-two-args)
615: (put 'eql 'byte-opcode 'byte-eq)
616:
617: (put 'memq 'byte-compile 'byte-compile-two-args)
618: (put 'memq 'byte-opcode 'byte-memq)
619:
620: (put 'cons 'byte-compile 'byte-compile-two-args)
621: (put 'cons 'byte-opcode 'byte-cons)
622:
623: (put 'aref 'byte-compile 'byte-compile-two-args)
624: (put 'aref 'byte-opcode 'byte-aref)
625:
626: (put 'set 'byte-compile 'byte-compile-two-args)
627: (put 'set 'byte-opcode 'byte-set)
628:
629: (put 'fset 'byte-compile 'byte-compile-two-args)
630: (put 'fset 'byte-opcode 'byte-fset)
631:
632: (put '= 'byte-compile 'byte-compile-two-args)
633: (put '= 'byte-opcode 'byte-eqlsign)
634:
635: (put '< 'byte-compile 'byte-compile-two-args)
636: (put '< 'byte-opcode 'byte-lss)
637:
638: (put '> 'byte-compile 'byte-compile-two-args)
639: (put '> 'byte-opcode 'byte-gtr)
640:
641: (put '<= 'byte-compile 'byte-compile-two-args)
642: (put '<= 'byte-opcode 'byte-leq)
643:
644: (put '>= 'byte-compile 'byte-compile-two-args)
645: (put '>= 'byte-opcode 'byte-geq)
646:
647: (put 'get 'byte-compile 'byte-compile-two-args)
648: (put 'get 'byte-opcode 'byte-get)
649:
650: (put 'nth 'byte-compile 'byte-compile-two-args)
651: (put 'nth 'byte-opcode 'byte-nth)
652:
653: (put 'aset 'byte-compile 'byte-compile-three-args)
654: (put 'aset 'byte-opcode 'byte-aset)
655:
656: (defun byte-compile-no-args (form)
657: (if (/= (length form) 1)
658: ;; get run-time wrong-number-of-args error.
659: ;; Would be nice if there were some way to do
660: ;; compile-time warnings.
661: (byte-compile-normal-call form)
662: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0)))
663:
664: (defun byte-compile-one-arg (form)
665: (if (/= (length form) 2)
666: (byte-compile-normal-call form)
667: (byte-compile-form (car (cdr form))) ;; Push the argument
668: (setq byte-compile-depth (1- byte-compile-depth))
669: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0)))
670:
671: (defun byte-compile-two-args (form)
672: (if (/= (length form) 3)
673: (byte-compile-normal-call form)
674: (byte-compile-form (car (cdr form))) ;; Push the arguments
675: (byte-compile-form (nth 2 form))
676: (setq byte-compile-depth (- byte-compile-depth 2))
677: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0)))
678:
679: (defun byte-compile-three-args (form)
680: (if (/= (length form) 4)
681: (byte-compile-normal-call form)
682: (byte-compile-form (car (cdr form))) ;; Push the arguments
683: (byte-compile-form (nth 2 form))
684: (byte-compile-form (nth 3 form))
685: (setq byte-compile-depth (- byte-compile-depth 3))
686: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0)))
687:
688: (put 'substring 'byte-compile 'byte-compile-substring)
689: (defun byte-compile-substring (form)
690: (if (or (> (length form) 4)
691: (< (length form) 2))
692: (byte-compile-normal-call form)
693: (byte-compile-form (nth 1 form))
694: (byte-compile-form (or (nth 2 form) ''nil)) ;Optional arguments
695: (byte-compile-form (or (nth 3 form) ''nil))
696: (setq byte-compile-depth (- byte-compile-depth 3))
697: (byte-compile-out byte-substring 0)))
698:
699: (put 'interactive-p 'byte-compile 'byte-compile-interactive-p)
700: (defun byte-compile-interactive-p (form)
701: (byte-compile-out byte-interactive-p 0))
702:
703: (put 'list 'byte-compile 'byte-compile-list)
704: (defun byte-compile-list (form)
705: (let ((len (length form)))
706: (if (= len 1)
707: (byte-compile-constant nil)
708: (if (< len 6)
709: (let ((args (cdr form)))
710: (while args
711: (byte-compile-form (car args))
712: (setq args (cdr args)))
713: (setq byte-compile-depth (- byte-compile-depth (1- len)))
714: (byte-compile-out (symbol-value
715: (nth (- len 2)
716: '(byte-list1 byte-list2 byte-list3 byte-list4)))
717: 0))
718: (byte-compile-normal-call form)))))
719:
720: (put 'concat 'byte-compile 'byte-compile-concat)
721: (defun byte-compile-concat (form)
722: (let ((len (length form)))
723: (cond ((= len 1)
724: (byte-compile-form ""))
725: ((= len 2)
726: ;; Concat of one arg is not a no-op if arg is not a string.
727: (byte-compile-normal-call form))
728: ((< len 6)
729: (let ((args (cdr form)))
730: (while args
731: (byte-compile-form (car args))
732: (setq args (cdr args)))
733: (setq byte-compile-depth (- byte-compile-depth (1- len)))
734: (byte-compile-out
735: (symbol-value (nth (- len 3)
736: '(byte-concat2 byte-concat3 byte-concat4)))
737: 0)))
738: (t
739: (byte-compile-normal-call form)))))
740:
741: (put '- 'byte-compile 'byte-compile-minus)
742: (defun byte-compile-minus (form)
743: (let ((len (length form)))
744: (cond ((= len 2)
745: (byte-compile-form (car (cdr form)))
746: (setq byte-compile-depth (- byte-compile-depth 1))
747: (byte-compile-out byte-negate 0))
748: ((= len 3)
749: (byte-compile-form (car (cdr form)))
750: (byte-compile-form (nth 2 form))
751: (setq byte-compile-depth (- byte-compile-depth 2))
752: (byte-compile-out byte-diff 0))
753: (t (byte-compile-normal-call form)))))
754:
755: (put '+ 'byte-compile 'byte-compile-maybe-two-args)
756: (put '+ 'byte-opcode 'byte-plus)
757:
758: (put 'max 'byte-compile 'byte-compile-maybe-two-args)
759: (put 'max 'byte-opcode 'byte-max)
760:
761: (put 'min 'byte-compile 'byte-compile-maybe-two-args)
762: (put 'min 'byte-opcode 'byte-min)
763:
764: (defun byte-compile-maybe-two-args (form)
765: (let ((len (length form)))
766: (if (= len 3)
767: (progn
768: (byte-compile-form (car (cdr form)))
769: (byte-compile-form (nth 2 form))
770: (setq byte-compile-depth (- byte-compile-depth 2))
771: (byte-compile-out (symbol-value (get (car form) 'byte-opcode)) 0))
772: (byte-compile-normal-call form))))
773:
774: (put 'function 'byte-compile 'byte-compile-function-form)
775: (defun byte-compile-function-form (form)
776: (cond ((symbolp (car (cdr form)))
777: (byte-compile-form
778: (list 'symbol-function (list 'quote (nth 1 form)))))
779: (t
780: (byte-compile-constant (byte-compile-lambda (car (cdr form)))))))
781:
782: (put 'indent-to 'byte-compile 'byte-compile-indent-to)
783: (defun byte-compile-indent-to (form)
784: (let ((len (length form)))
785: (if (= len 2)
786: (progn
787: (byte-compile-form (car (cdr form)))
788: (setq byte-compile-depth (- byte-compile-depth 1))
789: (byte-compile-out byte-indent-to 0))
790: (byte-compile-normal-call form))))
791:
792: (put 'insert 'byte-compile 'byte-compile-insert)
793: (defun byte-compile-insert (form)
794: (let ((len (length form)))
795: (if (< len 3)
796: (let ((args (cdr form)))
797: (while args
798: (byte-compile-form (car args))
799: (setq byte-compile-depth (- byte-compile-depth 1))
800: (byte-compile-out byte-insert 0)
801: (setq args (cdr args))))
802: (byte-compile-normal-call form))))
803:
804: (put 'setq-default 'byte-compile 'byte-compile-setq-default)
805: (defun byte-compile-setq-default (form)
806: (byte-compile-form (cons 'set-default (cons (list 'quote (nth 1 form))
807: (nthcdr 2 form)))))
808:
809: (put 'quote 'byte-compile 'byte-compile-quote)
810: (defun byte-compile-quote (form)
811: (byte-compile-constant (car (cdr form))))
812:
813: (put 'setq 'byte-compile 'byte-compile-setq)
814: (defun byte-compile-setq (form)
815: (let ((args (cdr form)))
816: (if args
817: (while args
818: (byte-compile-form (car (cdr args)))
819: (if (null (cdr (cdr args)))
820: (progn
821: (byte-compile-out 'byte-dup 0)
822: (setq byte-compile-maxdepth (max byte-compile-maxdepth (1+ byte-compile-depth)))))
823: (setq byte-compile-depth (1- byte-compile-depth))
824: (byte-compile-variable-ref 'byte-varset (car args))
825: (setq args (cdr (cdr args))))
826: ;; (setq), with no arguments.
827: (byte-compile-constant nil))))
828:
829: (put 'let 'byte-compile 'byte-compile-let)
830: (defun byte-compile-let (form)
831: (let ((varlist (car (cdr form))))
832: (while varlist
833: (if (symbolp (car varlist))
834: (byte-compile-push-constant nil)
835: (byte-compile-form (car (cdr (car varlist)))))
836: (setq varlist (cdr varlist))))
837: (let ((varlist (reverse (car (cdr form)))))
838: (setq byte-compile-depth (- byte-compile-depth (length varlist)))
839: (while varlist
840: (if (symbolp (car varlist))
841: (byte-compile-variable-ref 'byte-varbind (car varlist))
842: (byte-compile-variable-ref 'byte-varbind (car (car varlist))))
843: (setq varlist (cdr varlist))))
844: (byte-compile-body (cdr (cdr form)))
845: (byte-compile-out 'byte-unbind (length (car (cdr form)))))
846:
847: (put 'let* 'byte-compile 'byte-compile-let*)
848: (defun byte-compile-let* (form)
849: (let ((varlist (car (cdr form))))
850: (while varlist
851: (if (symbolp (car varlist))
852: (byte-compile-push-constant nil)
853: (byte-compile-form (car (cdr (car varlist)))))
854: (setq byte-compile-depth (1- byte-compile-depth))
855: (if (symbolp (car varlist))
856: (byte-compile-variable-ref 'byte-varbind (car varlist))
857: (byte-compile-variable-ref 'byte-varbind (car (car varlist))))
858: (setq varlist (cdr varlist))))
859: (byte-compile-body (cdr (cdr form)))
860: (byte-compile-out 'byte-unbind (length (car (cdr form)))))
861:
862: (put 'save-excursion 'byte-compile 'byte-compile-save-excursion)
863: (defun byte-compile-save-excursion (form)
864: (byte-compile-out 'byte-save-excursion 0)
865: (byte-compile-body (cdr form))
866: (byte-compile-out 'byte-unbind 1))
867:
868: (put 'save-restriction 'byte-compile 'byte-compile-save-restriction)
869: (defun byte-compile-save-restriction (form)
870: (byte-compile-out 'byte-save-restriction 0)
871: (byte-compile-body (cdr form))
872: (byte-compile-out 'byte-unbind 1))
873:
874: (put 'with-output-to-temp-buffer 'byte-compile 'byte-compile-with-output-to-temp-buffer)
875: (defun byte-compile-with-output-to-temp-buffer (form)
876: (byte-compile-form (car (cdr form)))
877: (byte-compile-out 'byte-temp-output-buffer-setup 0)
878: (byte-compile-body (cdr (cdr form)))
879: (byte-compile-out 'byte-temp-output-buffer-show 0)
880: (setq byte-compile-depth (1- byte-compile-depth)))
881:
882: (put 'progn 'byte-compile 'byte-compile-progn)
883: (defun byte-compile-progn (form)
884: (byte-compile-body (cdr form)))
885:
886: (put 'interactive 'byte-compile 'byte-compile-noop)
887: (defun byte-compile-noop (form)
888: (byte-compile-constant nil))
889:
890: (defun byte-compile-body (body)
891: (if (null body)
892: (byte-compile-constant nil)
893: (while body
894: (byte-compile-form (car body))
895: (if (cdr body)
896: (byte-compile-discard)
897: ;; Convention is this will be counted after we return.
898: (setq byte-compile-depth (1- byte-compile-depth)))
899: (setq body (cdr body)))))
900:
901: (put 'prog1 'byte-compile 'byte-compile-prog1)
902: (defun byte-compile-prog1 (form)
903: (byte-compile-form (car (cdr form)))
904: (if (cdr (cdr form))
905: (progn
906: (byte-compile-body (cdr (cdr form)))
907: ;; This discards the value pushed by ..-body
908: ;; (which is not counted now in byte-compile-depth)
909: ;; and decrements byte-compile-depth for the value
910: ;; pushed by byte-compile-form above, which by convention
911: ;; will be counted in byte-compile-depth after we return.
912: (byte-compile-discard))))
913:
914: (put 'prog2 'byte-compile 'byte-compile-prog2)
915: (defun byte-compile-prog2 (form)
916: (byte-compile-form (car (cdr form)))
917: (byte-compile-discard)
918: (byte-compile-form (nth 2 form))
919: (if (cdr (cdr (cdr form)))
920: (progn
921: (byte-compile-body (cdr (cdr (cdr form))))
922: (byte-compile-discard))))
923:
924: (defun byte-compile-discard ()
925: (byte-compile-out 'byte-discard 0)
926: (setq byte-compile-depth (1- byte-compile-depth)))
927:
928: (put 'if 'byte-compile 'byte-compile-if)
929: (defun byte-compile-if (form)
930: (if (null (nthcdr 3 form))
931: ;; No else-forms
932: (let ((donetag (byte-compile-make-tag)))
933: (byte-compile-form (car (cdr form)))
934: (byte-compile-goto 'byte-goto-if-nil-else-pop donetag)
935: (setq byte-compile-depth (1- byte-compile-depth))
936: (byte-compile-form (nth 2 form))
937: (setq byte-compile-depth (1- byte-compile-depth))
938: (byte-compile-out-tag donetag))
939: (let ((donetag (byte-compile-make-tag)) (elsetag (byte-compile-make-tag)))
940: (byte-compile-form (car (cdr form)))
941: (byte-compile-goto 'byte-goto-if-nil elsetag)
942: (setq byte-compile-depth (1- byte-compile-depth))
943: (byte-compile-form (nth 2 form))
944: (setq byte-compile-depth (1- byte-compile-depth))
945: (byte-compile-goto 'byte-goto donetag)
946: (byte-compile-out-tag elsetag)
947: (byte-compile-body (cdr (cdr (cdr form))))
948: (byte-compile-out-tag donetag))))
949:
950: (put 'cond 'byte-compile 'byte-compile-cond)
951: (defun byte-compile-cond (form)
952: (if (cdr form)
953: (byte-compile-cond-1 (cdr form))
954: (byte-compile-constant nil)))
955:
956: (defun byte-compile-cond-1 (clauses)
957: (if (or (eq (car (car clauses)) t)
958: (and (eq (car-safe (car (car clauses))) 'quote)
959: (car-safe (cdr-safe (car (car clauses))))))
960: ;; Unconditional clause
961: (if (cdr (car clauses))
962: (byte-compile-body (cdr (car clauses)))
963: (byte-compile-form (car (car clauses))))
964: (if (null (cdr clauses))
965: ;; Only one clause
966: (let ((donetag (byte-compile-make-tag)))
967: (byte-compile-form (car (car clauses)))
968: (cond ((cdr (car clauses))
969: (byte-compile-goto 'byte-goto-if-nil-else-pop donetag)
970: (setq byte-compile-depth (1- byte-compile-depth))
971: (byte-compile-body (cdr (car clauses)))
972: (byte-compile-out-tag donetag))))
973: (let ((donetag (byte-compile-make-tag))
974: (elsetag (byte-compile-make-tag)))
975: (byte-compile-form (car (car clauses)))
976: (if (null (cdr (car clauses)))
977: ;; First clause is a singleton.
978: (progn
979: (byte-compile-goto 'byte-goto-if-not-nil-else-pop donetag)
980: (setq byte-compile-depth (1- byte-compile-depth)))
981: (byte-compile-goto 'byte-goto-if-nil elsetag)
982: (setq byte-compile-depth (1- byte-compile-depth))
983: (byte-compile-body (cdr (car clauses)))
984: (byte-compile-goto 'byte-goto donetag)
985: (byte-compile-out-tag elsetag))
986: (byte-compile-cond-1 (cdr clauses))
987: (byte-compile-out-tag donetag)))))
988:
989: (put 'and 'byte-compile 'byte-compile-and)
990: (defun byte-compile-and (form)
991: (let ((failtag (byte-compile-make-tag))
992: (args (cdr form)))
993: (if (null args)
994: (progn
995: (byte-compile-form t)
996: (setq byte-compile-depth (1- byte-compile-depth)))
997: (while args
998: (byte-compile-form (car args))
999: (setq byte-compile-depth (1- byte-compile-depth))
1000: (if (null (cdr args))
1001: (byte-compile-out-tag failtag)
1002: (byte-compile-goto 'byte-goto-if-nil-else-pop failtag))
1003: (setq args (cdr args))))))
1004:
1005: (put 'or 'byte-compile 'byte-compile-or)
1006: (defun byte-compile-or (form)
1007: (let ((wintag (byte-compile-make-tag))
1008: (args (cdr form)))
1009: (if (null args)
1010: (byte-compile-constant nil)
1011: (while args
1012: (byte-compile-form (car args))
1013: (setq byte-compile-depth (1- byte-compile-depth))
1014: (if (null (cdr args))
1015: (byte-compile-out-tag wintag)
1016: (byte-compile-goto 'byte-goto-if-not-nil-else-pop wintag))
1017: (setq args (cdr args))))))
1018:
1019: (put 'while 'byte-compile 'byte-compile-while)
1020: (defun byte-compile-while (form)
1021: (let ((endtag (byte-compile-make-tag))
1022: (looptag (byte-compile-make-tag))
1023: (args (cdr (cdr form))))
1024: (byte-compile-out-tag looptag)
1025: (byte-compile-form (car (cdr form)))
1026: (byte-compile-goto 'byte-goto-if-nil-else-pop endtag)
1027: (byte-compile-body (cdr (cdr form)))
1028: (byte-compile-discard)
1029: (byte-compile-goto 'byte-goto looptag)
1030: (byte-compile-out-tag endtag)))
1031:
1032: (put 'catch 'byte-compile 'byte-compile-catch)
1033: (defun byte-compile-catch (form)
1034: (byte-compile-form (car (cdr form)))
1035: (byte-compile-push-constant (byte-compile-top-level (cons 'progn (cdr (cdr form)))))
1036: (setq byte-compile-depth (- byte-compile-depth 2))
1037: (byte-compile-out 'byte-catch 0))
1038:
1039: (put 'save-window-excursion 'byte-compile 'byte-compile-save-window-excursion)
1040: (defun byte-compile-save-window-excursion (form)
1041: (byte-compile-push-constant
1042: (list (byte-compile-top-level (cons 'progn (cdr form)))))
1043: (setq byte-compile-depth (1- byte-compile-depth))
1044: (byte-compile-out 'byte-save-window-excursion 0))
1045:
1046: (put 'unwind-protect 'byte-compile 'byte-compile-unwind-protect)
1047: (defun byte-compile-unwind-protect (form)
1048: (byte-compile-push-constant
1049: (list (byte-compile-top-level (cons 'progn (cdr (cdr form))))))
1050: (setq byte-compile-depth (1- byte-compile-depth))
1051: (byte-compile-out 'byte-unwind-protect 0)
1052: (byte-compile-form (car (cdr form)))
1053: (setq byte-compile-depth (1- byte-compile-depth))
1054: (byte-compile-out 'byte-unbind 1))
1055:
1056: (put 'condition-case 'byte-compile 'byte-compile-condition-case)
1057: (defun byte-compile-condition-case (form)
1058: (byte-compile-push-constant (car (cdr form)))
1059: (byte-compile-push-constant (byte-compile-top-level (nth 2 form)))
1060: (let ((clauses (cdr (cdr (cdr form))))
1061: compiled-clauses)
1062: (while clauses
1063: (let ((clause (car clauses)))
1064: (setq compiled-clauses
1065: (cons (list (car clause)
1066: (byte-compile-top-level (cons 'progn (cdr clause))))
1067: compiled-clauses)))
1068: (setq clauses (cdr clauses)))
1069: (byte-compile-push-constant (nreverse compiled-clauses)))
1070: (setq byte-compile-depth (- byte-compile-depth 3))
1071: (byte-compile-out 'byte-condition-case 0))
1072:
1073: (defun byte-compile-make-tag ()
1074: (cons nil nil))
1075:
1076: (defun byte-compile-out-tag (tag)
1077: (let ((uses (car tag)))
1078: (setcar tag byte-compile-pc)
1079: (while uses
1080: (byte-compile-store-goto (car uses) byte-compile-pc)
1081: (setq uses (cdr uses)))))
1082:
1083: (defun byte-compile-goto (opcode tag)
1084: (byte-compile-out opcode 0)
1085: (if (integerp (car tag))
1086: (byte-compile-store-goto byte-compile-pc (car tag))
1087: (setcar tag (cons byte-compile-pc (car tag))))
1088: (setq byte-compile-pc (+ byte-compile-pc 2)))
1089:
1090: (defun byte-compile-store-goto (at-pc to-pc)
1091: (setq byte-compile-output
1092: (cons (cons at-pc (logand to-pc 255))
1093: byte-compile-output))
1094: (setq byte-compile-output
1095: (cons (cons (1+ at-pc) (lsh to-pc -8))
1096: byte-compile-output)))
1097:
1098: (defun byte-compile-out (opcode offset)
1099: (setq opcode (eval opcode))
1100: (if (< offset 6)
1101: (byte-compile-out-1 (+ opcode offset))
1102: (if (< offset 256)
1103: (progn
1104: (byte-compile-out-1 (+ opcode 6))
1105: (byte-compile-out-1 offset))
1106: (byte-compile-out-1 (+ opcode 7))
1107: (byte-compile-out-1 (logand offset 255))
1108: (byte-compile-out-1 (lsh offset -8)))))
1109:
1110: (defun byte-compile-out-const (offset)
1111: (if (< offset byte-constant-limit)
1112: (byte-compile-out-1 (+ byte-constant offset))
1113: (byte-compile-out-1 byte-constant2)
1114: (byte-compile-out-1 (logand offset 255))
1115: (byte-compile-out-1 (lsh offset -8))))
1116:
1117: (defun byte-compile-out-1 (code)
1118: (setq byte-compile-output
1119: (cons (cons byte-compile-pc code)
1120: byte-compile-output))
1121: (setq byte-compile-pc (1+ byte-compile-pc)))
1122:
1123: ;;; by [email protected]
1124: ;;; Only works noninteractively.
1125: (defun batch-byte-compile ()
1126: "Runs byte-compile-file on the files remaining on the command line.
1127: Must be used only with -batch, and kills emacs on completion.
1128: Each file will be processed even if an error occurred previously.
1129: For example, invoke \"emacs -batch -f batch-byte-compile $emacs/ ~/*.el\""
1130: ;; command-line-args-left is what is left of the command line (from startup.el)
1131: (if (not noninteractive)
1132: (error "batch-byte-compile is to be used only with -batch"))
1133: (let ((error nil))
1134: (while command-line-args-left
1135: (if (file-directory-p (expand-file-name (car command-line-args-left)))
1136: (let ((files (directory-files (car command-line-args-left)))
1137: source dest)
1138: (while files
1139: (if (and (string-match ".el$" (car files))
1140: (not (auto-save-file-name-p (car files)))
1141: (setq source (expand-file-name (car files)
1142: (car command-line-args-left)))
1143: (setq dest (concat (file-name-sans-versions source) "c"))
1144: (file-exists-p dest)
1145: (file-newer-than-file-p source dest))
1146: (if (null (batch-byte-compile-file source))
1147: (setq error t)))
1148: (setq files (cdr files))))
1149: (if (null (batch-byte-compile-file (car command-line-args-left)))
1150: (setq error t)))
1151: (setq command-line-args-left (cdr command-line-args-left)))
1152: (message "Done")
1153: (kill-emacs (if error 1 0))))
1154:
1155: (defun batch-byte-compile-file (file)
1156: (condition-case err
1157: (progn (byte-compile-file file) t)
1158: (error
1159: (message (if (cdr err)
1160: ">>Error occurred processing %s: %s (%s)"
1161: ">>Error occurred processing %s: %s")
1162: file
1163: (get (car err) 'error-message)
1164: (prin1-to-string (cdr err)))
1165: nil)))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.