[今日のPiet]GridPietGenerator入門編1(無限ループを作る)

どもです。

前回までの、あまりの超大作(量的な意味で)に

疲れてしまったので、ちょっと趣向を変えます。

これまで紹介してきたGridPietGeneratorですが、

まともに説明していなかったので、今回からは

処理フローファイルの書き方の説明をしようかと思います。

とはいえ、体系的に説明してもつまらないので、

サンプルプログラムとして、ループを題材に取り上げようと思います。

無限ループを作ろう

まずはループの基本、悪名高き「無限ループ」を作ります。

処理フローファイルで無限ループを作るのは簡単です。

まず、お好きなテキストエディタを開きます。

次に、以下のプログラムをかきます。

:loop
goto:loop

できました。

ね?簡単でしょう?

解説

まず大前提として。

処理フローファイルは半角スペース、タブ、または改行で区切られた命令の羅列です。

条件分岐を除いて、基本的にはファイルの初めから順番に命令を実行します。

処理フローファイルの命令は全部で18こあります。1

 

また、Pietのメモリはスタックと呼ばれる構造を持っています。(今更ですが・・・)

命令の中には、スタックに変化を与えるものもありますし、

スタックには影響を及ぼさないものもあります。

 

さて、これを踏まえて、先ほど書いたファイルを見てみます。

先ほど書いたファイルには、「:loop」と「goto:loop」の

2つの命令(と便宜上呼びます)が含まれていることがわかります。

 

まず、1つ目の:loopの部分を「ラベル」と呼んでいます。

これは、プログラムのジャンプ先を表すものです。

色々ルールはありますが、ざっくり言えば、

コロン:で始まる文字列はラベルです。

ジャンプ先以外の意味はないので、ラベルを書いてもスタックは変化しません。

 

次にgoto命令が来ています。

お察しの通り、これは無条件のジャンプ命令です。

gotoの直後にラベルを指定して、そのラベルに無条件でジャンプします。

今回の場合は、先ほど書いたラベル:loopに無条件ジャンプさせています。

なお、goto命令を実行してもスタックは一切変化しません。

 

まとめると、先ほどのプログラムでは、

 goto命令でラベル:loopに戻る

を延々繰り返すため、無限ループができるのです。

命令解説

今日出てきた命令である、ラベルとgoto命令について説明します。

ラベル

書き方::ラベル名

入力:なし

スタック変化:なし

出力:なし

説明:ラベルを作るときは、コロン:に続けて英数字またはアンダースコア_を並べてください。

コロン:の後ろの文字列が「ラベル名」です。

ただし、以下のルールがあります。

  • ルール1:コロン:の後に、半角スペースなどの空白文字を入れてはいけません。
  • ルール2:コロン:の直後の1文字は必ず英字にしてください。 2
  • ルール3:同じラベルを複数回使ってはいけません。
goto命令

書き方:goto:ラベル名

入力:なし

スタック変化:なし

出力:なし

説明:指定したラベル名のラベルの位置に無条件でジャンプする。

コロン:の前後に、半角スペースなどの空白文字を入れてはいけません。

Piet化してみる

ではGridPietGeneratorでPiet化してみます。

先ほどの処理フローファイルを適当な名前(ここでは"loop.txt")で保存します。

 

その上で、GridPietGeneratorを実行します。

お使いのOSでコマンド画面を立ち上げて(←この辺は調べてください。すみません・・・)

実行します。Windows風に書くなら次の通りです。

GridPietGenerator.exe loop.txt loop.ppm

Linux風に書くなら次のような感じでしょうか。

./GridPietGenerator loop.txt loop.ppm

これで生成した画像"loop.ppm"ができます。

 

以前も説明しましたが、ppmファイルはあまり一般的な画像形式ではないため、

OS標準のビューアではみられないかもしれません。

実装の都合でこのようになっており申し訳ないです。

私の手元でpngに変換して拡大すると、次のような画像が出てきます。

f:id:y-mos:20210817230849p:plain
無限ループ

シンプルですね。

動作確認

さて、これをPietのインタプリタであるnpietデバッグしてみます。

(npietも今度解説しないとなあ。。。)

npietがインストールされているとして、以下のように実行します。 (Linux風の表記ですが)

./npiet loop.ppm -tpic -tpf 30

tpicオプションは、デバッグ画像を出力するオプションです。

デバッグ画像は"npiet-trace.png"といった名前で出力されます。

デバッグ画像ファイル名を指定するオプションはないようです。)

 

tpfオプションは、デバッグ画像の倍率を整数で指定するためのものです。

ここでは30倍にしています。

 

なお、npietはppm形式の画像に対応しています。

 

では実行します。

・・・

・・・

・・・

・・・

・・・

止まらん・・・

あぁ、無限ループだったわ(笑)

というジョークみたいなことをやらかした私のマネはしなくていいので、

すぐにcontrol-C(ctrl+C)で止めましょう。

 

さて、出力は次のようになります。

f:id:y-mos:20210817231751p:plain
無限ループのトレース画像

Pietは左上から出発するので、

下に見える四角形の黒線部分でループしているのだとわかります。

Pietのルールに則って丁寧に追えばわかるのですが、

この画像では時計回りにぐるぐる回り続けます。

 

なお、色々と色のマスがくっついており、所々命令も実行されていますが、

あくまでPietインタプリタを誘導して、

方向転換させるためだけに命令を実行させています。

 

Pietを方向転換させるだけでもメモリを使う必要が出てきます。

ですが、方向転換の際のメモリ使用は一時的なもので、

メモリの他の部分には影響を与えません。

つまり、一連の方向転換処理の前後を比較すると、

メモリの状態が保たれるようになっています。

 

こうした工夫によって、どんな状況でも自由自在に

Pietインタプリタの方向転換ができます。

メモリに影響しない方向転換は、

Piet画像生成自動化のポイントのひとつです。

最後に

・・・なんか、これで終わるとすごい怒られそうですね。

「えっ!無限ループなんか使えないやん。」ってな感じで。

ループの中で何か処理をさせるようなケースは次回解説します。

 

実は、無限ループでない方も、プログラム自体は書いたんですけどね。

ブログの方にまとめるのに労力がかかるみたいで、やはり気力との勝負になりがちです。

書く量を少なくしつつ、息長く続けていく方がいいのかな、

と思った今日この頃です。

 

最近その日の気分で「最後に」のコメント書いてるので、

方針ブレブレになっているかもしれませんが。。。

 

じゃ、今日はこのへんで。

では。


  1. そのうち15個は、Pietの命令と同じものです。

  2. 実は内部的に:1:2、・・・などの連番ラベルを使う可能性があるため、それらと重複しないように、このような仕様にしています。