宏和变量的常见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传递给宏,它被设置为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
  • 尝试计算代码以外的结果

最新更新