Лисп - ошибка "Попытка связать не символ" - PullRequest
0 голосов
/ 29 декабря 2018

Я новичок в Лиспе и делаю проект для колледжа.Проект представляет собой симулятор LMC (Little Man Computer).У меня есть состояние, которое представляет собой список вещей (состояние: ACC в соответствии: ПК pc: MEM mem: IN in: OUT out: FLAG flag), "acc" "pc" и "flag" являются значениями, "mem" "в"и" out "- списки.

Одна инструкция принимает состояние в качестве параметра и должна возвращать новое состояние с разными значениями, потому что в зависимости от результата (nth pc mem) мне нужно выполнить определенную операцию,Например, если результат (nth pc mem) находится между 100 и 199, я вызываю функцию do-add функции, которая должна дать мне новое значение для acc для нового состояния (с некоторыми элементами управления, которые еще не реализованы).

(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".

Так что это неправильно, когда я передаю состояние в качестве параметра в двух функциях?Или, может быть, я не могу использовать "pc" и "mem" без getf например?Последний вопрос, как я могу вернуть все новое состояние в одну инструкцию и сделать-добавить?Большое спасибо!(И извините за плохой английский, я итальянец :))

1 Ответ

0 голосов
/ 29 декабря 2018

Синтаксис для DEFUN предполагает обычный лямбда-список , который в своей основной форме представляет собой неоцененный список имен переменных.Ваш код начинается следующим образом:

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

У вас есть две основные ошибки:

  • вы цитировали список
  • ваш лямбда-список искажен

Попытка связать не-символ, (состояние: ACC в соотв .: PC pc: MEM mem: IN in: OUT out: флаг FLAG)

Ошибка немногонемного странно, но помните, что '(a b c) обозначает (quote (a b c)), который в контексте defun лямбда-списка анализируется как список из двух элементов, quote и список (a b c).Второй список не является символом, так как в вашем случае обнаруживается искаженный лямбда-список.

Синтаксис :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 ...) - нет функции.


In: (значение setf (nth pc mem))я хотел связать результат (nth pc mem), что если я прав, он должен дать мне значение в списке «mem» в позиции «pc», к переменной «value»

Вы не вводите переменные с setf, который только изменяет существующие привязки (и, в более общем случае, места).Вместо этого вы должны использовать LET:

(let ((instruction (nth n mem)))
  ...)

Внутри ..., instruction привязан к значению, полученному путем оценки (nth n mem).

Обратите также внимание, что ваши тестовые выражения в выражении cond также имеют неправильный формат:

(0 < istruzione < 99)

Выше приведено следующее: вызов функции 0 с аргументами <, istruzione, <и 99 </em>;нет функции с именем 0, и < не является переменной.Вместо этого вы хотели:

(< 0 istruzione 99)

Выше приведен вызов < с несколькими аргументами, который имеет значение true, когда все значения отсортированы в соответствии с <.

Обратите также внимание, что в следующем тесте у вас есть 100 < istruzione, что означает, что 99 и 100 являются угловыми случаями, которые не обрабатываются вашим cond (кроме случаев, когда это специально, в этом случае это штраф).

...