123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- % -*- Mode: TeX -*-
- \beginsubsection{Dynamic Control of the Lisp Reader}
- Various aspects of the \term{Lisp reader} can be controlled dynamically.
- \Seesection\Readtables\ and \secref\ReaderVars.
- \endsubsection%{Dynamic Control of the Lisp Reader}
-
- \beginsubsection{Effect of Readtable Case on the Lisp Reader}
- \DefineSection{ReadtableCaseReadEffect}
- The \term{readtable case} of the \term{current readtable} affects the \term{Lisp reader}
- in the following ways:
- \beginlist
- \itemitem{\kwd{upcase}}
- When the \term{readtable case} is \kwd{upcase},
- unescaped constituent \term{characters} are converted to \term{uppercase},
- as specified in \secref\ReaderAlgorithm.
- \itemitem{\kwd{downcase}}
- When the \term{readtable case} is \kwd{downcase},
- unescaped constituent \term{characters} are converted to \term{lowercase}.
- \itemitem{\kwd{preserve}}
- When the \term{readtable case} is \kwd{preserve},
- the case of all \term{characters} remains unchanged.
- \itemitem{\kwd{invert}}
- When the \term{readtable case} is \kwd{invert},
- then if all of the unescaped letters in the extended token are of the same \term{case},
- those (unescaped) letters are converted to the opposite \term{case}.
- \endlist
- \beginsubsubsection{Examples of Effect of Readtable Case on the Lisp Reader}
- \DefineSection{ReadtableCaseReadExamples}
- \code
- (defun test-readtable-case-reading ()
- (let ((*readtable* (copy-readtable nil)))
- (format t "READTABLE-CASE Input Symbol-name~
- ~%-----------------------------------~
- ~%")
- (dolist (readtable-case '(:upcase :downcase :preserve :invert))
- (setf (readtable-case *readtable*) readtable-case)
- (dolist (input '("ZEBRA" "Zebra" "zebra"))
- (format t "~&:~A~16T~A~24T~A"
- (string-upcase readtable-case)
- input
- (symbol-name (read-from-string input)))))))
- \endcode
-
- The output from \f{(test-readtable-case-reading)} should be as follows:
- \code
- READTABLE-CASE Input Symbol-name
- -------------------------------------
- :UPCASE ZEBRA ZEBRA
- :UPCASE Zebra ZEBRA
- :UPCASE zebra ZEBRA
- :DOWNCASE ZEBRA zebra
- :DOWNCASE Zebra zebra
- :DOWNCASE zebra zebra
- :PRESERVE ZEBRA ZEBRA
- :PRESERVE Zebra Zebra
- :PRESERVE zebra zebra
- :INVERT ZEBRA zebra
- :INVERT Zebra Zebra
- :INVERT zebra ZEBRA
- \endcode
- \endsubsubsection%{Examples of Effect of Readtable Case on the Lisp Reader}
- \endsubsection%{Effect of Readtable Case on the Lisp Reader}
- \beginsubsection{Argument Conventions of Some Reader Functions}
- \beginsubsubsection{The EOF-ERROR-P argument}
- %% 22.2.1 2
- \param{Eof-error-p} in input function calls
- controls what happens if input is from a file (or any other
- input source that has a definite end) and the end of the file is reached.
- If \param{eof-error-p} is \term{true} (the default),
- an error \oftype{end-of-file} is signaled
- at end of file. If it is \term{false}, then no error is signaled, and instead
- the function returns \param{eof-value}.
- Functions such as \funref{read} that read the representation
- of an \term{object} rather than a single
- character always signals an error, regardless of \param{eof-error-p}, if
- the file ends in the middle of an object representation.
- For example, if a file does
- not contain enough right parentheses to balance the left parentheses in
- it, \funref{read} signals an error. If a file ends in a
- \term{symbol} or a \term{number}
- immediately followed by end-of-file, \funref{read} reads the
- \term{symbol} or
- \term{number}
- successfully and when called again will
- %%Barmar thought this wasn't needed:
- % see the end-of-file and
- % only then
- act according to \param{eof-error-p}.
- Similarly, \thefunction{read-line}
- successfully reads the last line of a file even if that line
- is terminated by end-of-file rather than the newline character.
- Ignorable text, such as lines containing only \term{whitespace}\meaning{2} or comments,
- are not considered to begin an \term{object};
- if \funref{read} begins to read an \term{expression} but sees only such
- ignorable text, it does not consider the file to end in the middle of an \term{object}.
- Thus an \param{eof-error-p} argument controls what happens
- when the file ends between \term{objects}.
- \endsubsubsection%{The EOF-ERROR-P argument}
- \beginsubsubsection{The RECURSIVE-P argument}
- %% 22.2.1 4
- If \param{recursive-p} is supplied and not \nil, it specifies that
- this function call is not an outermost call to \funref{read} but an
- embedded call, typically from a \term{reader macro function}.
- It is important to distinguish such recursive calls for three reasons.
- %% 22.2.1 5
- \beginlist
- \itemitem{1.}
- An outermost call establishes the context within which the
- \f{\#\param{n}=} and \f{\#\param{n}\#} syntax is scoped. Consider, for example,
- the expression
- \code
- (cons '#3=(p q r) '(x y . #3#))
- \endcode
- If the \term{single-quote} \term{reader macro} were defined in this way:
- \code
- (set-macro-character #\\' ;incorrect
- #'(lambda (stream char)
- (declare (ignore char))
- (list 'quote (read stream))))
- \endcode
- % then the expression could not be read properly, because there would be no way
- % to know when \funref{read} is called recursively by the first
- % occurrence of \f{'} that the label \f{\#3=} would be referred to
- % later in the containing expression.
- % There would be no way to know because \funref{read}
- % could not determine that it was called by a \term{reader macro function}
- % rather than from an outermost form.
- %% per JonL:
- then each call to the \term{single-quote} \term{reader macro function} would establish
- independent contexts for the scope of \funref{read} information, including the scope of
- identifications between markers like ``\f{\#3=}'' and ``\f{\#3\#}''. However, for
- this expression, the scope was clearly intended to be determined by the outer set
- of parentheses, so such a definition would be incorrect.
- The correct way to define the \term{single-quote}
- \term{reader macro} uses \param{recursive-p}:
- \code
- (set-macro-character #\\' ;correct
- #'(lambda (stream char)
- (declare (ignore char))
- (list 'quote (read stream t nil t))))
- \endcode
- %% 22.2.1 6
- \itemitem{2.}
- A recursive call does not alter whether the reading process
- is to preserve \term{whitespace}\meaning{2} or not (as determined by whether the
- outermost call was to \funref{read} or \funref{read-preserving-whitespace}).
- Suppose again that \term{single-quote}
- % had the first, incorrect, \term{reader macro}
- % definition shown above.
- %% per JonL:
- were to be defined as shown above in the incorrect definition.
- Then a call to \funref{read-preserving-whitespace}
- that read the expression \f{'foo\SpaceChar} would fail to preserve the space
- character following the symbol \f{foo} because the \term{single-quote}
- \term{reader macro function} calls \funref{read},
- not \funref{read-preserving-whitespace},
- to read the following expression (in this case \f{foo}).
- The correct definition, which passes the value \term{true} for \param{recursive-p}
- to \funref{read}, allows the outermost call to determine
- whether \term{whitespace}\meaning{2} is preserved.
- %% 22.2.1 8
- \itemitem{3.}
- When end-of-file is encountered and the \param{eof-error-p} argument
- is not \nil, the kind of error that is signaled may depend on the value
- of \param{recursive-p}. If \param{recursive-p}
- is \term{true}, then the end-of-file
- is deemed to have occurred within the middle of a printed representation;
- if \param{recursive-p} is \term{false}, then the end-of-file may be deemed to have
- occurred between \term{objects} rather than within the middle of one.
- \endlist
- \endsubsubsection%{The EOF-ERROR-P argument}
- \endsubsection%{Argument Conventions of Some Reader Functions}
|