На этом шаге мы рассмотрим макросимволы, используемые при организации ввода.
Макросимволы вызывают свою функцию макроопределения по мере их прочтения функцией READ. Они способны не только сократить часто используемые сегменты кодов, но и изменять используемые в LISP файлы для более удобного использования их вручную.
Макросимволы подразделяются на:
Ограничивающие и неограничивающие макросимволы включают объекты во входной поток. Макросимволы комментариев не включают обьектов во входной поток.
Ограничивающие макросимволы и комментарии ограничивают знаки, считанные функцией READ. Неограничивающие макросимволы не ограничивают знаки, считанные функцией READ, и, следовательно, могут быть распознаны как макросимволы с помощью пробелов.
Вначале отметим функции, позволяющие работать с ограничивающими макросимволами.
1. Если FLAG - NIL или отсутствует, то функция
(SET-MACRO-CHAR CHARACTER DEFINITION FLAG)
Если FLAG есть символ COMMENT, то функция SET-MACRO-CHAR создает CHARACTER в форме макросимвола комментария. В противном случае функция создает CHARACTER в форме неограничивающего макросимвола.
2. Если FLAG - NIL или отсутствует, то функция
(GET-MACRO-CHAR CHARACTER FLAG)
Если FLAG - не NIL, то функция GET-MACRO-CHAR возвращает LAMBDA, если CHARACTER является макросимволом. В любом случае функция возвращает NIL, если CHARACTER не является макросимволом.
Теперь опишем ограничивающие макросимволы:
Если правая круглая скобка встретилась, то макрос возвращает список считанных выражений.
Если встретилась правая квадратная скобка, то макрос пропускает скобку, так что она снова может быть считана, и возвращает список считанных выражений. Это дает возмажность рассматривать правую квадратную скобку как "суперкруглую", которая закрывает все левые круглые скобки для функции READ вышестоящего уровня.
Если встретилась точка, то макро считывает следующее за точкой выражение и проверяет его с целью убедиться, что это непробельное выражение является либо правой круглой скобкой,либо правой квадратной скобкой. Если это так, то макро возвращает список выражений, считанных до того, как встретилась точка, не связанная с выражением, считанным после точки. Если нет, возникает прерывание "Синтаксическая ошибка".
Макрос правой круглой скобки и правой квадратной скобки генерирует прерывание "Синтаксическая ошибка", если функция READ встретила "слишком" много правых круглых или квадратных скобок.
Код описанных макросов приведен ниже:
(SET-MACRO-CHAR '\) '(LAMBDA () (BREAK '\) "Syntax Error") )) (SET-MACRO-CHAR '\] '(LAMBDA () (BREAK '\] "Syntax Error") ))
$ '(SUE TOM ANN) (SUE TOM ANN)
Приведем код макроса:
(SET-MACRO-CHAR (QUOTE (LAMBDA () (LIST (QUOTE QUOTE) (READ)))) )
$ "Yom said, \"I like Lisp\"" Tom said, "I like Lisp"
Приведем код описанного макроса:
(SET-MACRO-CHAR '\" '(LAMBDA (CHAR LST) (LOOP (SETQ CHAR (READ-CHAR)) ( (EQ CHAR '\") (PACK (NREVERSE LST)) ) ( ( (EQ CHAR '\\) (PUSH (READ-CHAR) LST)) (PUSH CHAR LST)))) )
$ (LIST 'DOG 'CAT <SPAN CLASS="comm">; Это комментарий</SPAN>
'COW)
(DOG CAT COW)
Код макроса имеет вид:
(SET-MACRO-CHAR '\" '(LAMBDA () (LOOP ( (EQ (READ-CHAR) (ASCII 13 ))))) 'COMMENT)
На следующем шаге мы рассмотрим функции вывода.