% 関数仕様 - スタックフレーム
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変数の操作関数です。
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
です。
symbol
とvalue
が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
の関数です。
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
の関数です。
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-bind
とhandler-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
用のコードを現在のスタックフレームに登録します。
name
がsymbol
の場合は、find-class
を呼び出します。
call
は引数1つを受け取る関数オブジェクトを指定します。
name
とcall
がhold変数の場合は、内容を使用します。
lisp_handler_case_
int lisp_handler_case_(addr name, addr call);
入力: name symbolかcondition
入力: call 関数オブジェクト
戻り値: 脱出時は0以外
handler-case
用のコードを現在のスタックフレームに登録します。
name
がsymbol
の場合は、find-class
を呼び出します。
call
は引数1つを受け取る関数オブジェクトを指定します。
name
とcall
がhold変数の場合は、内容を使用します。
lisp_handler_reverse
void lisp_handler_reverse(void);
handlerリストを逆順にします。
lisp_handler_bind_
とlisp_handler_case_
は複数登録することができますが、
現在のスタックフレームに対してpush
で追加していくため、
評価順が登録順ではなく逆順になってしまいます。
そこで本関数を実行することでhandlerリストを逆順にできます。
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
は関数オブジェクトを指定します。
casep
はrestart-bind
とrestart-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
は引数無しで呼び出す関数を指定します。
call
がNULL
の場合は指定無しです。
restart
とcall
がhold変数の場合は、内容を使用します。
lisp_restart_report
void lisp_restart_report(addr restart, addr call);
入力: restart restartオブジェクト
入力: call 関数オブジェクト
restart
オブジェクトにreportコードを設定します。
call
は引数1つで呼び出す関数を指定します。
call
がNULL
の場合は指定無しです。
restart
とcall
がhold変数の場合は、内容を使用します。
lisp_restart_test
void lisp_restart_test(addr restart, addr call);
入力: restart restartオブジェクト
入力: call 関数オブジェクト
restart
オブジェクトにtestコードを設定します。
call
は引数1つで呼び出す関数を指定します。
call
がNULL
の場合は指定無しです。
restart
とcall
が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リストを逆順にできます。