Обрабатывать аргументы макроса в Common Lisp как (чувствительные к регистру) строки - PullRequest
3 голосов
/ 19 февраля 2012

(Это одна из тех вещей, которая, кажется, должна быть настолько простой, что я думаю, что вообще может быть лучший подход)

Я пытаюсь определить макрос (для CLISP), который принимает переменное число аргументов в качестве символов (которые затем преобразуются в строки с учетом регистра).

(defmacro symbols-to-words (&body body)
  `(join-words (mapcar #'symbol-name '(,@body))))

преобразует символы в строчные буквы, тогда как

(defmacro symbols-to-words (&body body)
  `(join-words (mapcar #'symbol-name '(|,@body|))))

обрабатывает @ body как один символ без расширения.

Есть идеи? Я думаю, что, возможно, есть гораздо более простой способ.

Ответы [ 2 ]

6 голосов
/ 19 февраля 2012

Имена символов пишутся в верхнем регистре на этапе чтения, который происходит до макроразложения, и поэтому вы ничего не можете сделать с макросами, чтобы повлиять на это. Вы можете глобально установить READTABLE-CASE , но это повлияет на весь код, в частности вам придется писать все стандартные символы в верхнем регистре в вашем источнике. Существует также опция «-modern» для CLISP, которая предоставляет версию в нижнем регистре для имен стандартной библиотеки и устанавливает считывающее устройство в регистр, но оно само по себе нестандартно. Я никогда не использовал его сам, поэтому я не уверен, какие на самом деле применяются предостережения.

Другой способ управления читателем - через макросы читателя. Common Lisp уже имеет макрос для чтения, реализующий синтаксис для чувствительных к регистру строк: двойная кавычка . Трудно дать совет, не зная, почему вы его не используете.

3 голосов
/ 19 февраля 2012

Как правильно говорит Рамаррен, регистр символов определяется во время чтения.Не во время раскрытия макроса.

Common Lisp имеет синтаксис для указания символов без изменения регистра:

|This is a symbol| - использование вертикальной черты в качестве нескольких escape-символов.

и есть также обратная косая черта - один управляющий символ:

CL-USER > 'foo\bar
|FOObAR|

Другие варианты:

  • с использованием другого глобального читаемого регистра
  • с использованием макроса чтениякоторый читает и сохраняет регистр
  • , используя макрос чтения, который использует свой собственный считыватель

Также обратите внимание, что синтаксис для чего-то вроде |,@body| (где тело вставлено) не существуетв Common Lisp.Объединение работает только для списков, но не для имен символов.|, вертикальная черта, окружает символьные элементы символа.Объяснение в Common Lisp Hyperspec немного загадочно: Несколько символов Escape .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...