从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的通用方法.建议?
最佳答案 使用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))))))
)