如何解决宏和变量的常见 LIsp 问题
我有一个作业,需要使用 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 传递给宏的,该变量 N 设置为 5,但是,当我使用“(+= (eval结束)1)”我无法让它传递值。我尝试删除“(+= (eval end) 1)”行中的 eval,当我尝试在“+=”宏中使用“(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
- 尝试计算代码以外的结果
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。