changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > core / lisp/std/named-readtables.lisp

changeset 698: 96958d3eb5b0
parent: 00d1c8afcdbb
author: Richard Westhaver <ellis@rwest.io>
date: Fri, 04 Oct 2024 22:04:59 -0400
permissions: -rw-r--r--
description: fixes
1 ;;; named-readtables.lisp --- named-readtables
2 
3 ;; The standard readtable is controlled by the Lisp implementation and
4 ;; generally shouldn't be touched. There can be problems with
5 ;; 'stacking' multiple read-macros as can be seen in this SO post:
6 ;; https://stackoverflow.com/questions/73346051/how-can-i-modify-the-and-readtable-macros-in-lisp
7 
8 ;; Instead, if you really want to change standard readtable behavior,
9 ;; it is better to define your own readtables and be aware of the
10 ;; context in which they are enabled. For example, loading a system
11 ;; definition before enabling the readtable may cause divergent
12 ;; behavior (using standard) versus your source code (custom).
13 
14 ;;; Code:
15 (defpackage :std/named-readtables
16  (:use :cl)
17  (:export
18  :defreadtable
19  :in-readtable
20  :make-readtable
21  :merge-readtables-into
22  :find-readtable
23  :ensure-readtable
24  :rename-readtable
25  :readtable-name
26  :register-readtable
27  :unregister-readtable
28  :copy-named-readtable
29  :list-all-named-readtables
30  ;; Types
31  :named-readtable-designator
32  ;; Conditions
33  :readtable-error
34  :reader-macro-conflict
35  :readtable-does-already-exist
36  :readtable-does-not-exist
37  :parse-body))
38 
39 (in-package :std/named-readtables)
40 (pushnew :named-readtables *features*)
41 
42 (defmacro without-package-lock ((&rest package-names) &body body)
43  `(sb-ext:with-unlocked-packages (,@package-names) ,@body))
44 
45 ;;; Taken from SWANK (which is Public Domain.)
46 
47 (defmacro destructure-case (value &body patterns)
48  "Dispatch VALUE to one of PATTERNS.
49 A cross between `case' and `destructuring-bind'.
50 The pattern syntax is:
51  ((HEAD . ARGS) . BODY)
52 The list of patterns is searched for a HEAD `eq' to the car of
53 VALUE. If one is found, the BODY is executed with ARGS bound to the
54 corresponding values in the CDR of VALUE."
55  (let ((operator (gensym "op-"))
56  (operands (gensym "rand-"))
57  (tmp (gensym "tmp-")))
58  `(let* ((,tmp ,value)
59  (,operator (car ,tmp))
60  (,operands (cdr ,tmp)))
61  (case ,operator
62  ,@(loop for (pattern . body) in patterns collect
63  (if (eq pattern t)
64  `(t ,@body)
65  (destructuring-bind (op &rest rands) pattern
66  `(,op (destructuring-bind ,rands ,operands
67  ,@body)))))
68  ,@(if (eq (caar (last patterns)) t)
69  '()
70  `((t (error "destructure-case failed: ~S" ,tmp))))))))
71 
72 ;;; Taken from Alexandria (which is Public Domain, or BSD.)
73 
74 (define-condition simple-style-warning (simple-warning style-warning)
75  ())
76 
77 (defun simple-style-warn (format-control &rest format-args)
78  (warn 'simple-style-warning
79  :format-control format-control
80  :format-arguments format-args))
81 
82 (define-condition simple-program-error (simple-error program-error)
83  ())
84 
85 (defun simple-program-error (message &rest args)
86  (error 'simple-program-error
87  :format-control message
88  :format-arguments args))
89 
90 (defun required-argument (&optional name)
91  "Signals an error for a missing argument of NAME. Intended for
92 use as an initialization form for structure and class-slots, and
93 a default value for required keyword arguments."
94  (error "Required argument ~@[~S ~]missing." name))
95 
96 (defun ensure-list (list)
97  "If LIST is a list, it is returned. Otherwise returns the list
98 designated by LIST."
99  (if (listp list)
100  list
101  (list list)))
102 
103 (declaim (inline ensure-function)) ; to propagate return type.
104 (declaim (ftype (function (t) (values function &optional))
105  ensure-function))
106 (defun ensure-function (function-designator)
107  "Returns the function designated by FUNCTION-DESIGNATOR:
108 if FUNCTION-DESIGNATOR is a function, it is returned, otherwise
109 it must be a function name and its FDEFINITION is returned."
110  (if (functionp function-designator)
111  function-designator
112  (fdefinition function-designator)))
113 
114 (eval-when (:compile-toplevel :load-toplevel :execute)
115 (defun parse-body (body &key documentation whole)
116  "Parses BODY into (values remaining-forms declarations doc-string).
117 Documentation strings are recognized only if DOCUMENTATION is true.
118 Syntax errors in body are signalled and WHOLE is used in the signal
119 arguments when given."
120  (let ((doc nil)
121  (decls nil)
122  (current nil))
123  (tagbody
124  :declarations
125  (setf current (car body))
126  (when (and documentation (stringp current) (cdr body))
127  (if doc
128  (error "Too many documentation strings in ~S." (or whole body))
129  (setf doc (pop body)))
130  (go :declarations))
131  (when (and (listp current) (eql (first current) 'declare))
132  (push (pop body) decls)
133  (go :declarations)))
134  (values body (nreverse decls) doc)))
135 
136 (defun parse-ordinary-lambda-list (lambda-list)
137  "Parses an ordinary lambda-list, returning as multiple values:
138 
139  1. Required parameters.
140  2. Optional parameter specifications, normalized into form (NAME INIT SUPPLIEDP)
141  where SUPPLIEDP is NIL if not present.
142  3. Name of the rest parameter, or NIL.
143  4. Keyword parameter specifications, normalized into form ((KEYWORD-NAME NAME) INIT SUPPLIEDP)
144  where SUPPLIEDP is NIL if not present.
145  5. Boolean indicating &ALLOW-OTHER-KEYS presence.
146  6. &AUX parameter specifications, normalized into form (NAME INIT).
147 
148 Signals a PROGRAM-ERROR is the lambda-list is malformed."
149  (let ((state :required)
150  (allow-other-keys nil)
151  (auxp nil)
152  (required nil)
153  (optional nil)
154  (rest nil)
155  (keys nil)
156  (aux nil))
157  (labels ((simple-program-error (format-string &rest format-args)
158  (error 'simple-program-error
159  :format-control format-string
160  :format-arguments format-args))
161  (fail (elt)
162  (simple-program-error "Misplaced ~S in ordinary lambda-list:~% ~S"
163  elt lambda-list))
164  (check-variable (elt what)
165  (unless (and (symbolp elt) (not (constantp elt)))
166  (simple-program-error "Invalid ~A ~S in ordinary lambda-list:~% ~S"
167  what elt lambda-list)))
168  (check-spec (spec what)
169  (destructuring-bind (init suppliedp) spec
170  (declare (ignore init))
171  (check-variable suppliedp what)))
172  (make-keyword (name)
173  "Interns the string designated by NAME in the KEYWORD package."
174  (intern (string name) :keyword)))
175  (dolist (elt lambda-list)
176  (case elt
177  (&optional
178  (if (eq state :required)
179  (setf state elt)
180  (fail elt)))
181  (&rest
182  (if (member state '(:required &optional))
183  (setf state elt)
184  (progn
185  (break "state=~S" state)
186  (fail elt))))
187  (&key
188  (if (member state '(:required &optional :after-rest))
189  (setf state elt)
190  (fail elt)))
191  (&allow-other-keys
192  (if (eq state '&key)
193  (setf allow-other-keys t
194  state elt)
195  (fail elt)))
196  (&aux
197  (cond ((eq state '&rest)
198  (fail elt))
199  (auxp
200  (simple-program-error "Multiple ~S in ordinary lambda-list:~% ~S"
201  elt lambda-list))
202  (t
203  (setf auxp t
204  state elt))
205  ))
206  (otherwise
207  (when (member elt '#.(set-difference lambda-list-keywords
208  '(&optional &rest &key &allow-other-keys &aux)))
209  (simple-program-error
210  "Bad lambda-list keyword ~S in ordinary lambda-list:~% ~S"
211  elt lambda-list))
212  (case state
213  (:required
214  (check-variable elt "required parameter")
215  (push elt required))
216  (&optional
217  (cond ((consp elt)
218  (destructuring-bind (name &rest tail) elt
219  (check-variable name "optional parameter")
220  (if (cdr tail)
221  (check-spec tail "optional-supplied-p parameter")
222  (setf elt (append elt '(nil))))))
223  (t
224  (check-variable elt "optional parameter")
225  (setf elt (cons elt '(nil nil)))))
226  (push elt optional))
227  (&rest
228  (check-variable elt "rest parameter")
229  (setf rest elt
230  state :after-rest))
231  (&key
232  (cond ((consp elt)
233  (destructuring-bind (var-or-kv &rest tail) elt
234  (cond ((consp var-or-kv)
235  (destructuring-bind (keyword var) var-or-kv
236  (unless (symbolp keyword)
237  (simple-program-error "Invalid keyword name ~S in ordinary ~
238  lambda-list:~% ~S"
239  keyword lambda-list))
240  (check-variable var "keyword parameter")))
241  (t
242  (check-variable var-or-kv "keyword parameter")
243  (setf var-or-kv (list (make-keyword var-or-kv) var-or-kv))))
244  (if (cdr tail)
245  (check-spec tail "keyword-supplied-p parameter")
246  (setf tail (append tail '(nil))))
247  (setf elt (cons var-or-kv tail))))
248  (t
249  (check-variable elt "keyword parameter")
250  (setf elt (list (list (make-keyword elt) elt) nil nil))))
251  (push elt keys))
252  (&aux
253  (if (consp elt)
254  (destructuring-bind (var &optional init) elt
255  (declare (ignore init))
256  (check-variable var "&aux parameter"))
257  (check-variable elt "&aux parameter"))
258  (push elt aux))
259  (t
260  (simple-program-error "Invalid ordinary lambda-list:~% ~S" lambda-list)))))))
261  (values (nreverse required) (nreverse optional) rest (nreverse keys)
262  allow-other-keys (nreverse aux)))))
263 
264 (defmacro define-api (name lambda-list type-list &body body)
265  (flet ((parse-type-list (type-list)
266  (let ((pos (position '=> type-list)))
267  (assert pos () "You forgot to specify return type (`=>' missing.)")
268  (values (subseq type-list 0 pos)
269  `(values ,@(nthcdr (1+ pos) type-list) &optional)))))
270  (multiple-value-bind (body decls docstring)
271  (parse-body body :documentation t :whole `(define-api ,name))
272  (multiple-value-bind (arg-typespec value-typespec)
273  (parse-type-list type-list)
274  (multiple-value-bind (reqs opts rest keys)
275  (parse-ordinary-lambda-list lambda-list)
276  (declare (ignorable reqs opts rest keys))
277  `(progn
278  (declaim (ftype (function ,arg-typespec ,value-typespec) ,name))
279  (locally
280  ;; Muffle the annoying "&OPTIONAL and &KEY found in
281  ;; the same lambda list" style-warning
282  #+sbcl (declare (sb-ext:muffle-conditions style-warning))
283  (defun ,name ,lambda-list
284  ,docstring
285  ,@decls
286  (locally
287  #+sbcl (declare (sb-ext:unmuffle-conditions style-warning))
288  ;; SBCL will interpret the ftype declaration as
289  ;; assertion and will insert type checks for us.
290  ,@body)))))))))
291 
292 (defmacro define-cruft (name lambda-list &body (docstring . alternatives))
293  (assert (typep docstring 'string) (docstring) "Docstring missing!")
294  (assert (not (null alternatives)))
295  `(progn
296  (declaim (inline ,name))
297  (defun ,name ,lambda-list ,docstring ,(first alternatives))))
298 
299 (eval-when (:compile-toplevel :execute)
300  #+sbcl (when (find-symbol "ASSERT-NOT-STANDARD-READTABLE"
301  (find-package "SB-IMPL"))
302  (pushnew :sbcl+safe-standard-readtable *features*)))
303 
304 
305 
306 ;;;; Mapping between a readtable object and its readtable-name.
307 
308 (defvar *readtable-names* (make-hash-table :test 'eq))
309 
310 (define-cruft %associate-readtable-with-name (name readtable)
311  "Associate READTABLE with NAME for READTABLE-NAME to work."
312  #+ :common-lisp (setf (gethash readtable *readtable-names*) name))
313 
314 (define-cruft %unassociate-readtable-from-name (name readtable)
315  "Remove the association between READTABLE and NAME."
316  #+ :common-lisp (progn (assert (eq name (gethash readtable *readtable-names*)))
317  (remhash readtable *readtable-names*)))
318 
319 (define-cruft %readtable-name (readtable)
320  "Return the name associated with READTABLE."
321  #+ :common-lisp (values (gethash readtable *readtable-names*)))
322 
323 (define-cruft %list-all-readtable-names ()
324  "Return a list of all available readtable names."
325  #+ :common-lisp (list* :standard :current :modern
326  (loop for name being each hash-value of *readtable-names*
327  collect name)))
328 
329 ;;;; Mapping READTABLE objects to docstrings.
330 
331 (defvar *readtable-to-docstring* (make-hash-table :test 'eq))
332 
333 (defun %associate-docstring-with-readtable (readtable docstring)
334  (setf (gethash readtable *readtable-to-docstring*) docstring))
335 
336 (defun %unassociate-docstring-from-readtable (readtable)
337  (prog1 (gethash readtable *readtable-to-docstring*)
338  (remhash readtable *readtable-to-docstring*)))
339 
340 ;;;; Specialized DOCUMENTATION for named readtables.
341 
342 ;;; Lispworks, at least, forbids defining methods on DOCUMENTATION.
343 ;;; Wrapping these forms with WITHOUT-PACKAGE-LOCK (as for PRINT-OBJECT,
344 ;;; see below) allows this to compile on Lispworks.
345 
346 (without-package-lock (:common-lisp #+lispworks :implementation)
347 
348  (defmethod documentation ((name symbol) (doc-type (eql 'readtable)))
349  (let ((readtable (find-readtable name)))
350  (and readtable (gethash readtable *readtable-to-docstring*))))
351 
352  (defmethod documentation ((readtable readtable) (doc-type (eql 'readtable)))
353  (gethash readtable *readtable-to-docstring*))
354 
355  (defmethod (setf documentation) (docstring (name symbol)
356  (doc-type (eql 'readtable)))
357  (let ((readtable (find-readtable name)))
358  (unless readtable
359  (error 'readtable-does-not-exist :readtable-name name))
360  (setf (gethash readtable *readtable-to-docstring*) docstring)))
361 
362  (defmethod (setf documentation) (docstring (readtable readtable)
363  (doc-type (eql 'readtable)))
364  (setf (gethash readtable *readtable-to-docstring*) docstring)))
365 
366 
367 ;;;; Mapping between a readtable-name and the actual readtable object.
368 
369 ;;; On Allegro we reuse their named-readtable support so we work
370 ;;; nicely on their infrastructure.
371 
372 (defvar *named-readtables* (make-hash-table :test 'eq))
373 
374 (define-cruft %associate-name-with-readtable (name readtable)
375  "Associate NAME with READTABLE for FIND-READTABLE to work."
376  #+ :common-lisp (setf (gethash name *named-readtables*) readtable))
377 
378 (define-cruft %unassociate-name-from-readtable (name readtable)
379  "Remove the association between NAME and READTABLE"
380  #+ :common-lisp (progn (assert (eq readtable (gethash name *named-readtables*)))
381  (remhash name *named-readtables*)))
382 
383 (define-cruft %find-readtable (name)
384  "Return the readtable named NAME."
385  #+ :common-lisp (values (gethash name *named-readtables* nil)))
386 
387 
388 ;;;; Reader-macro related predicates
389 
390 ;;; CLISP creates new function objects for standard reader macros on
391 ;;; each readtable copy.
392 (define-cruft function= (fn1 fn2)
393  "Are reader-macro function-designators FN1 and FN2 the same?"
394  (let ((fn1 (ensure-function fn1))
395  (fn2 (ensure-function fn2)))
396  (or (eq fn1 fn2)
397  ;; After SBCL 1.1.18, for dispatch macro characters
398  ;; GET-MACRO-CHARACTER returns closures whose name is:
399  ;;
400  ;; (LAMBDA (STREAM CHAR) :IN SB-IMPL::%MAKE-DISPATCH-MACRO-CHAR)
401  ;;
402  ;; Treat all these closures equivalent.
403  (flet ((internal-dispatch-macro-closure-name-p (name)
404  (find "SB-IMPL::%MAKE-DISPATCH-MACRO-CHAR" name
405  :key #'prin1-to-string :test #'string-equal)))
406  (let ((n1 (sb-impl::%fun-name fn1))
407  (n2 (sb-impl::%fun-name fn2)))
408  (and (listp n1) (listp n2)
409  (internal-dispatch-macro-closure-name-p n1)
410  (internal-dispatch-macro-closure-name-p n2))))))
411  #+ :common-lisp
412  (eq (ensure-function fn1) (ensure-function fn2)))
413 
414 (define-cruft dispatch-macro-char-p (char rt)
415  "Is CHAR a dispatch macro character in RT?"
416  #+ :common-lisp
417  (handler-case (locally
418  (get-dispatch-macro-character char #\x rt)
419  t)
420  (error () nil)))
421 
422 ;; (defun macro-char-p (char rt)
423 ;; (let ((reader-fn (%get-macro-character char rt)))
424 ;; (and reader-fn t)))
425 
426 ;; (defun standard-macro-char-p (char rt)
427 ;; (multiple-value-bind (rt-fn rt-flag) (get-macro-character char rt)
428 ;; (multiple-value-bind (std-fn std-flag) (get-macro-character char *standard-readtable*)
429 ;; (and (eq rt-fn std-fn)
430 ;; (eq rt-flag std-flag)))))
431 
432 ;; (defun standard-dispatch-macro-char-p (disp-char sub-char rt)
433 ;; (flet ((non-terminating-p (ch rt) (nth-value 1 (get-macro-character ch rt))))
434 ;; (and (eq (non-terminating-p disp-char rt)
435 ;; (non-terminating-p disp-char *standard-readtable*))
436 ;; (eq (get-dispatch-macro-character disp-char sub-char rt)
437 ;; (get-dispatch-macro-character disp-char sub-char *standard-readtable*)))))
438 
439 
440 ;;;; Readtables Iterators
441 
442 (defmacro with-readtable-iterator ((name readtable) &body body)
443  (let ((it (gensym)))
444  `(let ((,it (%make-readtable-iterator ,readtable)))
445  (macrolet ((,name () `(funcall ,',it)))
446  ,@body))))
447 
448 (defun funcall-or (package-and-name-list &rest args)
449  (loop for (package name) in package-and-name-list
450  do (let ((symbol (find-symbol (string name) package)))
451  (when symbol
452  (return-from funcall-or (apply symbol args))))))
453 
454 (defun %make-readtable-iterator (readtable)
455  (let ((char-macro-array (funcall-or '((sb-impl base-char-macro-array)
456  (sb-impl character-macro-array))
457  readtable))
458  (char-macro-ht (funcall-or '((sb-impl extended-char-table)
459  (sb-impl character-macro-hash-table))
460  readtable))
461  (dispatch-tables (sb-impl::dispatch-tables readtable))
462  (char-code 0))
463  (with-hash-table-iterator (ht-iterator char-macro-ht)
464  (labels ((grovel-base-chars ()
465  (if (>= char-code sb-int:base-char-code-limit)
466  (grovel-unicode-chars)
467  (let ((reader-fn (svref char-macro-array char-code))
468  (char (code-char (shiftf char-code (1+ char-code)))))
469  (if reader-fn
470  (yield char)
471  (grovel-base-chars)))))
472  (grovel-unicode-chars ()
473  (multiple-value-bind (more? char) (ht-iterator)
474  (if (not more?)
475  (values nil nil nil nil nil)
476  (yield char))))
477  (yield (char)
478  (let ((disp-fn (get-macro-character char readtable))
479  (disp-ht))
480  (cond
481  ((setq disp-ht (cdr (assoc char dispatch-tables)))
482  (let ((sub-char-alist))
483  (maphash (lambda (k v)
484  (push (cons k v) sub-char-alist))
485  disp-ht)
486  (values t char disp-fn t sub-char-alist)))
487  (t
488  (values t char disp-fn nil nil))))))
489  #'grovel-base-chars))))
490 
491 (defmacro do-readtable ((entry-designator readtable &optional result)
492  &body body)
493  "Iterate through a readtable's macro characters, and dispatch macro characters."
494  (destructuring-bind (char &optional reader-fn non-terminating-p disp? table)
495  (if (symbolp entry-designator)
496  (list entry-designator)
497  entry-designator)
498  (let ((iter (gensym "ITER+"))
499  (more? (gensym "MORE?+"))
500  (rt (gensym "READTABLE+")))
501  `(let ((,rt ,readtable))
502  (with-readtable-iterator (,iter ,rt)
503  (loop
504  (multiple-value-bind (,more?
505  ,char
506  ,@(when reader-fn (list reader-fn))
507  ,@(when disp? (list disp?))
508  ,@(when table (list table)))
509  (,iter)
510  (unless ,more? (return ,result))
511  (let ,(when non-terminating-p
512  ;; FIXME: N-T-P should be incorporated in iterators.
513  `((,non-terminating-p
514  (nth-value 1 (get-macro-character ,char ,rt)))))
515  ,@body))))))))
516 
517 ;;;; Misc
518 
519 ;;; This should return an implementation's actual standard readtable
520 ;;; object only if the implementation makes the effort to guard against
521 ;;; modification of that object. Otherwise it should better return a
522 ;;; copy.
523 (define-cruft %standard-readtable ()
524  "Return the standard readtable."
525  #+ :sbcl+safe-standard-readtable sb-impl::*standard-readtable*
526  #+ :common-lisp (copy-readtable nil))
527 
528 ;;; On SBCL, SET-SYNTAX-FROM-CHAR does not get rid of a
529 ;;; readtable's dispatch table properly.
530 ;;; Same goes for Allegro but that does not seem to provide a
531 ;;; setter for their readtable's dispatch tables. Hence this ugly
532 ;;; workaround.
533 (define-cruft %clear-readtable (readtable)
534  "Make all macro characters in READTABLE be constituents."
535  (prog1 readtable
536  (do-readtable (char readtable)
537  (set-syntax-from-char char #\A readtable))
538  (setf (sb-impl::dispatch-tables readtable) nil))
539  #+ :common-lisp
540  (do-readtable (char readtable readtable)
541  (set-syntax-from-char char #\A readtable)))
542 
543 (define-cruft %get-dispatch-macro-character (char subchar rt)
544  "Ensure ANSI behaviour for GET-DISPATCH-MACRO-CHARACTER."
545  #+ :common-lisp (get-dispatch-macro-character char subchar rt))
546 
547 (define-cruft %get-macro-character (char rt)
548  "Ensure ANSI behaviour for GET-MACRO-CHARACTER."
549  #+ :common-lisp (get-macro-character char rt))
550 
551 
552 ;;;; Specialized PRINT-OBJECT for named readtables.
553 
554 ;;; As per #19 in CLHS 11.1.2.1.2 defining a method for PRINT-OBJECT
555 ;;; that specializes on READTABLE is actually forbidden. It's quite
556 ;;; likely to work (modulo package-locks) on most implementations,
557 ;;; though.
558 
559 (without-package-lock (:common-lisp)
560  (defmethod print-object :around ((rt readtable) stream)
561  (let ((name (readtable-name rt)))
562  (if name
563  (print-unreadable-object (rt stream :type nil :identity t)
564  (format stream "~A ~S" :named-readtable name))
565  (call-next-method)))))
566 
567 ;;;
568 ;;; ``This is enough of a foothold to implement a more elaborate
569 ;;; facility for using readtables in a localized way.''
570 ;;;
571 ;;; (X3J13 Cleanup Issue IN-SYNTAX)
572 ;;;
573 
574 ;;;;;; DEFREADTABLE &c.
575 (defmacro defreadtable (name &body options)
576  "Define a new named readtable, whose name is given by the symbol NAME.
577  Or, if a readtable is already registered under that name, redefine
578  that one.
579 
580  The readtable can be populated using the following OPTIONS:
581 
582  - If the first element of OPTIONS is a string then it is associated
583  with the readtable as in `(SETF (DOCUMENTATION NAME 'READTABLE)
584  DOCSTRING)`.
585 
586  - `(:MERGE READTABLE-DESIGNATORS+)`
587 
588  Merge the macro character definitions from the readtables
589  designated into the new readtable being defined as per
590  MERGE-READTABLES-INTO. The copied options are
591  :DISPATCH-MACRO-CHAR, :MACRO-CHAR and :SYNTAX-FROM, but not
592  READTABLE-CASE.
593 
594  If no :MERGE clause is given, an empty readtable is used. See
595  MAKE-READTABLE.
596 
597  - `(:FUSE READTABLE-DESIGNATORS+)`
598 
599  Like :MERGE except:
600 
601  Error conditions of type READER-MACRO-CONFLICT that are signaled
602  during the merge operation will be silently _continued_. It
603  follows that reader macros in earlier entries will be
604  overwritten by later ones. For backward compatibility, :FUZE is
605  accepted as an alias of :FUSE.
606 
607  - `(:DISPATCH-MACRO-CHAR MACRO-CHAR SUB-CHAR FUNCTION)`
608 
609  Define a new sub character `SUB-CHAR` for the dispatching macro
610  character `MACRO-CHAR`, per SET-DISPATCH-MACRO-CHARACTER. You
611  probably have to define `MACRO-CHAR` as a dispatching macro
612  character by the following option first.
613 
614  - `(:MACRO-CHAR MACRO-CHAR FUNCTION [NON-TERMINATING-P])`
615 
616  Define a new macro character in the readtable, per
617  SET-MACRO-CHARACTER. If [FUNCTION][argument] is the keyword
618  :DISPATCH, `MACRO-CHAR` is made a dispatching macro character,
619  per MAKE-DISPATCH-MACRO-CHARACTER.
620 
621  - `(:SYNTAX-FROM FROM-READTABLE-DESIGNATOR FROM-CHAR TO-CHAR)`
622 
623  Set the character syntax of TO-CHAR in the readtable being
624  defined to the same syntax as FROM-CHAR as per
625  SET-SYNTAX-FROM-CHAR.
626 
627  - `(:CASE CASE-MODE)`
628 
629  Defines the _case sensitivity mode_ of the resulting readtable.
630 
631  Any number of option clauses may appear. The options are grouped by
632  their type, but in each group the order the options appeared
633  textually is preserved. The following groups exist and are executed
634  in the following order: :MERGE and :FUSE (one group), :CASE,
635  :MACRO-CHAR and :DISPATCH-MACRO-CHAR (one group), finally
636  :SYNTAX-FROM.
637 
638  Notes:
639 
640  The readtable is defined at load-time. If you want to have it
641  available at compilation time -- say to use its reader-macros in the
642  same file as its definition -- you have to wrap the DEFREADTABLE
643  form in an explicit EVAL-WHEN.
644 
645  On redefinition, the target readtable is made empty first before
646  it's refilled according to the clauses.
647 
648  NIL, :STANDARD, :COMMON-LISP, :MODERN, and :CURRENT are
649  preregistered readtable names."
650  (check-type name symbol)
651  (when (reserved-readtable-name-p name)
652  (error "~A is the designator for a predefined readtable. ~
653  Not acceptable as a user-specified readtable name." name))
654  (flet ((process-option (option var)
655  (destructure-case option
656  ((:merge &rest readtable-designators)
657  `(merge-readtables-into ,var ,@(mapcar #'(lambda (x) `',x)
658  readtable-designators)))
659  ((:fuse &rest readtable-designators)
660  `(handler-bind ((reader-macro-conflict #'continue))
661  (merge-readtables-into ,var ,@(mapcar #'(lambda (x) `',x)
662  readtable-designators))))
663  ;; alias for :FUSE
664  ((:fuze &rest readtable-designators)
665  `(handler-bind ((reader-macro-conflict #'continue))
666  (merge-readtables-into ,var ,@(mapcar #'(lambda (x) `',x)
667  readtable-designators))))
668  ((:dispatch-macro-char disp-char sub-char function)
669  `(set-dispatch-macro-character ,disp-char ,sub-char
670  ,function ,var))
671  ((:macro-char char function &optional non-terminating-p)
672  (if (eq function :dispatch)
673  `(make-dispatch-macro-character ,char ,non-terminating-p ,var)
674  `(set-macro-character ,char ,function
675  ,non-terminating-p ,var)))
676  ((:syntax-from from-rt-designator from-char to-char)
677  `(set-syntax-from-char ,to-char ,from-char
678  ,var (find-readtable ,from-rt-designator)))
679  ((:case mode)
680  `(setf (readtable-case ,var) ,mode))))
681  (remove-clauses (clauses options)
682  (setq clauses (if (listp clauses) clauses (list clauses)))
683  (remove-if-not #'(lambda (x) (member x clauses))
684  options :key #'first)))
685  (let* ((docstring (when (stringp (first options))
686  (pop options)))
687  (merge-clauses (remove-clauses '(:merge :fuze :fuse) options))
688  (case-clauses (remove-clauses :case options))
689  (macro-clauses (remove-clauses '(:macro-char :dispatch-macro-char)
690  options))
691  (syntax-clauses (remove-clauses :syntax-from options))
692  (other-clauses
693  (set-difference options
694  (append merge-clauses case-clauses
695  macro-clauses syntax-clauses))))
696  (cond
697  ((not (null other-clauses))
698  (error "Bogus DEFREADTABLE clauses: ~/PPRINT-LINEAR/" other-clauses))
699  (t
700  `(eval-when (:load-toplevel :execute)
701  ;; The (FIND-READTABLE ...) is important for proper
702  ;; redefinition semantics, as redefining has to modify the
703  ;; already existing readtable object.
704  (let ((readtable (find-readtable ',name)))
705  (cond ((not readtable)
706  (setq readtable (make-readtable ',name)))
707  (t
708  (setq readtable (%clear-readtable readtable))
709  (simple-style-warn
710  "Overwriting already existing readtable ~S."
711  readtable)))
712  (setf (documentation readtable 'readtable) ,docstring)
713  ,@(loop for option in merge-clauses
714  collect (process-option option 'readtable))
715  ,@(loop for option in case-clauses
716  collect (process-option option 'readtable))
717  ,@(loop for option in macro-clauses
718  collect (process-option option 'readtable))
719  ,@(loop for option in syntax-clauses
720  collect (process-option option 'readtable))
721  readtable)))))))
722 
723 (defmacro in-readtable (name)
724  "Set *READTABLE* to the readtable referred to by the symbol NAME.
725  Return the readtable."
726  (check-type name symbol)
727  `(eval-when (:compile-toplevel :load-toplevel :execute)
728  ;; NB. The :LOAD-TOPLEVEL is needed for cases like (DEFVAR *FOO*
729  ;; (GET-MACRO-CHARACTER #\"))
730  (setf *readtable* (ensure-readtable ',name))
731  (when (find-package :swank)
732  (%frob-swank-readtable-alist *package* *readtable*))
733  *readtable*))
734 
735 ;;; KLUDGE: [interim solution]
736 ;;;
737 ;;; We need support for this in Slime itself, because we want IN-READTABLE
738 ;;; to work on a per-file basis, and not on a per-package basis.
739 ;;;
740 (defun %frob-swank-readtable-alist (package readtable)
741  (let ((readtable-alist (find-symbol (string '#:*readtable-alist*)
742  (find-package :swank))))
743  (when (boundp readtable-alist)
744  (let ((new-item (cons (package-name package) readtable)))
745  (setf (symbol-value readtable-alist)
746  (cons
747  new-item
748  (remove new-item (symbol-value readtable-alist)
749  :test (lambda (entry1 entry2)
750  (string= (car entry1) (car entry2))))))))))
751 
752 (deftype readtable-designator ()
753  `(or null readtable))
754 
755 (deftype named-readtable-designator ()
756  "Either a symbol or a readtable itself."
757  `(or readtable-designator symbol))
758 
759 ;;;;; Compiler macros
760 
761 ;;; Since the :STANDARD readtable is interned, and we can't enforce
762 ;;; its immutability, we signal a style-warning for suspicious uses
763 ;;; that may result in strange behaviour:
764 
765 ;;; Modifying the standard readtable would, obviously, lead to a
766 ;;; propagation of this change to all places which use the :STANDARD
767 ;;; readtable (and thus rendering this readtable to be non-standard,
768 ;;; in fact.)
769 (eval-when (:compile-toplevel :load-toplevel :execute)
770  (defun constant-standard-readtable-expression-p (thing)
771  (or (null thing)
772  (eq thing :standard)
773  (and (consp thing)
774  (find thing
775  '((find-readtable nil)
776  (find-readtable :standard)
777  (ensure-readtable nil)
778  (ensure-readtable :standard))
779  :test #'equal))))
780 
781  (defun signal-suspicious-registration-warning (name-expr readtable-expr)
782  (when (constant-standard-readtable-expression-p readtable-expr)
783  (simple-style-warn
784  "Caution: ~<You're trying to register the :STANDARD readtable ~
785  under a new name ~S. As modification of the :STANDARD readtable ~
786  is not permitted, subsequent modification of ~S won't be ~
787  permitted either. You probably want to wrap COPY-READTABLE ~
788  around~@:>~% ~S"
789  (list name-expr name-expr) readtable-expr))))
790 
791 (define-compiler-macro register-readtable (&whole form name readtable)
792  (signal-suspicious-registration-warning name readtable)
793  form)
794 
795 (define-compiler-macro ensure-readtable (&whole form name &optional
796  (default nil default-p))
797  (when default-p
798  (signal-suspicious-registration-warning name default))
799  form)
800 
801 (declaim (special *standard-readtable* *empty-readtable*))
802 
803 (define-api make-readtable
804  (&optional (name nil name-supplied-p) &key merge)
805  (&optional named-readtable-designator &key (:merge list) => readtable)
806  "Creates and returns a new readtable under the specified
807  NAME.
808 
809  MERGE takes a list of NAMED-READTABLE-DESIGNATORs and specifies the
810  readtables the new readtable is created from. (See the :MERGE clause
811  of DEFREADTABLE for details.)
812 
813  If MERGE is NIL, an empty readtable is used instead.
814 
815  If NAME is not given, an anonymous empty readtable is returned.
816 
817  Notes:
818 
819  An empty readtable is a readtable where each character's syntax is
820  the same as in the _standard readtable_ except that each macro
821  character has been made a constituent. Basically: whitespace stays
822  whitespace, everything else is constituent."
823  (cond ((not name-supplied-p)
824  (copy-readtable *empty-readtable*))
825  ((reserved-readtable-name-p name)
826  (error "~A is the designator for a predefined readtable. ~
827  Not acceptable as a user-specified readtable name." name))
828  ((let ((rt (find-readtable name)))
829  (and rt (prog1 nil
830  (cerror "Overwrite existing entry."
831  'readtable-does-already-exist :readtable-name name)
832  ;; Explicitly unregister to make sure that we do
833  ;; not hold on of any reference to RT.
834  (unregister-readtable rt)))))
835  (t (let ((result (apply #'merge-readtables-into
836  ;; The first readtable specified in
837  ;; the :merge list is taken as the
838  ;; basis for all subsequent
839  ;; (destructive!) modifications (and
840  ;; hence it's copied.)
841  (copy-readtable (if merge
842  (ensure-readtable
843  (first merge))
844  *empty-readtable*))
845  (rest merge))))
846 
847  (register-readtable name result)))))
848 
849 (define-api rename-readtable
850  (old-name new-name)
851  (named-readtable-designator symbol => readtable)
852  "Replaces the associated name of the readtable designated by
853  OLD-NAME with NEW-NAME. If a readtable is already registered under
854  NEW-NAME, an error of type READTABLE-DOES-ALREADY-EXIST is
855  signaled."
856  (when (find-readtable new-name)
857  (cerror "Overwrite existing entry."
858  'readtable-does-already-exist :readtable-name new-name))
859  (let* ((readtable (ensure-readtable old-name))
860  (readtable-name (readtable-name readtable)))
861  ;; We use the internal functions directly to omit repeated
862  ;; type-checking.
863  (%unassociate-name-from-readtable readtable-name readtable)
864  (%unassociate-readtable-from-name readtable-name readtable)
865  (%associate-name-with-readtable new-name readtable)
866  (%associate-readtable-with-name new-name readtable)
867  (%associate-docstring-with-readtable
868  readtable (%unassociate-docstring-from-readtable readtable))
869  readtable))
870 
871 (define-api merge-readtables-into
872  (result-readtable &rest named-readtables)
873  (named-readtable-designator &rest named-readtable-designator => readtable)
874  "Copy macro character definitions of each readtable in
875  NAMED-READTABLES into RESULT-READTABLE.
876 
877  If a macro character appears in more than one of the readtables,
878  i.e. if a conflict is discovered during the merge, an error of type
879  READER-MACRO-CONFLICT is signaled.
880 
881  The copied options are :DISPATCH-MACRO-CHAR, :MACRO-CHAR and
882  :SYNTAX-FROM, but not READTABLE-CASE."
883  (flet ((merge-into (to from)
884  (do-readtable ((char reader-fn non-terminating-p disp? table) from)
885  (check-reader-macro-conflict from to char)
886  (cond ((not disp?)
887  (set-macro-character char reader-fn non-terminating-p to))
888  (t
889  (ensure-dispatch-macro-character char non-terminating-p to)
890  (loop for (subchar . subfn) in table do
891  (check-reader-macro-conflict from to char subchar)
892  (set-dispatch-macro-character char subchar
893  subfn to)))))
894  to))
895  (let ((result-table (ensure-readtable result-readtable)))
896  (dolist (table (mapcar #'ensure-readtable named-readtables))
897  (merge-into result-table table))
898  result-table)))
899 
900 (defun ensure-dispatch-macro-character (char &optional non-terminating-p
901  (readtable *readtable*))
902  (if (dispatch-macro-char-p char readtable)
903  t
904  (make-dispatch-macro-character char non-terminating-p readtable)))
905 
906 (define-api copy-named-readtable
907  (named-readtable)
908  (named-readtable-designator => readtable)
909  "Like COPY-READTABLE but takes a NAMED-READTABLE-DESIGNATOR as argument."
910  (copy-readtable (ensure-readtable named-readtable)))
911 
912 (define-api list-all-named-readtables () (=> list)
913  "Returns a list of all registered readtables. The returned list is
914  guaranteed to be fresh, but may contain duplicates."
915  (mapcar #'ensure-readtable (%list-all-readtable-names)))
916 
917 
918 (define-condition readtable-error (error) ())
919 
920 (define-condition readtable-does-not-exist (readtable-error)
921  ((readtable-name :initarg :readtable-name
922  :initform (required-argument)
923  :accessor missing-readtable-name
924  :type named-readtable-designator))
925  (:report (lambda (condition stream)
926  (format stream "A readtable named ~S does not exist."
927  (missing-readtable-name condition)))))
928 
929 (define-condition readtable-does-already-exist (readtable-error)
930  ((readtable-name :initarg :readtable-name
931  :initform (required-argument)
932  :accessor existing-readtable-name
933  :type named-readtable-designator))
934  (:report (lambda (condition stream)
935  (format stream "A readtable named ~S already exists."
936  (existing-readtable-name condition))))
937  (:documentation "Continuable."))
938 
939 (define-condition reader-macro-conflict (readtable-error)
940  ((macro-char
941  :initarg :macro-char
942  :initform (required-argument)
943  :accessor conflicting-macro-char
944  :type character)
945  (sub-char
946  :initarg :sub-char
947  :initform nil
948  :accessor conflicting-dispatch-sub-char
949  :type (or null character))
950  (from-readtable
951  :initarg :from-readtable
952  :initform (required-argument)
953  :accessor from-readtable
954  :type readtable)
955  (to-readtable
956  :initarg :to-readtable
957  :initform (required-argument)
958  :accessor to-readtable
959  :type readtable))
960  (:report
961  (lambda (condition stream)
962  (format stream "~@<Reader macro conflict while trying to merge the ~
963  ~:[macro character~;dispatch macro characters~] ~
964  ~@C~@[ ~@C~] from ~A into ~A.~@:>"
965  (conflicting-dispatch-sub-char condition)
966  (conflicting-macro-char condition)
967  (conflicting-dispatch-sub-char condition)
968  (from-readtable condition)
969  (to-readtable condition))))
970  (:documentation "Continuable.
971 
972  This condition is signaled during the merge process if a reader
973  macro (be it a macro character or the sub character of a dispatch
974  macro character) is present in the both source and the target
975  readtable and the two respective reader macro functions differ."))
976 
977 (defun check-reader-macro-conflict (from to char &optional subchar)
978  (flet ((conflictp (from-fn to-fn)
979  (assert from-fn ()
980  "Bug in readtable iterators or concurrent access?")
981  (and to-fn (not (function= to-fn from-fn)))))
982  (when (if subchar
983  (conflictp (%get-dispatch-macro-character char subchar from)
984  (%get-dispatch-macro-character char subchar to))
985  (conflictp (%get-macro-character char from)
986  (%get-macro-character char to)))
987  (cerror (format nil "Overwrite ~@C in ~A." char to)
988  'reader-macro-conflict
989  :from-readtable from
990  :to-readtable to
991  :macro-char char
992  :sub-char subchar))))
993 
994 
995 ;;; Although there is no way to get at the standard readtable in
996 ;;; Common Lisp (cf. /standard readtable/, CLHS glossary), we make
997 ;;; up the perception of its existence by interning a copy of it.
998 ;;;
999 ;;; We do this for reverse lookup (cf. READTABLE-NAME), i.e. for
1000 ;;;
1001 ;;; (equal (readtable-name (find-readtable :standard)) "STANDARD")
1002 ;;;
1003 ;;; holding true.
1004 ;;;
1005 ;;; We, however, inherit the restriction that the :STANDARD
1006 ;;; readtable _must not be modified_ (cf. CLHS 2.1.1.2), although it'd
1007 ;;; technically be feasible (as *STANDARD-READTABLE* will contain a
1008 ;;; mutable copy of the implementation-internal standard readtable.)
1009 ;;; We cannot enforce this restriction without shadowing
1010 ;;; CL:SET-MACRO-CHARACTER and CL:SET-DISPATCH-MACRO-FUNCTION which
1011 ;;; is out of scope of this library, though. So we just threaten
1012 ;;; with nasal demons.
1013 ;;;
1014 (defvar *standard-readtable*
1015  (%standard-readtable))
1016 
1017 (defvar *empty-readtable*
1018  (%clear-readtable (copy-readtable nil)))
1019 
1020 (defvar *case-preserving-standard-readtable*
1021  (let ((readtable (copy-readtable nil)))
1022  (setf (readtable-case readtable) :preserve)
1023  readtable))
1024 
1025 (defparameter *reserved-readtable-names*
1026  '(nil :standard :common-lisp :modern :current))
1027 
1028 (defun reserved-readtable-name-p (name)
1029  (and (member name *reserved-readtable-names*) t))
1030 
1031 ;;; In principle, we could DEFREADTABLE some of these. But we do
1032 ;;; reserved readtable lookup seperately, since we can't register a
1033 ;;; readtable for :CURRENT anyway.
1034 
1035 (defun find-reserved-readtable (reserved-name)
1036  (cond ((eq reserved-name nil) *standard-readtable*)
1037  ((eq reserved-name :standard) *standard-readtable*)
1038  ((eq reserved-name :common-lisp) *standard-readtable*)
1039  ((eq reserved-name :modern) *case-preserving-standard-readtable*)
1040  ((eq reserved-name :current) *readtable*)
1041  (t (error "Bug: no such reserved readtable: ~S" reserved-name))))
1042 
1043 (define-api find-readtable
1044  (name)
1045  (named-readtable-designator => (or readtable null))
1046  "Looks for the readtable specified by NAME and returns it if it is
1047  found. Returns NIL otherwise."
1048  (cond ((readtablep name) name)
1049  ((reserved-readtable-name-p name)
1050  (find-reserved-readtable name))
1051  ((%find-readtable name))))
1052 
1053 ;;; FIXME: This doesn't take a NAMED-READTABLE-DESIGNATOR, but only a
1054 ;;; STRING-DESIGNATOR. (When fixing, heed interplay with compiler
1055 ;;; macros below.)
1056 (defsetf find-readtable register-readtable)
1057 
1058 (define-api ensure-readtable
1059  (name &optional (default nil default-p))
1060  (named-readtable-designator &optional (or named-readtable-designator null)
1061  => readtable)
1062  "Looks up the readtable specified by NAME and returns it if it's found.
1063  If it is not found, it registers the readtable designated by DEFAULT
1064  under the name represented by NAME; or if no default argument is
1065  given, it signals an error of type READTABLE-DOES-NOT-EXIST
1066  instead."
1067  (cond ((find-readtable name))
1068  ((not default-p)
1069  (error 'readtable-does-not-exist :readtable-name name))
1070  (t (setf (find-readtable name) (ensure-readtable default)))))
1071 
1072 
1073 (define-api register-readtable
1074  (name readtable)
1075  (symbol readtable => readtable)
1076  "Associate READTABLE with NAME. Returns the readtable."
1077  (assert (typep name '(not (satisfies reserved-readtable-name-p))))
1078  (%associate-readtable-with-name name readtable)
1079  (%associate-name-with-readtable name readtable)
1080  readtable)
1081 
1082 (define-api unregister-readtable
1083  (named-readtable)
1084  (named-readtable-designator => boolean)
1085  "Remove the association of NAMED-READTABLE. Returns T if successfull,
1086  NIL otherwise."
1087  (let* ((readtable (find-readtable named-readtable))
1088  (readtable-name (and readtable (readtable-name readtable))))
1089  (if (not readtable-name)
1090  nil
1091  (prog1 t
1092  (check-type readtable-name
1093  (not (satisfies reserved-readtable-name-p)))
1094  (%unassociate-readtable-from-name readtable-name readtable)
1095  (%unassociate-name-from-readtable readtable-name readtable)
1096  (%unassociate-docstring-from-readtable readtable)))))
1097 
1098 (define-api readtable-name
1099  (named-readtable)
1100  (named-readtable-designator => symbol)
1101  "Returns the name of the readtable designated by NAMED-READTABLE,
1102  or NIL."
1103  (let ((readtable (ensure-readtable named-readtable)))
1104  (cond ((%readtable-name readtable))
1105  ((eq readtable *readtable*) :current)
1106  ((eq readtable *standard-readtable*) :common-lisp)
1107  ((eq readtable *case-preserving-standard-readtable*) :modern)
1108  (t nil))))
1109 
1110 (provide :readtables)