Mercurial > hg > xemacs-beta
comparison lisp/edebug/cl-read.el-19.15-b1 @ 4:b82b59fe008d r19-15b3
Import from CVS: tag r19-15b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:46:56 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:30df88044ec6 | 4:b82b59fe008d |
---|---|
1 ;; Customizable, Common Lisp like reader for Emacs Lisp. | |
2 ;; | |
3 ;; Copyright (C) 1993 by Guido Bosch <Guido.Bosch@loria.fr> | |
4 | |
5 ;; This file is written in GNU Emacs Lisp, but not (yet) part of GNU Emacs. | |
6 | |
7 ;; The software contained in this file is free software; you can | |
8 ;; redistribute it and/or modify it under the terms of the GNU General | |
9 ;; Public License as published by the Free Software Foundation; either | |
10 ;; version 2, or (at your option) any later version. | |
11 | |
12 ;; GNU Emacs is distributed in the hope that it will be useful, | |
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 ;; GNU General Public License for more details. | |
16 | |
17 ;; You should have received a copy of the GNU General Public License | |
18 | |
19 ;; along with GNU Emacs; see the file COPYING. If not, write to | |
20 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
21 ;; | |
22 ;; Please send bugs and comments to the author. | |
23 ;; | |
24 ;; <DISCLAIMER> | |
25 ;; This program is still under development. Neither the author nor | |
26 ;; his employer accepts responsibility to anyone for the consequences of | |
27 ;; using it or for whether it serves any particular purpose or works | |
28 ;; at all. | |
29 | |
30 | |
31 ;; Introduction | |
32 ;; ------------ | |
33 ;; | |
34 ;; This package replaces the standard Emacs Lisp reader (implemented | |
35 ;; as a set of built-in Lisp function in C) by a flexible and | |
36 ;; customizable Common Lisp like one (implemented entirely in Emacs | |
37 ;; Lisp). During reading of Emacs Lisp source files, it is about 40% | |
38 ;; slower than the built-in reader, but there is no difference in | |
39 ;; loading byte compiled files - they dont contain any syntactic sugar | |
40 ;; and are loaded with the built in subroutine `load'. | |
41 ;; | |
42 ;; The user level functions for defining read tables, character and | |
43 ;; dispatch macros are implemented according to the Commom Lisp | |
44 ;; specification by Steel's (2nd edition), but the read macro functions | |
45 ;; themselves are implemented in a slightly different way, because the | |
46 ;; basic character reading is done in an Emacs buffer, and not by | |
47 ;; using the primitive functions `read-char' and `unread-char', as real | |
48 ;; CL does. To get 100% compatibility with CL, the above functions | |
49 ;; (or their equivalents) must be implemented as subroutines. | |
50 ;; | |
51 ;; Another difference with real CL reading is that basic tokens (symbols | |
52 ;; numbers, strings, and a few more) are still read by the original | |
53 ;; built-in reader. This is necessary to get reasonable performance. | |
54 ;; As a consquence, the read syntax of basic tokens can't be | |
55 ;; customized. | |
56 | |
57 ;; Most of the built-in reader syntax has been replaced by lisp | |
58 ;; character macros: parentheses and brackets, simple and double | |
59 ;; quotes, semicolon comments and the dot. In addition to that, the | |
60 ;; following new syntax features are provided: | |
61 | |
62 ;; Backquote-Comma-Atsign Macro: `(,el ,@list) | |
63 ;; | |
64 ;; (the clumsy Emacs Lisp syntax (` ((, el) (,@ list))) is also | |
65 ;; supported, but with one restriction: the blank behind the quote | |
66 ;; characters is mandatory when using the old syntax. The cl reader | |
67 ;; needs it as a landmark to distinguish between old and new syntax. | |
68 ;; An example: | |
69 ;; | |
70 ;; With blanks, both readers read the same: | |
71 ;; (` (, (head)) (,@ (tail))) -std-read-> (` (, (head)) (,@ (tail))) | |
72 ;; (` (, (head)) (,@ (tail))) -cl-read-> (` (, (head)) (,@ (tail))) | |
73 ;; | |
74 ;; Without blanks, the form is interpreted differently by the two readers: | |
75 ;; (`(,(head)) (,@(tail))) -std-read-> (` (, (head)) (,@ (tail))) | |
76 ;; (`(,(head)) (,@(tail))) -cl-read-> ((` ((, ((head)))) ((,@ ((tail))))) | |
77 ;; | |
78 ;; | |
79 ;; Dispatch Character Macro" `#' | |
80 ;; | |
81 ;; #'<function> function quoting | |
82 ;; #\<charcter> character syntax | |
83 ;; #.<form> read time evaluation | |
84 ;; #p<path>, #P<path> paths | |
85 ;; #+<feature>, #-<feature> conditional reading | |
86 ;; #<n>=, #<n># tags for shared structure reading | |
87 ;; | |
88 ;; Other read macros can be added easily (see the definition of the | |
89 ;; above ones in this file, using the functions `set-macro-character' | |
90 ;; and `set-dispatch-macro-character') | |
91 ;; | |
92 ;; The Cl reader is mostly downward compatile, (exception: backquote | |
93 ;; comma macro, see above). E.g., this file, which is written entirely | |
94 ;; in the standard Emacs Lisp syntax, can be read and compiled with the | |
95 ;; cl-reader activated (see Examples below). | |
96 | |
97 ;; This also works with package.el for Common Lisp packages. | |
98 | |
99 | |
100 ;; Requirements | |
101 ;; ------------ | |
102 ;; The package runs on Emacs 18 and Emacs 19 (FSF and Lucid) It is | |
103 ;; built on top of Dave Gillespie's cl.el package (version 2.02 or | |
104 ;; later). The old one (from Ceazar Quiroz, still shiped with some | |
105 ;; Emacs 19 disributions) will not do. | |
106 | |
107 ;; Usage | |
108 ;; ----- | |
109 ;; The package is implemented as a kind of minor mode to the | |
110 ;; emacs-lisp-mode. As most of the Emacs Lisp files are still written | |
111 ;; in the standard Emacs Lisp syntax, the cl reader is only activated | |
112 ;; on elisp files whose property lines contain the following entry: | |
113 ;; | |
114 ;; -*- Read-Syntax: Common-Lisp -*- | |
115 ;; | |
116 ;; Note that both property name ("Read-Syntax") and value | |
117 ;; ("Common-Lisp") are not case sensitive. There can also be other | |
118 ;; properties in this line: | |
119 ;; | |
120 ;; -*- Mode: Emacs-Lisp; Read-Syntax: Common-Lisp -*- | |
121 | |
122 ;; Installation | |
123 ;; ------------ | |
124 ;; Save this file in a directory where Emacs will find it, then | |
125 ;; byte compile it (M-x byte-compile-file). | |
126 ;; | |
127 ;; A permanent installation of the package can be done in two ways: | |
128 ;; | |
129 ;; 1.) If you want to have the package always loaded, put this in your | |
130 ;; .emacs, or in just the files that require it: | |
131 ;; | |
132 ;; (require 'cl-read) | |
133 ;; | |
134 ;; 2.) To load the cl-read package automatically when visiting an elisp | |
135 ;; file that needs it, it has to be installed using the | |
136 ;; emacs-lisp-mode-hook. In this case, put the following function | |
137 ;; definition and add-hook form in your .emacs: | |
138 ;; | |
139 ;; (defun cl-reader-autoinstall-function () | |
140 ;; "Activates the Common Lisp style reader for emacs-lisp-mode buffers, | |
141 ;; if the property line has a local variable setting like this: | |
142 ;; \;\; -*- Read-Syntax: Common-Lisp -*-" | |
143 ;; | |
144 ;; (or (boundp 'local-variable-hack-done) | |
145 ;; (let (local-variable-hack-done | |
146 ;; (case-fold-search t)) | |
147 ;; (hack-local-variables-prop-line 't) | |
148 ;; (cond | |
149 ;; ((and (boundp 'read-syntax) | |
150 ;; read-syntax | |
151 ;; (string-match "^common-lisp$" (symbol-name read-syntax))) | |
152 ;; (require 'cl-read) | |
153 ;; (make-local-variable 'cl-read-active) | |
154 ;; (setq cl-read-active 't)))))) | |
155 ;; | |
156 ;; (add-hook 'emacs-lisp-mode-hook 'cl-reader-autoinstall-function) | |
157 ;; | |
158 ;; The `cl-reader-autoinstall-function' function tests for the | |
159 ;; presence of the correct Read-Syntax property in the first line of | |
160 ;; the file and loads the cl-read package if necessary. cl-read | |
161 ;; replaces the following standard elisp functions: | |
162 ;; | |
163 ;; - read | |
164 ;; - read-from-string | |
165 ;; - eval-current-buffer | |
166 ;; - eval-buffer | |
167 ;; - eval-region | |
168 ;; - eval-expression (to call reader explicitly) | |
169 ;; | |
170 ;; There may be other built-in functions that need to be replaced | |
171 ;; (e.g. load). The behavior of the new reader function depends on | |
172 ;; the value of the buffer local variable `cl-read-active': if it is | |
173 ;; nil, they just call the original functions, otherwise they call the | |
174 ;; cl reader. If the cl reader is active in a buffer, this is | |
175 ;; indicated in the modeline by the string "CL" (minor mode like). | |
176 ;; | |
177 | |
178 ;; Examples: | |
179 ;; --------- | |
180 ;; After having installed the package as described above, the | |
181 ;; following forms can be evaluated (M-C-x) with the cl reader being | |
182 ;; active. (make sure that the mode line displays "(Emacs-Lisp CL)") | |
183 ;; | |
184 ;; (setq whitespaces '(#\space #\newline #\tab)) | |
185 ;; (setq more-whitespaces `(#\page ,@whitespaces #\linefeed)) | |
186 ;; (setq whitespace-strings (mapcar #'char-to-string more-whitespaces)) | |
187 ;; | |
188 ;; (setq shared-struct '(#1=[hello world] #1# #1#)) | |
189 ;; (progn (setq cirlist '#1=(a b . #1#)) 't) | |
190 ;; | |
191 ;; This file, though written in standard Emacs Lisp syntax, can also be | |
192 ;; compiled with the cl reader active: Type M-x byte-compile-file | |
193 | |
194 ;; TO DO List: | |
195 ;; ----------- | |
196 ;; - Provide a replacement for load so that uncompiled cl syntax | |
197 ;; source file can be loaded, too. For now prohibit loading un-bytecompiled. | |
198 ;; - Do we really need the (require 'cl) dependency? Yes. | |
199 ;; - More read macros: #S for structs, #A for array, #X for hex, #nR for radix | |
200 ;; - Refine the error signaling mechanism. | |
201 ;; - invalid-cl-read-syntax is now defined. what else? | |
202 | |
203 | |
204 ; Change History | |
205 ; | |
206 ; $Log: cl-read.el-19.15-b1,v $ | |
207 ; Revision 1.1.1.1 1996/12/18 03:54:31 steve | |
208 ; XEmacs 19.15-b3 | |
209 ; | |
210 ; Revision 1.19 94/03/21 19:59:24 liberte | |
211 ; Add invalid-cl-read-syntax error symbol. | |
212 ; Add reader::read-sexp and reader::read-sexp-func to allow customization | |
213 ; based on the results of reading. | |
214 ; Remove more dependencies on cl-package. | |
215 ; Remove reader::eval-current-buffer, eval-buffer, and eval-region, | |
216 ; and use elisp-eval-region package instead. | |
217 ; | |
218 ; Revision 1.18 94/03/04 23:42:24 liberte | |
219 ; Fix typos in comments. | |
220 ; | |
221 ; Revision 1.17 93/11/24 12:04:09 bosch | |
222 ; cl-packages dependency removed. `reader::read-constituent' and | |
223 ; corresponding variables moved to cl-packages.el. | |
224 ; Multi-line comment #| ... |# dispatch character read macro added. | |
225 ; | |
226 ; Revision 1.16 1993/11/23 10:21:02 bosch | |
227 ; Patches from Daniel LaLiberte integrated. | |
228 ; | |
229 ; Revision 1.15 1993/11/18 21:21:10 bosch | |
230 ; `reader::symbol-regexp1' modified. | |
231 ; | |
232 ; Revision 1.14 1993/11/17 19:06:32 bosch | |
233 ; More characters added to `reader::symbol-characters'. | |
234 ; `reader::read-constituent' modified. | |
235 ; defpackage form added. | |
236 ; | |
237 ; Revision 1.13 1993/11/16 13:06:41 bosch | |
238 ; - Symbol reading for CL package convention implemented. | |
239 ; Variables `reader::symbol-characters', `reader::symbol-regexp1' and | |
240 ; `reader::symbol-regexp2' and functions `reader::lookup-symbol' and | |
241 ; `reader::read-constituent' added. | |
242 ; - Prefix for internal symbols is now "reader::" (Common Lisp | |
243 ; compatible). | |
244 ; - Dispatch character macro #: for reading uninterned symbols added. | |
245 ; | |
246 ; Revision 1.12 1993/11/07 19:29:07 bosch | |
247 ; Minor bug fix. | |
248 ; | |
249 ; Revision 1.11 1993/11/07 19:23:59 bosch | |
250 ; Comment added. Character read macro #\<char> rewritten. Now reads | |
251 ; e.g. #\meta-control-x. Needs to be checked. | |
252 ; fix in `reader::restore-shared-structure'. `cl-reader-autoinstall-function' improved. | |
253 ; | |
254 ; Revision 1.10 1993/11/06 18:35:35 bosch | |
255 ; Included Daniel LaLiberte's Patches. | |
256 ; Efficiency of `reader::restore-shared-structure' improved. | |
257 ; Implementation notes for shared structure reading added. | |
258 ; | |
259 ; Revision 1.9 1993/09/08 07:44:54 bosch | |
260 ; Comment modified. | |
261 ; | |
262 ; Revision 1.8 1993/08/10 13:43:34 bosch | |
263 ; Hook function `cl-reader-autoinstall-function' for automatic installation added. | |
264 ; Buffer local variable `cl-read-active' added: together with the above | |
265 ; hook it allows the file specific activation of the cl reader. | |
266 ; | |
267 ; Revision 1.7 1993/08/10 10:35:21 bosch | |
268 ; Functions `read*' and `read-from-string*' renamed into `reader::read' | |
269 ; and `reader::read-from-string'. Whitespace character skipping after | |
270 ; recursive reader calls removed (Emacs 19 should not need this). | |
271 ; Functions `cl-reader-install' and `cl-reader-uninstall' updated. | |
272 ; Introduction text and function comments added. | |
273 ; | |
274 ; Revision 1.6 1993/08/09 15:36:05 bosch Function `read*' now nearly | |
275 ; elisp compatible (no functions as streams, yet -- I don't think I | |
276 ; will ever implement this, it would be far too slow). Elisp | |
277 ; compatible function `read-from-string*' added. Replacements for | |
278 ; `eval-current-buffer', `eval-buffer' and `eval-region' added. | |
279 ; Renamed feature `cl-dg' in `cl', as Dave Gillespie's cl.el package | |
280 ; is rather stable now. Function `cl-reader-install' and | |
281 ; `cl-reader-uninstall' modified. | |
282 ; | |
283 ; Revision 1.5 1993/08/09 10:23:35 bosch | |
284 ; Functions `copy-readtable' and `set-syntax-from-character' added. | |
285 ; Variable `reader::internal-standard-readtable' added. Standard | |
286 ; readtable initialization modified. Whitespace skipping placed back | |
287 ; inside the read loop. | |
288 ; | |
289 ; Revision 1.4 1993/05/14 13:00:48 bosch | |
290 ; Included patches from Daniel LaLiberte. | |
291 ; | |
292 ; Revision 1.3 1993/05/11 09:57:39 bosch | |
293 ; `read*' renamed in `reader::read-from-buffer'. `read*' now can read | |
294 ; from strings. | |
295 ; | |
296 ; Revision 1.2 1993/05/09 16:30:50 bosch | |
297 ; (require 'cl-read) added. | |
298 ; Calling of `{before,after}-read-hook' modified. | |
299 ; | |
300 ; Revision 1.1 1993/03/29 19:37:21 bosch | |
301 ; Initial revision | |
302 ; | |
303 ; | |
304 | |
305 ;; | |
306 (require 'cl) | |
307 | |
308 (provide 'cl-read) | |
309 ;; load before compiling | |
310 (require 'cl-read) | |
311 | |
312 ;; bootstrapping with cl-packages | |
313 ;; defpackage and in-package are ignored until cl-read is installed. | |
314 '(defpackage reader | |
315 (:nicknames "rd") | |
316 (:use el) | |
317 (:export | |
318 cl-read-active | |
319 copy-readtable | |
320 set-macro-character | |
321 get-macro-character | |
322 set-syntax-from-character | |
323 make-dispatch-macro-character | |
324 set-dispatch-macro-character | |
325 get-dispatch-macro-character | |
326 before-read-hook | |
327 after-read-hook | |
328 cl-reader-install | |
329 cl-reader-uninstall | |
330 read-syntax | |
331 cl-reader-autoinstall-function)) | |
332 | |
333 '(in-package reader) | |
334 | |
335 | |
336 (autoload 'compiled-function-p "bytecomp") | |
337 | |
338 ;; This makes cl-read behave as a kind of minor mode: | |
339 | |
340 (make-variable-buffer-local 'cl-read-active) | |
341 (defvar cl-read-active nil | |
342 "Buffer local variable that enables Common Lisp style syntax reading.") | |
343 (setq-default cl-read-active nil) | |
344 | |
345 (or (assq 'cl-read-active minor-mode-alist) | |
346 (setq minor-mode-alist | |
347 (cons '(cl-read-active " CL") minor-mode-alist))) | |
348 | |
349 ;; Define a new error symbol: invalid-cl-read-syntax | |
350 ;; XEmacs change | |
351 (define-error 'invalid-cl-read-syntax "Invalid CL read syntax" | |
352 'invalid-read-syntax) | |
353 | |
354 (defun reader::error (msg &rest args) | |
355 (signal 'invalid-cl-read-syntax (list (apply 'format msg args)))) | |
356 | |
357 | |
358 ;; The readtable | |
359 | |
360 (defvar reader::readtable-size 256 | |
361 "The size of a readtable." | |
362 ;; Actually, the readtable is a vector of size (1+ | |
363 ;; reader::readtable-size), because the last element contains the | |
364 ;; symbol `readtable', used for defining `readtablep. | |
365 ) | |
366 | |
367 ;; An entry of the readtable must have one of the following forms: | |
368 ;; | |
369 ;; 1. A symbol, one of {illegal, constituent, whitespace}. It means | |
370 ;; the character's reader class. | |
371 ;; | |
372 ;; 2. A function (i.e., a symbol with a function definition, a byte | |
373 ;; compiled function or an uncompiled lambda expression). It means the | |
374 ;; character is a macro character. | |
375 ;; | |
376 ;; 3. A vector of length `reader::readtable-size'. Elements of this vector | |
377 ;; may be `nil' or a function (see 2.). It means the charater is a | |
378 ;; dispatch character, and the vector its dispatch fucntion table. | |
379 | |
380 (defvar *readtable*) | |
381 (defvar reader::internal-standard-readtable) | |
382 | |
383 (defun* copy-readtable | |
384 (&optional (from-readtable *readtable*) | |
385 (to-readtable | |
386 (make-vector (1+ reader::readtable-size) 'illegal))) | |
387 "Return a copy of FROM-READTABLE \(default: *readtable*\). If the | |
388 FROM-READTABLE argument is provided as `nil', make a copy of a | |
389 standard \(CL-like\) readtable. If TO-READTABLE is provided, modify and | |
390 return it, otherwise create a new readtable object." | |
391 | |
392 (if (null from-readtable) | |
393 (setq from-readtable reader::internal-standard-readtable)) | |
394 | |
395 (loop for i to reader::readtable-size | |
396 as from-syntax = (aref from-readtable i) | |
397 do (setf (aref to-readtable i) | |
398 (if (vectorp from-syntax) | |
399 (copy-sequence from-syntax) | |
400 from-syntax)) | |
401 finally return to-readtable)) | |
402 | |
403 | |
404 (defmacro reader::get-readtable-entry (char readtable) | |
405 (` (aref (, readtable) (, char)))) | |
406 | |
407 (defun set-macro-character | |
408 (char function &optional readtable) | |
409 "Makes CHAR to be a macro character with FUNCTION as handler. | |
410 When CHAR is seen by reader::read-from-buffer, it calls FUNCTION. | |
411 Returns always t. Optional argument READTABLE is the readtable to set | |
412 the macro character in (default: *readtable*)." | |
413 (or readtable (setq readtable *readtable*)) | |
414 (or (reader::functionp function) | |
415 (reader::error "Not valid character macro function: %s" function)) | |
416 (setf (reader::get-readtable-entry char readtable) function) | |
417 t) | |
418 | |
419 | |
420 (put 'set-macro-character 'edebug-form-spec | |
421 '(&define sexp function-form &optional sexp)) | |
422 (put 'set-macro-character 'lisp-indent-function 1) | |
423 | |
424 (defun get-macro-character (char &optional readtable) | |
425 "Return the function associated with the character CHAR. | |
426 Optional READTABLE defaults to *readtable*. If char isn't a macro | |
427 character in READTABLE, return nil." | |
428 (or readtable (setq readtable *readtable*)) | |
429 (let ((entry (reader::get-readtable-entry char readtable))) | |
430 (if (reader::functionp entry) | |
431 entry))) | |
432 | |
433 (defun set-syntax-from-character | |
434 (to-char from-char &optional to-readtable from-readtable) | |
435 "Make the syntax of TO-CHAR be the same as the syntax of FROM-CHAR. | |
436 Optional TO-READTABLE and FROM-READTABLE are the corresponding tables | |
437 to use. TO-READTABLE defaults to the current readtable | |
438 \(*readtable*\), and FROM-READTABLE to nil, meaning to use the | |
439 syntaxes from the standard Lisp Readtable." | |
440 (or to-readtable (setq to-readtable *readtable*)) | |
441 (or from-readtable | |
442 (setq from-readtable reader::internal-standard-readtable)) | |
443 (let ((from-syntax | |
444 (reader::get-readtable-entry from-char from-readtable))) | |
445 (if (vectorp from-syntax) | |
446 ;; dispatch macro character table | |
447 (setq from-syntax (copy-sequence from-syntax))) | |
448 (setf (reader::get-readtable-entry to-char to-readtable) | |
449 from-syntax)) | |
450 t) | |
451 | |
452 | |
453 ;; Dispatch macro character | |
454 (defun make-dispatch-macro-character (char &optional readtable) | |
455 "Let CHAR be a dispatch macro character in READTABLE (default: *readtable*)." | |
456 (or readtable (setq readtable *readtable*)) | |
457 (setf (reader::get-readtable-entry char readtable) | |
458 ;; create a dispatch character table | |
459 (make-vector reader::readtable-size nil))) | |
460 | |
461 | |
462 (defun set-dispatch-macro-character | |
463 (disp-char sub-char function &optional readtable) | |
464 "Make reading CHAR1 followed by CHAR2 be handled by FUNCTION. | |
465 Optional argument READTABLE (default: *readtable*). CHAR1 must first be | |
466 made a dispatch char with `make-dispatch-macro-character'." | |
467 (or readtable (setq readtable *readtable*)) | |
468 (let ((disp-table (reader::get-readtable-entry disp-char readtable))) | |
469 ;; check whether disp-char is a valid dispatch character | |
470 (or (vectorp disp-table) | |
471 (reader::error "`%c' not a dispatch macro character." disp-char)) | |
472 ;; check whether function is a valid function | |
473 (or (reader::functionp function) | |
474 (reader::error "Not valid dispatch character macro function: %s" | |
475 function)) | |
476 (setf (aref disp-table sub-char) function))) | |
477 | |
478 (put 'set-dispatch-macro-character 'edebug-form-spec | |
479 '(&define sexp sexp function-form &optional sexp)) | |
480 (put 'set-dispatch-macro-character 'lisp-indent-function 2) | |
481 | |
482 | |
483 (defun get-dispatch-macro-character | |
484 (disp-char sub-char &optional readtable) | |
485 "Return the macro character function for SUB-CHAR unser DISP-CHAR. | |
486 Optional READTABLE defaults to *readtable*. | |
487 Returns nil if there is no such function." | |
488 (or readtable (setq readtable *readtable*)) | |
489 (let ((disp-table (reader::get-readtable-entry disp-char readtable))) | |
490 (and (vectorp disp-table) | |
491 (reader::functionp (aref disp-table sub-char)) | |
492 (aref disp-table sub-char)))) | |
493 | |
494 | |
495 (defun reader::functionp (function) | |
496 ;; Check whether FUNCTION is a valid function object to be used | |
497 ;; as (dispatch) macro character function. | |
498 (or (and (symbolp function) (fboundp function)) | |
499 (compiled-function-p function) | |
500 (and (consp function) (eq (first function) 'lambda)))) | |
501 | |
502 | |
503 ;; The basic reader loop | |
504 | |
505 ;; shared and circular structure reading | |
506 (defvar reader::shared-structure-references nil) | |
507 (defvar reader::shared-structure-labels nil) | |
508 | |
509 (defun reader::read-sexp-func (point func) | |
510 ;; This function is called to read a sexp at POINT by calling FUNC. | |
511 ;; reader::read-sexp-func is here to be advised, e.g. by Edebug, | |
512 ;; to do something before or after reading. | |
513 (funcall func)) | |
514 | |
515 (defmacro reader::read-sexp (point &rest body) | |
516 ;; Called to return a sexp starting at POINT. BODY creates the sexp result | |
517 ;; and should leave point after the sexp. The body is wrapped in | |
518 ;; a lambda expression and passed to reader::read-sexp-func. | |
519 (` (reader::read-sexp-func (, point) (function (lambda () (,@ body)))))) | |
520 | |
521 (put 'reader::read-sexp 'edebug-form-spec '(form body)) | |
522 (put 'reader::read-sexp 'lisp-indent-function 2) | |
523 (put 'reader::read-sexp 'lisp-indent-hook 1) ;; Emacs 18 | |
524 | |
525 | |
526 (defconst before-read-hook nil) | |
527 (defconst after-read-hook nil) | |
528 | |
529 ;; Set the hooks to `read-char' in order to step through the reader. e.g. | |
530 ;; (add-hook 'before-read-hook '(lambda () (message "before") (read-char))) | |
531 ;; (add-hook 'after-read-hook '(lambda () (message "after") (read-char))) | |
532 | |
533 (defmacro reader::encapsulate-recursive-call (reader-call) | |
534 ;; Encapsulate READER-CALL, a form that contains a recursive call to | |
535 ;; the reader, for usage inside the main reader loop. The macro | |
536 ;; wraps two hooks around READER-CALL: `before-read-hook' and | |
537 ;; `after-read-hook'. | |
538 ;; | |
539 ;; If READER-CALL returns normally, the macro exits immediately from | |
540 ;; the surrounding loop with the value of READER-CALL as result. If | |
541 ;; it exits non-locally (with tag `reader-ignore'), it just returns | |
542 ;; the value of READER-CALL, in which case the surrounding reader | |
543 ;; loop continues its execution. | |
544 ;; | |
545 ;; In both cases, `before-read-hook' and `after-read-hook' are | |
546 ;; called before and after executing READER-CALL. | |
547 ;; Are there any other uses for these hooks? Edebug doesn't need them. | |
548 (` (prog2 | |
549 (run-hooks 'before-read-hook) | |
550 ;; this catch allows to ignore the return, in the case that | |
551 ;; reader::read-from-buffer should continue looping (e.g. | |
552 ;; skipping over comments) | |
553 (catch 'reader-ignore | |
554 ;; this only works inside a block (e.g., in a loop): | |
555 ;; go outside | |
556 (return | |
557 (prog1 | |
558 (, reader-call) | |
559 ;; this occurrence of the after hook fires if the | |
560 ;; reader-call returns normally ... | |
561 (run-hooks 'after-read-hook)))) | |
562 ;; ... and that one if it was thrown to the tag 'reader-ignore | |
563 (run-hooks 'after-read-hook)))) | |
564 | |
565 (put 'reader::encapsulate-recursive-call 'edebug-form-spec '(form)) | |
566 (put 'reader::encapsulate-recursive-call 'lisp-indent-function 0) | |
567 | |
568 (defun reader::read-from-buffer (&optional stream reader::recursive-p) | |
569 (or (bufferp stream) | |
570 (reader::error "Sorry, can only read on buffers")) | |
571 (if (not reader::recursive-p) | |
572 ;; set up environment for shared structure reading | |
573 (let (reader::shared-structure-references | |
574 reader::shared-structure-labels | |
575 tmp-sexp) | |
576 ;; the reader returns an unshared sexpr, possibly containing | |
577 ;; symbolic references | |
578 (setq tmp-sexp (reader::read-from-buffer stream 't)) | |
579 (if ;; sexpr actually contained shared structures | |
580 reader::shared-structure-references | |
581 (reader::restore-shared-structure tmp-sexp) | |
582 ;; it did not, so don't bother about restoring | |
583 tmp-sexp)) | |
584 | |
585 (loop for char = (following-char) | |
586 for entry = (reader::get-readtable-entry char *readtable*) | |
587 if (eobp) do (reader::error "End of file during reading") | |
588 do | |
589 (cond | |
590 | |
591 ((eq entry 'illegal) | |
592 (reader::error "`%c' has illegal character syntax" char)) | |
593 | |
594 ;; skipping whitespace characters must be done inside this | |
595 ;; loop as character macro subroutines may return without | |
596 ;; leaving the loop using (throw 'reader-ignore ...) | |
597 ((eq entry 'whitespace) | |
598 (forward-char 1) | |
599 ;; skip all whitespace | |
600 (while (eq 'whitespace | |
601 (reader::get-readtable-entry | |
602 (following-char) *readtable*)) | |
603 (forward-char 1))) | |
604 | |
605 ;; for every token starting with a constituent character | |
606 ;; call the built-in reader (symbols, numbers, strings, | |
607 ;; characters with ?<char> syntax) | |
608 ((eq entry 'constituent) | |
609 (reader::encapsulate-recursive-call | |
610 (reader::read-constituent stream))) | |
611 | |
612 ((vectorp entry) | |
613 ;; Dispatch macro character. The dispatch macro character | |
614 ;; function is contained in the vector `entry', at the | |
615 ;; place indicated by <sub-char>, the first non-digit | |
616 ;; character following the <disp-char>: | |
617 ;; <disp-char><digit>*<sub-char> | |
618 (reader::encapsulate-recursive-call | |
619 (loop initially do (forward-char 1) | |
620 for sub-char = (prog1 (following-char) | |
621 (forward-char 1)) | |
622 while (memq sub-char | |
623 '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) | |
624 collect sub-char into digit-args | |
625 finally | |
626 (return | |
627 (funcall | |
628 ;; no test is done here whether a non-nil | |
629 ;; contents is a correct dispatch character | |
630 ;; function to apply. | |
631 (or (aref entry sub-char) | |
632 (reader::error | |
633 "Undefined subsequent dispatch character `%c'" | |
634 sub-char)) | |
635 stream | |
636 sub-char | |
637 (string-to-int | |
638 (apply 'concat | |
639 (mapcar | |
640 'char-to-string digit-args)))))))) | |
641 | |
642 (t | |
643 ;; must be a macro character. In this case, `entry' is | |
644 ;; the function to be called | |
645 (reader::encapsulate-recursive-call | |
646 (progn | |
647 (forward-char 1) | |
648 (funcall entry stream char)))))))) | |
649 | |
650 | |
651 ;; Constituent reader fix for Emacs 18 | |
652 (if (string-match "^19" emacs-version) | |
653 (defun reader::read-constituent (stream) | |
654 (reader::read-sexp (point) | |
655 (reader::original-read stream))) | |
656 | |
657 (defun reader::read-constituent (stream) | |
658 (reader::read-sexp (point) | |
659 (prog1 (reader::original-read stream) | |
660 ;; For Emacs 18, backing up is necessary because the `read' function | |
661 ;; reads one character too far after reading a symbol or number. | |
662 ;; This doesnt apply to reading chars (e.g. ?n). | |
663 ;; This still loses for escaped chars. | |
664 (if (not (eq (reader::get-readtable-entry | |
665 (preceding-char) *readtable*) 'constituent)) | |
666 (forward-char -1)))))) | |
667 | |
668 | |
669 ;; Make the default current CL readtable | |
670 | |
671 (defconst *readtable* | |
672 (loop with raw-readtable = | |
673 (make-vector (1+ reader::readtable-size) 'illegal) | |
674 initially do (setf (aref raw-readtable reader::readtable-size) | |
675 'readtable) | |
676 for entry in | |
677 '((constituent ?! ?@ ?$ ?% ?& ?* ?_ ?- ?+ ?= ?/ ?\\ ?0 ?1 ?2 | |
678 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?: ?~ ?> ?< ?a ?b | |
679 ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o ?p | |
680 ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z ?A ?B ?C ?D | |
681 ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R | |
682 ?S ?T ?U ?V ?W ?X ?Y ?Z) | |
683 (whitespace ? ?\t ?\n ?\r ?\f) | |
684 | |
685 ;; The following CL character classes are only useful for | |
686 ;; token parsing. We don't need them, as token parsing is | |
687 ;; left to the built-in reader. | |
688 ;; (single-escape ?\\) | |
689 ;; (multiple-escape ?|) | |
690 ) | |
691 do | |
692 (loop for char in (rest entry) | |
693 do (setf (reader::get-readtable-entry char raw-readtable) | |
694 (first entry))) | |
695 finally return raw-readtable) | |
696 "The current readtable.") | |
697 | |
698 | |
699 ;; Variables used non-locally in the standard readmacros | |
700 (defvar reader::context) | |
701 (defvar reader::stack) | |
702 (defvar reader::recursive-p) | |
703 | |
704 | |
705 ;;;; Read macro character definitions | |
706 | |
707 ;;; Hint for modifying, testing and debugging new read macros: All the | |
708 ;;; read macros and dispatch character macros below are defined in | |
709 ;;; the `*readtable*'. Modifications or | |
710 ;;; instrumenting with edebug are effective immediately without having to | |
711 ;;; copy the internal readtable to the standard *readtable*. However, | |
712 ;;; if you wish to modify reader::internal-standard-readtable, then | |
713 ;;; you must recopy *readtable*. | |
714 | |
715 ;; Chars and strings | |
716 | |
717 ;; This is defined to distinguish chars from constituents | |
718 ;; since chars are read by the standard reader without reading too far. | |
719 (set-macro-character ?\? | |
720 (function | |
721 (lambda (stream char) | |
722 (forward-char -1) | |
723 (reader::read-sexp (point) | |
724 (reader::original-read stream))))) | |
725 | |
726 ;; ?\M-\C-a | |
727 | |
728 ;; This is defined to distinguish strings from constituents | |
729 ;; since backing up after reading a string is simpler. | |
730 (set-macro-character ?\" | |
731 (function | |
732 (lambda (stream char) | |
733 (forward-char -1) | |
734 (reader::read-sexp (point) | |
735 (prog1 (reader::original-read stream) | |
736 ;; This is not needed with Emacs 19, but it is OK. See above. | |
737 (if (/= (preceding-char) ?\") | |
738 (forward-char -1))))))) | |
739 | |
740 ;; Lists and dotted pairs | |
741 (set-macro-character ?\( | |
742 (function | |
743 (lambda (stream char) | |
744 (reader::read-sexp (1- (point)) | |
745 (catch 'read-list | |
746 (let ((reader::context 'list) reader::stack ) | |
747 ;; read list elements up to a `.' | |
748 (catch 'dotted-pair | |
749 (while t | |
750 (setq reader::stack (cons (reader::read-from-buffer stream 't) | |
751 reader::stack)))) | |
752 ;; In dotted pair. Read one more element | |
753 (setq reader::stack (cons (reader::read-from-buffer stream 't) | |
754 reader::stack) | |
755 ;; signal it to the closing paren | |
756 reader::context 'dotted-pair) | |
757 ;; Next char *must* be the closing paren that throws read-list | |
758 (reader::read-from-buffer stream 't) | |
759 ;; otherwise an error is signalled | |
760 (reader::error "Illegal dotted pair read syntax"))))))) | |
761 | |
762 (set-macro-character ?\) | |
763 (function | |
764 (lambda (stream char) | |
765 (cond ((eq reader::context 'list) | |
766 (throw 'read-list (nreverse reader::stack))) | |
767 ((eq reader::context 'dotted-pair) | |
768 (throw 'read-list (nconc (nreverse (cdr reader::stack)) | |
769 (car reader::stack)))) | |
770 (t | |
771 (reader::error "`)' doesn't end a list")))))) | |
772 | |
773 (set-macro-character ?\. | |
774 (function | |
775 (lambda (stream char) | |
776 (and (eq reader::context 'dotted-pair) | |
777 (reader::error "No more than one `.' allowed in list")) | |
778 (throw 'dotted-pair nil)))) | |
779 | |
780 ;; '(#\a . #\b) | |
781 ;; '(a . (b . c)) | |
782 | |
783 ;; Vectors: [a b] | |
784 (set-macro-character ?\[ | |
785 (function | |
786 (lambda (stream char) | |
787 (reader::read-sexp (1- (point)) | |
788 (let ((reader::context 'vector)) | |
789 (catch 'read-vector | |
790 (let ((reader::context 'vector) | |
791 reader::stack) | |
792 (while t (push (reader::read-from-buffer stream 't) | |
793 reader::stack))))))))) | |
794 | |
795 (set-macro-character ?\] | |
796 (function | |
797 (lambda (stream char) | |
798 (if (eq reader::context 'vector) | |
799 (throw 'read-vector (apply 'vector (nreverse reader::stack))) | |
800 (reader::error "`]' doesn't end a vector"))))) | |
801 | |
802 ;; Quote and backquote/comma macro | |
803 (set-macro-character ?\' | |
804 (function | |
805 (lambda (stream char) | |
806 (reader::read-sexp (1- (point)) | |
807 (list (reader::read-sexp (point) 'quote) | |
808 (reader::read-from-buffer stream 't)))))) | |
809 | |
810 (set-macro-character ?\` | |
811 (function | |
812 (lambda (stream char) | |
813 (if (= (following-char) ?\ ) | |
814 ;; old backquote syntax. This is ambigous, because | |
815 ;; (`(sexp)) is a valid form in both syntaxes, but | |
816 ;; unfortunately not the same. | |
817 ;; old syntax: read -> (` (sexp)) | |
818 ;; new syntax: read -> ((` (sexp))) | |
819 (reader::read-sexp (1- (point)) '\`) | |
820 (reader::read-sexp (1- (point)) | |
821 (list (reader::read-sexp (point) '\`) | |
822 (reader::read-from-buffer stream 't))))))) | |
823 | |
824 (set-macro-character ?\, | |
825 (function | |
826 (lambda (stream char) | |
827 (cond ((eq (following-char) ?\ ) | |
828 ;; old syntax | |
829 (reader::read-sexp (point) '\,)) | |
830 ((eq (following-char) ?\@) | |
831 (forward-char 1) | |
832 (cond ((eq (following-char) ?\ ) | |
833 (reader::read-sexp (point) '\,\@)) | |
834 (t | |
835 (reader::read-sexp (- (point) 2) | |
836 (list | |
837 (reader::read-sexp (point) '\,\@) | |
838 (reader::read-from-buffer stream 't)))))) | |
839 (t | |
840 (reader::read-sexp (1- (point)) | |
841 (list | |
842 (reader::read-sexp (1- (point)) '\,) | |
843 (reader::read-from-buffer stream 't)))))))) | |
844 | |
845 ;; 'a | |
846 ;; '(a b c) | |
847 ;; (let ((a 10) (b '(20 30))) `(,a ,@b c)) | |
848 ;; the old syntax is also supported: | |
849 ;; (let ((a 10) (b '(20 30))) (` ((, a) (,@ b) c))) | |
850 | |
851 ;; Single line character comment: ; | |
852 (set-macro-character ?\; | |
853 (function | |
854 (lambda (stream char) | |
855 (skip-chars-forward "^\n\r") | |
856 (throw 'reader-ignore nil)))) | |
857 | |
858 | |
859 | |
860 ;; Dispatch character character # | |
861 (make-dispatch-macro-character ?\#) | |
862 | |
863 (defsubst reader::check-0-infix (n) | |
864 (or (= n 0) | |
865 (reader::error "Numeric infix argument not allowed: %d" n))) | |
866 | |
867 | |
868 (defalias 'search-forward-regexp 're-search-forward) | |
869 | |
870 ;; nested multi-line comments #| ... |# | |
871 (set-dispatch-macro-character ?\# ?\| | |
872 (function | |
873 (lambda (stream char n) | |
874 (reader::check-0-infix n) | |
875 (let ((counter 0)) | |
876 (while (search-forward-regexp "#|\\||#" nil t) | |
877 (if (string-equal | |
878 (buffer-substring | |
879 (match-beginning 0) (match-end 0)) | |
880 "|#") | |
881 (cond ((> counter 0) | |
882 (decf counter)) | |
883 ((= counter 0) | |
884 ;; stop here | |
885 (goto-char (match-end 0)) | |
886 (throw 'reader-ignore nil)) | |
887 ('t | |
888 (reader::error "Unmatching closing multicomment"))) | |
889 (incf counter))) | |
890 (reader::error "Unmatching opening multicomment"))))) | |
891 | |
892 ;; From cl-packages.el | |
893 (defconst reader::symbol-characters "[A-Za-z0-9-_!@$%^&*+=|~{}<>/]") | |
894 (defconst reader::symbol-regexp2 | |
895 (format "\\(%s+\\)" reader::symbol-characters)) | |
896 | |
897 (set-dispatch-macro-character ?\# ?\: | |
898 (function | |
899 (lambda (stream char n) | |
900 (reader::check-0-infix n) | |
901 (or (looking-at reader::symbol-regexp2) | |
902 (reader::error "Invalid symbol read syntax")) | |
903 (goto-char (match-end 0)) | |
904 (make-symbol | |
905 (buffer-substring (match-beginning 0) (match-end 0)))))) | |
906 | |
907 ;; Function quoting: #'<function> | |
908 (set-dispatch-macro-character ?\# ?\' | |
909 (function | |
910 (lambda (stream char n) | |
911 (reader::check-0-infix n) | |
912 ;; Probably should test if cl is required by current buffer. | |
913 ;; Currently, cl will always be a feature because cl-read requires it. | |
914 (reader::read-sexp (- (point) 2) | |
915 (list | |
916 (reader::read-sexp (point) (if (featurep 'cl) 'function* 'function)) | |
917 (reader::read-from-buffer stream 't)))))) | |
918 | |
919 ;; Character syntax: #\<char> | |
920 ;; Not yet implemented: #\Control-a #\M-C-a etc. | |
921 ;; This definition is not used - the next one is more general. | |
922 '(set-dispatch-macro-character ?# ?\\ | |
923 (function | |
924 (lambda (stream char n) | |
925 (reader::check-0-infix n) | |
926 (let ((next (following-char)) | |
927 name) | |
928 (if (not (and (<= ?a next) (<= next ?z))) | |
929 (progn (forward-char 1) next) | |
930 (setq next (reader::read-from-buffer stream t)) | |
931 (cond ((symbolp next) (setq name (symbol-name next))) | |
932 ((integerp next) (setq name (int-to-string next)))) | |
933 (if (= 1 (length name)) | |
934 (string-to-char name) | |
935 (case next | |
936 (linefeed ?\n) | |
937 (newline ?\r) | |
938 (space ?\ ) | |
939 (rubout ?\b) | |
940 (page ?\f) | |
941 (tab ?\t) | |
942 (return ?\C-m) | |
943 (t | |
944 (reader::error "Unknown character specification `%s'" | |
945 next)))))))) | |
946 ) | |
947 | |
948 (defvar reader::special-character-name-table | |
949 '(("linefeed" . ?\n) | |
950 ("newline" . ?\r) | |
951 ("space" . ?\ ) | |
952 ("rubout" . ?\b) | |
953 ("page" . ?\f) | |
954 ("tab" . ?\t) | |
955 ("return" . ?\C-m))) | |
956 | |
957 (set-dispatch-macro-character ?# ?\\ | |
958 (function | |
959 (lambda (stream char n) | |
960 (reader::check-0-infix n) | |
961 (forward-char -1) | |
962 ;; We should read in a special package to avoid creating symbols. | |
963 (let ((symbol (reader::read-from-buffer stream t)) | |
964 (case-fold-search t) | |
965 name modifier character char-base) | |
966 (setq name (symbol-name symbol)) | |
967 (if (string-match "^\\(meta-\\|m-\\|control-\\|c-\\)+" name) | |
968 (setq modifier (substring name | |
969 (match-beginning 1) | |
970 (match-end 1)) | |
971 character (substring name (match-end 1))) | |
972 (setq character name)) | |
973 (setq char-base | |
974 (cond ((= (length character) 1) | |
975 (string-to-char character)) | |
976 ('t | |
977 (cdr (assoc character | |
978 reader::special-character-name-table))))) | |
979 (or char-base | |
980 (reader::error | |
981 "Unknown character specification `%s'" character)) | |
982 | |
983 (and modifier | |
984 (progn | |
985 (and (string-match "control-\\|c-" modifier) | |
986 (decf char-base 32)) | |
987 (and (string-match "meta-\\|m-" modifier) | |
988 (incf char-base 128)))) | |
989 char-base)))) | |
990 | |
991 ;; '(#\meta-space #\tab #\# #\> #\< #\a #\A #\return #\space) | |
992 ;; (eq #\m-tab ?\M-\t) | |
993 ;; (eq #\c-m-x #\m-c-x) | |
994 ;; (eq #\Meta-Control-return #\M-C-return) | |
995 ;; (eq #\m-m-c-c-x #\m-c-x) | |
996 ;; #\C-space #\C-@ ?\C-@ | |
997 | |
998 | |
999 | |
1000 ;; Read and load time evaluation: #.<form> | |
1001 ;; Not yet implemented: #,<form> | |
1002 (set-dispatch-macro-character ?\# ?\. | |
1003 (function | |
1004 (lambda (reader::stream reader::char reader::n) | |
1005 (reader::check-0-infix reader::n) | |
1006 ;; This eval will see all internal vars of reader, | |
1007 ;; e.g. stream, reader::recursive-p. Anything that might be bound. | |
1008 ;; We must use `read' here rather than read-from-buffer with 'recursive-p | |
1009 ;; because the expression must not have unresolved #n#s in it anyway. | |
1010 ;; Otherwise the top-level expression must be completely read before | |
1011 ;; any embedded evaluation(s) occur(s). CLtL2 does not specify this. | |
1012 ;; Also, call `read' so that it may be customized, by e.g. Edebug | |
1013 (eval (read reader::stream))))) | |
1014 ;; '(#.(current-buffer) #.(get-buffer "*scratch*")) | |
1015 | |
1016 ;; Path names (kind of): #p<string>, #P<string>, | |
1017 (set-dispatch-macro-character ?\# ?\P | |
1018 (function | |
1019 (lambda (stream char n) | |
1020 (reader::check-0-infix n) | |
1021 (let ((string (reader::read-from-buffer stream 't))) | |
1022 (or (stringp string) | |
1023 (reader::error "Pathname must be a string: %s" string)) | |
1024 (expand-file-name string))))) | |
1025 | |
1026 (set-dispatch-macro-character ?\# ?\p | |
1027 (get-dispatch-macro-character ?\# ?\P)) | |
1028 | |
1029 ;; #P"~/.emacs" | |
1030 ;; #p"~root/home" | |
1031 | |
1032 ;; Feature reading: #+<feature>, #-<feature> | |
1033 ;; Not yet implemented: #+<boolean expression>, #-<boolean expression> | |
1034 | |
1035 | |
1036 (defsubst reader::read-feature (stream char n flag) | |
1037 (reader::check-0-infix n) | |
1038 (let (;; Use the original reader to only read the feature. | |
1039 ;; This is not exactly correct without *read-suppress*. | |
1040 ;; Also Emacs 18 read goes one too far, | |
1041 ;; so we assume there is a space after the feature. | |
1042 (feature (reader::original-read stream)) | |
1043 (object (reader::read-from-buffer stream 't))) | |
1044 (if (eq (featurep feature) flag) | |
1045 object | |
1046 ;; Ignore it. | |
1047 (throw 'reader-ignore nil)))) | |
1048 | |
1049 (set-dispatch-macro-character ?\# ?\+ | |
1050 (function | |
1051 (lambda (stream char n) | |
1052 (reader::read-feature stream char n t)))) | |
1053 | |
1054 (set-dispatch-macro-character ?\# ?\- | |
1055 (function | |
1056 (lambda (stream char n) | |
1057 (reader::read-feature stream char n nil)))) | |
1058 | |
1059 ;; (#+cl loop #+cl do #-cl while #-cl t (body)) | |
1060 | |
1061 | |
1062 | |
1063 | |
1064 ;; Shared structure reading: #<n>=, #<n># | |
1065 | |
1066 ;; Reading of sexpression with shared and circular structure read | |
1067 ;; syntax is done in two steps: | |
1068 ;; | |
1069 ;; 1. Create an sexpr with unshared structures, just as the ordinary | |
1070 ;; read macros do, with two exceptions: | |
1071 ;; - each label (#<n>=) creates, as a side effect, a symbolic | |
1072 ;; reference for the sexpr that follows it | |
1073 ;; - each reference (#<n>#) is replaced by the corresponding | |
1074 ;; symbolic reference. | |
1075 ;; | |
1076 ;; 2. This non-cyclic and unshared lisp structure is given to the | |
1077 ;; function `reader::restore-shared-structure' (see | |
1078 ;; `reader::read-from-buffer'), which simply replaces | |
1079 ;; destructively all symbolic references by the lisp structures the | |
1080 ;; references point at. | |
1081 ;; | |
1082 ;; A symbolic reference is an uninterned symbol whose name is obtained | |
1083 ;; from the label/reference number using the function `int-to-string': | |
1084 ;; | |
1085 ;; There are two non-locally used variables (bound in | |
1086 ;; `reader::read-from-buffer') which control shared structure reading: | |
1087 ;; `reader::shared-structure-labels': | |
1088 ;; A list of integers that correspond to the label numbers <n> in | |
1089 ;; the string currently read. This is used to avoid multiple | |
1090 ;; definitions of the same label. | |
1091 ;; `reader::shared-structure-references': | |
1092 ;; The list of symbolic references that will be used as temporary | |
1093 ;; placeholders for the shared objects introduced by a reference | |
1094 ;; with the same number identification. | |
1095 | |
1096 (set-dispatch-macro-character ?\# ?\= | |
1097 (function | |
1098 (lambda (stream char n) | |
1099 (and (= n 0) (reader::error "0 not allowed as label")) | |
1100 ;; check for multiple definition of the same label | |
1101 (if (memq n reader::shared-structure-labels) | |
1102 (reader::error "Label defined twice") | |
1103 (push n reader::shared-structure-labels)) | |
1104 ;; create an uninterned symbol as symbolic reference for the label | |
1105 (let* ((string (int-to-string n)) | |
1106 (ref (or (find string reader::shared-structure-references | |
1107 :test 'string=) | |
1108 (first | |
1109 (push (make-symbol string) | |
1110 reader::shared-structure-references))))) | |
1111 ;; the link between the symbolic reference and the lisp | |
1112 ;; structure it points at is done using the symbol value cell | |
1113 ;; of the reference symbol. | |
1114 (setf (symbol-value ref) | |
1115 ;; this is also the return value | |
1116 (reader::read-from-buffer stream 't)))))) | |
1117 | |
1118 | |
1119 (set-dispatch-macro-character ?\# ?\# | |
1120 (function | |
1121 (lambda (stream char n) | |
1122 (and (= n 0) (reader::error "0 not allowed as label")) | |
1123 ;; use the non-local variable `reader::recursive-p' (from the reader | |
1124 ;; main loop) to detect labels at the top level of an sexpr. | |
1125 (if (not reader::recursive-p) | |
1126 (reader::error "References at top level not allowed")) | |
1127 (let* ((string (int-to-string n)) | |
1128 (ref (or (find string reader::shared-structure-references | |
1129 :test 'string=) | |
1130 (first | |
1131 (push (make-symbol string) | |
1132 reader::shared-structure-references))))) | |
1133 ;; the value of reading a #n# form is a reference symbol | |
1134 ;; whose symbol value is or will be the shared structure. | |
1135 ;; `reader::restore-shared-structure' then replaces the symbol by | |
1136 ;; its value. | |
1137 ref)))) | |
1138 | |
1139 (defun reader::restore-shared-structure (obj) | |
1140 ;; traverses recursively OBJ and replaces all symbolic references by | |
1141 ;; the objects they point at. Remember that a symbolic reference is | |
1142 ;; an uninterned symbol whose value is the object it points at. | |
1143 (cond | |
1144 ((consp obj) | |
1145 (loop for rest on obj | |
1146 as lastcdr = rest | |
1147 do | |
1148 (if;; substructure is a symbolic reference | |
1149 (memq (car rest) reader::shared-structure-references) | |
1150 ;; replace it by its symbol value, i.e. the associated object | |
1151 (setf (car rest) (symbol-value (car rest))) | |
1152 (reader::restore-shared-structure (car rest))) | |
1153 finally | |
1154 (if (memq (cdr lastcdr) reader::shared-structure-references) | |
1155 (setf (cdr lastcdr) (symbol-value (cdr lastcdr))) | |
1156 (reader::restore-shared-structure (cdr lastcdr))))) | |
1157 ((vectorp obj) | |
1158 (loop for i below (length obj) | |
1159 do | |
1160 (if;; substructure is a symbolic reference | |
1161 (memq (aref obj i) reader::shared-structure-references) | |
1162 ;; replace it by its symbol value, i.e. the associated object | |
1163 (setf (aref obj i) (symbol-value (aref obj i))) | |
1164 (reader::restore-shared-structure (aref obj i)))))) | |
1165 obj) | |
1166 | |
1167 | |
1168 ;; #1=(a b #3=[#2=c]) | |
1169 ;; (#1=[#\return #\a] #1# #1#) | |
1170 ;; (#1=[a b c] #1# #1#) | |
1171 ;; #1=(a b . #1#) | |
1172 | |
1173 ;; Creation and initialization of an internal standard readtable. | |
1174 ;; Do this after all the macros and dispatch chars above have been defined. | |
1175 | |
1176 (defconst reader::internal-standard-readtable (copy-readtable) | |
1177 "The original (CL-like) standard readtable. If you ever modify this | |
1178 readtable, you won't be able to recover a standard readtable using | |
1179 \(copy-readtable nil\)") | |
1180 | |
1181 | |
1182 ;; Replace built-in functions that call the built-in reader | |
1183 ;; | |
1184 ;; The following functions are replaced here: | |
1185 ;; | |
1186 ;; read by reader::read | |
1187 ;; read-from-string by reader::read-from-string | |
1188 ;; | |
1189 ;; eval-expression by reader::eval-expression | |
1190 ;; Why replace eval-expression? Not needed for Lucid Emacs since the | |
1191 ;; reader for arguments is also written in Lisp, and so may be overridden. | |
1192 ;; | |
1193 ;; eval-current-buffer by reader::eval-current-buffer | |
1194 ;; eval-buffer by reader::eval-buffer | |
1195 ;; original-eval-region by reader::original-eval-region | |
1196 | |
1197 | |
1198 ;; Temporary read buffer used for reading from strings | |
1199 (defconst reader::tmp-buffer | |
1200 (get-buffer-create " *CL Read*")) | |
1201 | |
1202 ;; Save a pointer to the original read function | |
1203 (or (fboundp 'reader::original-read) | |
1204 (fset 'reader::original-read (symbol-function 'read))) | |
1205 | |
1206 (defun reader::read (&optional stream reader::recursive-p) | |
1207 "Read one Lisp expression as text from STREAM, return as Lisp object. | |
1208 If STREAM is nil, use the value of `standard-input' \(which see\). | |
1209 STREAM or the value of `standard-input' may be: | |
1210 a buffer \(read from point and advance it\) | |
1211 a marker \(read from where it points and advance it\) | |
1212 a string \(takes text from string, starting at the beginning\) | |
1213 t \(read text line using minibuffer and use it\). | |
1214 | |
1215 This is the cl-read replacement of the standard elisp function | |
1216 `read'. The only incompatibility is that functions as stream arguments | |
1217 are not supported." | |
1218 (if (not cl-read-active) | |
1219 (reader::original-read stream) | |
1220 (if (null stream) ; read from standard-input | |
1221 (setq stream standard-input)) | |
1222 | |
1223 (if (eq stream 't) ; read from minibuffer | |
1224 (setq stream (read-from-minibuffer "Common Lisp Expression: "))) | |
1225 | |
1226 (cond | |
1227 | |
1228 ((bufferp stream) ; read from buffer | |
1229 (reader::read-from-buffer stream reader::recursive-p)) | |
1230 | |
1231 ((markerp stream) ; read from marker | |
1232 (save-excursion | |
1233 (set-buffer (marker-buffer stream)) | |
1234 (goto-char (marker-position stream)) | |
1235 (reader::read-from-buffer (current-buffer) reader::recursive-p))) | |
1236 | |
1237 ((stringp stream) ; read from string | |
1238 (save-excursion | |
1239 (set-buffer reader::tmp-buffer) | |
1240 (auto-save-mode -1) | |
1241 (erase-buffer) | |
1242 (insert stream) | |
1243 (goto-char (point-min)) | |
1244 (reader::read-from-buffer reader::tmp-buffer reader::recursive-p))) | |
1245 (t | |
1246 (reader::error "Not a valid stream: %s" stream))))) | |
1247 | |
1248 ;; read-from-string | |
1249 ;; save a pointer to the original `read-from-string' function | |
1250 (or (fboundp 'reader::original-read-from-string) | |
1251 (fset 'reader::original-read-from-string | |
1252 (symbol-function 'read-from-string))) | |
1253 | |
1254 (defun reader::read-from-string (string &optional start end) | |
1255 "Read one Lisp expression which is represented as text by STRING. | |
1256 Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX). | |
1257 START and END optionally delimit a substring of STRING from which to read; | |
1258 they default to 0 and (length STRING) respectively. | |
1259 | |
1260 This is the cl-read replacement of the standard elisp function | |
1261 `read-from-string'. It uses the reader macros in *readtable* if | |
1262 `cl-read-active' is non-nil in the current buffer." | |
1263 | |
1264 ;; Does it really make sense to have read-from-string depend on | |
1265 ;; what the current buffer happens to be? Yes, so code that | |
1266 ;; has nothing to do with cl-read uses original reader. | |
1267 (if (not cl-read-active) | |
1268 (reader::original-read-from-string string start end) | |
1269 (or start (setq start 0)) | |
1270 (or end (setq end (length string))) | |
1271 (save-excursion | |
1272 (set-buffer reader::tmp-buffer) | |
1273 (auto-save-mode -1) | |
1274 (erase-buffer) | |
1275 (insert (substring string 0 end)) | |
1276 (goto-char (1+ start)) | |
1277 (cons | |
1278 (reader::read-from-buffer reader::tmp-buffer nil) | |
1279 (1- (point)))))) | |
1280 | |
1281 ;; (read-from-string "abc (car 'a) bc" 4) | |
1282 ;; (reader::read-from-string "abc (car 'a) bc" 4) | |
1283 ;; (read-from-string "abc (car 'a) bc" 2 11) | |
1284 ;; (reader::read-from-string "abc (car 'a) bc" 2 11) | |
1285 ;; (reader::read-from-string "`(car ,first ,@rest)") | |
1286 ;; (read-from-string ";`(car ,first ,@rest)") | |
1287 ;; (reader::read-from-string ";`(car ,first ,@rest)") | |
1288 | |
1289 ;; We should replace eval-expression, too, so that it reads (and | |
1290 ;; evals) in the current buffer. Alternatively, this could be fixed | |
1291 ;; in C. In Lemacs 19.6 and later, this function is already written | |
1292 ;; in lisp, and based on more primitive read functions we already | |
1293 ;; replaced. The reading happens during the interactive parameter | |
1294 ;; retrieval, which is written in lisp, too. So this replacement of | |
1295 ;; eval-expresssion is only required fro (FSF) Emacs 18 (and 19?). | |
1296 | |
1297 (or (fboundp 'reader::original-eval-expression) | |
1298 (fset 'reader::original-eval-expression | |
1299 (symbol-function 'eval-expression))) | |
1300 | |
1301 (defun reader::eval-expression (reader::expression) | |
1302 "Evaluate EXPRESSION and print value in minibuffer. | |
1303 Value is also consed on to front of variable `values'." | |
1304 (interactive | |
1305 (list | |
1306 (car (read-from-string | |
1307 (read-from-minibuffer | |
1308 "Eval: " nil | |
1309 ;;read-expression-map ;; not for emacs 18 | |
1310 nil ;; use default map | |
1311 nil ;; don't do read with minibuffer current. | |
1312 ;; 'edebug-expression-history ;; not for emacs 18 | |
1313 ))))) | |
1314 (setq values (cons (eval reader::expression) values)) | |
1315 (prin1 (car values) t)) | |
1316 | |
1317 (require 'eval-reg "eval-reg") | |
1318 (require 'advice) | |
1319 | |
1320 | |
1321 ;; installing/uninstalling the cl reader | |
1322 ;; These two should always be used in pairs, or just install once and | |
1323 ;; never uninstall. | |
1324 (defun cl-reader-install () | |
1325 (interactive) | |
1326 (fset 'read 'reader::read) | |
1327 (fset 'read-from-string 'reader::read-from-string) | |
1328 (fset 'eval-expression 'reader::eval-expression) | |
1329 (elisp-eval-region-install)) | |
1330 | |
1331 (defun cl-reader-uninstall () | |
1332 (interactive) | |
1333 (fset 'read | |
1334 (symbol-function 'reader::original-read)) | |
1335 (fset 'read-from-string | |
1336 (symbol-function 'reader::original-read-from-string)) | |
1337 (fset 'eval-expression | |
1338 (symbol-function 'reader::original-eval-expression)) | |
1339 (elisp-eval-region-uninstall)) | |
1340 | |
1341 ;; Globally installing the cl-read replacement functions is safe, even | |
1342 ;; for buffers without cl read syntax. The buffer local variable | |
1343 ;; `cl-read-active' controls whether the replacement funtions of this | |
1344 ;; package or the original ones are actually called. | |
1345 (cl-reader-install) | |
1346 (cl-reader-uninstall) | |
1347 | |
1348 ;; Advise the redefined eval-region | |
1349 (defadvice eval-region (around cl-read activate) | |
1350 "Use the reader::read instead of the original read if cl-read-active." | |
1351 (with-elisp-eval-region (not cl-read-active) | |
1352 (ad-do-it))) | |
1353 ;;(ad-unadvise 'eval-region) | |
1354 | |
1355 | |
1356 (add-hook 'emacs-lisp-mode-hook 'cl-reader-autoinstall-function) | |
1357 | |
1358 '(defvar read-syntax) | |
1359 | |
1360 '(defun cl-reader-autoinstall-function () | |
1361 "Activates the Common Lisp style reader for emacs-lisp-mode buffers, | |
1362 if the property line has a local variable setting like this: | |
1363 \;\; -*- Read-Syntax: Common-Lisp -*-" | |
1364 ;; this is a hack to avoid recursion in the case that the prop line | |
1365 ;; containes "Mode: emacs-lisp" entry | |
1366 (or (boundp 'local-variable-hack-done) | |
1367 (let (local-variable-hack-done | |
1368 (case-fold-search t)) | |
1369 ;; Usually `hack-local-variables-prop-line' is called only after | |
1370 ;; installation of the major mode. But we need to know about the | |
1371 ;; local variables before that, so we call the local variable hack | |
1372 ;; explicitly here: | |
1373 (hack-local-variables-prop-line 't) | |
1374 ;; But hack-local-variables-prop-line not defined in emacs 18. | |
1375 (cond | |
1376 ((and (boundp 'read-syntax) | |
1377 read-syntax | |
1378 (string-match "^common-lisp$" (symbol-name read-syntax))) | |
1379 (require 'cl-read) | |
1380 (make-local-variable 'cl-read-active) | |
1381 (setq cl-read-active 't)))))) | |
1382 | |
1383 ;; Emacs 18 doesnt have hack-local-variables-prop-line. So use this instead. | |
1384 (defun cl-reader-autoinstall-function () | |
1385 (save-excursion | |
1386 (goto-char (point-min)) | |
1387 (let ((case-fold-search t)) | |
1388 (cond ((re-search-forward | |
1389 "read-syntax: *common-lisp" | |
1390 (save-excursion | |
1391 (end-of-line) | |
1392 (point)) | |
1393 t) | |
1394 (require 'cl-read) | |
1395 (make-local-variable 'cl-read-active) | |
1396 (setq cl-read-active t)))))) | |
1397 | |
1398 | |
1399 (run-hooks 'cl-read-load-hooks) | |
1400 ;; end cl-read.el |