我有一个任务,需要使用lisp编写脚本。我在传递变量时遇到问题
这是代码。以下问题:
(defmacro while (test &rest bodies)
`(do ()
((not ,test))
,@ bodies)
)
(defmacro += (var inc)
`(print (eval var))
;(setf (eval var) (+ (eval var) inc))
)
(defmacro iterate (i begin end inc &rest others)
(setf i begin)
(while (<= i (eval end))
;(dolist (item others)
; (eval item)
;)
(print (list 'two i (eval end)))
(+= (eval end) 1)
(setf i (+ i inc))
)
)
(setf n 5)
(iterate i 1 n 1
(print (list 'one i))
(+= n 1)
)
第一个问题在于将语句传递给迭代宏。当我尝试运行注释输出dolist时,print语句在涉及变量I时会抛出一个错误。由于某些原因,我无法使用有值的宏变量I来打印它,但它似乎希望默认为尚未设置的全局变量I。我得到错误:
- EVAL: variable I has no value
第二个问题是+="宏。迭代宏中end的值是5,通过使用变量N传递给宏,它被设置为5,然而,当我将它传递给"+="宏使用行";(+=(eval-end(1(";我无法让它通过值。我试着删除"行中的eval;(+=(eval-end(1(";当我尝试用";(print(eval-var((";在"+="宏,我得到错误-EVAL:变量END没有值
我将如何解决这些问题?
您的第一个宏基本上是正确的。它生成代码。
(defmacro while (test &body body)
`(do ()
((not ,test))
,@body))
可以用一个例子来检验。我们使用示例代码展开宏。函数MACROEXPAND-1
仅对顶级宏进行一次扩展。您需要将代码传递给函数MACROEXPAND-1
:
CL-USER 1 > (macroexpand-1 '(while (< i 10)
(print i)
(incf i)))
(DO NIL ; NIL is the same as ()
((NOT (< I 10)))
(PRINT I)
(INCF I))
T
生成的代码是一个DO
循环。就像预定的一样。
因此,我们可以使用您的宏:
CL-USER 2 > (let ((i 5))
(while (< i 10)
(print i)
(incf i)))
5
6
7
8
9
NIL
您的其他宏应该是这样
- 他们应该生成代码
- 示例的宏扩展应该显示正确生成的代码
- 生成的代码应该可以工作
您的宏不应该
- 正在使用
EVAL
- 尝试计算代码以外的结果