GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Bindat-Computed-Types.html ・ emacs-doc.conao3.com

41.20.3 高度なデータレイアウト仕様

Bindat型の式は、前述の型に限定されるものではありません。Bindat型の式を返す任意のLisp形式である場合もあります。例えば、以下の型は、24ビットのエラーコードまたはバイトベクトルのいずれかを保持できるデータを記述しています:

(bindat-type
  (len      u8)
  (payload  . (if (zerop len) (uint 24) (vec (1- len)))))

さらに、複合型は通常アソシエーションリストに展開(およびそこからパック)されますが、以下の特殊なキーワード引数を用いることでこれを変更できます。

:unpack-val exp

フィールドのリストがこのキーワード引数で終わっている場合、アンパック時に返される値は、標準的なalistではなくexpの値となります。expでは、それまでのすべてのフィールドを名前で参照できます。

:pack-val exp

フィールドの型の後にこのキーワード引数が続く場合、このフィールドに格納された値は、alistから抽出されるのではなく 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-defmacro を使用して、Bindat型式で用いる新しいBindat型フォームを定義できます:

マクロ: bindat-defmacro name args &rest body

name という名前で、引数 args を取る新しい Bindat 型の式を定義します。その挙動は defmacro に従いますが、重要な違いは、新しい形式が Bindat 型の式内でのみ使用可能であるという点です。