0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Paraphrase での条件分岐の書きかた

Last updated at Posted at 2019-01-17

はじめに

 この文書は、マルチコア対応 Forth 系言語 Paraphrase での条件分岐処理はどのように書くのか? について説明します。

いわゆる普通の if

 スタックの一番上にある値(TOS=Top Of Stack)が true の時のみ、ある処理を行う場合は、

if ある処理 then

と書きます。もちろん、ある処理の部分は複数のワードから構成されていても構いません。例として、TOS の絶対値を計算する abs というワードを定義してみます。

> "abs" : dup 0 < if -1 * then ;
 ok.
> 5 abs .
 5 ok.
> -5 abs .
 5 ok.

TOS の値を複製(dup)しておき、その複製した値と 0 とを比べ、0 よりも小さい場合に限り、if 〜 then の間にある -1 を掛ける処理を実行します。正の場合は、if 〜 then の間は実行されないので、TOS の値は変化しないこととなります。

if - else

 上の例は、ある条件を満たした時のみ特定の処理を実行するものでしたが、プログラムにおいては、ある条件を満たしているときは処理 A を、満たしていないときは処理 B を実行したい場合があります。これは C などでは if( 条件式 ) { 処理 A } else { 処理 B } などと書かれます。

 Paraphrase でも、このような処理を記述できます(Forth でもできます)。以下の様に書きます:

if
    TOS が true の時の処理
else
    TOS が true でない時の処理
then

これを用いて、TOS の逆数を計算する rcp というワードを定義してみます。TOS が 0 の時は逆数を計算できませんので、このときは "ERROR" という文字列を TOS に積むこととします。

> "rcp" : dup 0 != if 1.0 swap / else drop "ERROR" then ;
 ok.
> 2 rcp .
 0.500000 ok.
> 0 rcp .
 ERROR ok.

switch - case

 Paraphrase でも他の言語同様、多方向分岐を行うための仕組みが用意されています。関連するワードは switch, case, ->, break, dispatch です。これについては、言葉で説明するよりも、以下の擬似コードを見たほうが分かりやすいかと思います:

switch
    case TOS に対するテスト1 -> テスト1 が true の時に実行される処理 break
    case TOS に対するテスト2 -> テスト2 が true の時に実行される処理 break
      :
    case TOS に対するテストN -> テストN が true の時に実行される処理 break
    上記のテスト、いずれにも合致しない場合に実行される処理
dispatch

ある条件を満たした時に実行される処理が終了すると、dispatch の後に書かれた処理より実行が再開されます(dispatch の次に書かれている処理までジャンプします)。

 有名な Fizz Buzz 問題(Wikipedia の説明へ)を処理するワード FizzBuzz は以下のように記述できます。このワードは、TOS が 3 の倍数なら "Fizz" を、5 の倍数なら "Buzz" を、3 および 5 の倍数(つまり 15 の倍数)であれば "FizzBuzz" という文字列をスタックに積みます:

"FizzBuzz" :
    switch
        case 15 % 0 == -> "FizzBuzz" break
        case  5 % 0 == -> "Buzz" break
        case  3 % 0 == -> "Fizz" break
    dispatch
;

switch ブロックでは case は順次上から実行されていきますので、15 の約数であるか否かは最初に確認しなければなりません(でないと 5 の倍数もしくは 3 の倍数であると判断されてしまうので)。

実際のこのワードを用いて FizzBuzz 列を出力させると、以下のようになります。

> 1 20 for+ i FizzBuzz . next
 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz ok.

その他

 拡張辞書の extFactor を用いると、factor:if というワードを使用することもできます。これは Factor という連鎖性言語で使われている if 文と同様の条件判断を行うものです。こちらについては Paraphrase に同梱されているドキュメント docs/ext/extFactor.html を参照して下さい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?