try〜catch〜finallyマクロ †
擬似例外処理マクロです。
#define global try %ttry %i0
#define global throw(%1) %ttry %s1 goto *%p1
#define global catchbegin %ttry *%p1 %c if 0 {
#define global catch(%1) %ttry } if (%p) = (%1) {
#define global catchend %ttry } %o0 %o0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
-
-
!
| #define global try %ttry %i0
#define global throw(%1) %ttry %s1 goto *%p1
#define global catchbegin %ttry *%p1 %c if 0 {
#define global catch(%1) %ttry } if (%p) = (%1) {
#define global catchend %ttry } %o0 %o0
try
randomize
a = rnd(5) : dialog "aの内容は" + a + "です"
if a : throw a
catchbegin
catch 1 : dialog "1"
catch 2 : dialog "2"
catch 3 : dialog "3"
catch 4 : dialog "4"
catchend
dialog "例外処理終了"
end
|
- 特殊展開マクロ・・・全く扱ったことがなく、先ほどドキュメントを読み、なんとなく分かったところですが、最初の try の定義は %i でユニークなラベル名をスタックに積み、 __try_sw_ 変数にラベル名( 文字列 )を代入しているように思われますが、このようにしているのは %i だけだと生成したラベル名が代入・参照を伴わない変数名ということでシンタックスエラーになるのを回避しているだけかと思われます。
それなら %i0 を指定するのはどうでしょう。ユニークなラベル名を生成してスタックには積むが生成したラベル名の展開は行われないそうです。 -- kz3
- モノがあるからコメント出せるけど自分でやろうと思ったらまず無理です^^; -- kz3
- あ、そんなのあったんですか。#defineの説明は長いのであまりよく読んでませんでした。 -- QIG
- 名前変えたらいろんな言語をミックスしたような変なマクロになってしまった。少なくとも、C++,Java,Delphiは混ざってます。(^^; -- QIG
- C++のtry文を参考に「型」で処理わけしてみました。ただ、モジュールやサブルーチン内でthrowした場合のcatchの処理(エラー?gotoで抜ける?それともreturn・・・など)が微妙です。
+
| | try案1
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
| #define try %ttry %i0
#define ctype throw(%1,%2) %ttry %p _val = %2: \
if vartype("%1") == vartype(%p _val): goto *%p _%1: else: \
dialog "型が異なっています。\nline:"+__line__,1,"型の不一致": end
#define ctype catch(%1) %ttry goto *%p _end%c *%p _%1
#define cat %ttry %p _val
#define tryend %ttry *%o _end
randomize
repeat
wait 10
try
switch rnd(3)
case 0: throw(int, rnd(5)
case 1: throw(str, "HELLO")
swend
catch(int): mes cat
catch(str): mes cat
catch(double): mes cat
tryend
loop
|
|
- 型名の前にスペースが入っていると動作しない^^;ラベル名に型名をくっつける方法を模索したものの・・・ラベル変数が実装できたら恐らく文字列を連結したりして実装できるかも知れないですよ。 -- kz3
- 指定したマクロ引数にトークン区切り字も含まれたりしているって事なのかな・・・この辺りプリプロセッサの強化で改善されると良かったり・・・。
%p _%1 とかも %p_%1 で動作して欲しかったり・・・#演算子とか・・・ -- kz3
- tryの次に現在のネストレベルを保存、catchの所でネストレベルチェック、ネストレベルが増えていたらサブルーチン及びモジュール内から飛んできたってことでreturn・・・同じならgoto・・・と考え中。やることが増えてマクロとして割りに合わないかも・・・ -- kz3
- 型名に関しては冗長だけどcatch_intなどそれぞれ用意すればとりあえず解決するとして、if文でブロック構造を作っていないからcatchが上に書けてしまうのでボツですorz -- kz3