throw ( n -- )
は、 n がゼロでない限り例外を引き起こします。
100 throw .s 0 throw .s
catch ( ... xt -- ... n )
は execute
と同様に動作しますが、 例外をキャッチし、
スタック上に例外の数値(または XT が例外なしで実行された場合は 0)をプッシュします。 例外があった場合、 スタックの深さは
catch
の実行直前と同一です。
.s 3 0 ' / catch .s 3 2 ' / catch .s
研究課題(assignment):
catch
の代わりにexecute
を使用して同じことを試してみましょう。
throw
は、常に動的に直近にこの throw
を囲んでいる(定義の) catch
にジャンプします、
たとえそのジャンプを達成するために複数の呼び出しレベルを飛び越す必要がある場合でもです:
: foo 100 throw ; : foo1 foo ." after foo" ; : bar ['] foo1 catch ; bar .
多くの場合、 定義が例外によって終了した場合でも、 定義を終了したときに値を復元することが重要です。 以下のようにしてみるのはどうでしょうか:
: ... save-x ['] word-changing-x catch ( ... n ) restore-x ( ... n ) throw ;
しかし、 これでも、 たとえば、catch
と restore-x
の間を実行中にユーザーが Ctrl-C
を押すなどしたら安全ではありません。
Gforth は、そのような場合に対して安全な代替例外処理構文(alternative exception handling syntax)
try ...restore ... endtry
を提供します。 try
と endtry
の間のコードに例外があった場合、 スタックの深さが復元され、 例外数値がスタックにプッシュされ、 restore
の直後から実行が続行されます。
以下は、 上記のコードと同等の、 より安全なコードです
: ... save-x try word-changing-x 0 restore restore-x endtry throw ;
こちらも参照ください: Exception Handling