Уточнения по структуре данных
Выражения типа Bindat не ограничиваются типами, описанными ранее. Они также могут быть произвольными Lisp-формами, возвращающими выражения типа Bindat. Например, тип ниже описывает данные, которые могут содержать 24-битовый код ошибки или вектор байтов:
(bindat-type (len u8) (payload . (if (zerop len) (uint 24) (vec (1- len)))))
Кроме того, хотя составные типы обычно распаковываются в (и упаковываются из) списков ассоциаций, это можно изменить, используя следующие специальные ключевые аргументы:
:unpack-val exp-
Когда список полей заканчивается этим ключевым аргументом, возвращаемое значение при распаковке — значение exp, а не стандартный список ассоциаций. exp может ссылаться на все предыдущие поля по их имени.
:pack-val exp-
Если тип поля следует за этим ключевым аргументом, то значение, упакованное в это поле, возвращается выражением exp, а не извлекается из списка ассоциаций.
:pack-var nameЕсли список полей предваряется этим ключевым аргументом, то все последующие
:pack-valаргументы могут ссылаться на общее значение для упаковки в этот составной тип через переменную с именем name.
Например, можно описать 16-битовое знаковое целое число следующим образом:
(defconst sint16-bindat-spec
(let* ((max (ash 1 15))
(wrap (+ max max)))
(bindat-type :pack-var v
(n uint 16 :pack-val (if (< v 0) (+ v wrap) v))
:unpack-val (if (>= n max) (- n wrap) n))))
Что затем будет работать следующим образом:
(bindat-pack sint16-bindat-spec -8)
⇒ "\377\370"
(bindat-unpack sint16-bindat-spec "\300\100")
⇒ -16320
Наконец, вы можете определять новые формы типа Bindat для использования в выражениях типа Bindat с bindat-defmacro:
- Макрос: bindat-defmacro name args &rest body
Определить новое выражение типа Bindat с именем name и принимающее аргументы args. Его поведение следует за
defmacro, за исключением важного различия, что новые формы могут использоваться только внутри выражений типа Bindat.
Copyright © 1990-1996, 1998-2026 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Bindat-Computed-Types.html