Given the following LISP eval function - what is required to add defmacro?

谁说我不能喝 提交于 2019-11-28 15:40:22

The representation of an anonymous macro is by convention a list of the form (macro lambda ...). Try evaling these in your favorite Lisp interpreter (tested in Emacs):

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

triple

> (symbol-function 'triple)

(macro lambda (x) (\` (+ (\, x) (\, x) (\, x))))

Although things don't work that way in Emacs, the only thing left to do is to give the adequate semantics to such a form. That is, when eval. sees ((macro lambda (x) EXPR) FORM), it must

  1. Replace every occurence of x in FORM with EXPR without evaluating EXPR first (as opposed to what happens in a function call);
  2. eval. the result of above.

You can achieve this by adding a clause to the outermost cond in eval. that deals with the ((macro lambda ...) ...) case. Here is a crude prototype:

((eq (caar e) 'macro)
     (cond
      ((eq (cadar e) 'lambda)
       (eval. (eval. (car (cdddar e))
                     (cons (list. (car (caddar e)) (cadr e)) a))
              a))))

This code only works for single-argument macros. Fixing that involves writing an auxiliary function substlis. that works like evlis. but without looping to eval.; that is left as an exercise to the reader :-)

To test, define cadr. as a macro thusly:

(defmacro cadr. (x)
  (list. 'car (list. 'cdr x)))

After this you would have

> (symbol-function 'cadr.)

(macro lambda (x) (list. (quote car) (list. (quote cdr) x)))

You can construct a form that applies this (macro lambda ...) to an expression, and eval that construction within a context that contains a definition for list. (because it is not considered primitive by the eval. interpreter). For instance,

(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

Tada!

hawkeye

This is also quite good: https://web.archive.org/web/20120702032624/http://jlongster.com/2012/02/18/its-not-about-macros-its-about-read.html

"You can implement a macro system in 30 lines of Lisp. All you need is read, and it's easy." https://gist.github.com/1712455

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!