Kill *READ-PREFER-BASE-STRING* and expose its capability differently
[sbcl.git] / src / code / reader.lisp
bloba37d171341f3a4d85a1a851e8043929bbb746c54
1 ;;;; READ and friends
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!IMPL")
14 ;;;; miscellaneous global variables
16 ;;; ANSI: "the floating-point format that is to be used when reading a
17 ;;; floating-point number that has no exponent marker or that has e or
18 ;;; E for an exponent marker"
19 (!defvar *read-default-float-format* 'single-float)
20 (declaim (type (member short-float single-float double-float long-float)
21 *read-default-float-format*))
23 (defvar *readtable*)
24 (declaim (type readtable *readtable*))
25 #!+sb-doc
26 (setf (fdocumentation '*readtable* 'variable)
27 "Variable bound to current readtable.")
29 ;;; A standard Lisp readtable (once cold-init is through). This is for
30 ;;; recovery from broken read-tables (and for
31 ;;; WITH-STANDARD-IO-SYNTAX), and should not normally be user-visible.
32 ;;; If the initial value is changed from NIL to something more interesting,
33 ;;; be sure to update the duplicated definition in "src/code/print.lisp"
34 (defglobal *standard-readtable* nil)
36 ;;; In case we get an error trying to parse a symbol, we want to rebind the
37 ;;; above stuff so it's cool.
40 ;;;; reader errors
42 (defun reader-eof-error (stream context)
43 (declare (optimize allow-non-returning-tail-call))
44 (error 'reader-eof-error
45 :stream stream
46 :context context))
48 ;;; If The Gods didn't intend for us to use multiple namespaces, why
49 ;;; did They specify them?
50 (defun simple-reader-error (stream control &rest args)
51 (declare (optimize allow-non-returning-tail-call))
52 (error 'simple-reader-error
53 :stream stream
54 :format-control control
55 :format-arguments args))
57 ;;;; macros and functions for character tables
59 (declaim (ftype (sfunction (character readtable) (unsigned-byte 8))
60 get-cat-entry))
61 (defun get-cat-entry (char rt)
62 (if (typep char 'base-char)
63 (elt (character-attribute-array rt) (char-code char))
64 (values (gethash char (character-attribute-hash-table rt)
65 +char-attr-constituent+))))
67 (defun set-cat-entry (char newvalue &optional (rt *readtable*))
68 (declare (character char) (type (unsigned-byte 8) newvalue) (readtable rt))
69 (if (typep char 'base-char)
70 (setf (elt (character-attribute-array rt) (char-code char)) newvalue)
71 (if (= newvalue +char-attr-constituent+)
72 ;; Default value for the C-A-HASH-TABLE is +CHAR-ATTR-CONSTITUENT+.
73 (%remhash char (character-attribute-hash-table rt))
74 (setf (gethash char (character-attribute-hash-table rt)) newvalue)))
75 (values))
77 ;; Set the character-macro-table entry without coercing NEW-VALUE.
78 ;; As used by set-syntax-from-char it must always process "raw" values.
79 (defun set-cmt-entry (char new-value &optional (rt *readtable*))
80 (declare (character char)
81 (type (or null function fdefn) new-value)
82 (type readtable rt))
83 (if (typep char 'base-char)
84 (setf (svref (character-macro-array rt) (char-code char)) new-value)
85 (if new-value ; never store NILs
86 (setf (gethash char (character-macro-hash-table rt)) new-value)
87 (remhash char (character-macro-hash-table rt)))))
89 ;;; the value actually stored in the character macro table. As per
90 ;;; ANSI #'GET-MACRO-CHARACTER and #'SET-MACRO-CHARACTER, this can
91 ;;; be either a function-designator or NIL, except that we store
92 ;;; symbols not as themselves but as their #<fdefn>.
93 (defun get-raw-cmt-entry (char readtable)
94 (declare (character char) (readtable readtable))
95 (if (typep char 'base-char)
96 (svref (character-macro-array readtable) (char-code char))
97 (values (gethash char (character-macro-hash-table readtable) nil))))
99 ;; As above but get the entry for SUB-CHAR in a dispatching macro table.
100 (defun get-raw-cmt-dispatch-entry (sub-char sub-table)
101 (declare (character sub-char))
102 (if (typep sub-char 'base-char)
103 (svref (truly-the (simple-vector #.base-char-code-limit)
104 (cdr (truly-the cons sub-table)))
105 (char-code sub-char))
106 (awhen (car sub-table)
107 (gethash sub-char it))))
109 ;; Coerce THING to a character-macro-table entry
110 (defmacro !coerce-to-cmt-entry (thing)
111 `(let ((x ,thing))
112 (if (typep x '(or null function)) x (find-or-create-fdefn x))))
114 ;; Return a callable function given a character-macro-table entry.
115 (defmacro !cmt-entry-to-function (val fallback)
116 `(let ((x ,val))
117 (truly-the
118 function
119 (cond ((functionp x) x)
120 ((null x) ,fallback)
121 (t (sb!c:safe-fdefn-fun x))))))
123 ;; Return a function-designator given a character-macro-table entry.
124 (defmacro !cmt-entry-to-fun-designator (val)
125 `(let ((x ,val))
126 (if (fdefn-p x) (fdefn-name x) x)))
128 ;;; The character attribute table is a BASE-CHAR-CODE-LIMIT vector
129 ;;; of (unsigned-byte 8) plus a hashtable to handle higher character codes.
131 (defmacro test-attribute (char whichclass rt)
132 `(= (get-cat-entry ,char ,rt) ,whichclass))
134 ;;; predicates for testing character attributes
136 #!-sb-fluid
137 (progn
138 (declaim (inline whitespace[1]p whitespace[2]p))
139 (declaim (inline constituentp terminating-macrop))
140 (declaim (inline single-escape-p multiple-escape-p))
141 (declaim (inline token-delimiterp)))
143 ;;; the [1] and [2] here refer to ANSI glossary entries for
144 ;;; "whitespace".
145 ;; whitespace[2]p is the only predicate whose readtable is optional
146 ;; - other than whitespace[1]p which has a fixed readtable - due to
147 ;; callers not otherwise needing a readtable at all, and so not binding
148 ;; *READTABLE* into a local variable throughout their lifetime.
149 (defun whitespace[1]p (char)
150 (test-attribute char +char-attr-whitespace+ *standard-readtable*))
151 (defun whitespace[2]p (char &optional (rt *readtable*))
152 (test-attribute char +char-attr-whitespace+ rt))
154 (defun constituentp (char rt)
155 (test-attribute char +char-attr-constituent+ rt))
157 (defun terminating-macrop (char rt)
158 (test-attribute char +char-attr-terminating-macro+ rt))
160 (defun single-escape-p (char rt)
161 (test-attribute char +char-attr-single-escape+ rt))
163 (defun multiple-escape-p (char rt)
164 (test-attribute char +char-attr-multiple-escape+ rt))
166 (defun token-delimiterp (char &optional (rt *readtable*))
167 ;; depends on actual attribute numbering in readtable.lisp.
168 (<= (get-cat-entry char rt) +char-attr-terminating-macro+))
170 ;;;; constituent traits (see ANSI 2.1.4.2)
172 ;;; There are a number of "secondary" attributes which are constant
173 ;;; properties of characters (as long as they are constituents).
175 (declaim (type attribute-table *constituent-trait-table*))
176 (defglobal *constituent-trait-table*
177 (make-array base-char-code-limit
178 :element-type '(unsigned-byte 8)
179 :initial-element +char-attr-constituent+))
181 (defun !set-constituent-trait (char trait)
182 (aver (typep char 'base-char))
183 (setf (elt *constituent-trait-table* (char-code char))
184 trait))
186 (defun !cold-init-constituent-trait-table ()
187 (!set-constituent-trait #\: +char-attr-package-delimiter+)
188 (!set-constituent-trait #\. +char-attr-constituent-dot+)
189 (!set-constituent-trait #\+ +char-attr-constituent-sign+)
190 (!set-constituent-trait #\- +char-attr-constituent-sign+)
191 (!set-constituent-trait #\/ +char-attr-constituent-slash+)
192 (do ((i (char-code #\0) (1+ i)))
193 ((> i (char-code #\9)))
194 (!set-constituent-trait (code-char i) +char-attr-constituent-digit+))
195 (!set-constituent-trait #\E +char-attr-constituent-expt+)
196 (!set-constituent-trait #\F +char-attr-constituent-expt+)
197 (!set-constituent-trait #\D +char-attr-constituent-expt+)
198 (!set-constituent-trait #\S +char-attr-constituent-expt+)
199 (!set-constituent-trait #\L +char-attr-constituent-expt+)
200 (!set-constituent-trait #\e +char-attr-constituent-expt+)
201 (!set-constituent-trait #\f +char-attr-constituent-expt+)
202 (!set-constituent-trait #\d +char-attr-constituent-expt+)
203 (!set-constituent-trait #\s +char-attr-constituent-expt+)
204 (!set-constituent-trait #\l +char-attr-constituent-expt+)
205 (!set-constituent-trait #\Space +char-attr-invalid+)
206 (!set-constituent-trait #\Newline +char-attr-invalid+)
207 (dolist (c (list backspace-char-code tab-char-code form-feed-char-code
208 return-char-code rubout-char-code))
209 (!set-constituent-trait (code-char c) +char-attr-invalid+)))
211 (declaim (inline get-constituent-trait))
212 (defun get-constituent-trait (char)
213 (if (typep char 'base-char)
214 (elt *constituent-trait-table* (char-code char))
215 +char-attr-constituent+))
217 ;;;; Readtable Operations
219 (defun assert-not-standard-readtable (readtable operation)
220 (when (eq readtable *standard-readtable*)
221 (cerror "Frob it anyway!" 'standard-readtable-modified-error
222 :operation operation)))
224 (defun readtable-case (readtable)
225 (aref #(:upcase :downcase :preserve :invert) (%readtable-case readtable)))
227 (defun (setf readtable-case) (case readtable)
228 ;; This function does not accept a readtable designator, only a readtable.
229 (assert-not-standard-readtable readtable '(setf readtable-case))
230 (setf (%readtable-case readtable)
231 (ecase case (:upcase 0) (:downcase 1) (:preserve 2) (:invert 3)))
232 case)
234 (defun readtable-normalization (readtable)
235 #!+sb-doc
236 "Returns T if READTABLE normalizes strings to NFKC, and NIL otherwise.
237 The READTABLE-NORMALIZATION of the standard readtable is T."
238 (%readtable-normalization readtable))
240 (defun (setf readtable-normalization) (new-value readtable)
241 #!+sb-doc
242 "Sets the READTABLE-NORMALIZATION of the given READTABLE to NEW-VALUE.
243 Pass T to make READTABLE normalize symbols to NFKC (the default behavior),
244 and NIL to suppress normalization."
245 ;; This function does not accept a readtable designator, only a readtable.
246 (assert-not-standard-readtable readtable '(setf readtable-normalization))
247 (setf (%readtable-normalization readtable) new-value))
249 (defun readtable-base-char-preference (readtable)
250 #!+sb-doc
251 "Returns :SYMBOLS, :STRINGS, :BOTH, or NIL, depending on whether the
252 reader should try to intern a base-string when reading a symbol name,
253 respectively produce a base-string when reading a quoted string, or in both
254 cases, or neither. The preference applies when a symbol-name or string
255 contains only BASE-CHAR characters. An (ARRAY CHARACTER (*)) can always
256 be interned (returned, respectively) as required. The default is :SYMBOLS."
257 ;; For efficiency the single preference occupies two slots internally.
258 (let ((symbols (eq (%readtable-symbol-preference readtable) 'base-char))
259 (strings (eq (%readtable-string-preference readtable) 'base-char)))
260 (cond ((and strings symbols) :both)
261 (symbols :symbols)
262 (strings :strings))))
264 (defun (setf readtable-base-char-preference) (new-value readtable)
265 (declare (type (member :symbols :strings :both nil) new-value))
266 #!+sb-doc
267 "Sets the READTABLE-BASE-CHAR-PREFERENCE of the given READTABLE."
268 (setf (%readtable-symbol-preference readtable)
269 (if (member new-value '(:symbols :both)) 'base-char 'character)
270 (%readtable-string-preference readtable)
271 (if (member new-value '(:strings :both)) 'base-char 'character))
272 new-value)
274 (defun replace/eql-hash-table (to from &optional (transform #'identity))
275 (maphash (lambda (k v) (setf (gethash k to) (funcall transform v))) from)
278 (defun %make-dispatch-macro-char (dtable)
279 (lambda (stream char)
280 (declare (ignore char))
281 (read-dispatch-char stream dtable)))
283 (defun %dispatch-macro-char-table (fun)
284 (and (closurep fun)
285 (eq (%closure-fun fun)
286 (load-time-value (%closure-fun (%make-dispatch-macro-char nil))
288 (find-if-in-closure #'consp fun)))
290 ;; If ENTRY is a dispatching macro, copy its dispatch table.
291 ;; Otherwise return it without alteration.
292 (defun copy-cmt-entry (entry)
293 (let ((dtable (%dispatch-macro-char-table entry)))
294 (if dtable
295 (%make-dispatch-macro-char
296 (cons (awhen (car dtable)
297 (replace/eql-hash-table (make-hash-table) it))
298 (copy-seq (cdr dtable))))
299 entry)))
301 (defun copy-readtable (&optional (from-readtable *readtable*) to-readtable)
302 #!+sb-doc
303 "Copies FROM-READTABLE and returns the result. Uses TO-READTABLE as a target
304 for the copy when provided, otherwise a new readtable is created. The
305 FROM-READTABLE defaults to the standard readtable when NIL and to the current
306 readtable when not provided."
307 (assert-not-standard-readtable to-readtable 'copy-readtable)
308 (let ((really-from-readtable (or from-readtable *standard-readtable*))
309 (really-to-readtable (or to-readtable (make-readtable))))
310 (replace (character-attribute-array really-to-readtable)
311 (character-attribute-array really-from-readtable))
312 (replace/eql-hash-table
313 (clrhash (character-attribute-hash-table really-to-readtable))
314 (character-attribute-hash-table really-from-readtable))
315 (map-into (character-macro-array really-to-readtable)
316 #'copy-cmt-entry
317 (character-macro-array really-from-readtable))
318 (replace/eql-hash-table
319 (clrhash (character-macro-hash-table really-to-readtable))
320 (character-macro-hash-table really-from-readtable)
321 #'copy-cmt-entry)
322 (setf (readtable-case really-to-readtable)
323 (readtable-case really-from-readtable))
324 (setf (%readtable-string-preference really-to-readtable)
325 (%readtable-string-preference really-from-readtable)
326 (%readtable-symbol-preference really-to-readtable)
327 (%readtable-symbol-preference really-from-readtable))
328 (setf (readtable-normalization really-to-readtable)
329 (readtable-normalization really-from-readtable))
330 really-to-readtable))
332 (defun set-syntax-from-char (to-char from-char &optional
333 (to-readtable *readtable*) (from-readtable nil))
334 #!+sb-doc
335 "Causes the syntax of TO-CHAR to be the same as FROM-CHAR in the optional
336 readtable (defaults to the current readtable). The FROM-TABLE defaults to the
337 standard Lisp readtable when NIL."
338 ;; TO-READTABLE is a readtable, not a readtable-designator
339 (assert-not-standard-readtable to-readtable 'set-syntax-from-char)
340 (let* ((really-from-readtable (or from-readtable *standard-readtable*))
341 (att (get-cat-entry from-char really-from-readtable))
342 (mac (get-raw-cmt-entry from-char really-from-readtable)))
343 (set-cat-entry to-char att to-readtable)
344 (set-cmt-entry to-char (copy-cmt-entry mac) to-readtable))
347 (defun set-macro-character (char function &optional
348 (non-terminatingp nil)
349 (rt-designator *readtable*))
350 #!+sb-doc
351 "Causes CHAR to be a macro character which invokes FUNCTION when seen
352 by the reader. The NON-TERMINATINGP flag can be used to make the macro
353 character non-terminating, i.e. embeddable in a symbol name."
354 (let ((designated-readtable (or rt-designator *standard-readtable*)))
355 (assert-not-standard-readtable designated-readtable 'set-macro-character)
356 (set-cat-entry char (if non-terminatingp
357 +char-attr-constituent+
358 +char-attr-terminating-macro+)
359 designated-readtable)
360 (set-cmt-entry char (!coerce-to-cmt-entry function) designated-readtable)
361 t)) ; (ANSI-specified return value)
363 (defun get-macro-character (char &optional (rt-designator *readtable*))
364 #!+sb-doc
365 "Return the function associated with the specified CHAR which is a macro
366 character, or NIL if there is no such function. As a second value, return
367 T if CHAR is a macro character which is non-terminating, i.e. which can
368 be embedded in a symbol name."
369 (let* ((designated-readtable (or rt-designator *standard-readtable*))
370 ;; the first return value: (OR FUNCTION SYMBOL) if CHAR is a macro
371 ;; character, or NIL otherwise
372 (fun-value (!cmt-entry-to-fun-designator
373 (get-raw-cmt-entry char designated-readtable))))
374 (values fun-value
375 ;; NON-TERMINATING-P return value:
376 (if fun-value
377 (or (constituentp char designated-readtable)
378 (not (terminating-macrop char designated-readtable)))
379 ;; ANSI's definition of GET-MACRO-CHARACTER says this
380 ;; value is NIL when CHAR is not a macro character.
381 ;; I.e. this value means not just "non-terminating
382 ;; character?" but "non-terminating macro character?".
383 nil))))
385 (defun get-dispatch-macro-char-table (disp-char readtable &optional (errorp t))
386 (cond ((%dispatch-macro-char-table (get-raw-cmt-entry disp-char readtable)))
387 (errorp (error "~S is not a dispatching macro character." disp-char))))
389 (defun make-dispatch-macro-character (char &optional
390 (non-terminating-p nil)
391 (rt *readtable*))
392 #!+sb-doc
393 "Cause CHAR to become a dispatching macro character in readtable (which
394 defaults to the current readtable). If NON-TERMINATING-P, the char will
395 be non-terminating."
396 ;; This used to call ERROR if the character was already a dispatching
397 ;; macro but I saw no evidence of that in other implementations except cmucl.
398 ;; Without a portable way to inquire whether a character is dispatching,
399 ;; a file that frobs *READTABLE* can't be repeatedly loaded except
400 ;; by catching the error, so I removed it.
401 ;; RT is a readtable, not a readtable-designator, as per CLHS.
402 (unless (get-dispatch-macro-char-table char rt nil)
403 ;; The dtable is a cons whose whose CAR is initially NIL but upgraded
404 ;; to a hashtable if required, and whose CDR is a vector indexed by
405 ;; char-code up to the maximum base-char.
406 (let ((dtable (cons nil (make-array base-char-code-limit
407 :initial-element nil))))
408 (set-macro-character char (%make-dispatch-macro-char dtable)
409 non-terminating-p rt)))
412 (defun set-dispatch-macro-character (disp-char sub-char function
413 &optional (rt-designator *readtable*))
414 #!+sb-doc
415 "Cause FUNCTION to be called whenever the reader reads DISP-CHAR
416 followed by SUB-CHAR."
417 ;; Get the dispatch char for macro (error if not there), diddle
418 ;; entry for sub-char.
419 (let* ((sub-char (char-upcase sub-char))
420 (readtable (or rt-designator *standard-readtable*)))
421 (assert-not-standard-readtable readtable 'set-dispatch-macro-character)
422 (when (digit-char-p sub-char)
423 (error "SUB-CHAR must not be a decimal digit: ~S" sub-char))
424 (let ((dtable (get-dispatch-macro-char-table disp-char readtable))
425 (function (!coerce-to-cmt-entry function)))
426 ;; (SET-MACRO-CHARACTER #\$ (GET-MACRO-CHARACTER #\#)) will share
427 ;; the dispatch table. Perhaps it should be copy-on-write?
428 (if (typep sub-char 'base-char)
429 (setf (svref (cdr dtable) (char-code sub-char)) function)
430 (let ((hashtable (car dtable)))
431 (cond (function ; allocate the hashtable if it wasn't made yet
432 (setf (gethash sub-char
433 (or hashtable (setf (car dtable)
434 (make-hash-table))))
435 function))
436 (hashtable ; remove an existing entry
437 (remhash sub-char hashtable)))))))
440 (defun get-dispatch-macro-character (disp-char sub-char
441 &optional (rt-designator *readtable*))
442 #!+sb-doc
443 "Return the macro character function for SUB-CHAR under DISP-CHAR
444 or NIL if there is no associated function."
445 (let ((dtable (get-dispatch-macro-char-table
446 disp-char (or rt-designator *standard-readtable*))))
447 (!cmt-entry-to-fun-designator
448 (get-raw-cmt-dispatch-entry (char-upcase sub-char) dtable))))
451 ;;;; definitions to support internal programming conventions
453 (defconstant +EOF+ 0)
455 (defun flush-whitespace (stream)
456 ;; This flushes whitespace chars, returning the last char it read (a
457 ;; non-white one). It always gets an error on end-of-file.
458 (let* ((stream (in-stream-from-designator stream))
459 (rt *readtable*)
460 (attribute-array (character-attribute-array rt))
461 (attribute-hash-table (character-attribute-hash-table rt)))
462 (macrolet ((done-p ()
463 '(not (eql (if (typep char 'base-char)
464 (aref attribute-array (char-code char))
465 (gethash char attribute-hash-table
466 +char-attr-constituent+))
467 +char-attr-whitespace+))))
468 (if (ansi-stream-p stream)
469 (prepare-for-fast-read-char stream
470 (loop (let ((char (fast-read-char t)))
471 (cond ((done-p)
472 (done-with-fast-read-char)
473 (return char))))))
474 ;; CLOS stream
475 (loop (let ((char (read-char stream nil +EOF+)))
476 ;; (THE) should not be needed if DONE-P, but it was not
477 ;; being derived to return a character, causing an extra
478 ;; check in consumers of flush-whitespace despite the
479 ;; promise to return a character or else signal EOF.
480 (cond ((eq char +EOF+) (error 'end-of-file :stream stream))
481 ((done-p) (return (the character char))))))))))
483 ;;;; temporary initialization hack
485 ;; Install the (easy) standard macro-chars into *READTABLE*.
486 (defun !cold-init-standard-readtable ()
487 (/show0 "entering !cold-init-standard-readtable")
488 ;; All characters get boring defaults in MAKE-READTABLE. Now we
489 ;; override the boring defaults on characters which need more
490 ;; interesting behavior.
491 (flet ((whitespaceify (char)
492 (set-cmt-entry char nil)
493 (set-cat-entry char +char-attr-whitespace+)))
494 (whitespaceify (code-char tab-char-code))
495 (whitespaceify #\Newline)
496 (whitespaceify #\Space)
497 (whitespaceify (code-char form-feed-char-code))
498 (whitespaceify (code-char return-char-code)))
500 (set-cat-entry #\\ +char-attr-single-escape+)
501 (set-cmt-entry #\\ nil)
503 (set-cat-entry #\| +char-attr-multiple-escape+)
504 (set-cmt-entry #\| nil)
506 ;; Easy macro-character definitions are in this source file.
507 (set-macro-character #\" #'read-string)
508 (set-macro-character #\' #'read-quote)
509 ;; Using symbols makes these traceable and redefineable with ease,
510 ;; as well as avoids a forward-referenced function (from "backq")
511 (set-macro-character #\( 'read-list)
512 (set-macro-character #\) 'read-right-paren)
513 (set-macro-character #\; #'read-comment)
514 ;; (The hairier macro-character definitions, for #\# and #\`, are
515 ;; defined elsewhere, in their own source files.)
517 ;; all constituents
518 (do ((ichar 0 (1+ ichar))
519 (char))
520 ((= ichar base-char-code-limit))
521 (setq char (code-char ichar))
522 (when (constituentp char *readtable*)
523 (set-cmt-entry char nil)))
525 (/show0 "leaving !cold-init-standard-readtable"))
527 ;;;; implementation of the read buffer
529 (defstruct (token-buf (:predicate nil) (:copier nil)
530 (:constructor
531 make-token-buf
532 (&aux
533 (initial-string (make-string 128))
534 (string initial-string)
535 (adjustable-string
536 (make-array 0
537 :element-type 'character
538 :fill-pointer nil
539 :displaced-to string)))))
540 ;; The string accumulated during reading of tokens.
541 ;; Always starts out EQ to 'initial-string'.
542 (string nil :type (simple-array character (*)))
543 ;; Counter advanced as characters are placed into 'string'
544 (fill-ptr 0 :type index)
545 ;; Counter advanced as characters are consumed from 'string' on re-scan
546 ;; by auxilliary functions MAKE-{INTEGER,FLOAT,RATIONAL} etc.
547 (cursor 0 :type index)
548 ;; A string used only for FIND-PACKAGE calls in package-qualified
549 ;; symbols so that we don't need to call SUBSEQ on the 'string'.
550 (adjustable-string nil :type (and (array character (*)) (not simple-array)))
551 ;; A small string that is permanently assigned into this token-buf.
552 (initial-string nil :type (simple-array character (128))
553 :read-only t)
554 (escapes (make-array 10 :element-type 'fixnum :fill-pointer 0 :adjustable t)
555 :type (and (vector fixnum) (not simple-array)) :read-only t)
556 ;; Link to next TOKEN-BUF, to chain the *TOKEN-BUF-POOL* together.
557 (next nil :type (or null token-buf))
558 (only-base-chars t :type boolean))
559 (declaim (freeze-type token-buf))
561 (defmethod print-object ((self token-buf) stream)
562 (print-unreadable-object (self stream :identity t :type t)
563 (format stream "~@[next=~S~]" (token-buf-next self))))
565 ;; The current TOKEN-BUF
566 (declaim (type token-buf *read-buffer*))
567 (defvar *read-buffer*)
569 ;; A list of available TOKEN-BUFs
570 ;; Should need no toplevel binding if multi-threaded,
571 ;; but doesn't really matter, as INITIAL-THREAD-FUNCTION-TRAMPOLINE
572 ;; rebinds to NIL.
573 (declaim (type (or null token-buf) *token-buf-pool*))
574 (defvar *token-buf-pool* nil)
576 (defun reset-read-buffer (buffer)
577 ;; Turn BUFFER into an empty read buffer.
578 (setf (fill-pointer (token-buf-escapes buffer)) 0)
579 (setf (token-buf-fill-ptr buffer) 0)
580 (setf (token-buf-cursor buffer) 0)
581 (setf (token-buf-only-base-chars buffer) t)
582 buffer)
584 ;; "Output" a character into the reader's buffer.
585 (declaim (inline ouch-read-buffer))
586 (defun ouch-read-buffer (char buffer)
587 ;; When buffer overflow
588 (let ((op (token-buf-fill-ptr buffer)))
589 (declare (optimize (sb!c::insert-array-bounds-checks 0)))
590 (when (>= op (length (token-buf-string buffer)))
591 ;; an out-of-line call for the uncommon case avoids bloat.
592 ;; Size should be doubled.
593 (grow-read-buffer))
594 (unless (typep char 'base-char)
595 (setf (token-buf-only-base-chars buffer) nil))
596 (setf (elt (token-buf-string buffer) op) char)
597 (setf (token-buf-fill-ptr buffer) (1+ op))))
599 (defun ouch-read-buffer-escaped (char buf)
600 (vector-push-extend (token-buf-fill-ptr buf) (token-buf-escapes buf))
601 (ouch-read-buffer char buf))
603 (defun grow-read-buffer ()
604 (let* ((b *read-buffer*)
605 (string (token-buf-string b)))
606 (setf (token-buf-string b)
607 (replace (make-string (* 2 (length string))) string))))
609 ;; Retun the next character from the buffered token, or NIL.
610 (declaim (maybe-inline token-buf-getchar))
611 (defun token-buf-getchar (b)
612 (declare (optimize (sb!c::insert-array-bounds-checks 0)))
613 (let ((i (token-buf-cursor (truly-the token-buf b))))
614 (and (< i (token-buf-fill-ptr b))
615 (prog1 (elt (token-buf-string b) i)
616 (setf (token-buf-cursor b) (1+ i))))))
618 ;; Grab a buffer off the token-buf pool if there is one, or else make one.
619 ;; This does not need to be protected against other threads because the
620 ;; pool is thread-local, or against async interrupts. An async signal
621 ;; delivered anywhere in the midst of the code sequence below can not
622 ;; corrupt the buffer given to the caller of ACQUIRE-TOKEN-BUF.
623 ;; Additionally the cleanup is on a "best effort" basis. Async unwinds
624 ;; through WITH-READ-BUFFER fail to recycle token-bufs, but that's ok.
625 (defun acquire-token-buf ()
626 (let ((this-buffer *token-buf-pool*))
627 (cond (this-buffer
628 (shiftf *token-buf-pool* (token-buf-next this-buffer) nil)
629 this-buffer)
631 (make-token-buf)))))
633 (defun release-token-buf (chain)
634 (named-let free ((buffer chain))
635 ;; If 'adjustable-string' was displaced to 'string',
636 ;; adjust it back down to allow GC of the abnormally large string.
637 (unless (eq (%array-data-vector (token-buf-adjustable-string buffer))
638 (token-buf-initial-string buffer))
639 (adjust-array (token-buf-adjustable-string buffer) '(0)
640 :displaced-to (token-buf-initial-string buffer)))
641 ;; 'initial-string' is assigned into 'string'
642 ;; so not to preserve huge buffers in the pool indefinitely.
643 (setf (token-buf-string buffer) (token-buf-initial-string buffer))
644 (if (token-buf-next buffer)
645 (free (token-buf-next buffer))
646 (setf (token-buf-next buffer) *token-buf-pool*)))
647 (setf *token-buf-pool* chain))
649 ;; Return a fresh copy of BUFFER's string
650 (defun copy-token-buf-string (buffer)
651 (subseq (token-buf-string buffer) 0 (token-buf-fill-ptr buffer)))
653 ;; Return a string displaced to BUFFER's string.
654 ;; The string should not be held onto - either a copy must be made
655 ;; by the receiver, or it should be parsed into something else.
656 (defun sized-token-buf-string (buffer)
657 ;; It would in theory be faster to make the adjustable array have
658 ;; a fill-pointer, and just set that most of the time. Except we still
659 ;; need the ability to displace to a different string if a package name
660 ;; has >128 characters, so then there'd be two modes of sharing, one of
661 ;; which is rarely exercised and most likely to be subtly wrong.
662 ;; At any rate, SET-ARRAY-HEADER is faster than ADJUST-ARRAY.
663 ;; TODO: find evidence that it is/is-not worth having complicated
664 ;; mechanism involving a fill-pointer or not.
665 (set-array-header
666 (token-buf-adjustable-string buffer) ; the array
667 (token-buf-string buffer) ; the underlying data
668 (token-buf-fill-ptr buffer) ; total size
669 nil ; fill-pointer
670 0 ; displacement
671 (token-buf-fill-ptr buffer) ; dimension 0
672 t nil)) ; displacedp / newp
674 ;; Acquire a TOKEN-BUF from the pool and execute the body, returning only
675 ;; the primary value therefrom. Recycle the buffer when done.
676 ;; No UNWIND-PROTECT - recycling is designed to help with the common case
677 ;; of normal return and is not intended to be resilient against nonlocal exit.
678 (defmacro with-read-buffer (() &body body)
679 `(let* ((*read-buffer* (acquire-token-buf))
680 (result (progn ,@body)))
681 (release-token-buf *read-buffer*)
682 result))
684 (defun check-for-recursive-read (stream recursive-p operator-name)
685 (when (and recursive-p (not (boundp '*read-buffer*)))
686 (simple-reader-error
687 stream
688 "~A was invoked with RECURSIVE-P being true outside ~
689 of a recursive read operation."
690 `(,operator-name))))
692 ;;;; READ-PRESERVING-WHITESPACE, READ-DELIMITED-LIST, and READ
694 ;;; A list for #=, used to keep track of objects with labels assigned that
695 ;;; have been completely read. Each entry is a SHARP-EQUAL-WRAPPER object.
697 ;;; KLUDGE: Should this really be a list? It seems as though users
698 ;;; could reasonably expect N log N performance for large datasets.
699 ;;; On the other hand, it's probably very very seldom a problem in practice.
700 ;;; On the third hand, it might be just as easy to use a hash table,
701 ;;; so maybe we should. -- WHN 19991202
702 (defvar *sharp-equal* ())
704 (declaim (ftype (sfunction (t t) (values bit t)) read-maybe-nothing))
706 ;;; Like READ-PRESERVING-WHITESPACE, but doesn't check the read buffer
707 ;;; for being set up properly.
708 (defun %read-preserving-whitespace (stream eof-error-p eof-value recursive-p)
709 (declare (optimize (sb!c::check-tag-existence 0)))
710 (if recursive-p
711 ;; a loop for repeating when a macro returns nothing
712 (let* ((tracking-p (form-tracking-stream-p stream))
713 (outermost-p
714 (and tracking-p
715 (null (form-tracking-stream-form-start-char-pos stream)))))
716 (loop
717 (let ((char (read-char stream eof-error-p +EOF+)))
718 (cond ((eq char +EOF+) (return eof-value))
719 ((whitespace[2]p char))
721 (when outermost-p
722 ;; Calling FILE-POSITION at each token seems to slow down
723 ;; the reader by somewhere between 8x to 10x.
724 ;; Once per outermost form is acceptably fast though.
725 (setf (form-tracking-stream-form-start-byte-pos stream)
726 ;; pretend we queried the position before reading CHAR
727 (- (file-position stream)
728 (or (file-string-length stream (string char)) 0))
729 (form-tracking-stream-form-start-char-pos stream)
730 ;; likewise
731 (1- (form-tracking-stream-input-char-pos stream))))
732 (multiple-value-bind (result-p result)
733 (read-maybe-nothing stream char)
734 (unless (zerop result-p)
735 (return (unless *read-suppress* result)))
736 ;; Repeat if macro returned nothing.
737 (when tracking-p
738 (funcall (form-tracking-stream-observer stream)
739 :reset nil nil))))))))
740 (let ((*sharp-equal* nil))
741 (with-read-buffer ()
742 (%read-preserving-whitespace stream eof-error-p eof-value t)))))
744 ;;; READ-PRESERVING-WHITESPACE behaves just like READ, only it makes
745 ;;; sure to leave terminating whitespace in the stream. (This is a
746 ;;; COMMON-LISP exported symbol.)
747 (defun read-preserving-whitespace (&optional (stream *standard-input*)
748 (eof-error-p t)
749 (eof-value nil)
750 (recursive-p nil))
751 #!+sb-doc
752 "Read from STREAM and return the value read, preserving any whitespace
753 that followed the object."
754 (declare (explicit-check))
755 (check-for-recursive-read stream recursive-p 'read-preserving-whitespace)
756 (%read-preserving-whitespace stream eof-error-p eof-value recursive-p))
758 ;;; Read from STREAM given starting CHAR, returning 1 and the resulting
759 ;;; object, unless CHAR is a macro yielding no value, then 0 and NIL,
760 ;;; for functions that want comments to return so that they can look
761 ;;; past them. CHAR must not be whitespace.
762 (defun read-maybe-nothing (stream char)
763 (truly-the
764 (values bit t) ; avoid a type-check. M-V-CALL is lame
765 (multiple-value-call
766 (lambda (stream start-pos &optional (result nil supplied-p) &rest junk)
767 (declare (ignore junk)) ; is this ANSI-specified?
768 (when (and supplied-p start-pos)
769 (funcall (form-tracking-stream-observer stream)
770 start-pos
771 (form-tracking-stream-input-char-pos stream) result))
772 (values (if supplied-p 1 0) result))
773 ;; KLUDGE: not capturing anything in the lambda avoids closure consing
774 stream
775 (and (form-tracking-stream-p stream)
776 ;; Subtract 1 because the position points _after_ CHAR.
777 (1- (form-tracking-stream-input-char-pos stream)))
778 (funcall (!cmt-entry-to-function
779 (get-raw-cmt-entry char *readtable*) #'read-token)
780 stream char))))
782 (defun read (&optional (stream *standard-input*)
783 (eof-error-p t)
784 (eof-value nil)
785 (recursive-p nil))
786 #!+sb-doc
787 "Read the next Lisp value from STREAM, and return it."
788 (declare (explicit-check))
789 (check-for-recursive-read stream recursive-p 'read)
790 (let* ((local-eof-val (load-time-value (cons nil nil) t))
791 (result (%read-preserving-whitespace
792 stream eof-error-p local-eof-val recursive-p)))
793 ;; This function generally discards trailing whitespace. If you
794 ;; don't want to discard trailing whitespace, call
795 ;; CL:READ-PRESERVING-WHITESPACE instead.
796 (unless (or (eql result local-eof-val) recursive-p)
797 (let ((next-char (read-char stream nil +EOF+)))
798 (unless (or (eq next-char +EOF+)
799 (whitespace[2]p next-char))
800 (unread-char next-char stream))))
801 (if (eq result local-eof-val) eof-value result)))
804 ;;;; basic readmacro definitions
805 ;;;;
806 ;;;; Some large, hairy subsets of readmacro definitions (backquotes
807 ;;;; and sharp macros) are not here, but in their own source files.
809 (defun read-quote (stream ignore)
810 (declare (ignore ignore))
811 (list 'quote (read stream t nil t)))
813 (defun read-comment (stream ignore)
814 (declare (ignore ignore))
815 (handler-bind
816 ((character-decoding-error
817 #'(lambda (decoding-error)
818 (declare (ignorable decoding-error))
819 (style-warn
820 'sb!kernel::character-decoding-error-in-macro-char-comment
821 :position (file-position stream) :stream stream)
822 (invoke-restart 'attempt-resync))))
823 (let ((stream (in-stream-from-designator stream)))
824 (if (ansi-stream-p stream)
825 (prepare-for-fast-read-char stream
826 (loop (let ((char (fast-read-char nil +EOF+)))
827 (when (or (eq char +EOF+) (char= char #\newline))
828 (return (done-with-fast-read-char))))))
829 ;; CLOS stream
830 (loop (let ((char (read-char stream nil +EOF+)))
831 (when (or (eq char +EOF+) (char= char #\newline))
832 (return)))))))
833 ;; Don't return anything.
834 (values))
836 ;;; FIXME: for these two macro chars, if STREAM is a FORM-TRACKING-STREAM,
837 ;;; every cons cell should generate a notification so that the readtable
838 ;;; manipulation in SB-COVER can be eliminated in favor of a stream observer.
839 ;;; It is cheap to add events- it won't increase consing in the compiler
840 ;;; because it the extra events can simply be ignored.
841 (macrolet
842 ((with-list-reader ((streamvar delimiter) &body body)
843 `(let* ((thelist (list nil))
844 (listtail thelist)
845 (collectp (if *read-suppress* 0 -1)))
846 (declare (dynamic-extent thelist))
847 (loop (let ((firstchar (flush-whitespace ,streamvar)))
848 (when (eq firstchar ,delimiter)
849 (return (cdr thelist)))
850 ,@body))))
851 (read-list-item (streamvar)
852 `(multiple-value-bind (winp obj)
853 (read-maybe-nothing ,streamvar firstchar)
854 ;; allow for a character macro return to return nothing
855 (unless (zerop (logand winp collectp))
856 (setq listtail
857 (cdr (rplacd (truly-the cons listtail) (list obj))))))))
859 ;;; The character macro handler for left paren
860 (defun read-list (stream ignore)
861 (declare (ignore ignore))
862 (with-list-reader (stream #\))
863 (when (eq firstchar #\.)
864 (let ((nextchar (read-char stream t)))
865 (cond ((token-delimiterp nextchar)
866 (cond ((eq listtail thelist)
867 (unless (zerop collectp)
868 (simple-reader-error
869 stream "Nothing appears before . in list.")))
870 ((whitespace[2]p nextchar)
871 (setq nextchar (flush-whitespace stream))))
872 (rplacd (truly-the cons listtail)
873 (read-after-dot stream nextchar collectp))
874 ;; Check for improper ". ,@" or ". ,." now rather than
875 ;; in the #\` reader. The resulting QUASIQUOTE macro might
876 ;; never be exapanded, but nonetheless could be erroneous.
877 (unless (zerop (logand *backquote-depth* collectp))
878 (let ((lastcdr (cdr (last listtail))))
879 (when (and (comma-p lastcdr) (comma-splicing-p lastcdr))
880 (simple-reader-error
881 stream "~S contains a splicing comma after a dot"
882 (cdr thelist)))))
883 (return (cdr thelist)))
884 ;; Put back NEXTCHAR so that we can read it normally.
885 (t (unread-char nextchar stream)))))
886 ;; Next thing is not an isolated dot.
887 (read-list-item stream)))
889 ;;; (This is a COMMON-LISP exported symbol.)
890 (defun read-delimited-list (endchar &optional
891 (input-stream *standard-input*)
892 recursive-p)
893 #!+sb-doc
894 "Read Lisp values from INPUT-STREAM until the next character after a
895 value's representation is ENDCHAR, and return the objects as a list."
896 (declare (explicit-check))
897 (check-for-recursive-read input-stream recursive-p 'read-delimited-list)
898 (flet ((%read-delimited-list ()
899 (with-list-reader (input-stream endchar)
900 (read-list-item input-stream))))
901 (if recursive-p
902 (%read-delimited-list)
903 (with-read-buffer () (%read-delimited-list)))))) ; end MACROLET
905 (defun read-after-dot (stream firstchar collectp)
906 ;; FIRSTCHAR is non-whitespace!
907 (let ((lastobj ()))
908 (do ((char firstchar (flush-whitespace stream)))
909 ((eq char #\))
910 (if (zerop collectp)
911 (return-from read-after-dot nil)
912 (simple-reader-error stream "Nothing appears after . in list.")))
913 ;; See whether there's something there.
914 (multiple-value-bind (winp obj) (read-maybe-nothing stream char)
915 (unless (zerop winp) (return (setq lastobj obj)))))
916 ;; At least one thing appears after the dot.
917 ;; Check for more than one thing following dot.
918 (loop
919 (let ((char (flush-whitespace stream)))
920 (cond ((eq char #\)) (return lastobj)) ;success!
921 ;; Try reading virtual whitespace.
922 ((not (zerop (logand (read-maybe-nothing stream char)
923 (truly-the fixnum collectp))))
924 (simple-reader-error
925 stream "More than one object follows . in list.")))))))
927 (defun read-string (stream closech)
928 ;; This accumulates chars until it sees same char that invoked it.
929 ;; We avoid copying any given input character more than twice-
930 ;; once to a temp buffer and then to the result. In the worst case,
931 ;; we can waste space equal the unwasted space, if the final character
932 ;; causes allocation of a new buffer for just that character,
933 ;; because the buffer size is doubled each time it overflows.
934 ;; (Would be better to peek at the frc-buffer if the stream has one.)
935 ;; Scratch vectors are GC-able as soon as this function returns though.
936 (declare (character closech))
937 (macrolet ((scan (read-a-char eofp &optional finish)
938 `(loop (let ((char ,read-a-char))
939 (declare (optimize (sb!c::insert-array-bounds-checks 0)))
940 (cond (,eofp (error 'end-of-file :stream stream))
941 ((eql char closech)
942 (return ,finish))
943 ((single-escape-p char rt)
944 (setq char ,read-a-char)
945 (when ,eofp
946 (error 'end-of-file :stream stream))))
947 (when (>= ptr lim)
948 (unless suppress
949 (push buf chain)
950 (setq lim (the index (ash lim 1))
951 buf (make-array lim :element-type 'character)))
952 (setq ptr 0))
953 (setf (schar buf ptr) (truly-the character char))
954 #!+sb-unicode ; BASE-CHAR-P does not exist if not
955 (unless (base-char-p char) (setq only-base-chars nil))
956 (incf ptr)))))
957 (let* ((token-buf *read-buffer*)
958 (buf (token-buf-string token-buf))
959 (rt *readtable*)
960 (stream (in-stream-from-designator stream))
961 (suppress *read-suppress*)
962 (lim (length buf))
963 (ptr 0)
964 (only-base-chars t)
965 (chain))
966 (declare (type (simple-array character (*)) buf))
967 (reset-read-buffer token-buf)
968 (if (ansi-stream-p stream)
969 (prepare-for-fast-read-char stream
970 (scan (fast-read-char t) nil (done-with-fast-read-char)))
971 ;; CLOS stream
972 (scan (read-char stream nil +EOF+) (eq char +EOF+)))
973 (if suppress
975 (let* ((sum (loop for buf in chain sum (length buf)))
976 (result
977 (make-array (+ sum ptr)
978 :element-type (if only-base-chars
979 (%readtable-string-preference rt)
980 'character))))
981 (setq ptr sum)
982 ;; Now work backwards from the end
983 (replace result buf :start1 ptr)
984 (dolist (buf chain result)
985 (declare (type (simple-array character (*)) buf))
986 (let ((len (length buf)))
987 (decf ptr len)
988 (replace result buf :start1 ptr))))))))
990 (defun read-right-paren (stream ignore)
991 (declare (ignore ignore))
992 (simple-reader-error stream "unmatched close parenthesis"))
994 ;;; Read from the stream up to the next delimiter. Leave the resulting
995 ;;; token in *READ-BUFFER*, and return three values:
996 ;;; -- a TOKEN-BUF
997 ;;; -- whether any escape character was seen (even if no character is escaped)
998 ;;; -- whether a package delimiter character was seen
999 ;;; Normalizes the input to NFKC before returning
1000 (defun internal-read-extended-token (stream firstchar escape-firstchar
1001 &aux (read-buffer *read-buffer*))
1002 (reset-read-buffer read-buffer)
1003 (when escape-firstchar
1004 (ouch-read-buffer-escaped firstchar read-buffer)
1005 (setq firstchar (read-char stream nil +EOF+)))
1006 (do ((char firstchar (read-char stream nil +EOF+))
1007 (seen-multiple-escapes nil)
1008 (rt *readtable*)
1009 (colon nil))
1010 ((cond ((eq char +EOF+) t)
1011 ((token-delimiterp char rt)
1012 (unread-char char stream)
1014 (t nil))
1015 (progn
1016 (multiple-value-setq (read-buffer colon)
1017 (normalize-read-buffer read-buffer colon))
1018 (values read-buffer
1019 (or (plusp (fill-pointer (token-buf-escapes read-buffer)))
1020 seen-multiple-escapes)
1021 colon)))
1022 (flet ((escape-1-char ()
1023 ;; It can't be a number, even if it's 1\23.
1024 ;; Read next char here, so it won't be casified.
1025 (let ((nextchar (read-char stream nil +EOF+)))
1026 (if (eq nextchar +EOF+)
1027 (reader-eof-error stream "after escape character")
1028 (ouch-read-buffer-escaped nextchar read-buffer)))))
1029 (cond ((single-escape-p char rt) (escape-1-char))
1030 ((multiple-escape-p char rt)
1031 (setq seen-multiple-escapes t)
1032 ;; Read to next multiple-escape, escaping single chars
1033 ;; along the way.
1034 (loop
1035 (let ((ch (read-char stream nil +EOF+)))
1036 (cond ((eq ch +EOF+)
1037 (reader-eof-error stream "inside extended token"))
1038 ((multiple-escape-p ch rt) (return))
1039 ((single-escape-p ch rt) (escape-1-char))
1040 (t (ouch-read-buffer-escaped ch read-buffer))))))
1042 (when (and (not colon) ; easiest test first
1043 (constituentp char rt)
1044 (eql (get-constituent-trait char)
1045 +char-attr-package-delimiter+))
1046 (setq colon t))
1047 (ouch-read-buffer char read-buffer))))))
1049 ;;;; character classes
1051 ;;; Return the character class for CHAR.
1053 ;;; FIXME: why aren't these ATT-getting forms using GET-CAT-ENTRY?
1054 ;;; Because we've cached the readtable tables?
1055 (defmacro char-class (char attarray atthash)
1056 `(let ((att (if (typep (truly-the character ,char) 'base-char)
1057 (aref ,attarray (char-code ,char))
1058 (gethash ,char ,atthash +char-attr-constituent+))))
1059 (declare (fixnum att))
1060 (cond
1061 ((<= att +char-attr-terminating-macro+) +char-attr-delimiter+)
1062 ((< att +char-attr-constituent+) att)
1063 (t (setf att (get-constituent-trait ,char))
1064 (if (= att +char-attr-invalid+)
1065 (simple-reader-error stream "invalid constituent")
1066 att)))))
1068 ;;; Return the character class for CHAR, which might be part of a
1069 ;;; rational number.
1070 (defmacro char-class2 (char attarray atthash read-base)
1071 `(let ((att (if (typep (truly-the character ,char) 'base-char)
1072 (aref ,attarray (char-code ,char))
1073 (gethash ,char ,atthash +char-attr-constituent+))))
1074 (declare (fixnum att))
1075 (cond
1076 ((<= att +char-attr-terminating-macro+) +char-attr-delimiter+)
1077 ((< att +char-attr-constituent+) att)
1078 (t (setf att (get-constituent-trait ,char))
1079 (cond
1080 ((digit-char-p ,char ,read-base) +char-attr-constituent-digit+)
1081 ((= att +char-attr-constituent-digit+) +char-attr-constituent+)
1082 ((= att +char-attr-invalid+)
1083 (simple-reader-error stream "invalid constituent"))
1084 (t att))))))
1086 ;;; Return the character class for a char which might be part of a
1087 ;;; rational or floating number. (Assume that it is a digit if it
1088 ;;; could be.)
1089 (defmacro char-class3 (char attarray atthash read-base)
1090 `(let ((att (if (typep (truly-the character ,char) 'base-char)
1091 (aref ,attarray (char-code ,char))
1092 (gethash ,char ,atthash +char-attr-constituent+))))
1093 (declare (fixnum att))
1094 (cond
1095 ((<= att +char-attr-terminating-macro+) +char-attr-delimiter+)
1096 ((< att +char-attr-constituent+) att)
1097 (t (setf att (get-constituent-trait ,char))
1098 (when possibly-rational
1099 (setq possibly-rational
1100 (or (digit-char-p ,char ,read-base)
1101 (= att +char-attr-constituent-slash+))))
1102 (when possibly-float
1103 (setq possibly-float
1104 (or (digit-char-p ,char 10)
1105 (= att +char-attr-constituent-dot+))))
1106 (cond
1107 ((digit-char-p ,char (max ,read-base 10))
1108 (if (digit-char-p ,char ,read-base)
1109 (if (= att +char-attr-constituent-expt+)
1110 +char-attr-constituent-digit-or-expt+
1111 +char-attr-constituent-digit+)
1112 +char-attr-constituent-decimal-digit+))
1113 ((= att +char-attr-invalid+)
1114 (simple-reader-error stream "invalid constituent"))
1115 (t att))))))
1117 ;;;; token fetching
1119 (defvar *read-suppress* nil
1120 #!+sb-doc
1121 "Suppress most interpreting in the reader when T.")
1123 (defvar *read-base* 10
1124 #!+sb-doc
1125 "the radix that Lisp reads numbers in")
1126 (declaim (type (integer 2 36) *read-base*))
1128 ;;; Normalize TOKEN-BUF to NFKC, returning a new TOKEN-BUF and the
1129 ;;; COLON value
1130 (defun normalize-read-buffer (token-buf &optional colon)
1131 (when (or (token-buf-only-base-chars token-buf)
1132 (not (readtable-normalization *readtable*)))
1133 (return-from normalize-read-buffer (values token-buf colon)))
1134 (let ((current-buffer (copy-token-buf-string token-buf))
1135 (old-escapes (copy-seq (token-buf-escapes token-buf)))
1136 (str-to-normalize (make-string (token-buf-fill-ptr token-buf)))
1137 (normalize-ptr 0) (escapes-ptr 0))
1138 (reset-read-buffer token-buf)
1139 (macrolet ((clear-str-to-normalize ()
1140 `(progn
1141 (loop for char across (sb!unicode:normalize-string
1142 (subseq str-to-normalize 0 normalize-ptr)
1143 :nfkc) do
1144 (ouch-read-buffer char token-buf))
1145 (setf normalize-ptr 0)))
1146 (push-to-normalize (ch)
1147 (let ((ch-gen (gensym)))
1148 `(let ((,ch-gen ,ch))
1149 (setf (char str-to-normalize normalize-ptr) ,ch-gen)
1150 (incf normalize-ptr)))))
1151 (loop for c across current-buffer
1152 for i from 0
1154 (if (and (< escapes-ptr (length old-escapes))
1155 (eql i (aref old-escapes escapes-ptr)))
1156 (progn
1157 (clear-str-to-normalize)
1158 (ouch-read-buffer-escaped c token-buf)
1159 (incf escapes-ptr))
1160 (push-to-normalize c)))
1161 (clear-str-to-normalize)
1162 (values token-buf colon))))
1164 ;;; Modify the read buffer according to READTABLE-CASE, ignoring
1165 ;;; ESCAPES. ESCAPES is a vector of the escaped indices.
1166 (defun casify-read-buffer (token-buf)
1167 (let ((case (readtable-case *readtable*))
1168 (escapes (token-buf-escapes token-buf)))
1169 (cond
1170 ((and (zerop (length escapes)) (eq case :upcase))
1171 (let ((buffer (token-buf-string token-buf)))
1172 (dotimes (i (token-buf-fill-ptr token-buf))
1173 (declare (optimize (sb!c::insert-array-bounds-checks 0)))
1174 (setf (schar buffer i) (char-upcase (schar buffer i))))))
1175 ((eq case :preserve))
1177 (macrolet ((skip-esc (&body body)
1178 `(do ((i (1- (token-buf-fill-ptr token-buf)) (1- i))
1179 (buffer (token-buf-string token-buf))
1180 (esc (if (zerop (fill-pointer escapes))
1181 -1 (vector-pop escapes))))
1182 ((minusp i))
1183 (declare (fixnum i)
1184 (optimize (sb!c::insert-array-bounds-checks 0)))
1185 (if (< esc i)
1186 (let ((ch (schar buffer i)))
1187 ,@body)
1188 (progn
1189 (aver (= esc i))
1190 (setq esc (if (zerop (fill-pointer escapes))
1191 -1 (vector-pop escapes))))))))
1192 (flet ((lower-em ()
1193 (skip-esc (setf (schar buffer i) (char-downcase ch))))
1194 (raise-em ()
1195 (skip-esc (setf (schar buffer i) (char-upcase ch)))))
1196 (ecase case
1197 (:upcase (raise-em))
1198 (:downcase (lower-em))
1199 (:invert
1200 (let ((all-upper t)
1201 (all-lower t)
1202 (fillptr (fill-pointer escapes)))
1203 (skip-esc
1204 (when (both-case-p ch)
1205 (if (upper-case-p ch)
1206 (setq all-lower nil)
1207 (setq all-upper nil))))
1208 (setf (fill-pointer escapes) fillptr)
1209 (cond (all-lower (raise-em))
1210 (all-upper (lower-em))))))))))))
1212 (eval-when (:compile-toplevel :load-toplevel :execute)
1213 (defvar *reader-package* nil))
1214 (declaim (type (or null package) *reader-package*)
1215 (always-bound *reader-package*))
1217 (defun reader-find-package (package-designator stream)
1218 (if (%instancep package-designator)
1219 package-designator
1220 (let ((package (find-package package-designator)))
1221 (cond (package
1222 ;; Release the token-buf that was used for the designator
1223 (release-token-buf (shiftf (token-buf-next *read-buffer*) nil))
1224 package)
1226 (error 'simple-reader-package-error
1227 :package package-designator
1228 :stream stream
1229 :format-control "Package ~A does not exist."
1230 :format-arguments (list package-designator)))))))
1232 (defun read-token (stream firstchar)
1233 #!+sb-doc
1234 "Default readmacro function. Handles numbers, symbols, and SBCL's
1235 extended <package-name>::<form-in-package> syntax."
1236 ;; Check explicitly whether FIRSTCHAR has an entry for
1237 ;; NON-TERMINATING in CHARACTER-ATTRIBUTE-TABLE and
1238 ;; READ-DOT-NUMBER-SYMBOL in CMT. Report an error if these are
1239 ;; violated. (If we called this, we want something that is a
1240 ;; legitimate token!) Read in the longest possible string satisfying
1241 ;; the Backus-Naur form for "unqualified-token". Leave the result in
1242 ;; the *READ-BUFFER*. Return next char after token (last char read).
1243 (when *read-suppress*
1244 (internal-read-extended-token stream firstchar nil)
1245 (return-from read-token nil))
1246 (let* ((rt *readtable*)
1247 (base *read-base*)
1248 (attribute-array (character-attribute-array rt))
1249 (attribute-hash-table (character-attribute-hash-table rt))
1250 (buf *read-buffer*)
1251 (package-designator nil)
1252 (colons 0)
1253 (possibly-rational t)
1254 (seen-digit-or-expt nil)
1255 (possibly-float t)
1256 (was-possibly-float nil)
1257 (seen-multiple-escapes nil))
1258 (declare (token-buf buf))
1259 (reset-read-buffer buf)
1260 (macrolet ((getchar-or-else (what)
1261 `(when (eq (setq char (read-char stream nil +EOF+)) +EOF+)
1262 ,what)))
1263 (prog ((char firstchar))
1264 (case (char-class3 char attribute-array attribute-hash-table base)
1265 (#.+char-attr-constituent-sign+ (go SIGN))
1266 (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
1267 (#.+char-attr-constituent-digit-or-expt+
1268 (setq seen-digit-or-expt t)
1269 (go LEFTDIGIT))
1270 (#.+char-attr-constituent-decimal-digit+ (go LEFTDECIMALDIGIT))
1271 (#.+char-attr-constituent-dot+ (go FRONTDOT))
1272 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1273 (#.+char-attr-package-delimiter+ (go COLON))
1274 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1275 (#.+char-attr-invalid+ (simple-reader-error stream
1276 "invalid constituent"))
1277 ;; can't have eof, whitespace, or terminating macro as first char!
1278 (t (go SYMBOL)))
1279 SIGN ; saw "sign"
1280 (ouch-read-buffer char buf)
1281 (getchar-or-else (go RETURN-SYMBOL))
1282 (setq possibly-rational t
1283 possibly-float t)
1284 (case (char-class3 char attribute-array attribute-hash-table base)
1285 (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
1286 (#.+char-attr-constituent-digit-or-expt+
1287 (setq seen-digit-or-expt t)
1288 (go LEFTDIGIT))
1289 (#.+char-attr-constituent-decimal-digit+ (go LEFTDECIMALDIGIT))
1290 (#.+char-attr-constituent-dot+ (go SIGNDOT))
1291 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1292 (#.+char-attr-package-delimiter+ (go COLON))
1293 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1294 (#.+char-attr-delimiter+ (unread-char char stream) (go RETURN-SYMBOL))
1295 (t (go SYMBOL)))
1296 LEFTDIGIT ; saw "[sign] {digit}+"
1297 (ouch-read-buffer char buf)
1298 (getchar-or-else (return (make-integer)))
1299 (setq was-possibly-float possibly-float)
1300 (case (char-class3 char attribute-array attribute-hash-table base)
1301 (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
1302 (#.+char-attr-constituent-decimal-digit+ (if possibly-float
1303 (go LEFTDECIMALDIGIT)
1304 (go SYMBOL)))
1305 (#.+char-attr-constituent-dot+ (if possibly-float
1306 (go MIDDLEDOT)
1307 (go SYMBOL)))
1308 (#.+char-attr-constituent-digit-or-expt+
1309 (if (or seen-digit-or-expt (not was-possibly-float))
1310 (progn (setq seen-digit-or-expt t) (go LEFTDIGIT))
1311 (progn (setq seen-digit-or-expt t) (go LEFTDIGIT-OR-EXPT))))
1312 (#.+char-attr-constituent-expt+
1313 (if was-possibly-float
1314 (go EXPONENT)
1315 (go SYMBOL)))
1316 (#.+char-attr-constituent-slash+ (if possibly-rational
1317 (go RATIO)
1318 (go SYMBOL)))
1319 (#.+char-attr-delimiter+ (unread-char char stream)
1320 (return (make-integer)))
1321 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1322 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1323 (#.+char-attr-package-delimiter+ (go COLON))
1324 (t (go SYMBOL)))
1325 LEFTDIGIT-OR-EXPT
1326 (ouch-read-buffer char buf)
1327 (getchar-or-else (return (make-integer)))
1328 (case (char-class3 char attribute-array attribute-hash-table base)
1329 (#.+char-attr-constituent-digit+ (go LEFTDIGIT))
1330 (#.+char-attr-constituent-decimal-digit+ (bug "impossible!"))
1331 (#.+char-attr-constituent-dot+ (go SYMBOL))
1332 (#.+char-attr-constituent-digit-or-expt+ (go LEFTDIGIT))
1333 (#.+char-attr-constituent-expt+ (go SYMBOL))
1334 (#.+char-attr-constituent-sign+ (go EXPTSIGN))
1335 (#.+char-attr-constituent-slash+ (if possibly-rational
1336 (go RATIO)
1337 (go SYMBOL)))
1338 (#.+char-attr-delimiter+ (unread-char char stream)
1339 (return (make-integer)))
1340 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1341 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1342 (#.+char-attr-package-delimiter+ (go COLON))
1343 (t (go SYMBOL)))
1344 LEFTDECIMALDIGIT ; saw "[sign] {decimal-digit}+"
1345 (aver possibly-float)
1346 (ouch-read-buffer char buf)
1347 (getchar-or-else (go RETURN-SYMBOL))
1348 (case (char-class char attribute-array attribute-hash-table)
1349 (#.+char-attr-constituent-digit+ (go LEFTDECIMALDIGIT))
1350 (#.+char-attr-constituent-dot+ (go MIDDLEDOT))
1351 (#.+char-attr-constituent-expt+ (go EXPONENT))
1352 (#.+char-attr-constituent-slash+ (aver (not possibly-rational))
1353 (go SYMBOL))
1354 (#.+char-attr-delimiter+ (unread-char char stream)
1355 (go RETURN-SYMBOL))
1356 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1357 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1358 (#.+char-attr-package-delimiter+ (go COLON))
1359 (t (go SYMBOL)))
1360 MIDDLEDOT ; saw "[sign] {digit}+ dot"
1361 (ouch-read-buffer char buf)
1362 (getchar-or-else (return (make-integer 10)))
1363 (case (char-class char attribute-array attribute-hash-table)
1364 (#.+char-attr-constituent-digit+ (go RIGHTDIGIT))
1365 (#.+char-attr-constituent-expt+ (go EXPONENT))
1366 (#.+char-attr-delimiter+
1367 (unread-char char stream)
1368 (return (make-integer 10)))
1369 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1370 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1371 (#.+char-attr-package-delimiter+ (go COLON))
1372 (t (go SYMBOL)))
1373 RIGHTDIGIT ; saw "[sign] {decimal-digit}* dot {digit}+"
1374 (ouch-read-buffer char buf)
1375 (getchar-or-else (return (make-float stream)))
1376 (case (char-class char attribute-array attribute-hash-table)
1377 (#.+char-attr-constituent-digit+ (go RIGHTDIGIT))
1378 (#.+char-attr-constituent-expt+ (go EXPONENT))
1379 (#.+char-attr-delimiter+
1380 (unread-char char stream)
1381 (return (make-float stream)))
1382 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1383 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1384 (#.+char-attr-package-delimiter+ (go COLON))
1385 (t (go SYMBOL)))
1386 SIGNDOT ; saw "[sign] dot"
1387 (ouch-read-buffer char buf)
1388 (getchar-or-else (go RETURN-SYMBOL))
1389 (case (char-class char attribute-array attribute-hash-table)
1390 (#.+char-attr-constituent-digit+ (go RIGHTDIGIT))
1391 (#.+char-attr-delimiter+ (unread-char char stream) (go RETURN-SYMBOL))
1392 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1393 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1394 (t (go SYMBOL)))
1395 FRONTDOT ; saw "dot"
1396 (ouch-read-buffer char buf)
1397 (getchar-or-else (simple-reader-error stream "dot context error"))
1398 (case (char-class char attribute-array attribute-hash-table)
1399 (#.+char-attr-constituent-digit+ (go RIGHTDIGIT))
1400 (#.+char-attr-constituent-dot+ (go DOTS))
1401 (#.+char-attr-delimiter+ (simple-reader-error stream
1402 "dot context error"))
1403 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1404 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1405 (#.+char-attr-package-delimiter+ (go COLON))
1406 (t (go SYMBOL)))
1407 EXPONENT
1408 (ouch-read-buffer char buf)
1409 (getchar-or-else (go RETURN-SYMBOL))
1410 (setq possibly-float t)
1411 (case (char-class char attribute-array attribute-hash-table)
1412 (#.+char-attr-constituent-sign+ (go EXPTSIGN))
1413 (#.+char-attr-constituent-digit+ (go EXPTDIGIT))
1414 (#.+char-attr-delimiter+ (unread-char char stream) (go RETURN-SYMBOL))
1415 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1416 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1417 (#.+char-attr-package-delimiter+ (go COLON))
1418 (t (go SYMBOL)))
1419 EXPTSIGN ; got to EXPONENT, and saw a sign character
1420 (ouch-read-buffer char buf)
1421 (getchar-or-else (go RETURN-SYMBOL))
1422 (case (char-class char attribute-array attribute-hash-table)
1423 (#.+char-attr-constituent-digit+ (go EXPTDIGIT))
1424 (#.+char-attr-delimiter+ (unread-char char stream) (go RETURN-SYMBOL))
1425 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1426 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1427 (#.+char-attr-package-delimiter+ (go COLON))
1428 (t (go SYMBOL)))
1429 EXPTDIGIT ; got to EXPONENT, saw "[sign] {digit}+"
1430 (ouch-read-buffer char buf)
1431 (getchar-or-else (return (make-float stream)))
1432 (case (char-class char attribute-array attribute-hash-table)
1433 (#.+char-attr-constituent-digit+ (go EXPTDIGIT))
1434 (#.+char-attr-delimiter+
1435 (unread-char char stream)
1436 (return (make-float stream)))
1437 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1438 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1439 (#.+char-attr-package-delimiter+ (go COLON))
1440 (t (go SYMBOL)))
1441 RATIO ; saw "[sign] {digit}+ slash"
1442 (ouch-read-buffer char buf)
1443 (getchar-or-else (go RETURN-SYMBOL))
1444 (case (char-class2 char attribute-array attribute-hash-table base)
1445 (#.+char-attr-constituent-digit+ (go RATIODIGIT))
1446 (#.+char-attr-delimiter+ (unread-char char stream) (go RETURN-SYMBOL))
1447 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1448 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1449 (#.+char-attr-package-delimiter+ (go COLON))
1450 (t (go SYMBOL)))
1451 RATIODIGIT ; saw "[sign] {digit}+ slash {digit}+"
1452 (ouch-read-buffer char buf)
1453 (getchar-or-else (return (make-ratio stream)))
1454 (case (char-class2 char attribute-array attribute-hash-table base)
1455 (#.+char-attr-constituent-digit+ (go RATIODIGIT))
1456 (#.+char-attr-delimiter+
1457 (unread-char char stream)
1458 (return (make-ratio stream)))
1459 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1460 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1461 (#.+char-attr-package-delimiter+ (go COLON))
1462 (t (go SYMBOL)))
1463 DOTS ; saw "dot {dot}+"
1464 (ouch-read-buffer char buf)
1465 (getchar-or-else (simple-reader-error stream "too many dots"))
1466 (case (char-class char attribute-array attribute-hash-table)
1467 (#.+char-attr-constituent-dot+ (go DOTS))
1468 (#.+char-attr-delimiter+
1469 (unread-char char stream)
1470 (simple-reader-error stream "too many dots"))
1471 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1472 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1473 (#.+char-attr-package-delimiter+ (go COLON))
1474 (t (go SYMBOL)))
1475 SYMBOL ; not a dot, dots, or number
1476 (let ((stream (in-stream-from-designator stream)))
1477 (macrolet
1478 ((scan (read-a-char &optional finish)
1479 `(prog ()
1480 SYMBOL-LOOP
1481 (ouch-read-buffer char buf)
1482 (setq char ,read-a-char)
1483 (when (eq char +EOF+) (go RETURN-SYMBOL))
1484 (case (char-class char attribute-array attribute-hash-table)
1485 (#.+char-attr-single-escape+ ,finish (go SINGLE-ESCAPE))
1486 (#.+char-attr-delimiter+ ,finish
1487 (unread-char char stream)
1488 (go RETURN-SYMBOL))
1489 (#.+char-attr-multiple-escape+ ,finish (go MULT-ESCAPE))
1490 (#.+char-attr-package-delimiter+ ,finish (go COLON))
1491 (t (go SYMBOL-LOOP))))))
1492 (if (ansi-stream-p stream)
1493 (prepare-for-fast-read-char stream
1494 (scan (fast-read-char nil +EOF+) (done-with-fast-read-char)))
1495 ;; CLOS stream
1496 (scan (read-char stream nil +EOF+)))))
1497 SINGLE-ESCAPE ; saw a single-escape
1498 ;; Don't put the escape character in the read buffer.
1499 ;; READ-NEXT CHAR, put in buffer (no case conversion).
1500 (let ((nextchar (read-char stream nil +EOF+)))
1501 (when (eq nextchar +EOF+)
1502 (reader-eof-error stream "after single-escape character"))
1503 (ouch-read-buffer-escaped nextchar buf))
1504 (getchar-or-else (go RETURN-SYMBOL))
1505 (case (char-class char attribute-array attribute-hash-table)
1506 (#.+char-attr-delimiter+ (unread-char char stream) (go RETURN-SYMBOL))
1507 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1508 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1509 (#.+char-attr-package-delimiter+ (go COLON))
1510 (t (go SYMBOL)))
1511 MULT-ESCAPE
1512 (setq seen-multiple-escapes t)
1513 ;; sometimes we pass eof-error=nil but check. here we just let it err.
1514 ;; should pick one style and stick with it.
1515 (do ((char (read-char stream t) (read-char stream t)))
1516 ((multiple-escape-p char rt))
1517 (if (single-escape-p char rt) (setq char (read-char stream t)))
1518 (ouch-read-buffer-escaped char buf))
1519 (getchar-or-else (go RETURN-SYMBOL))
1520 (case (char-class char attribute-array attribute-hash-table)
1521 (#.+char-attr-delimiter+ (unread-char char stream) (go RETURN-SYMBOL))
1522 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1523 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1524 (#.+char-attr-package-delimiter+ (go COLON))
1525 (t (go SYMBOL)))
1526 COLON
1527 (unless (zerop colons)
1528 (simple-reader-error
1529 stream "too many colons in ~S" (copy-token-buf-string buf)))
1530 (setf buf (normalize-read-buffer buf))
1531 (casify-read-buffer buf)
1532 (setq colons 1)
1533 (setq package-designator
1534 (if (or (plusp (token-buf-fill-ptr buf)) seen-multiple-escapes)
1535 (prog1 (sized-token-buf-string buf)
1536 (let ((new (acquire-token-buf)))
1537 (setf (token-buf-next new) buf ; new points to old
1538 buf new *read-buffer* new)))
1539 *keyword-package*))
1540 (reset-read-buffer buf)
1541 (getchar-or-else (reader-eof-error stream "after reading a colon"))
1542 (case (char-class char attribute-array attribute-hash-table)
1543 (#.+char-attr-delimiter+
1544 (unread-char char stream)
1545 (simple-reader-error stream
1546 "illegal terminating character after a colon: ~S"
1547 char))
1548 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1549 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1550 (#.+char-attr-package-delimiter+ (go INTERN))
1551 (t (go SYMBOL)))
1552 INTERN
1553 (setq colons 2)
1554 (getchar-or-else (reader-eof-error stream "after reading a colon"))
1555 (case (char-class char attribute-array attribute-hash-table)
1556 (#.+char-attr-delimiter+
1557 (unread-char char stream)
1558 (if package-designator
1559 (let* ((*reader-package*
1560 (reader-find-package package-designator stream)))
1561 (return (read stream t nil t)))
1562 (simple-reader-error stream
1563 "illegal terminating character after a double-colon: ~S"
1564 char)))
1565 (#.+char-attr-single-escape+ (go SINGLE-ESCAPE))
1566 (#.+char-attr-multiple-escape+ (go MULT-ESCAPE))
1567 (#.+char-attr-package-delimiter+
1568 (simple-reader-error stream
1569 "too many colons after ~S name"
1570 package-designator))
1571 (t (go SYMBOL)))
1572 RETURN-SYMBOL
1573 (setf buf (normalize-read-buffer buf))
1574 (casify-read-buffer buf)
1575 (let* ((pkg (if package-designator
1576 (reader-find-package package-designator stream)
1577 (or *reader-package* (sane-package))))
1578 (intern-p (or (/= colons 1) (eq pkg *keyword-package*))))
1579 (unless intern-p ; Try %FIND-SYMBOL
1580 (multiple-value-bind (symbol accessibility)
1581 (%find-symbol (token-buf-string buf) (token-buf-fill-ptr buf) pkg)
1582 (when (eq accessibility :external) (return symbol))
1583 (with-simple-restart (continue "Use symbol anyway.")
1584 (error 'simple-reader-package-error
1585 :package pkg
1586 :stream stream
1587 :format-arguments
1588 (list (copy-token-buf-string buf) (package-name pkg))
1589 :format-control
1590 (if accessibility
1591 "The symbol ~S is not external in the ~A package."
1592 "Symbol ~S not found in the ~A package.")))))
1593 (return (%intern (token-buf-string buf)
1594 (token-buf-fill-ptr buf)
1596 (if (token-buf-only-base-chars buf)
1597 (%readtable-symbol-preference rt)
1598 'character))))))))
1600 ;;; For semi-external use: Return 3 values: the token-buf,
1601 ;;; a flag for whether there was an escape char, and the position of
1602 ;;; any package delimiter. The returned token-buf is not case-converted.
1603 (defun read-extended-token (stream)
1604 ;; recursive-p = T is basically irrelevant.
1605 (let ((first-char (read-char stream nil +EOF+ t)))
1606 (if (neq first-char +EOF+)
1607 (internal-read-extended-token stream first-char nil)
1608 (values (reset-read-buffer *read-buffer*) nil nil))))
1610 ;;; for semi-external use:
1612 ;;; Read an extended token with the first character escaped. Return
1613 ;;; the token-buf. The returned token-buf is not case-converted.
1614 (defun read-extended-token-escaped (stream)
1615 (let ((first-char (read-char stream nil +EOF+)))
1616 (if (neq first-char +EOF+)
1617 (values (internal-read-extended-token stream first-char t))
1618 (reader-eof-error stream "after escape"))))
1620 ;;;; number-reading functions
1622 ;; Mapping of read-base to the max input characters in a positive fixnum.
1623 (eval-when (:compile-toplevel :execute)
1624 (defun integer-reader-safe-digits ()
1625 (do ((a (make-array 35 :element-type '(unsigned-byte 8)))
1626 (base 2 (1+ base)))
1627 ((> base 36) a)
1628 (do ((total (1- base) (+ (* total base) (1- base)))
1629 (n-digits 0 (1+ n-digits)))
1630 ((sb!xc:typep total 'bignum)
1631 (setf (aref a (- base 2)) n-digits))
1632 ;; empty DO body
1635 ;; self-test
1636 (do ((maxdigits (integer-reader-safe-digits))
1637 (base 2 (1+ base)))
1638 ((> base 36))
1639 (let* ((n-digits (aref maxdigits (- base 2)))
1640 (d (char (write-to-string (1- base) :base base) 0))
1641 (string (make-string (1+ n-digits) :initial-element d))) ; 1 extra
1642 (assert (not (typep (parse-integer string :radix base)
1643 `(unsigned-byte ,sb!vm:n-positive-fixnum-bits))))
1644 (assert (typep (parse-integer string :end n-digits :radix base)
1645 `(unsigned-byte ,sb!vm:n-positive-fixnum-bits))))))
1647 (defmacro !setq-optional-leading-sign (sign-flag token-buf rewind)
1648 ;; guaranteed to have at least one character in buffer at the start
1649 ;; or immediately following [ESFDL] marker depending on 'rewind' flag.
1650 `(locally (declare (optimize (sb!c::insert-array-bounds-checks 0)))
1651 (,(if rewind 'setf 'incf)
1652 (token-buf-cursor ,token-buf)
1653 (case (elt (token-buf-string ,token-buf)
1654 ,(if rewind 0 `(token-buf-cursor ,token-buf)))
1655 (#\- (setq ,sign-flag t) 1)
1656 (#\+ 1)
1657 (t 0)))))
1659 (defun make-integer (&optional (base *read-base*))
1660 #!+sb-doc
1661 "Minimizes bignum-fixnum multiplies by reading a 'safe' number of digits,
1662 then multiplying by a power of the base and adding."
1663 (declare ((integer 2 36) base)
1664 (inline token-buf-getchar)) ; makes for smaller code
1665 (let* ((fixnum-max-digits
1666 (macrolet ((maxdigits ()
1667 (!coerce-to-specialized (integer-reader-safe-digits)
1668 '(unsigned-byte 8))))
1669 (aref (maxdigits) (- base 2))))
1670 (base-power
1671 (macrolet ((base-powers ()
1672 (do ((maxdigits (integer-reader-safe-digits))
1673 (a (make-array 35))
1674 (base 2 (1+ base)))
1675 ((> base 36) a)
1676 (setf (aref a (- base 2))
1677 (expt base (aref maxdigits (- base 2)))))))
1678 (truly-the integer (aref (base-powers) (- base 2)))))
1679 (negativep nil)
1680 (result 0)
1681 (buf *read-buffer*))
1682 (!setq-optional-leading-sign negativep buf t)
1683 (loop
1684 (let ((acc 0))
1685 (declare (type (and fixnum unsigned-byte) acc))
1686 (dotimes (digit-count fixnum-max-digits)
1687 (let ((ch (token-buf-getchar buf)))
1688 (if (or (not ch) (eql ch #\.))
1689 (return-from make-integer
1690 (let ((result
1691 (if (zerop result) acc
1692 (+ (* result (expt base digit-count)) acc))))
1693 (if negativep (- result) result)))
1694 (setq acc (truly-the fixnum
1695 (+ (digit-char-p ch base)
1696 (truly-the fixnum (* acc base))))))))
1697 (setq result (+ (* result base-power) acc))))))
1699 (defun truncate-exponent (exponent number divisor)
1700 #!+sb-doc
1701 "Truncate exponent if it's too large for a float"
1702 ;; Work with base-2 logarithms to avoid conversions to floats,
1703 ;; and convert to base-10 conservatively at the end.
1704 ;; Use the least positive float, because denormalized exponent
1705 ;; can be larger than normalized.
1706 (let* ((max-exponent
1707 #!-long-float
1708 (+ sb!vm:double-float-digits sb!vm:double-float-bias))
1709 (number-magnitude (integer-length number))
1710 (divisor-magnitude (1- (integer-length divisor)))
1711 (magnitude (- number-magnitude divisor-magnitude)))
1712 (if (minusp exponent)
1713 (max exponent (ceiling (- (+ max-exponent magnitude))
1714 #.(floor (log 10 2))))
1715 (min exponent (floor (- max-exponent magnitude)
1716 #.(floor (log 10 2)))))))
1718 (defun make-float (stream)
1719 ;; Assume that the contents of *read-buffer* are a legal float, with nothing
1720 ;; else after it.
1721 (let ((buf *read-buffer*)
1722 (negative-fraction nil)
1723 (number 0)
1724 (divisor 1)
1725 (negative-exponent nil)
1726 (exponent 0)
1727 (float-char ())
1728 char)
1729 (!setq-optional-leading-sign negative-fraction buf t)
1730 ;; Read digits before the dot.
1731 (macrolet ((accumulate (expr)
1732 `(let (digit)
1733 (loop (if (and (setq char (token-buf-getchar buf))
1734 (setq digit (digit-char-p char)))
1735 ,expr
1736 (return))))))
1737 (accumulate (setq number (+ (* number 10) digit)))
1738 ;; Deal with the dot, if it's there.
1739 (when (char= char #\.)
1740 ;; Read digits after the dot.
1741 (accumulate (setq divisor (* divisor 10)
1742 number (+ (* number 10) digit))))
1743 ;; Is there an exponent letter?
1744 (cond
1745 ((null char)
1746 ;; If not, we've read the whole number.
1747 (let ((num (make-float-aux number divisor
1748 *read-default-float-format*
1749 stream)))
1750 (return-from make-float (if negative-fraction (- num) num))))
1751 ((= (get-constituent-trait char) +char-attr-constituent-expt+)
1752 (setq float-char char)
1753 ;; Check leading sign.
1754 (!setq-optional-leading-sign negative-exponent buf nil)
1755 ;; Read digits for exponent.
1756 (accumulate (setq exponent (+ (* exponent 10) digit)))
1757 (setq exponent (if negative-exponent (- exponent) exponent))
1758 ;; Generate and return the float, depending on FLOAT-CHAR:
1759 (let* ((float-format (case (char-upcase float-char)
1760 (#\E *read-default-float-format*)
1761 (#\S 'short-float)
1762 (#\F 'single-float)
1763 (#\D 'double-float)
1764 (#\L 'long-float)))
1765 (exponent (truncate-exponent exponent number divisor))
1766 (result (make-float-aux (* (expt 10 exponent) number)
1767 divisor float-format stream)))
1768 (return-from make-float
1769 (if negative-fraction (- result) result))))
1770 (t (bug "bad fallthrough in floating point reader"))))))
1772 (defun make-float-aux (number divisor float-format stream)
1773 (handler-case
1774 (coerce (/ number divisor) float-format)
1775 (type-error (c)
1776 (error 'reader-impossible-number-error
1777 :error c :stream stream
1778 :format-control "failed to build float from ~a"
1779 :format-arguments (list (copy-token-buf-string *read-buffer*))))))
1781 (defun make-ratio (stream)
1782 ;; Assume *READ-BUFFER* contains a legal ratio. Build the number from
1783 ;; the string.
1784 ;; This code is inferior to that of MAKE-INTEGER because it makes no
1785 ;; attempt to perform as few bignum multiplies as possible.
1787 (let ((numerator 0) (denominator 0) (negativep nil)
1788 (base *read-base*) (buf *read-buffer*))
1789 (!setq-optional-leading-sign negativep buf t)
1790 ;; Get numerator.
1791 (loop (let ((dig (digit-char-p (token-buf-getchar buf) base)))
1792 (if dig
1793 (setq numerator (+ (* numerator base) dig))
1794 (return))))
1795 ;; Get denominator.
1796 (do* ((ch (token-buf-getchar buf) (token-buf-getchar buf))
1797 (dig ()))
1798 ((or (null ch) (not (setq dig (digit-char-p ch base)))))
1799 (setq denominator (+ (* denominator base) dig)))
1800 (let ((num (handler-case
1801 (/ numerator denominator)
1802 (arithmetic-error (c)
1803 (error 'reader-impossible-number-error
1804 :error c :stream stream
1805 :format-control "failed to build ratio")))))
1806 (if negativep (- num) num))))
1808 ;;;; General reader for dispatch macros
1810 (defun dispatch-char-error (stream sub-char ignore)
1811 (declare (optimize allow-non-returning-tail-call))
1812 (declare (ignore ignore))
1813 (if *read-suppress*
1814 (values)
1815 (simple-reader-error stream
1816 "no dispatch function defined for ~S"
1817 sub-char)))
1819 (defun read-dispatch-char (stream dispatch-table)
1820 ;; Read some digits.
1821 (let ((numargp nil)
1822 (numarg 0)
1823 (sub-char ()))
1824 (loop
1825 (let ((ch (read-char stream nil +EOF+)))
1826 (if (eq ch +EOF+)
1827 (reader-eof-error stream "inside dispatch character")
1828 ;; Take care of the extra char.
1829 (let ((dig (digit-char-p ch)))
1830 (if dig
1831 (setq numargp t numarg (+ (* numarg 10) dig))
1832 (return (setq sub-char (char-upcase ch))))))))
1833 ;; Look up the function and call it.
1834 (let ((fn (get-raw-cmt-dispatch-entry sub-char dispatch-table)))
1835 (funcall (!cmt-entry-to-function fn #'dispatch-char-error)
1836 stream sub-char (if numargp numarg nil)))))
1838 ;;;; READ-FROM-STRING
1840 (declaim (ftype (sfunction (string t t index (or null index) t) (values t index))
1841 %read-from-string))
1842 (defun %read-from-string (string eof-error-p eof-value start end preserve-whitespace)
1843 (with-array-data ((string string :offset-var offset)
1844 (start start)
1845 (end end)
1846 :check-fill-pointer t)
1847 (let ((stream (make-string-input-stream string start end)))
1848 (values (if preserve-whitespace
1849 (%read-preserving-whitespace stream eof-error-p eof-value nil)
1850 (read stream eof-error-p eof-value))
1851 (- (string-input-stream-current stream) offset)))))
1853 (locally
1854 (declare (muffle-conditions style-warning))
1855 (defun read-from-string (string &optional (eof-error-p t) eof-value
1856 &key (start 0) end preserve-whitespace)
1857 #!+sb-doc
1858 "The characters of string are successively given to the lisp reader
1859 and the lisp object built by the reader is returned. Macro chars
1860 will take effect."
1861 (declare (string string))
1862 (maybe-note-read-from-string-signature-issue eof-error-p)
1863 (%read-from-string string eof-error-p eof-value start end preserve-whitespace)))
1865 ;;;; PARSE-INTEGER
1867 (defun parse-integer (string &key (start 0) end (radix 10) junk-allowed)
1868 #!+sb-doc
1869 "Examine the substring of string delimited by start and end
1870 (default to the beginning and end of the string) It skips over
1871 whitespace characters and then tries to parse an integer. The
1872 radix parameter must be between 2 and 36."
1873 (flet ((parse-error (format-control)
1874 (declare (optimize allow-non-returning-tail-call))
1875 (error 'simple-parse-error
1876 :format-control format-control
1877 :format-arguments (list string))))
1878 (with-array-data ((string string :offset-var offset)
1879 (start start)
1880 (end end)
1881 :check-fill-pointer t)
1882 (let ((index (do ((i start (1+ i)))
1883 ((= i end)
1884 (if junk-allowed
1885 (return-from parse-integer (values nil end))
1886 (parse-error "no non-whitespace characters in string ~S.")))
1887 (declare (fixnum i))
1888 (unless (whitespace[1]p (char string i)) (return i))))
1889 (minusp nil)
1890 (found-digit nil)
1891 (result 0))
1892 (declare (fixnum index))
1893 (let ((char (char string index)))
1894 (cond ((char= char #\-)
1895 (setq minusp t)
1896 (incf index))
1897 ((char= char #\+)
1898 (incf index))))
1899 (loop
1900 (when (= index end) (return nil))
1901 (let* ((char (char string index))
1902 (weight (digit-char-p char radix)))
1903 (cond (weight
1904 (setq result (+ weight (* result radix))
1905 found-digit t))
1906 (junk-allowed (return nil))
1907 ((whitespace[1]p char)
1908 (loop
1909 (incf index)
1910 (when (= index end) (return))
1911 (unless (whitespace[1]p (char string index))
1912 (parse-error "junk in string ~S")))
1913 (return nil))
1915 (parse-error "junk in string ~S"))))
1916 (incf index))
1917 (values
1918 (if found-digit
1919 (if minusp (- result) result)
1920 (if junk-allowed
1922 (parse-error "no digits in string ~S")))
1923 (- index offset))))))
1925 ;;;; reader initialization code
1927 (defun !reader-cold-init ()
1928 (!cold-init-constituent-trait-table)
1929 (!cold-init-standard-readtable))
1931 (defmethod print-object ((readtable readtable) stream)
1932 (print-unreadable-object (readtable stream :identity t :type t)))
1934 ;; Backward-compatibility adapter. The "named-readtables" system in
1935 ;; Quicklisp expects this interface, and it's a reasonable thing to support.
1936 ;; What is silly however is that DISPATCH-TABLES was an alist each of whose
1937 ;; values was a hashtable which got immediately coerced to an alist.
1938 ;; In anticipation of perhaps not doing an extra re-shaping, if HASH-TABLE-P
1939 ;; is NIL then return nested alists: ((#\# (#\R . #<FUNCTION SHARP-R>) ...))
1940 (defun dispatch-tables (readtable &optional (hash-table-p t))
1941 (let (alist)
1942 (flet ((process (char fn &aux (dtable (%dispatch-macro-char-table fn)))
1943 (when dtable
1944 (let ((output (awhen (car dtable) (%hash-table-alist it))))
1945 (loop for fn across (the simple-vector (cdr dtable))
1946 and ch from 0
1947 when fn do (push (cons (code-char ch) fn) output))
1948 (dolist (cell output) ; coerce values to function-designator
1949 (rplacd cell (!cmt-entry-to-fun-designator (cdr cell))))
1950 (when hash-table-p ; caller wants hash-tables
1951 (setq output (%stuff-hash-table (make-hash-table) output)))
1952 (push (cons char output) alist)))))
1953 (loop for fn across (character-macro-array readtable) and ch from 0
1954 do (process (code-char ch) fn))
1955 (maphash #'process (character-macro-hash-table readtable)))
1956 alist))
1958 ;; Stub - should never get called with anything but NIL
1959 ;; and only after all macros have been changed to constituents already.
1960 (defun (setf dispatch-tables) (new-alist readtable)
1961 (declare (ignore readtable))
1962 (unless (null new-alist)
1963 (error "Assignment to virtual DISPATCH-TABLES slot not allowed"))
1964 new-alist)
1966 ;;; like LISTEN, but any whitespace in the input stream will be flushed
1967 (defun listen-skip-whitespace (&optional (stream *standard-input*))
1968 (do ((char (read-char-no-hang stream nil nil nil)
1969 (read-char-no-hang stream nil nil nil)))
1970 ((null char) nil)
1971 (cond ((not (whitespace[1]p char))
1972 (unread-char char stream)
1973 (return t)))))