関数名は, 慣習上組み込み関数名の先頭に ``P'' を付ける. 即ち今の場合 Pput_byte である. まず, file_tab[] にエントリを追加する. このテーブルの上にプロトタイプvoid Pput_byte(); を宣言する. さらに, テーブルの適当な位置に, 先に決定した仕様で登録する.
void Pput_byte();
...
struct ftab file_tab[] = {
{"purge_stdin",Ppurge_stdin,0},
/* 関数本体は Popen_file, 引数は最大で 2 */
{"open_file",Popen_file,1},
{"close_file",Pclose_file,1},
{"get_byte",Pget_byte,1},
/* 追加したエントリ. 引数は 2 */
{"put_byte",Pput_byte,2},
...
次に, 関数本体を file.c の適当な位置に書く.
void Pput_byte(arg,rp)
NODE arg;
Q *rp;
{
int i,c;
FILE *fp;
/* 引数のチェック */
asir_assert(ARG0(arg),O_N,"put_byte");
asir_assert(ARG1(arg),O_N,"put_byte");
/* ファイル記述子の取り出し */
i = QTOS((Q)ARG0(arg));
/* 書き出すバイトの取り出し */
c = QTOS((Q)ARG1(arg));
if ( fp = file_ptrs[i] ) {
/* ファイルへ書き出す */
putc(c,fp);
/* この関数の出力を作る */
STOQ(c,*rp);
} else
error("put_byte : invalid argument");
}
マクロ QTOS は, 内部形式で有理数として表現されているものの, 実際には 32 bit 符号付き整数であることが分かっているオブジェクトを 32 bit 符号付き整数に変換する. また, STOQ はその逆の働きをする. 関数は必ず何らかのオブジェクトを内部形式で返さなければならない. それを書き込む場所は, この関数でいえば rp というポインタ として渡されているので, そこにオブジェクトのポインタを書く. この関数の場合, 書いたバイトをそのまま返すことにしている.