Piet(和訳Ver)

原文(Original)
Composition with Red, Yellow and Blue by Piet Mondrian
Composition with Red,
Yellow and Blue
.
1921, Piet Mondrian.

初めに

Piet(ピエト)は抽象絵画っぽく見えるように作ったプログラミング言語です。名前の由来は、抽象絵画の先駆者 Piet Mondrian(ピエト・モンドリアン)です。 本当はこの言語をMondrian(モンドリアン)と名付けたかったのですが こんな (リンク切れにつきWebArchiveのキャッシュをどうぞ)極平凡な言語があったのでやめました。 難解言語じゃなくなっちゃうし仕方ない。

基本理念

Pietの構成

#FFC0C0
明るい赤
#FFFFC0
明るい黄
#C0FFC0
明るい緑
#C0FFFF
明るいシアン
#C0C0FF
明るい青
#FFC0FF
明るいマゼンタ
#FF0000
#FFFF00
#00FF00
#00FFFF
シアン
#0000FF
#FF00FF
マゼンタ
#C00000
暗い赤
#C0C000
暗い黄
#00C000
暗い緑
#00C0C0
暗いシアン
#0000C0
暗い青
#C000C0
暗いマゼンタ
#FFFFFF 白 #000000 黒
Pietでは右表に示した見分けやすい20色を使用します。 上三段の18色は以下の二通りの方法で循環関係になっています: 「明色」は「暗色」より一周回って「暗い」と考えます。そして白と黒はこの循環に属しません。注意して下さい。

もし上記20色以外の追加色(例えばオレンジ色とか茶色とか)が入ったら、その処理は各処理系に依存します。 例えば簡単な例を挙げると、追加色が白として解釈される処理系であれば、白と同様に使用することが出来ます。 (逆に黒と同様として扱うこともできます。)

codel

Pietは上で定義された色で出来た絵で表現されます。 ピクセル一つ一つの色がこの言語では重要になるので見やすくするために拡大することがよくあります。 拡大すると「ピクセル」と呼んだ時それが元のサイズでの尺度なのか拡大後のサイズでの尺度なのかが紛らわしくなってしまいます。 そこで拡大されている時、拡大前の1ピクセル分のブロック一つを"codel"と呼ぶことにします。

カラーブロック

Pietの基本単位はカラーブロックになります。カラーブロックは隣接した同じ色の複数のcodelで作られ、 違う色のブロックに当たるまでが一つの塊になります。ただし、対角線上に隣接してるものは一塊にカウントしません。 カラーブロックは様々な形になり場合によっては違う色の"穴"を内包するかもしれませんが、 その穴はブロックにもカウントされず無視されます。

スタック

Pietは記憶領域としてスタックを一つだけ持っています。データは整数型しか持ちませんが、コマンドを利用すれば この整数をUnicodeの値と解釈して文字を表示することも可能です。

プログラムの実行

DPCC選ばれるCodel
右端の上
右端の下
下端の右
下端の左
左端の下
左端の上
上端の左
上端の右
Pietのインタプリタは左上からプログラムの実行を始めます。インタプリタはDirection Pointer (DP) 向きのポインタ)を持っていてこれは最初は右向きを指しています。DPは上下左右のいずれかを指します。 また、Codel Chooser (CC)(codelを選ぶもの)も持っていてこの初期値は左です。CCは左か右を指します。 DPとCCの指す向きはプログラムの実行中にどんどん変化していきます。

プログラムポインタは実行中以下のルールに従ってカラーブロックを移動していきます。

  1. プログラムは今いるカラーブロックの中でDPの向きに一番離れた端っこを探します。(形によってはこの端は一繋がりではないかもしれません。)
  2. DP方向に向かってCC側の端をさっき見つけた端の中から見つけます。(プログラムの上に立っていてDPの方向に歩いている感じ。 右表も参考のこと。)
  3. そしてそのcodelからDPの方向にある隣のカラーブロックのcodelに移動します。
これをプログラムの終了まで繰り返します。

構文要素

数値

Pietでは白でも黒でもないカラーブロックはそのcodel数(面積)が整数値を表します。負の数は表現できませんが、 命令を組み合わせれば可能です。インタプリタが整数を検知したからといってそれが必ずしもプログラムに影響するとは限りません。 値をプッシュする命令の場合に限りその数値をスタックにプッシュします。(命令の詳細は後で説明する。)

黒ブロックと端について

黒のカラーブロックとプログラムの端っこはプログラムの行き止まりに当たります。インタプリタがこれに差し掛かった時 一旦停止してCCを切り替えます(右なら左、左なら右に)。切り替えてから再度移動を試みます。 CCを切り替えても移動できなかった場合はDPを時計回りに90度回します。このようにして全てのパターンのCCとDPを試していきます。 もし8通り全て試みて移動できなかった場合は移動を諦めプログラム終了となります。

白ブロックについて

白ブロックは"フリーゾーン"となりインタプリタは妨げられること無く通り過ぎます。白のエリアに突入してきた時 インタプリタはこの上をDPの方向に滑るように白以外のカラーブロックにたどり着くまで真っ直ぐ通り過ぎて行きます。 もし白の上を通って黒か端までたどり着いてしまった場合はやはり行き止まりになります(上の項目参照)。 それ以外の普通のカラーブロックに着いた場合はそこから普通に進みます。 白を通り抜けてたどり着いた先の色では命令として解釈はしません(下の項目参照)。 持っている色を命令を実行せずに変更できるのでループ等の実装に最適です。

白ブロックの挙動について(追記:2008.1.25):    (この辺り訳がちょっと微妙 by訳者)

インタプリタは白ブロック上を一直線に色の着いたブロックに当たるまで進みます。 先に説明した普通のカラーブロックの時のような動き方はしません。

白ブロックを通りすぎて黒ブロックや端に当たった時正確にどうなるのかが元の仕様では不明確でした。 私の解釈を以下に記しておきました。

コマンド

 明度
色相変化なし1段階変化2段階変化
変化なし pushpop
1段階変化addsubtractmultiply
2段階変化dividemodnot
3段階変化greaterpointerswitch
4段階変化duplicaterollin(number)
5段階変化in(char)out(number)out(char)
コメンドは今いるカラーブロックから次にインタプリタが移動する先のカラーブロックの色の変化で示されます。 色相と明度の変化量が実行する命令を右表のように決定します。白ブロックを挟んでの命令実行はされません。 それぞれのコマンドの内容を以下に説明します。 これらの命令が実行できない場合(例えばポップする程スタックに値が無いとか)は単純に無視されます。

サンプルプログラム及びその他情報等


原文 | DM氏のサイト | 訳者のサイト
原文の最終更新日: 2008/1/25(金) 02:48:17 PST.
Copyright © 1990-2010, David Morgan-Mar. dmm@dangermouse.net
Copyright © 2012, けんぼー lupin@kembo.org