Lisp-“尝试绑定非符号”错误

时间:2018-12-29 13:23:29

标签: lisp common-lisp

我是Lisp的新手,并且正在做一个大学项目。该项目是LMC(小矮人计算机)的模拟。我有一个状态列表(状态:ACC acc:PC pc:MEM mem:IN in:OUT out:FLAG标志),“ acc”“ pc”和“ flag”是值,“ mem”“ in “和” out是列表。

一个指令以状态为参数,应该返回一个具有不同值的新状态,因为根据(nth pc mem)的结果,我必须执行某些操作。例如,如果(nth pc mem)的结果在100到199之间,我将调用函数do-add,这应该为我提供新状态acc的新值(某些控件尚未实现)。 / p>

(defun one-instruction '(state:ACC acc :PC pc  :MEM mem :IN in :OUT out :FLAG flag)
    ((setf (nth pc mem) istruzione)
    (cond ( (0 < istruzione < 99) (do-halt '(state :ACC acc :PC pc :MEM mem :IN in :OUT out :FLAG flag))))
          ( (100 < istruzione < 199) (do-add '(state :ACC acc :PC pc :MEM mem :IN in :OUT out :FLAG flag)))))))
          ... 

(defun do-add '(state :ACC acc :PC pc  :MEM mem :IN in :OUT out :FLAG flag)))
   ((setf (nth pc mem) value)
   ((setf (nth (- value 100) mem) addendo)
   (setf (+ acc addendo) newacc))))

当我编译并加载时出现以下错误:

** ++++单指令错误

试图绑定非符号(状态:ACC acc:PC pc:MEM mem:IN in:OUT out:FLAG标志),并且“ do-add”也发生同样的情况。

所以我在两个函数中将状态作为参数传递的方式是错误的吗?或者也许我不能在没有getf的情况下使用“ pc”和“ mem”? 最后一个问题,我如何才能在一个指令中执行整个新状态并执行添加操作? 非常感谢! (对不起,英语不好,我是意大利语:))

1 个答案:

答案 0 :(得分:3)

DEFUN的语法需要一个普通lambda列表,它的最基本形式是一个 unvaluated 变量名列表。您的代码开始如下:

(defun one-instruction '(state:ACC acc :PC pc  :MEM mem :IN in :OUT out :FLAG flag)
   ...)

您有两个主要错误:

  • 您引用了列表
  • 您的lambda列表格式错误
  

试图绑定非符号,(状态:ACC acc:PC pc:MEM mem:IN in:OUT out:FLAG标志)

该错误有些奇怪,但是请记住,'(a b c)代表(quote (a b c)),在defun lambda-list的上下文中,它被解析为两个元素的列表, quote(a b c)列表。第二个列表不是符号,这是在您的情况下如何检测格式错误的lambda列表。

:pc pc语法用于传递关键字参数,而不是将其绑定到函数中。如果要使用一个强制性状态变量和关键字参数正确定义函数,则应编写:

(defun one-instruction (state &key acc pc mem in out flag)
  ...)

您会这样称呼它:

(one-instruction my-state :acc 0 :pc 0 :mem big-table ...)

另外,您有:

((setf (nth pc mem) istruzione) ...)

这不是有效的表达式,该表达式看起来像(x ...),其中xsetf表达式;但是在正常评估环境中,(x ...)表示函数调用,而(setf ...)不是函数。


  

在:(setf(第n个pc内存)值)中,我想绑定(第n个pc内存)的结果,我是正确的,它应该给我列表“ mem”中的值位置“ pc”,到变量“值”

您不会在变量setf中引入变量,(let ((instruction (nth n mem))) ...) 只会修改现有的绑定(一般来说,是位置)。相反,您必须使用LET

...

instruction内,(nth n mem)绑定到通过评估cond获得的值。

请注意,(0 < istruzione < 99) 表达式中的测试表达式也格式错误:

0

以上内容表示为:使用参数<,istruzione,<和99 调用函数0;没有名为<的函数,并且(< 0 istruzione 99) 作为变量未绑定。相反,您想要的是:

<

上面是对带有多个参数的<的调用,当所有值都根据100 < istruzione排序时,则为true。

还要注意,在下一个测试中,您有x = getattr(data, 'title', None),这意味着99和100都是您的cond不能处理的极端情况(除非是故意的,在这种情况下可以)。