関数仕様 - スタックフレーム

nptのドキュメントです。
参照元:ANSI Common Lisp npt

関数仕様

lisp.hに記載されている下記の関数仕様を示します。

■スタックフレーム
void lisp_push_control(addr *ret);
int lisp_pop_control_(addr control);

■special変数
int lisp_push_special_(addr symbol, addr value);
int lisp_push_special8_(const void *name, addr value);
int lisp_push_special16_(const void *name, addr value);
int lisp_push_special32_(const void *name, addr value);
int lisp_get_special_(addr x, addr symbol);
int lisp_get_special8_(addr x, const void *name);
int lisp_get_special16_(addr x, const void *name);
int lisp_get_special32_(addr x, const void *name);
int lisp_set_special_(addr symbol, addr value);
int lisp_set_special8_(const void *name, addr value);
int lisp_set_special16_(const void *name, addr value);
int lisp_set_special32_(const void *name, addr value);

■defvar
int lisp_defvar_(addr symbol);
int lisp_defvar8_(const void *str);
int lisp_defvar16_(const void *str);
int lisp_defvar32_(const void *str);

■catch / throw
void lisp_catch(addr symbol);
int lisp_throw_(addr symbol);

■handler
int lisp_handler_bind_(addr name, addr call);
int lisp_handler_case_(addr name, addr call);
void lisp_handler_reverse(void);

■restart
void lisp_restart_make(addr x, addr name, addr call, int casep);
void lisp_restart_interactive(addr restart, addr call);
void lisp_restart_report(addr restart, addr call);
void lisp_restart_test(addr restart, addr call);
void lisp_restart_push(addr restart);
void lisp_restart_reverse(void);

■スタックフレーム

スタックフレームの領域確保と解放の関数です。

void lisp_push_control(addr *ret);
int lisp_pop_control_(addr control);

関数lisp_push_control

void lisp_push_control(addr *ret);

出力: ret 新しいスタックフレーム返却

新しいスタックフレームを確保します。
スタックフレームは、主にhold変数に使われます。

脱出関数lisp_pop_control_

int lisp_pop_control_(addr control);

入力: control 解放するスタックフレーム
戻り値: 脱出時は0以外

スタックフレームを解放します。
現在のスタックフレームは実行環境でも保有しており、 もし引数controlと現在のスタックフレームが違う場合はエラーです。

本関数は脱出時にも使用可能です。
controlがhold変数であった場合はエラーです。

■special変数

special変数の操作関数です。

int lisp_push_special_(addr symbol, addr value);
int lisp_push_special8_(const void *name, addr value);
int lisp_push_special16_(const void *name, addr value);
int lisp_push_special32_(const void *name, addr value);
int lisp_get_special_(addr x, addr symbol);
int lisp_get_special8_(addr x, const void *name);
int lisp_get_special16_(addr x, const void *name);
int lisp_get_special32_(addr x, const void *name);
int lisp_set_special_(addr symbol, addr value);
int lisp_set_special8_(const void *name, addr value);
int lisp_set_special16_(const void *name, addr value);
int lisp_set_special32_(const void *name, addr value);

脱出関数lisp_push_special_

int lisp_push_special_(addr symbol, addr value);

入力: symbol symbol
入力: value オブジェクト
戻り値: 脱出時は0以外

現在のスタックフレームにsymbolのspecial変数を追加します。
valueはspecial変数の初期値であり、NULLの場合はunboundです。
symbolvalueがhold変数の場合は、内容が使用されます。

脱出関数lisp_push_special8_

int lisp_push_special8_(const void *name, addr value);
int lisp_push_special16_(const void *name, addr value);
int lisp_push_special32_(const void *name, addr value);

入力: name Unicode文字列
入力: value オブジェクト
戻り値: 脱出時は0以外

現在のpackageからnameというsymbolを探し、special変数を追加します。
valueはspecial変数の初期値であり、NULLの場合はunboundです。
valueがhold変数の場合は、内容が使用されます。
Unicode文字列の詳細はlisp_string8_関数をご確認ください。

脱出関数lisp_push_special16_

lisp_push_special8_で解説

脱出関数lisp_push_special32_

lisp_push_special8_で解説

脱出関数lisp_get_special_

int lisp_get_special_(addr x, addr symbol);

入力: symbol symbol
出力: x hold変数
戻り値: 脱出時は0以外

special変数の値を取得します。
取得した値がunboundの場合はNULLが格納されます。
hold変数に格納されたNULL値はlisp_null_p関数で確認できます。
symbolがhold変数の場合は、内容が使用されます。

脱出関数lisp_get_special8_

int lisp_get_special8_(addr x, const void *name);
int lisp_get_special16_(addr x, const void *name);
int lisp_get_special32_(addr x, const void *name);

入力: name Unicode文字列
出力: x hold変数

現在のpackageからnameというsymbolを探し、special変数の値を取得します。
取得した値がunboundの場合はNULLが格納されます。
hold変数に格納されたNULL値はlisp_null_p関数で確認できます。
Unicode文字列の詳細はlisp_string8_関数をご確認ください。

脱出関数lisp_get_special16_

lisp_get_special8_で解説

脱出関数lisp_get_special32_

lisp_get_special8_で解説

脱出関数lisp_set_special_

int lisp_set_special_(addr symbol, addr value);

入力: symbol symbol
入力: value オブジェクト
戻り値: 脱出時に0以外

special変数に値を設定します。
valueがNULLの場合はunboundが設定されます。
symbol, valueがhold変数の場合は、内容が使用されます。

脱出関数lisp_set_special8_

int lisp_set_special8_(const void *name, addr value);
int lisp_set_special16_(const void *name, addr value);
int lisp_set_special32_(const void *name, addr value);

入力: name Unicode文字列
入力: value オブジェクト
戻り値: 脱出時に0以外

現在のpackageからnameというsymbolを探し、special変数に値を設定します。
valueがNULLの場合はunboundが設定されます。
Unicode文字列の詳細はlisp_string8_関数をご確認ください。

脱出関数lisp_set_special16_

lisp_set_special8_で解説

脱出関数lisp_set_special32_

lisp_set_special8_で解説

■defvar

defvarの関数です。

int lisp_defvar_(addr symbol);
int lisp_defvar8_(const void *str);
int lisp_defvar16_(const void *str);
int lisp_defvar32_(const void *str);

脱出関数lisp_defvar_

int lisp_defvar_(addr symbol);

入力: symbol
戻り値: 脱出時は0以外

symbolをspecial変数にします。
symbolがhold変数の場合は、内容を使用します。

脱出関数lisp_defvar8_

int lisp_defvar8_(const void *str);
int lisp_defvar16_(const void *str);
int lisp_defvar32_(const void *str);

入力: str Unicode文字列
戻り値: 脱出時は0以外

strで表されるsymbolをspecial変数にします。
Unicode文字列の詳細はlisp_string8_関数をご確認ください。

脱出関数lisp_defvar16_

lisp_defvar8_で解説

脱出関数lisp_defvar32_

lisp_defvar8_で解説

■catch / throw

catch / throwの関数です。

void lisp_catch(addr symbol);
int lisp_throw_(addr symbol);

関数lisp_catch

void lisp_catch(addr symbol);

入力: symbol symbolオブジェクト

現在のスタックフレームに、catch用のsymbolを登録します。
symbolがhold変数の場合は、内容を使用します。

脱出関数lisp_throw_

int lisp_throw_(addr symbol);

入力: symbol symbolオブジェクト
戻り値: 0以外

引数symbolを用いてthrowを実行します。
スタックフレームを遡って探索し、 catch用のsymbolが見つかったら脱出を開始します。
symbolが見つからなかったらerrorが発生します。
symbolがhold変数の場合は、内容を使用します。

■handler

handler-bindhandler-caseの関数です。

int lisp_handler_bind_(addr name, addr call);
int lisp_handler_case_(addr name, addr call);
void lisp_handler_reverse(void);

脱出関数lisp_handler_bind_

int lisp_handler_bind_(addr name, addr call);

入力: name symbolかcondition
入力: call 関数オブジェクト
戻り値: 脱出時は0以外

handler-bind用のコードを現在のスタックフレームに登録します。
namesymbolの場合は、find-classを呼び出します。
callは引数1つを受け取る関数オブジェクトを指定します。
namecallがhold変数の場合は、内容を使用します。

脱出関数lisp_handler_case_

int lisp_handler_case_(addr name, addr call);

入力: name symbolかcondition
入力: call 関数オブジェクト
戻り値: 脱出時は0以外

handler-case用のコードを現在のスタックフレームに登録します。
namesymbolの場合は、find-classを呼び出します。
callは引数1つを受け取る関数オブジェクトを指定します。
namecallがhold変数の場合は、内容を使用します。

関数lisp_handler_reverse

void lisp_handler_reverse(void);

handlerリストを逆順にします。
lisp_handler_bind_lisp_handler_case_は複数登録することができますが、 現在のスタックフレームに対してpushで追加していくため、 評価順が登録順ではなく逆順になってしまいます。
そこで本関数を実行することでhandlerリストを逆順にできます。

■restart

restartの関数です。

void lisp_restart_make(addr x, addr name, addr call, int casep);
void lisp_restart_interactive(addr restart, addr call);
void lisp_restart_report(addr restart, addr call);
void lisp_restart_test(addr restart, addr call);
void lisp_restart_push(addr restart);
void lisp_restart_reverse(void);

関数lisp_restart_make

void lisp_restart_make(addr x, addr name, addr call, int casep);

入力: name symbolオブジェクトかNULL
入力: call 関数オブジェクト
入力: casep `restart-bind`は0、`restart-case`は0以外
出力: x hold変数

restartオブジェクトを生成します。
nameは名前であり、NULLの場合はNILです。
callは関数オブジェクトを指定します。
caseprestart-bindrestart-caseを区別するための引数であり、 restart-caseを指定したい場合は0以外を指定します。
本関数はrestartオブジェクトを生成するだけであり、 スタックフレームに登録するわけではありません。
name, callがhold変数の場合は、内容を使用します。

関数lisp_restart_interactive

void lisp_restart_interactive(addr restart, addr call);

入力: restart restartオブジェクト
入力: call 関数オブジェクト

restartオブジェクトにinteractiveコードを設定します。
callは引数無しで呼び出す関数を指定します。
callNULLの場合は指定無しです。
restartcallがhold変数の場合は、内容を使用します。

関数lisp_restart_report

void lisp_restart_report(addr restart, addr call);

入力: restart restartオブジェクト
入力: call 関数オブジェクト

restartオブジェクトにreportコードを設定します。
callは引数1つで呼び出す関数を指定します。
callNULLの場合は指定無しです。
restartcallがhold変数の場合は、内容を使用します。

関数lisp_restart_test

void lisp_restart_test(addr restart, addr call);

入力: restart restartオブジェクト
入力: call 関数オブジェクト

restartオブジェクトにtestコードを設定します。
callは引数1つで呼び出す関数を指定します。
callNULLの場合は指定無しです。
restartcallがhold変数の場合は、内容を使用します。

関数lisp_restart_push

void lisp_restart_push(addr restart);

入力: restart restartオブジェクト

restartを現在のスタックフレームに登録します。
restartがhold変数の場合は、内容を使用します。

関数lisp_restart_reverse

void lisp_restart_reverse(void);

restartリストを逆順にします。
lisp_restart_pushは複数登録することができますが、 現在のスタックフレームに対してpushで追加していくため、 評価順が登録順ではなく逆順になってしまいます。
そこで本関数を実行することでrestartリストを逆順にできます。