ToC DocOverview CGDoc RelNotes Index PermutedIndex
Allegro CL
Home Previous Up Next Table of Contents Index
  ANSI Common Lisp   23 Reader   23.2 Dictionary of Reader

23.2.5 read-delimited-list Function

Syntax:
read-delimited-list char &optional input-stream recursive-p    list

Arguments and Values:
char - a character.

input-stream - an input stream designator. The default is standard input.

recursive-p - a generalized boolean. The default is false.

list - a list of the objects read.

Description:
read-delimited-list reads objects from input-stream until the next character after an object's representation (ignoring whitespace2 characters and comments) is char.

read-delimited-list looks ahead at each step for the next non-whitespace2 character and peeks at it as if with peek-char. If it is char, then the character is consumed and the list of objects is returned. If it is a constituent or escape character, then read is used to read an object, which is added to the end of the list. If it is a macro character, its reader macro function is called; if the function returns a value, that value is added to the list. The peek-ahead process is then repeated.

If recursive-p is true, this call is expected to be embedded in a higher-level call to read or a similar function.

It is an error to reach end-of-file during the operation of read-delimited-list.

The consequences are undefined if char has a syntax type of whitespace2 in the current readtable.

Examples:
 (read-delimited-list #\]) 1 2 3 4 5 6 ]
 (1 2 3 4 5 6)
Suppose you wanted #{a b c ... z} to read as a list of all pairs of the elements a, b, c, ... , z, for example.

 #{p q z a}  reads as  ((p q) (p z) (p a) (q z) (q a) (z a))
This can be done by specifying a macro-character definition for #{ that does two things: reads in all the items up to the }, and constructs the pairs. read-delimited-list performs the first task.

 (defun |#{-reader| (stream char arg)
   (declare (ignore char arg))
   (mapcon #'(lambda (x)
              (mapcar #'(lambda (y) (list (car x) y)) (cdr x)))
          (read-delimited-list #\} stream t)))  |#{-reader|

 (set-dispatch-macro-character #\# #\{ #'|#{-reader|)   T 
 (set-macro-character #\} (get-macro-character #\) nil))
Note that true is supplied for the recursive-p argument.

It is necessary here to give a definition to the character } as well to prevent it from being a constituent. If the line

 (set-macro-character #\} (get-macro-character #\) nil))
shown above were not included, then the } in

 #{ p q z a}
would be considered a constituent character, part of the symbol named a}. This could be corrected by putting a space before the }, but it is better to call set-macro-character.

Giving } the same definition as the standard definition of the character ) has the twin benefit of making it terminate tokens for use with read-delimited-list and also making it invalid for use in any other context. Attempting to read a stray } will signal an error.

Affected By:
*standard-input*, *readtable*, *terminal-io*.

See Also:
read, peek-char, read-char, unread-char.

Notes:
read-delimited-list is intended for use in implementing reader macros. Usually it is desirable for char to be a terminating macro character so that it can be used to delimit tokens; however, read-delimited-list makes no attempt to alter the syntax specified for char by the current readtable. The caller must make any necessary changes to the readtable syntax explicitly.

Allegro CL Implementation Details:
None.

Home Previous Up Next Table of Contents Index
© Franz Inc. All Rights Reserved - File last updated 2022-07-25