如下面的Lisp代码所示,
(defvar a 1)
(defvar b 2)
(defmacro macro-add (c d)
`(+ ,c ,d))
(macro-add a b)
调用宏的最后一行将宏参数c绑定到传入,这是否意味着c绑定到符号a或绑定到符号a的值?更具体地说,c将在宏观上下文中评估为a或1吗?
答案 0 :(得分:4)
宏基本上是代码转换器。它们将代码作为输入,解构并绑定到宏参数。他们使用任意计算生成新代码。对于简单的类似模板的代码生成,反引用列表很受欢迎。
Lisp中的源代码有两种不同的外观:文本s表达式和内部所谓的表单,它们已经是Lisp数据。这个转换由Lisp 读者完成。
然后在这些Lisp表单上完成宏转换。这种转变的结果是一种新形式。最后,在扩展所有宏之后,将评估生成的源代码。这张图片略有错误,但它有助于想象有三个独立的阶段:阅读,宏观扩展,执行。
在您的情况下,源表单是三个符号的列表:(macro-add a b)
。第一个符号命名一个宏,因此表单将被宏扩展。该列表是被破坏的:第一个符号是宏名称,第二个符号将绑定到C
,第三个符号将绑定到D
。有了这个参数,宏现在就被执行了。结果它产生了一个新表格:三个项目的清单。第一项是符号+
,第二项是C
的值,符号A
,第三项是D
的值,符号{{ 1}}。 B
是宏扩展的结果。
如有必要,宏扩展的结果现在将再次进行宏扩展。由于代码中的(+ A B)
不是宏,因此不会进行宏扩展。 +
是一个功能。现在进行普通评估:计算+
的值,计算A
的值,然后使用这两个值调用B
来计算新的结果值。
答案 1 :(得分:3)
它与符号'a'绑定。与函数相比,基本上不评估宏的参数。