The behaviour of the reader is controlled by a data structure called a "readtable". The reader uses the symbol *READTABLE* to locate the current readtable. This table controls the interpretation of input characters. It is an array with 128 entries, one for each of the ASCII character codes. Each entry contains one of the following things:
NIL Indicating an invalid character :CONSTITUENT Indicating a symbol constituent :WHITE-SPACE Indicating a whitespace character (:TMACRO . fun) Terminating readmacro (:NMACRO . fun) Non-terminating readmacro :SESCAPE Single escape character ('\') :MESCAPE Multiple escape character ('|')
In the case of :TMACRO and :NMACRO, the "fun" component is a function. This can either be a built-in readmacro function or a lambda expression. The function should take two parameters. The first is the input stream and the second is the character that caused the invocation of the readmacro. The readmacro function should return NIL to indicate that the character should be treated as white space or a value consed with NIL to indicate that the readmacro should be treated as an occurance of the specified value. Of course, the readmacro code is free to read additional characters from the input stream.
XLISP defines several useful read macros:
'<expr> == (quote <expr>) #'<expr> == (function <expr>) #(<expr>...) == an array of the specified expressions #x<hdigits> == a hexadecimal number (0-9,A-F) #o<odigits> == an octal number (0-7) #b<bdigits> == a binary number (0-1) #\<char> == the ASCII code of the character #| ... |# == a comment #:<symbol> == an uninterned symbol `<expr> == (backquote <expr>) ,<expr> == (comma <expr>) ,@<expr> == (comma-at