Написание макроса Lisp с вложенным квазицитированием - PullRequest
1 голос
/ 22 марта 2012

Я пытаюсь написать макрос на Лиспе, который пишет кучу макросов, но у меня возникают проблемы при генерации кода макроса, который использует оператор соединения (в build-bind), который сначала раскрывает внутренние выражения.*

После первого прохода я хочу получить:

(define-term-construct some some-p (args name))

->

(PROGN
  (DEFMACRO DO-SOME-LIST (LS (&KEY ARGS NAME ID OPERATION) &BODY BODY)
   (WITH-GENSYMS (EL)
     `(LOOP-LIST (,EL ,LS :ID ,ID :OPERATION ,OPERATION)
        (LET (,@(BUILD-BIND ,SOME ,EL))
         (WHEN (SOME-P ,EL)
           (WITH-SOME ,EL
              ,@BODY)))))))

Есть идеи, какие кавычки / квазиквоты использовать для получения нужного кода?

1 Ответ

1 голос
/ 22 марта 2012

Вывод, который вы хотите получить, имеет несбалансированные запятые.,@ уже балансирует обратную цитату, поэтому вы не можете иметь ,SOME и ,EL.Это два уровня отмены цитирования / объединения внутри только одного уровня обратного цитирования.

Я подозреваю, что вы хотите:

`(WITH-GENSYMS (EL) ... (LET (,@(BUILD-BIND 'SOME EL)) ...))

Символ some входит в качестве аргумента для исходного макроса и имеетзаканчиваться символом в кавычках при передаче функции build-bind.EL оценивается прямо.Это просто локальная переменная, введенная связывающей конструкцией WITH-GENSYMS, и она больше не находится в контексте обратной кавычки, потому что она находится внутри сращивания.

Транслитерация этого обратно в обратную цитату исходного внешнего макроса: SOME становится,name:

,@(build-bind ',name el)  ;; two commas out balance two backquotes in

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

elне нуждается в сращивании;это не переменный материал, а жестко запрограммированная особенность создаваемого шаблона.Если бы вы поместили ,el, он бы искал переменную el в области видимости макроса define-term-construct, где такой вещи не существует.

...