我在一个文件中编写了宏和函数,如下所示:
(defun test ()
(let ((x '(1 2 3)))
(macro-test (x real-b)
(print (+ 1 (car real-b))))))
(defmacro macro-test ((a b) &body body)
`(do ((,b ,a (cdr ,b)))
((not ,b))
,@body))然后在repl中加载这个文件并运行(test)。我发现了一个错误:
The variable REAL-B is unbound.然而,当我把defmacro 放在 defun之前。百事大吉。
我对常见的lisp编译顺序感到困惑。我知道如果defmacro在内部使用一些函数,那么这些函数应该是(eval-when (:compile-toplevel :load-toplevel :execute)),否则编译将失败。
但是,如果宏定义和函数定义在编译时间是相同的,那么顺序就是问题,对吗?宏应该位于使用它们之前(如果我做了两个函数,顺序就无关紧要了)。我能更详细地了解一下SBCL的编译顺序吗?是只给SBCL的吗?还是普通的Lisp标准?
谢谢!
发布于 2020-04-21 05:59:22
顺序总是重要的:当您想要使用宏时,必须知道它。宏执行源转换。如何使用未知的宏进行源转换?
Common标准不需要进行多次编译,首先读取所有源代码,收集所有宏,然后从文件顶部开始编译。在Common中的文件编译只是从头到尾地遍历源代码。以后可能会有多个编译阶段,但这取决于实现.
当宏test未知时,Lisp应该如何编译函数macro-test?Lisp编译器需要( a)知道它是宏,b)它需要有它的定义来展开宏形式。
对于Common,这是一个基本规则:
如果我们有一个表单(foo bar baz),那么计算基本上会查看foo。
如果arguments
foo是宏运算符->宏,则展开代码并重新启动foo是一个函数->调用该函数,则该函数具有求值的foo错误< code >H 217G 218在编译中,它看起来类似于:
如果
foo是宏运算符->宏,则展开宏表单并编译代码foo是函数->编译该函数形式H 230H 131else ->警告,然后假设foo是一个函数,然后编译对未来函数的调用H 233G 234https://stackoverflow.com/questions/61335056
复制相似问题