先日公式BBSに例外処理のマクロがありまして
http://hsp.tv/play/pforum.php?mode=all&num=32385
それは、どう書く?orzを参考にしていまして
http://ja.doukaku.org/comment/8783/
著作権どうしよう?だなんて考えながらマクロ(?)を書きました
作成に二日かかったので
作成時間2〜4時間くらいで書いたままサイトにUPしてなかったんですけど
UPしてみます
公式BBSのは関数から例外が返って来ないんですけど
例外処理って普通の返り値と例外の二つ返す仕組みだとか
どこかで読んだ気がするんですけれど
なら返り値は引数に代入して
一つしかないけど返り値で例外を返せばいいじゃないか?という仕様です
例外の値は数値っぽいんですけど
しっかり設計しないといけなそうなので
例外の値は文字列にしました
文字列が等しければcatchという流れです
catchとfinallyは構造がまんまswitchではないか?
と思いまんまswitch使用して呼び方が違うだけです
FILE名:FILE_EX.hsp
以下TESTコード
http://hsp.tv/play/pforum.php?mode=all&num=32385
それは、どう書く?orzを参考にしていまして
http://ja.doukaku.org/comment/8783/
著作権どうしよう?だなんて考えながらマクロ(?)を書きました
作成に二日かかったので
作成時間2〜4時間くらいで書いたままサイトにUPしてなかったんですけど
UPしてみます
公式BBSのは関数から例外が返って来ないんですけど
例外処理って普通の返り値と例外の二つ返す仕組みだとか
どこかで読んだ気がするんですけれど
なら返り値は引数に代入して
一つしかないけど返り値で例外を返せばいいじゃないか?という仕様です
例外の値は数値っぽいんですけど
しっかり設計しないといけなそうなので
例外の値は文字列にしました
文字列が等しければcatchという流れです
catchとfinallyは構造がまんまswitchではないか?
と思いまんまswitch使用して呼び方が違うだけです
FILE名:FILE_EX.hsp
#module EX // ユニークラベル操作 // ユニークラベル取り出し。スタック維持 #define global __p_u_label %tEX_unique_label *%p // ユニークラベルをpop #define global __o_u_label %tEX_unique_label *%o goto *@f // 変数をグローバル変数として扱いたいのでアクセサ付きとする #deffunc __set_EX_val str p __EX_val=p return #defcfunc __get_EX_val return __EX_val *@ // アクセサ変数を空文字代入でRESET #define global throw_RESET __set_EX_val "" // 文字列をアクセサ変数に代入してユニークラベルにJUMP #define global try_throw(%1) __set_EX_val %1:goto __p_u_label // ユニークラベルをスタックに積む #define global try_begin %tEX_unique_label %i0 // 空命令 #define global try_end /**/ // ユニークラベルを取り出して、そこがswitch文の開始 #define global b_catch __o_u_label:switch(__get_EX_val()) // switch文終了 #define global b_catch_end swend // catchはcase文 #define global catch_begin(%1) case %1 #define global catch_end swbreak // finallyはdefault文 #define global finally_begin default #define global finally_end swbreak // throwすると見せかけてreturnするだけ #define global throw(%1) return %1 // 例外文字列が""か"nil"でなければ例外を投げる #define global Does_try_throw(%1) __on_does_throw=%1:\ if (__on_does_throw!="")&(__on_does_throw!="nil"){try_throw __on_does_throw} // 例外文字列が""か"nil"でなければ例外を返す #define global Does_throw(%1) __on_does_throw=%1:\ if (__on_does_throw!="")&(__on_does_throw!="nil"){throw __on_does_throw} #global |
以下TESTコード
#include "FILE_EX.hsp" goto *@f #defcfunc throw_a01 throw "a01" #defcfunc throw_a02 throw "a02" #defcfunc throw_abc throw "abc" #defcfunc throw_null throw "" #defcfunc throw_nil throw "nil" *@ // TEST例外処理の流れ try_begin try_throw "a01" try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end try_begin try_throw "a02" try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end try_begin try_throw "abc" try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end // TEST例外が返ってくる try_begin try_throw throw_a01() try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end try_begin try_throw throw_a02() try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end try_begin try_throw throw_abc() try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end // Does_try_throwのTEST try_begin Does_try_throw throw_a01() try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end try_begin Does_try_throw throw_null() mes "null throw" goto *@f try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end *@ try_begin Does_try_throw throw_nil() mes "nil throw" goto *@f try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end *@ goto *@f // Does_throwのTEST用関数 #defcfunc throw_call_a01 Does_throw throw_a01() return "" // Does_throwのTEST用関数 #defcfunc throw_call_null Does_throw throw_null() return "" *@ // Does_throwのTEST try_begin Does_try_throw throw_call_a01() mes "null throw" goto *@f try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end *@ // Does_throwのTEST try_begin Does_try_throw throw_call_null() mes "null throw" goto *@f try_end b_catch catch_begin "a01" mes "EX:This is a01" catch_end catch_begin "a02" mes "EX:This is a02" catch_end finally_begin mes "EX:This is fin" finally_end b_catch_end *@ |