CHAPTER 7 The Lisp Reader _7._1. _I_n_t_r_o_d_u_c_t_i_o_n The _r_e_a_d function is responsible for converting a stream of characters into a Lisp expression. _R_e_a_d is table driven and the table it uses is called a _r_e_a_d_t_a_b_l_e. The _p_r_i_n_t function does the inverse of _r_e_a_d; it converts a Lisp expression into a stream of characters. Typically the conversion is done in such a way that if that stream of characters were read by _r_e_a_d, the result would be an expres- sion equal to the one _p_r_i_n_t was given. _P_r_i_n_t must also refer to the readtable in order to determine how to format its output. The _e_x_p_l_o_d_e function, which returns a list of characters rather than printing them, must also refer to the readtable. A readtable is created with the _m_a_k_e_r_e_a_d_t_a_b_l_e function, modified with the _s_e_t_s_y_n_t_a_x function and interrogated with the _g_e_t_s_y_n_t_a_x function. The structure of a readtable is hidden from the user - a readtable should only be manipu- lated with the three functions mentioned above. There is one distinguished readtable called the _c_u_r_r_e_n_t _r_e_a_d_t_a_b_l_e whose value determines what _r_e_a_d, _p_r_i_n_t and _e_x_p_l_o_d_e do. The current readtable is the value of the sym- bol _r_e_a_d_t_a_b_l_e. Thus it is possible to rapidly change the current syntax by lambda binding a different readtable to the symbol _r_e_a_d_t_a_b_l_e. When the binding is undone, the syn- tax reverts to its old form. _7._2. _S_y_n_t_a_x _C_l_a_s_s_e_s The readtable describes how each of the 128 ascii char- acters should be treated by the reader and printer. Each character belongs to a _s_y_n_t_a_x _c_l_a_s_s which has three proper- ties: character class - Tells what the reader should do when it sees this char- acter. There are a large number of character classes. The Lisp Reader 7-1 The Lisp Reader 7-2 They are described below. separator - Most types of tokens the reader constructs are one character long. Four token types have an arbitrary length: number (1234), symbol print name (franz), escaped symbol print name (|franz|), and string ("franz"). The reader can easily determine when it has come to the end of one of the last two types: it just looks for the matching delimiter (| or "). When the reader is reading a number or symbol print name, it stops reading when it comes to a character with the _s_e_p_a_r_a_t_o_r property. The separator character is pushed back into the input stream and will be the first char- acter read when the reader is called again. escape - Tells the printer when to put escapes in front of, or around, a symbol whose print name contains this charac- ter. There are three possibilities: always escape a symbol with this character in it, only escape a symbol if this is the only character in the symbol, and only escape a symbol if this is the first character in the symbol. [note: The printer will always escape a symbol which, if printed out, would look like a valid number.] When the Lisp system is built, Lisp code is added to a C coded kernel and the result becomes the standard lisp sys- tem. The readtable present in the C-coded kernel, called the _r_a_w _r_e_a_d_t_a_b_l_e, contains the bare necessities for reading in Lisp code. During the construction of the complete Lisp system, a copy is made of the raw readtable and then the copy is modified by adding macro characters. The result is what is called the _s_t_a_n_d_a_r_d _r_e_a_d_t_a_b_l_e. When a new readtable is created with _m_a_k_e_r_e_a_d_t_a_b_l_e, a copy is made of either the raw readtable or the current readtable (which is likely to be the standard readtable). _7._3. _R_e_a_d_e_r _o_p_e_r_a_t_i_o_n_s The reader has a very simple algorithm. It is either _s_c_a_n_n_i_n_g for a token, _c_o_l_l_e_c_t_i_n_g a token, or _p_r_o_c_e_s_s_i_n_g a token. Scanning involves reading characters and throwing away those which don't start tokens (such as blanks and tabs). Collecting means gathering the characters which make up a token into a buffer. Processing may involve creating symbols, strings, lists, fixnums, bignums or flonums or cal- ling a user written function called a character macro. 9 9 Printed: March 26, 1982 The Lisp Reader 7-3 The components of the syntax class determine when the reader switches between the scanning, collecting and pro- cessing states. The reader will continue scanning as long as the character class of the characters it reads is _c_s_e_p_a_r_a_t_o_r. When it reads a character whose character class is not _c_s_e_p_a_r_a_t_o_r it stores that character in its buffer and begins the collecting phase. If the character class of that first character is _c_c_h_a_r_a_c_t_e_r, _c_n_u_m_b_e_r, _c_p_e_r_i_o_d, or _c_s_i_g_n. then it will con- tinue collecting until it runs into a character whose syntax class has the _s_e_p_a_r_a_t_o_r property. (That last character will be pushed back into the input buffer and will be the first character read next time.) Now the reader goes into the pro- cessing phase, checking to see if the token it read is a number or symbol. It is important to note that after the first character is collected the component of the syntax class which tells the reader to stop collecting is the _s_e_p_a_r_a_t_o_r property, not the character class. If the character class of the character which stopped the scanning is not _c_c_h_a_r_a_c_t_e_r, _c_n_u_m_b_e_r, _c_p_e_r_i_o_d, or _c_s_i_g_n. then the reader processes that character immediately. The character classes _c_s_i_n_g_l_e-_m_a_c_r_o, _c_s_i_n_g_l_e-_s_p_l_i_c_i_n_g-_m_a_c_r_o, and _c_s_i_n_g_l_e-_i_n_f_i_x-_m_a_c_r_o will act like _c_c_h_a_r_a_c_t_e_r if the follow- ing token is not a _s_e_p_a_r_a_t_o_r. The processing which is done for a given character class is described in detail in the next section. _7._4. _C_h_a_r_a_c_t_e_r _c_l_a_s_s_e_s _c_c_h_a_r_a_c_t_e_r raw readtable:A-Z a-z ^H !#$%&*,/:;<=>?@^_`{}~ standard readtable:A-Z a-z ^H !$%&*/:;<=>?@^_{}~ A normal character. _c_n_u_m_b_e_r raw readtable:0-9 standard readtable:0-9 This type is a digit. The syntax for an integer (fixnum or bignum) is a string of _c_n_u_m_b_e_r characters optionally fol- lowed by a _c_p_e_r_i_o_d. If the digits are not followed by a _c_p_e_r_i_o_d, then they are interpreted in base _i_b_a_s_e which must be eight or ten. The syntax for a floating point number is either zero or more _c_n_u_m_b_e_r's followed by a cperiod and then followed by one or more _c_n_u_m_b_e_r's. A floating point number may also be an integer or floating point number followed by 'e' or 'd', an optional '+' or '-' and then zero or more _c_n_u_m_b_e_r's. 9 9 Printed: March 26, 1982 The Lisp Reader 7-4 _c_s_i_g_n raw readtable:+- standard readtable:+- A leading sign for a number. No other characters should be given this class. _c_l_e_f_t_-_p_a_r_e_n raw readtable:( standard readtable:( A left parenthesis. Tells the reader to begin forming a list. _c_r_i_g_h_t_-_p_a_r_e_n raw readtable:) standard readtable:) A right parenthesis. Tells the reader that it has reached the end of a list. _c_l_e_f_t_-_b_r_a_c_k_e_t raw readtable:[ standard readtable:[ A left bracket. Tells the reader that it should begin form- ing a list. See the description of _c_r_i_g_h_t-_b_r_a_c_k_e_t for the difference between cleft-bracket and cleft-paren. _c_r_i_g_h_t_-_b_r_a_c_k_e_t raw readtable:] standard readtable:] A right bracket. A _c_r_i_g_h_t-_b_r_a_c_k_e_t finishes the formation of the current list and all super lists until it finds one which begins with a _c_l_e_f_t-_b_r_a_c_k_e_t or until it reaches the top level list. _c_p_e_r_i_o_d raw readtable:. standard readtable:. The period is used to separate element of a cons cell [e.g. (a . (b . nil)) is the same as (a b)]. _c_p_e_r_i_o_d is also used in numbers as described above. _c_s_e_p_a_r_a_t_o_r raw readtable:^I-^M esc space standard readtable:^I-^M esc space Separates tokens. When the reader is scanning, these char- acter are passed over. Note: there is a difference between the _c_s_e_p_a_r_a_t_o_r character class and the _s_e_p_a_r_a_t_o_r property of a syntax class. _c_s_i_n_g_l_e_-_q_u_o_t_e raw readtable:' standard readtable:' This causes _r_e_a_d to be called recursively and the list (quote <value read>) to be returned. 9 9 Printed: March 26, 1982 The Lisp Reader 7-5 _c_s_y_m_b_o_l_-_d_e_l_i_m_i_t_e_r raw readtable:| standard readtable:| This causes the reader to begin collecting characters and to stop only when another identical _c_s_y_m_b_o_l-_d_e_l_i_m_i_t_e_r is seen. The only way to escape a _c_s_y_m_b_o_l-_d_e_l_i_m_i_t_e_r within a symbol name is with a _c_e_s_c_a_p_e character. The collected characters are converted into a string which becomes the print name of a symbol. If a symbol with an identical print name already exists, then the allocation is not done, rather the existing symbol is used. _c_e_s_c_a_p_e raw readtable:\ standard readtable:\ This causes the next character to read in to be treated as a _v_c_h_a_r_a_c_t_e_r. A character whose syntax class is _v_c_h_a_r_a_c_t_e_r has a character class _c_c_h_a_r_a_c_t_e_r and does not have the _s_e_p_a_r_a_t_o_r property so it will not separate symbols. _c_s_t_r_i_n_g_-_d_e_l_i_m_i_t_e_r raw readtable:" standard readtable:" This is the same as _c_s_y_m_b_o_l-_d_e_l_i_m_i_t_e_r except the result is returned as a string instead of a symbol. _c_s_i_n_g_l_e_-_c_h_a_r_a_c_t_e_r_-_s_y_m_b_o_l raw readtable:none standard readtable:none This returns a symbol whose print name is the the single character which has been collected. _c_m_a_c_r_o raw readtable:none standard readtable:`, The reader calls the macro function associated with this character and the current readtable, passing it no argu- ments. The result of the macro is added to the structure the reader is building, just as if that form were directly read by the reader. More details on macros are provided below. _c_s_p_l_i_c_i_n_g_-_m_a_c_r_o raw readtable:none standard readtable:#; A _c_s_p_l_i_c_i_n_g-_m_a_c_r_o differs from a _c_m_a_c_r_o in the way the result is incorporated in the structure the reader is build- ing. A _c_s_p_l_i_c_i_n_g-_m_a_c_r_o must return a list of forms (possi- bly empty). The reader acts as if it read each element of the list itself without the surrounding parenthesis. _c_s_i_n_g_l_e_-_m_a_c_r_o raw readtable:none standard readtable:none Printed: March 26, 1982 The Lisp Reader 7-6 This causes to reader to check the next character. If it is a _c_s_e_p_a_r_a_t_o_r then this acts like a _c_m_a_c_r_o. Otherwise, it acts like a _c_c_h_a_r_a_c_t_e_r. _c_s_i_n_g_l_e_-_s_p_l_i_c_i_n_g_-_m_a_c_r_o raw readtable:none standard readtable:none This is triggered like a _c_s_i_n_g_l_e-_m_a_c_r_o however the result is spliced in like a _c_s_p_l_i_c_i_n_g-_m_a_c_r_o. _c_i_n_f_i_x_-_m_a_c_r_o raw readtable:none standard readtable:none This is differs from a _c_m_a_c_r_o in that the macro function is passed a form representing what the reader has read so far. The result of the macro replaces what the reader had read so far. _c_s_i_n_g_l_e_-_i_n_f_i_x_-_m_a_c_r_o raw readtable:none standard readtable:none This differs from the _c_i_n_f_i_x-_m_a_c_r_o in that the macro will only be triggered if the character following the _c_s_i_n_g_l_e- _i_n_f_i_x-_m_a_c_r_o character is a _c_s_e_p_a_r_a_t_o_r. _c_i_l_l_e_g_a_l raw readtable:^@-^G^N-^Z^\-^_rubout standard readtable:^@-^G^N-^Z^\-^_rubout The characters cause the reader to signal an error if read. _7._5. _S_y_n_t_a_x _c_l_a_s_s_e_s The readtable maps each character into a syntax class. The syntax class contains three pieces of information: the character class, whether this is a separator, and the escape properties. The first two properties are used by the reader, the last by the printer (and _e_x_p_l_o_d_e). The initial lisp system has the following syntax classes defined. The user may add syntax classes with _a_d_d-_s_y_n_t_a_x-_c_l_a_s_s. For each syntax class, we list the properties of the class and which characters have this syntax class by default. More informa- tion about each syntax class can be found under the descrip- tion of the syntax class's character class. vcharacter raw readtable:A-Z a-z ^H !#$%&*,/:;<=>?@^_`{}~ _c_c_h_a_r_a_c_t_e_r standard readtable:A-Z a-z ^H !$%&*/:;<=>?@^_{}~ vnumber raw readtable:0-9 Printed: March 26, 1982 The Lisp Reader 7-7 _c_n_u_m_b_e_r standard readtable:0-9 vsign raw readtable:+- _c_s_i_g_n standard readtable:+- vleft-paren raw readtable:( _c_l_e_f_t_-_p_a_r_e_n standard readtable:( _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vright-paren raw readtable:) _c_r_i_g_h_t_-_p_a_r_e_n standard readtable:) _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vleft-bracket raw readtable:[ _c_l_e_f_t_-_b_r_a_c_k_e_t standard readtable:[ _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vright-bracket raw readtable:] _c_r_i_g_h_t_-_b_r_a_c_k_e_t standard readtable:] _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vperiod raw readtable:. _c_p_e_r_i_o_d standard readtable:. _e_s_c_a_p_e_-_w_h_e_n_-_u_n_i_q_u_e vseparator raw readtable:^I-^M esc space _c_s_e_p_a_r_a_t_o_r standard readtable:^I-^M esc space _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vsingle-quote raw readtable:' _c_s_i_n_g_l_e_-_q_u_o_t_e standard readtable:' _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vsymbol-delimiter raw readtable:| _c_s_i_n_g_l_e_-_d_e_l_i_m_i_t_e_r standard readtable:| _e_s_c_a_p_e_-_a_l_w_a_y_s vescape raw readtable:\ _c_e_s_c_a_p_e standard readtable:\ _e_s_c_a_p_e_-_a_l_w_a_y_s Printed: March 26, 1982 The Lisp Reader 7-8 vstring-delimiter raw readtable:" _c_s_t_r_i_n_g_-_d_e_l_i_m_i_t_e_r standard readtable:" _e_s_c_a_p_e_-_a_l_w_a_y_s vsingle-character-symbol raw readtable:none _c_s_i_n_g_l_e_-_c_h_a_r_a_c_t_e_r_-_s_y_m_b_o_l standard readtable:none _s_e_p_a_r_a_t_o_r vmacro raw readtable:none _c_m_a_c_r_o standard readtable:`, _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vsplicing-macro raw readtable:none _c_s_p_l_i_c_i_n_g_-_m_a_c_r_o standard readtable:#; _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vsingle-macro raw readtable:none _c_s_i_n_g_l_e_-_m_a_c_r_o standard readtable:none _e_s_c_a_p_e_-_w_h_e_n_-_u_n_i_q_u_e vsingle-splicing-macro raw readtable:none _c_s_i_n_g_l_e_-_s_p_l_i_c_i_n_g_-_m_a_c_r_o standard readtable:none _e_s_c_a_p_e_-_w_h_e_n_-_u_n_i_q_u_e vinfix-macro raw readtable:none _c_i_n_f_i_x_-_m_a_c_r_o standard readtable:none _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r vsingle-infix-macro raw readtable:none _c_s_i_n_g_l_e_-_i_n_f_i_x_-_m_a_c_r_o standard readtable:none _e_s_c_a_p_e_-_w_h_e_n_-_u_n_i_q_u_e villegal raw readtable:^@-^G^N-^Z^\-^_rubout _c_i_l_l_e_g_a_l standard readtable:^@-^G^N-^Z^\-^_rubout _e_s_c_a_p_e_-_a_l_w_a_y_s _s_e_p_a_r_a_t_o_r _7._6. _C_h_a_r_a_c_t_e_r _M_a_c_r_o_s Character macros are user written functions which are executed during the reading process. The value returned by a character macro may or may not be used by the reader, Printed: March 26, 1982 The Lisp Reader 7-9 depending on the type of macro and the value returned. Character macros are always attached to a single character with the _s_e_t_s_y_n_t_a_x function. _7._6._1. _T_y_p_e_s There are three types of character macros: normal, splicing and infix. These types differ in the argu- ments they are given or in what is done with the result they return. _7._6._1._1. _N_o_r_m_a_l A normal macro is passed no arguments. The value returned by a normal macro is simply used by the reader as if it had read the value itself. Here is an example of a macro which returns the abbreviation for a given state. ____________________________________________________ ->(_d_e_f_u_n _s_t_a_t_e_a_b_b_r_e_v _n_i_l (_c_d_r (_a_s_s_q (_r_e_a_d) '((_c_a_l_i_f_o_r_n_i_a . _c_a) (_p_e_n_n_s_y_l_v_a_n_i_a . _p_a))))) stateabbrev -> (_s_e_t_s_y_n_t_a_x '_\! '_v_m_a_c_r_o '_s_t_a_t_e_a_b_b_r_e_v) t -> '( !_c_a_l_i_f_o_r_n_i_a ! _w_y_o_m_i_n_g ! _p_e_n_n_s_y_l_v_a_n_i_a) (ca nil pa) ____________________________________________________ Notice what happened to !_w_y_o_m_i_n_g. Since it wasn't in the table, the macro probably didn't want to return anything at all, but it had to return something, and whatever it returned was put in the list. The splicing macro, described next, allows a character macro function to return a value that is ignored. _7._6._1._2. _S_p_l_i_c_i_n_g The value returned from a splicing macro must be a list or nil. If the value is nil, then the value is ignored, otherwise the reader acts as if it read each object in the list. Usually the list only contains one element. If the reader is reading at the top level (i.e. not collecting Printed: March 26, 1982 The Lisp Reader 7-10 elements of list), then it is illegal for a splicing macro to return more then one element in the list. The major advantage of a splicing macro over a normal macro is the ability of the splicing macro to return nothing. The comment character (usually ;) is a splicing macro bound to a func- tion which reads to the end of the line and always returns nil. Here is the previous example written as a splicing macro ____________________________________________________ -> (_d_e_f_u_n _s_t_a_t_e_a_b_b_r_e_v _n_i_l ((_l_a_m_b_d_a (_v_a_l_u_e) (_c_o_n_d (_v_a_l_u_e (_l_i_s_t _v_a_l_u_e)) (_t _n_i_l))) (_c_d_r (_a_s_s_q (_r_e_a_d) '((_c_a_l_i_f_o_r_n_i_a . _c_a) (_p_e_n_n_s_y_l_v_a_n_i_a . _p_a)))))) -> (_s_e_t_s_y_n_t_a_x ' '_v_s_p_l_i_c_i_n_g-_m_a_c_r_o '_s_t_a_t_e_a_b_b_r_e_v) -> '(!_p_e_n_n_s_y_l_v_a_n_i_a ! _f_o_o !_c_a_l_i_f_o_r_n_i_a) (pa ca) -> '!_f_o_o !_b_a_r !_p_e_n_n_s_y_l_v_a_n_i_a pa -> ____________________________________________________ _7._6._1._3. _I_n_f_i_x Infix macros are passed a _t_c_o_n_c structure representing what has been read so far. Briefly, a tconc structure is a single list cell whose car points to a list and whose cdr points to the last list cell in that list. The interpreta- tion by the reader of the value returned by an infix macro depends on whether the macro is called while the reader is constructing a list or whether it is called at the top level of the reader. If the macro is called while a list is being constructed, then the value returned should be a tconc structure. The car of that structure replaces the list of elements that the reader has been collecting. If the macro is called at top level, then it will be passed the value nil, and the value it returns should either be nil or a tconc structure. If the macro returns nil, then the value is ignored and the reader continues to read. If the macro returns a tconc structure of one element (i.e. whose car is a list of one element), then that single element is returned as the value of _r_e_a_d. If the macro returns a tconc struc- ture of more than one element, then that list of elements is returned as the value of read. Printed: March 26, 1982 The Lisp Reader 7-11 ____________________________________________________ -> (_d_e_f_u_n _p_l_u_s_o_p (_x) (_c_o_n_d ((_n_u_l_l _x) (_t_c_o_n_c _n_i_l '_\+)) (_t (_l_c_o_n_c _n_i_l (_l_i_s_t '_p_l_u_s (_c_a_a_r _x) (_r_e_a_d)))))) plusop -> (_s_e_t_s_y_n_t_a_x '_\+ '_v_i_n_f_i_x-_m_a_c_r_o '_p_l_u_s_o_p) t -> '(_a + _b) (plus a b) -> '+ |+| -> ____________________________________________________ _7._6._2. _I_n_v_o_c_a_t_i_o_n_s There are three different circumstances in which you would like a macro function to be triggered. _A_l_w_a_y_s - Whenever the macro character is seen, the macro should be invoked. This is accomplished by using the charac- ter classes _c_m_a_c_r_o, _c_s_p_l_i_c_i_n_g-_m_a_c_r_o, or _c_i_n_f_i_x-_m_a_c_r_o, and by using the _s_e_p_a_r_a_t_o_r property. The syntax classes _v_m_a_c_r_o, _v_s_p_l_i_c_i_n_g-_m_a_c_r_o, and _v_s_i_n_g_l_e-_m_a_c_r_o are defined this way. _W_h_e_n _f_i_r_s_t - The macro should only be triggered when the macro char- acter is the first character found after the scanning process. A syntax class for a _w_h_e_n _f_i_r_s_t macro would be defined using _c_m_a_c_r_o, _c_s_p_l_i_c_i_n_g-_m_a_c_r_o, or _c_i_n_f_i_x- _m_a_c_r_o and not including the _s_e_p_a_r_a_t_o_r property. _W_h_e_n _u_n_i_q_u_e - The macro should only be triggered when the macro char- acter is the only character collected in the token col- lection phase of the reader, i.e the macro character is preceeded by zero or more _c_s_e_p_a_r_a_t_o_rs and followed by a _s_e_p_a_r_a_t_o_r. A syntax class for a _w_h_e_n _u_n_i_q_u_e macro would be defined using _c_s_i_n_g_l_e-_m_a_c_r_o, _c_s_i_n_g_l_e- _s_p_l_i_c_i_n_g-_m_a_c_r_o, or _c_s_i_n_g_l_e-_i_n_f_i_x-_m_a_c_r_o and not includ- ing the _s_e_p_a_r_a_t_o_r property. The syntax classes so defined are _v_s_i_n_g_l_e-_m_a_c_r_o, _v_s_i_n_g_l_e-_s_p_l_i_c_i_n_g-_m_a_c_r_o, and Printed: March 26, 1982 The Lisp Reader 7-12 _v_s_i_n_g_l_e-_i_n_f_i_x-_m_a_c_r_o. _7._7. _F_u_n_c_t_i_o_n_s (setsyntax 's_symbol 's_synclass ['ls_func]) WHERE: ls_func is the name of a function or a lambda body. RETURNS: t SIDE EFFECT: The syntax class for the character which begins s_symbol's print name is set to s_synclass in the current readtable. s_symbol should be a symbol whose print name is only one character. If s_synclass is a class that requires a character macro, then ls_func must be supplied. NOTE: The symbolic syntax codes are new to Opus 38. For compatibility, s_synclass can be one of the fixnum syntax codes which appeared in older ver- sions of the FRANZ LISP Manual. This compatibil- ity is only temporary: existing code which uses the fixnum syntax codes should be converted. (getsyntax 's_symbol) RETURNS: the syntax class of the first character of s_symbol's print name. s_symbol's print name must be exactly one character long. NOTE: This function is new to Opus 38. It supercedes (_s_t_a_t_u_s _s_y_n_t_a_x) which no longer exists. (add-syntax-class 's_synclass 'l_properties) RETURNS: s_synclass SIDE EFFECT: Defines the syntax class s_synclass to have properties l_properties. The list l_properties should contain a character classes mentioned above. l_properties may contain one of the escape properties: _e_s_c_a_p_e-_a_l_w_a_y_s, _e_s_c_a_p_e-_w_h_e_n-_u_n_i_q_u_e, or _e_s_c_a_p_e-_w_h_e_n-_f_i_r_s_t. l_properties may con- tain the _s_e_p_a_r_a_t_o_rproperty. After a syn- tax class has been defined with _a_d_d- _s_y_n_t_a_x-_c_l_a_s_s, the _s_e_t_s_y_n_t_a_x function can be used to give characters that syntax Printed: March 26, 1982 The Lisp Reader 7-13 class. ____________________________________________________ ; Define a non-separating macro character. ; This type of macro character is used in UCI-Lisp, and ; it corresponds to a FIRST MACRO in Interlisp -> (_a_d_d-_s_y_n_t_a_x-_c_l_a_s_s '_v_u_c_i-_m_a_c_r_o '(_c_m_a_c_r_o _e_s_c_a_p_e-_w_h_e_n-_f_i_r_s_t)) vuci-macro -> ____________________________________________________ 9 9 Printed: March 26, 1982