XLISP reader

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference

# Reader

## read-from-string

    (defun read-from-string (string)
      (read (make-string-input-stream string)))

Back to top

## *readtable*

The *readtable* system variable contains the reader table array. The table is 128 entries [0..127] for each of the 7-bit ASCII characters that XLISP can read.

- read - function to read a lisp expression
- *readtable* - system variable, holding the readtable

- NIL - invalid character
- :constituent - symbol constituent
- :sescape - whitespace character
- :mescape - multiple escape character
- :white-space - single escape character
- :tmacro - terminating readmacro
- :nmacro - non-terminating readmacro

See also the Lexical Conventions and Readtable sections in the XLISP 2.0 manual.

## print-readtable

    (defun print-readtable ()
      (dotimes (index 128)
        (format t "ASCII-~a ~a = ~a~%"
                  (cond ((<=  0 index  9) (format nil "00~a" index))
                        ((<= 10 index 99) (format nil "0~a"  index))
                        (t index))
                  (if (< 31 index 127)
                      (code-char index)
                      (case index
                        (0   "[null]                  ")
                        (1   "[start of heading]      ")
                        (2   "[start of text]         ")
                        (3   "[end of text]           ")
                        (4   "[end of transmission]   ")
                        (5   "[enquiry]               ")
                        (6   "[acknowledge]           ")
                        (7   "[terminal bell]         ")
                        (8   "[backspace]             ")
                        (9   "[horizontal tab]        ")
                        (10  "[line feed]             ")
                        (11  "[vertical tab]          ")
                        (12  "[form feed]             ")
                        (13  "[carriage return]       ")
                        (14  "[shift out]             ")
                        (15  "[shift in]              ")
                        (16  "[data link escape]      ")
                        (17  "[device control 1, xon] ")
                        (18  "[device control 2]      ")
                        (19  "[device control 3, xoff]")
                        (20  "[device control 4]      ")
                        (21  "[negative acknowledge]  ")
                        (22  "[synchronous idle]      ")
                        (23  "[end transmission block]")
                        (24  "[cancel line]           ")
                        (25  "[end of medium]         ")
                        (26  "[substitute]            ")
                        (27  "[escape]                ")
                        (28  "[file separator]        ")
                        (29  "[group separator]       ")
                        (30  "[record separator]      ")
                        (31  "[unit separator]        ")
                        (127 "[delete]")))
                  (aref *readtable* index))))

## get-macro-character

(get-macro-character char)
  char - a character
  returns - the code associated with the *readtable* entry or NIL

    (defun get-macro-character (char)
      (if (consp (aref *readtable* (char-code char)))
          (cdr (aref *readtable* (char-int char)))
          nil))

The 'get-macro-character' function returns the code that will be executed when the specified character 'char' is encountered by the XLISP reader.

The 'get-macro-character' function will return a NIL value if the table entry is NIL , :constituent , :sescape , :mescape or :white-space. If the table entry is :tmacro or :nmacro , then the code associated with the entry is returned. :tmacro is used for a terminating read-macro. :nmacro is used for a non-terminating read-macro. 'get-macro-character' does not differentiate whether the code returned is a :tmacro or an :nmacro.

The function returned may be a built-in read-macro function or a user defined lambda expression. The function takes two parameters, an input stream specification, and an integer that is the character value. The function should return NIL if the character is 'white-space' or a value consed with NIL to return the value.

Examples:

    (get-macro-character #\()      => #<Subr-(null): #...>
    (get-macro-character #\#)      => #<Subr-(null): #...>
    (get-macro-character #\Space)  => NIL

Back to Top

## set-macro-character

(set-macro-character char function [termination-flag])
  char - a character expression
  function - a function definition
  termination-flag - an expression, NIL or non-NIL
  returns - always returns T

    (defun set-macro-character (char function &optional terminate-p)
      (setf (aref *readtable* (char-code char))
            (cons (if terminate-p :tmacro :nmacro) function))
      t)

The 'set-macro-character' function installs the code that will be executed when the specified character 'char' is encountered by the XLISP reader.

The 'set-macro-character' function only allows you to put in a terminating read-macro function :tmacro or a non-terminating read-macro-function :nmacro. If the 'termflag' is present and non-NIL , then the 'function' will be put in *readtable* as a :tmacro entry. If 'termflag' is not present or NIL , then 'function' will be put in *readtable* as a :nmacro entry. The 'function' can be a built-in read-macro function or a user defined defun symbol or a lambda expression.

The 'function' takes two parameters, an input stream specification, and an integer that is the character value. The 'function' should return NIL if the character is 'white-space' or a value consed with NIL to return the value. The function 'set-macro-character' always returns T .

Examples:

    > (print "hi") % comment
    "hi"
    "hi"
    error: unbound variable - %       ; % is interpreted as a variable

    > (setq readtable-backup *readtable*)
    #( ... very-long-value ... )

    > (set-macro-character #\% (get-macro-character #\;) t)
    T

    > (print "hi") % comment
    "hi"                              ; no error because
    "hi"                              ; % is now a comment character

    > (setq *readtable* readtable-backup)
    #( ... very-long-value ... )

Important: before manipulating the XLISP *readtable* it's always a good idea to store the original contents in some other variable.

Back to Top

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference