Franz LISP到Common LISP转换2 - 生成宏的宏

时间:2017-01-19 02:17:01

标签: macros lisp common-lisp franz-lisp

我从20世纪80年代早期开始复兴旧的LISP计划。 (它是Nelson-Oppen简化器,一个早期的证明系统。这个版本是Ford Pascal-F Verifier的一部分,并且在1982年在Franz LISP中运行。)以下是整个程序:

https://github.com/John-Nagle/pasv/tree/master/src/CPC4

我将代码转换为在Linux上的clisp下运行,并需要一些建议。大多数问题都与宏有关。这是今天的问题。

DEFSMAC和DEFMAC

更旧的斯坦福AI实验室宏,在defmacro成为该语言的一部分之前,使宏定义更容易。这些宏及其文档在这里:

https://github.com/John-Nagle/pasv/blob/master/src/CPC4/defmac.l

这些是生成更多宏的宏。

;;; defmac (define macro) and defsmac (define simple macro) are like defun,
;;; but they define the function as a macro instead of as an expr.  They are
;;; less powerful then defining a macro directly (for example, they cannot be
;;; used to define macros with arbitrarily many arguments) but are easier to
;;; use.   For example,
;;; 
;;; (defsmac f (x y) (foo (bar x) (bar y)))
;;; 
;;; causes f to be defined as a macro in such a way that every call (f e1 e2)
;;; will expand to (foo (bar e1) (bar e2)) before it is evaluated.

(defun defsmac macro (args)
       (defsmac1 (cadr args) (caddr args) (cdddr args)))


(defun defsmac1 (name formals body)
       `(defun ,name macro (app) 
                     ,(defsmac2 formals
                                  (cond ((cdr body) (cons 'progn body)) 
                                        (t (car body))))))

(defun defsmac2 (formals body)
       `(sublis  ,(defsmac3 formals 1) (quote ,body)))

(defun defsmac3 (formals n)
       (cond ((null formals) nil)
             (`(cons (cons (quote ,(car formals)) (car ,(defsmac4 n)))
                           ,(defsmac3 (cdr formals) (1+ n))))))

(defun defsmac4 (n) (cond ((= n 0) 'app) ((list 'cdr (defsmac4 (1- n))))))

直接转换为" defmacro"不起作用。我不清楚"如何用宏来解决问题"事情有效。

第46页记录了这一点

http://www.softwarepreservation.org/projects/LISP/franz/Franz_Lisp_July_1983.pdf

但这没有太大帮助。目前尚不清楚如何处理参数列表。从字面上看,旧的文档似乎是说''''''传递参数,而不是args本身。这不是正确的解释。

上面的代码似乎假设在宏处理期间可以使用常规的defun定义函数。但普通的LISP不允许这样做,是吗?

我正在寻找一种将旧式Franz LISP / MacLISP宏转换为现代通用LISP的通用方法。建议?

2 个答案:

答案 0 :(得分:2)

我从" pwd"得到了一个有用的答案。在黑客新闻:

(defmacro defsmac (name params &rest expr)
      `(defmacro ,name ,params
         `,(cons 'progn (sublis (mapcar 'cons ',params 
              (list ,@params))  ', expr))))

这似乎有效。

答案 1 :(得分:1)

使用eval-when在编译器环境中定义函数,以便在宏扩展期间使用它们。

(eval-when (:compile-toplevel :load-toplevel :execute)
    (defun defsmac1 (name formals body)
           `(defmacro ,name (app) 
                         ,(defsmac2 formals
                                      (cond ((cdr body) (cons 'progn body)) 
                                            (t (car body))))))

    (defun defsmac2 (formals body)
           `(sublis  ,(defsmac3 formals 1) (quote ,body)))

    (defun defsmac3 (formals n)
           (cond ((null formals) nil)
                 (`(cons (cons (quote ,(car formals)) (car ,(defsmac4 n)))
                               ,(defsmac3 (cdr formals) (1+ n))))))

    (defun defsmac4 (n) (cond ((= n 0) 'app) ((list 'cdr (defsmac4 (1- n))))))
)