Replace "Maintainer: FSF" with the emacs-devel mailing address
[bpt/emacs.git] / lisp / emacs-lisp / backquote.el
CommitLineData
b035a678 1;;; backquote.el --- implement the ` Lisp construct
b578f267 2
ba318903 3;; Copyright (C) 1990, 1992, 1994, 2001-2014 Free Software Foundation,
ab422c4d 4;; Inc.
c0274f38 5
41ea659a 6;; Author: Rick Sladkey <jrs@world.std.com>
34dc21db 7;; Maintainer: emacs-devel@gnu.org
41ea659a 8;; Keywords: extensions, internal
bd78fa1d 9;; Package: emacs
9750e079 10
be010748 11;; This file is part of GNU Emacs.
c440e42b 12
d6cba7ae 13;; GNU Emacs is free software: you can redistribute it and/or modify
c440e42b 14;; it under the terms of the GNU General Public License as published by
d6cba7ae
GM
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
c440e42b
RS
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
d6cba7ae 24;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
c440e42b 25
be010748 26;;; Commentary:
41ea659a 27
574cb02e
RS
28;; When the Lisp reader sees `(...), it generates (\` (...)).
29;; When it sees ,... inside such a backquote form, it generates (\, ...).
30;; For ,@... it generates (\,@ ...).
31
288f95bd 32;; This backquote will generate calls to the backquote-list* form.
41ea659a
RS
33;; Both a function version and a macro version are included.
34;; The macro version is used by default because it is faster
35;; and needs no run-time support. It should really be a subr.
c440e42b 36
e5167999 37;;; Code:
c440e42b 38
49116ac0
JB
39(provide 'backquote)
40
288f95bd 41;; function and macro versions of backquote-list*
41ea659a 42
288f95bd 43(defun backquote-list*-function (first &rest list)
41ea659a
RS
44 "Like `list' but the last argument is the tail of the new list.
45
288f95bd 46For example (backquote-list* 'a 'b 'c) => (a b . c)"
1de9630d
SM
47 ;; The recursive solution is much nicer:
48 ;; (if list (cons first (apply 'backquote-list*-function list)) first))
49 ;; but Emacs is not very good at efficiently processing recursion.
41ea659a
RS
50 (if list
51 (let* ((rest list) (newlist (cons first nil)) (last newlist))
52 (while (cdr rest)
53 (setcdr last (cons (car rest) nil))
54 (setq last (cdr last)
55 rest (cdr rest)))
56 (setcdr last (car rest))
57 newlist)
58 first))
59
288f95bd
RS
60(defmacro backquote-list*-macro (first &rest list)
61 "Like `list' but the last argument is the tail of the new list.
41ea659a 62
288f95bd 63For example (backquote-list* 'a 'b 'c) => (a b . c)"
1de9630d
SM
64 ;; The recursive solution is much nicer:
65 ;; (if list (list 'cons first (cons 'backquote-list*-macro list)) first))
66 ;; but Emacs is not very good at efficiently processing such things.
67 (setq list (nreverse (cons first list))
41ea659a
RS
68 first (car list)
69 list (cdr list))
70 (if list
71 (let* ((second (car list))
72 (rest (cdr list))
73 (newlist (list 'cons second first)))
74 (while rest
75 (setq newlist (list 'cons (car rest) newlist)
76 rest (cdr rest)))
77 newlist)
78 first))
79
c9c7f2c4 80(defalias 'backquote-list* (symbol-function 'backquote-list*-macro))
41ea659a
RS
81
82;; A few advertised variables that control which symbols are used
83;; to represent the backquote, unquote, and splice operations.
4c548238 84(defconst backquote-backquote-symbol '\`
cdab3e50 85 "Symbol used to represent a backquote or nested backquote.")
4c548238 86
727fb8cc 87(defconst backquote-unquote-symbol '\,
cdab3e50 88 "Symbol used to represent an unquote inside a backquote.")
4c548238 89
727fb8cc 90(defconst backquote-splice-symbol '\,@
cdab3e50 91 "Symbol used to represent a splice inside a backquote.")
41ea659a 92
82bb5643 93(defmacro backquote (structure)
41ea659a
RS
94 "Argument STRUCTURE describes a template to build.
95
96The whole structure acts as if it were quoted except for certain
97places where expressions are evaluated and inserted or spliced in.
98
99For example:
100
1df90f8f
RS
101b => (ba bb bc) ; assume b has this value
102`(a b c) => (a b c) ; backquote acts like quote
2b1c5e12
RS
103`(a ,b c) => (a (ba bb bc) c) ; insert the value of b
104`(a ,@b c) => (a ba bb bc c) ; splice in the value of b
41ea659a 105
288f95bd 106Vectors work just like lists. Nested backquotes are permitted."
82bb5643 107 (cdr (backquote-process structure)))
41ea659a
RS
108
109;; GNU Emacs has no reader macros
110
1df90f8f 111(defalias '\` (symbol-function 'backquote))
41ea659a 112
288f95bd 113;; backquote-process returns a dotted-pair of a tag (0, 1, or 2) and
41ea659a
RS
114;; the backquote-processed structure. 0 => the structure is
115;; constant, 1 => to be unquoted, 2 => to be spliced in.
116;; The top-level backquote macro just discards the tag.
117
3527bdcc
SM
118(defun backquote-delay-process (s level)
119 "Process a (un|back|splice)quote inside a backquote.
120This simply recurses through the body."
5d3440f4
SM
121 (let ((exp (backquote-listify (list (cons 0 (list 'quote (car s))))
122 (backquote-process (cdr s) level))))
3527bdcc
SM
123 (if (eq (car-safe exp) 'quote)
124 (cons 0 (list 'quote s))
125 (cons 1 exp))))
126
127(defun backquote-process (s &optional level)
128 "Process the body of a backquote.
129S is the body. Returns a cons cell whose cdr is piece of code which
130is the macro-expansion of S, and whose car is a small integer whose value
131can either indicate that the code is constant (0), or not (1), or returns
132a list which should be spliced into its environment (2).
133LEVEL is only used internally and indicates the nesting level:
1340 (the default) is for the toplevel nested inside a single backquote."
135 (unless level (setq level 0))
41ea659a
RS
136 (cond
137 ((vectorp s)
3527bdcc 138 (let ((n (backquote-process (append s ()) level)))
41ea659a
RS
139 (if (= (car n) 0)
140 (cons 0 s)
141 (cons 1 (cond
ea4a56de
RS
142 ((not (listp (cdr n)))
143 (list 'vconcat (cdr n)))
41ea659a
RS
144 ((eq (nth 1 n) 'list)
145 (cons 'vector (nthcdr 2 n)))
146 ((eq (nth 1 n) 'append)
147 (cons 'vconcat (nthcdr 2 n)))
148 (t
149 (list 'apply '(function vector) (cdr n))))))))
150 ((atom s)
151 (cons 0 (if (or (null s) (eq s t) (not (symbolp s)))
152 s
153 (list 'quote s))))
154 ((eq (car s) backquote-unquote-symbol)
3527bdcc 155 (if (<= level 0)
f2223371
SM
156 (if (> (length s) 2)
157 ;; We could support it with: (cons 2 `(list . ,(cdr s)))
158 ;; But let's not encourage such uses.
159 (error "Multiple args to , are not supported: %S" s)
160 (cons 1 (nth 1 s)))
3527bdcc 161 (backquote-delay-process s (1- level))))
41ea659a 162 ((eq (car s) backquote-splice-symbol)
3527bdcc 163 (if (<= level 0)
f2223371
SM
164 (if (> (length s) 2)
165 ;; (cons 2 `(append . ,(cdr s)))
166 (error "Multiple args to ,@ are not supported: %S" s)
167 (cons 2 (nth 1 s)))
3527bdcc 168 (backquote-delay-process s (1- level))))
41ea659a 169 ((eq (car s) backquote-backquote-symbol)
3527bdcc 170 (backquote-delay-process s (1+ level)))
41ea659a 171 (t
cd320f32
RS
172 (let ((rest s)
173 item firstlist list lists expression)
174 ;; Scan this list-level, setting LISTS to a list of forms,
175 ;; each of which produces a list of elements
176 ;; that should go in this level.
a1506d29 177 ;; The order of LISTS is backwards.
cd320f32
RS
178 ;; If there are non-splicing elements (constant or variable)
179 ;; at the beginning, put them in FIRSTLIST,
180 ;; as a list of tagged values (TAG . FORM).
181 ;; If there are any at the end, they go in LIST, likewise.
3527bdcc
SM
182 (while (and (consp rest)
183 ;; Stop if the cdr is an expression inside a backquote or
184 ;; unquote since this needs to go recursively through
185 ;; backquote-process.
186 (not (or (eq (car rest) backquote-unquote-symbol)
187 (eq (car rest) backquote-backquote-symbol))))
188 (setq item (backquote-process (car rest) level))
41ea659a
RS
189 (cond
190 ((= (car item) 2)
1d08cb50
RS
191 ;; Put the nonspliced items before the first spliced item
192 ;; into FIRSTLIST.
193 (if (null lists)
41ea659a
RS
194 (setq firstlist list
195 list nil))
1d08cb50 196 ;; Otherwise, put any preceding nonspliced items into LISTS.
41ea659a 197 (if list
3527bdcc
SM
198 (push (backquote-listify list '(0 . nil)) lists))
199 (push (cdr item) lists)
41ea659a
RS
200 (setq list nil))
201 (t
202 (setq list (cons item list))))
203 (setq rest (cdr rest)))
cd320f32
RS
204 ;; Handle nonsplicing final elements, and the tail of the list
205 ;; (which remains in REST).
41ea659a 206 (if (or rest list)
3527bdcc
SM
207 (push (backquote-listify list (backquote-process rest level))
208 lists))
a1506d29 209 ;; Turn LISTS into a form that produces the combined list.
cd320f32 210 (setq expression
41ea659a 211 (if (or (cdr lists)
cd320f32 212 (eq (car-safe (car lists)) backquote-splice-symbol))
41ea659a
RS
213 (cons 'append (nreverse lists))
214 (car lists)))
cd320f32 215 ;; Tack on any initial elements.
41ea659a 216 (if firstlist
cd320f32
RS
217 (setq expression (backquote-listify firstlist (cons 1 expression))))
218 (if (eq (car-safe expression) 'quote)
41ea659a 219 (cons 0 (list 'quote s))
cd320f32 220 (cons 1 expression))))))
41ea659a 221
288f95bd
RS
222;; backquote-listify takes (tag . structure) pairs from backquote-process
223;; and decides between append, list, backquote-list*, and cons depending
41ea659a
RS
224;; on which tags are in the list.
225
288f95bd 226(defun backquote-listify (list old-tail)
41ea659a
RS
227 (let ((heads nil) (tail (cdr old-tail)) (list-tail list) (item nil))
228 (if (= (car old-tail) 0)
229 (setq tail (eval tail)
230 old-tail nil))
231 (while (consp list-tail)
232 (setq item (car list-tail))
233 (setq list-tail (cdr list-tail))
234 (if (or heads old-tail (/= (car item) 0))
235 (setq heads (cons (cdr item) heads))
236 (setq tail (cons (eval (cdr item)) tail))))
237 (cond
238 (tail
239 (if (null old-tail)
240 (setq tail (list 'quote tail)))
241 (if heads
242 (let ((use-list* (or (cdr heads)
243 (and (consp (car heads))
244 (eq (car (car heads))
245 backquote-splice-symbol)))))
288f95bd 246 (cons (if use-list* 'backquote-list* 'cons)
41ea659a
RS
247 (append heads (list tail))))
248 tail))
249 (t (cons 'list heads)))))
250
55535639 251;;; backquote.el ends here