Учитывая следующую функцию eval LISP - что требуется для добавления defmacro?

Для Swift 5 с последней версией FBSDK (FBSDKCoreKit 5.2.1)

func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        let handled = ApplicationDelegate.shared.application(app, open: url, options: options)

        return handled
    }
26
задан Robert Harvey 14 December 2010 в 15:57
поделиться

1 ответ

Представление анонимного макроса по соглашению представляет собой список вида (macro lambda ...). Попробуйте проверить их в своем любимом интерпретаторе Lisp (протестирован в Emacs):

> (defmacro triple (x) `(+, x, x, x))

тройной

> (символ-функция 'тройной)

(макро лямбда (x) (\ `(+ (\, x) (\, x) (\, x))))

Хотя в Emacs все работает не так, остается только дать адекватную семантику такой форма. То есть, когда eval. видит ((macro lambda (x) EXPR) FORM), он должен

  1. Заменить каждое вхождение x в FORM на EXPR без , предварительно оценив EXPR (в отличие от того, что происходит при вызове функции);
  2. 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) (list. (Quote car) (list. (Quote cdr) x)))

Вы можете создать форму, которая применяет это (macro lambda ...) к выражению, и оценить эту конструкцию в контексте, который содержит определение для 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))

y

Тада!

21
ответ дан 28 November 2019 в 17:17
поделиться