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

标签 macros lisp common-lisp

我正在恢复 1980 年代早期的旧 LISP 程序。 (这是 Nelson-Oppen 简化器,一个早期的证明系统。这个版本是 Ford Pascal-F Verifier 的一部分,并于 1982 年在 Franz LISP 中运行。)这是整个程序:

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

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

DEFSMAC 和 DEFMAC

更多旧的 Stanford AI Lab 宏,以便在 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”是行不通的。我不清楚“defun with macro”是如何工作的。它记录在

的第 46 页

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

但这不是很有帮助。目前尚不清楚如何处理参数列表。从字面上看,旧文档似乎说传入的参数“数量”,而不是参数本身。这不可能是正确的解释。

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

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

最佳答案

我从 Hacker News 上的“pwd”那里得到了一个有用的答案:

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

这似乎可行。

关于macros - Franz LISP 到 Common LISP 的转换 2 - 生成宏的宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41732655/

相关文章:

c++ - 在 VC 2015 上使用带有字符串的宏失败

common-lisp - 是否可以在Common Lisp中解析日期?

iphone - iOS——使用宏转发一堆消息?

visual-studio-code - 是否有用于从选定代码或剪贴板代码创建新文件的 VS 代码快捷方式?

lisp - 优化 lisp 中的函数(内存)- trie 数据结构

lisp - 'Paradigms of Artificial Intelligence Programming' 是用哪种 LISP 方言写的?

emacs - 如何在SLIME REPL中停止正在运行的操作?

function - lisp函数的实现

macros - 如何将 C 预处理器宏与 Rust 的 FFI 一起使用?

emacs - 为所有事件缓冲区重新加载 .emacs