Ответ 1
Представление анонимного макроса является условным списком формы (macro lambda ...)
. Попробуйте убрать их в своем любимом интерпретаторе Lisp (тестируется в Emacs):
(defmacro triple (x) `(+, x, x, x))
тройной
(символ-функция 'тройка)
(макрос lambda (x) (\ `(+ (\, x) (\, x) (\, x))))
Несмотря на то, что в Emacs это не так, единственное, что осталось сделать - это дать адекватную семантику такой форме. То есть, когда eval.
видит ((macro lambda (x) EXPR) FORM)
, он должен
- Замените каждое событие
x
вFORM
наEXPR
без, сначала оцениваяEXPR
(в отличие от того, что происходит при вызове функции); -
eval.
результат выше.
Вы можете добиться этого, добавив предложение к внешнему cond
в eval.
, которое относится к случаю ((macro lambda ...) ...)
. Вот грубый прототип:
((eq (caar e) 'macro)
(cond
((eq (cadar e) 'lambda)
(eval. (eval. (car (cdddar e))
(cons (list. (car (caddar e)) (cadr e)) a))
a))))
Этот код работает только для макросов с одним аргументом. Фиксация, которая включает в себя запись вспомогательной функции substlis.
, которая работает как evlis.
, но без цикла до eval.
; который остается в качестве упражнения для читателя: -)
Чтобы проверить, определите cadr.
как макрос:
(defmacro cadr. (x)
(list. 'car (list. 'cdr x)))
После этого у вас будет
(символ-функция 'cadr.)
(макрос lambda (x) (список. (quote car) (список. (quote cdr) x)))
Вы можете создать форму, которая применяет этот (macro lambda ...)
к выражению, и eval эта конструкция в контексте, который содержит определение для list.
(потому что он не считается примитивным интерпретатором eval.
). Например,
(let ((e '((macro lambda (x) (list (quote car) (list (quote cdr) x)))
(cons (quote x) (cons (quote y) nil))))
(bindings `((list ,(symbol-function 'list.)))))
(eval. e bindings))
у
Тада!