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

8.4 Cへの脱線

The copy-region-as-kill function (see copy-region-as-kill) uses the filter-buffer-substring function, which in turn uses the delete-and-extract-region function. It removes the contents of a region and you cannot get them back.

ここで扱う他のコードとは異なり、delete-and-extract-region 関数は Emacs Lisp で書かれているわけではなく、C で書かれており、GNU Emacs システムのプリミティブの一つです。非常にシンプルなので、Lisp から少し脱線して、ここで説明します。

他の多くのEmacsプリミティブと同様に、delete-and-extract-regionはCマクロのインスタンスとして記述されます。マクロとは、コードのテンプレートのことです。完全なマクロは以下のようになります。

DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
       Sdelete_and_extract_region, 2, 2, 0,
       doc: /* Delete the text between START and END and return it.  */)
  (Lisp_Object start, Lisp_Object end)
{
  validate_region (&start, &end);
  if (XFIXNUM (start) == XFIXNUM (end))
    return empty_unibyte_string;
  return del_range_1 (XFIXNUM (start), XFIXNUM (end), 1, 1);
}

マクロの記述プロセスの詳細には触れませんが、このマクロは DEFUN という単語から始まる点を指摘しておきます。DEFUN という単語を選んだのは、このコードが Lisp における defun と同じ役割を果たすためです。(C のマクロ DEFUN は emacs/src/lisp.h で定義されています。)

DEFUN という単語の後には、括弧内に7つの部分が続いています:

Cのマクロでは、次に仮引数が続き、それがどのようなオブジェクトであるかが記述され、その後にマクロの本体が続きます。delete-and-extract-regionの場合、本体は以下の4行で構成されています。

validate_region (&start, &end);
if (XFIXNUM (start) == XFIXNUM (end))
  return empty_unibyte_string;
return del_range_1 (XFIXNUM (start), XFIXNUM (end), 1, 1);

validate_region 関数は、領域の開始位置および終了位置として渡された値が適切な型であり、かつ範囲内にあるかを判定します。開始位置と終了位置が同一の場合は、空文字列を返します。

del_range_1 関数は、実際にはテキストを削除します。これは複雑な関数であるため、ここでは詳しく見ません。バッファを更新したり、その他の処理を行ったりします。とはいえ、del_range_1 に渡される2つの引数については見ておく価値があります。それが XFIXNUM (start) と XFIXNUM (end) です。

C言語の観点から言えば、start と end は、削除対象領域の開始と終了を示す2つの不透明な値である。より正確に言えば――理解にはより高度な専門知識を要するが――これら2つの値は Lisp_Object 型であり、Cのポインタ、Cの整数、あるいはCの struct のいずれかとなり得る。通常、Cコードは Lisp_Object がどのように実装されているかを気にする必要はない。

Lisp_Object 幅はマシンによって異なり、通常は32ビットまたは64ビットです。ビットの一部は情報の種類を指定するために使用され、残りのビットはコンテンツとして使用されます。

‘XFIXNUM’は、より長いビット列から該当する整数を抽出するCマクロであり、型ビットは破棄されます。

delete-and-extract-region 内のコマンドは次のようになります。

del_range_1 (XFIXNUM (start), XFIXNUM (end), 1, 1);

開始位置 start と終了位置 end の間の領域を削除します。

Lispを書く者の視点からすれば、Emacsはすべて非常にシンプルだ。だが、その裏側には、すべてを動作させるための多大な複雑さが潜んでいる。