给定以下 LISP eval 函数 - 添加 defmacro 需要什么? [英] Given the following LISP eval function - what is required to add defmacro?

查看:13
本文介绍了给定以下 LISP eval 函数 - 添加 defmacro 需要什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于 LISP eval 函数的以下 定义 - 什么是需要添加 defmacro 函数吗?(或者甚至只是评估一个宏)

Given the following definition of the LISP eval function - what is required to add the defmacro function? (Or even just evaluate a macro)

(defun null. (x)
      (eq x '()))

(defun and. (x y)
  (cond (x (cond (y 't) ('t '())))
        ('t '())))

(defun not. (x)
  (cond (x '())
        ('t 't)))

(defun append. (x y)
  (cond ((null. x) y)
        ('t (cons (car x) (append. (cdr x) y)))))

(defun list. (x y)
  (cons x (cons y '())))

(defun pair. (x y)
  (cond ((and. (null. x) (null. y)) '())
        ((and. (not. (atom x)) (not. (atom y)))
         (cons (list. (car x) (car y))
               (pair. (cdr x) (cdr y))))))

(defun assoc. (x y)
  (cond ((eq (caar y) x) (cadar y))
        ('t (assoc. x (cdr y)))))

(defun eval. (e a)
  (cond
    ((atom e) (assoc. e a))
    ((atom (car e))
     (cond
       ((eq (car e) 'quote) (cadr e))
       ((eq (car e) 'atom)  (atom   (eval. (cadr e) a)))
       ((eq (car e) 'eq)    (eq     (eval. (cadr e) a)
                                    (eval. (caddr e) a)))
       ((eq (car e) 'car)   (car    (eval. (cadr e) a)))
       ((eq (car e) 'cdr)   (cdr    (eval. (cadr e) a)))
       ((eq (car e) 'cons)  (cons   (eval. (cadr e) a)
                                    (eval. (caddr e) a)))
       ((eq (car e) 'cond)  (evcon. (cdr e) a))
       ('t (eval. (cons (assoc. (car e) a)
                        (cdr e))
                  a))))
    ((eq (caar e) 'label)
     (eval. (cons (caddar e) (cdr e))
            (cons (list. (cadar e) (car e)) a)))
    ((eq (caar e) 'lambda)
     (eval. (caddar e)
            (append. (pair. (cadar e) (evlis. (cdr e) a))
                     a)))))

(defun evcon. (c a)
  (cond ((eval. (caar c) a)
         (eval. (cadar c) a))
        ('t (evcon. (cdr c) a))))

(defun evlis. (m a)
  (cond ((null. m) '())
        ('t (cons (eval.  (car m) a)
                  (evlis. (cdr m) a)))))


(eval '(car '(a a)) )

推荐答案

按照惯例,匿名宏的表示形式是 (macro lambda ...) 形式的列表.尝试在你最喜欢的 Lisp 解释器中评估这些(在 Emacs 中测试):

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 三元组 (x) `(+ ,x ,x ,x))

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

三重

>(符号函数'三元组)

(宏 lambda (x) (` (+ (, x) (, x) (, x))))

虽然在 Emacs 中事情不是这样工作的,但剩下要做的就是为这种形式提供足够的语义.即当eval.看到((macro lambda (x) EXPR) FORM)时,必须

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. EXPR 替换 FORM 中所有出现的 x 而不评估 EXPR首先(与函数调用中发生的情况相反);
  2. eval.上面的结果.
  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.

您可以通过在 eval. 中处理 ((macro lambda ...) ...) 的情况.这是一个粗略的原型:

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))))

此代码仅适用于单参数宏.修复涉及编写一个辅助函数 substlis.,其工作方式类似于 evlis. 但不循环到 eval.;留给读者作为练习:-)

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 :-)

为了测试,将 cadr. 定义为宏:

To test, define cadr. as a macro thusly:

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

在这之后你会有

>(符号函数'cadr.)

> (symbol-function 'cadr.)

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

您可以构造一个将此 (macro lambda ...) 应用于表达式的表单,并在包含 list 定义的上下文中评估该构造.(因为 eval. 解释器不认为它是原始的).例如,

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))

多田!

这篇关于给定以下 LISP eval 函数 - 添加 defmacro 需要什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆