我是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”? 最后一个问题,我如何才能在一个指令中执行整个新状态并执行添加操作? 非常感谢! (对不起,英语不好,我是意大利语:))
答案 0 :(得分:3)
DEFUN
的语法需要一个普通lambda列表,它的最基本形式是一个 unvaluated 变量名列表。您的代码开始如下:
(defun one-instruction '(state:ACC acc :PC pc :MEM mem :IN in :OUT out :FLAG flag)
...)
您有两个主要错误:
试图绑定非符号,(状态: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 ...)
,其中x
是setf
表达式;但是在正常评估环境中,(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不能处理的极端情况(除非是故意的,在这种情况下可以)。