難解プログラミング言語を整える
専門><>(Fish)を整える。
= 盤面を走るポインタと、増やせるスタックを、ステップごとに眺める
><> が初めての方は、先に そもそも ><> とは をどうぞ。
サンプル(クリックでエディタに入れる)
出力
「実行」を押すと、ここに出力が出ます。
ステップ再生
ポインタの向きと、複数のスタックを見る
スタック(左が底・右が一番上。いま使っているのは太枠)
レジスタ(いまのスタックのもの)
出力(ステップ再生中の途中経過)
そもそも ><> とは
盤面を走り、スタックを何枚にも増やせる2次元の言語。
><>(フィッシュ)は、2009年に Harpyon が作った2次元の言語です。名前は「fish(魚)」と読み、記号の見た目が魚に似ています。esolangs.org では、Befunge などに着想を得た、スタックを使う2次元の言語として紹介されています。
プログラムは文字を並べた盤面で、左上から右へ向かって動き出す「ポインタ」が、矢印や鏡の命令で向きを変えながら進みます。盤面の端まで来ると反対側へ回り込み、; に当たるかエラーになるまで止まりません。
特徴は、スタックを何枚でも作れることです。[ で新しいスタックを作って上の数個だけを移すと、新しいスタックは元のものと切り離された作業場になります。] で消すと、中身は下のスタックへ戻ります。関数の中の変数のように使えます。
プログラム自身の文字を読み書きする g・p もあります。エラーの時の表示は、どんな間違いでも something smells fishy...(何かが怪しい匂いがする)の1つだけです。
Befunge との違い
- スタックを何枚にも増やせます(Befunge は1枚)。
- 向きを変える命令が増え、向きを曲げる鏡(
/\)があります。 - 数は 0〜9 に加えて a〜f(10〜15)を直接書け、割り算は小数のままです。
- 命令の間違いや空のスタックからの取り出しは、すべてエラーで止まります(Befunge は 0 として続けます)。
ほかの2次元の言語は Befunge の遊び場、言語の一覧は エソラング図鑑の ><> のページで見られます。
早見表
このページが対応している命令(すべて)。
| 命令 | 意味 |
|---|---|
| > < ^ v | 進む向きを 右・左・上・下 に変える |
| / \ | 鏡。ぶつかった向きに応じて曲がる(/ は 右→上・左→下・上→右・下→左、\ は 右→下・左→上・上→左・下→右) |
| | | 横向きに進んでいるときだけ向きを反対にする(縦向きのときは何もしない) |
| _ | 縦向きに進んでいるときだけ向きを反対にする(横向きのときは何もしない) |
| # | 向きを無条件で反対にする |
| x | 進む向きをランダムに変える |
| ! | 次の1マスを飛ばす(トランポリン) |
| ? | 値を1つ取り出し、0のときだけ次の1マスを飛ばす(0以外なら次を実行する) |
| . | y と x を取り出し、ポインタをそのマス (x, y) へ飛ばす。向きはそのまま。着いた次のマスから実行されるので、行きたい場所の1つ手前を指定する |
| 0〜9 a〜f | 16進数の 0〜15 をスタックに積む |
| + - * , % | 足す・引く・掛ける・割る・余り(下の値 演算 上の値)。割り算は小数のまま(9÷4 は 2.25)。0で割るとエラー |
| = | 2つが等しければ 1、違えば 0 |
| ) ( | 「)」は 下の値 > 上の値 なら 1、「(」は 下の値 < 上の値 なら 1、そうでなければ 0 |
| " ' | 文字列モードに入る。同じ引用符が来るまで、見た文字を1文字ずつ積む(空白も積む) |
| : | 一番上の値を複製する |
| ~ | 一番上の値を捨てる |
| $ | 上の2つを入れ替える |
| @ | 上の3つを右へ回す(1 2 3 4 → 1 4 2 3) |
| } { | スタック全体を右へ・左へ回す(1 2 3 4 → 4 1 2 3 / 2 3 4 1) |
| r | スタックを逆順にする |
| l | スタックの長さを積む |
| [ | 値 n を取り出し、スタックから上の n 個を移した新しいスタックを作る |
| ] | 今のスタックを消し、中身を下のスタックの上へ戻す(最後の1枚なら空にする) |
| o n | 一番上の値を 文字/数 として出力する |
| i | 標準入力から1文字を読んで積む。もう無ければ -1 を積む |
| & | レジスタが空なら値を1つ入れる。入っていればその値を積んで空に戻す(スタックごとに1つ) |
| g | y と x を取り出し、盤面の (x, y) にある文字の番号を積む(空きマスは 0) |
| p | y・x・v を取り出し、盤面の (x, y) を文字 v に書き換える |
| ; | プログラムを終了する |
| (空白) | 何もしない。これ以外の文字は「命令の間違い」でエラーになる |
サンプルの「Hello World」は、文字列を積んだあと r で逆順にし、o で1文字ずつ出しています。スタックが空になると ? が v を飛ばさず、下の行へ降りて ; に着きます。「1から10まで数える」は、行の右端から出ると同じ行の左端へ回り込む性質で、ループを作っています。
資料: esolangs.org: Fish(Hello World の例も同ページ)。 このページの実装は、命令の動きを上の資料の記述に合わせています。公式のインタプリタ(fish.py)とは次の点が違います。数は JavaScript の数値(桁数に限りあり)で、盤面は書き込み(p)で最大2000マス四方まで広がり、実行は100万命令で、出力は20万文字で止まります。標準入力は実行の前にまとめて渡す形です。送信ゼロ(入力したものはこの端末から出ません)。
このツールについて
盤面の上を、ポインタが矢印や鏡で向きを変えながら走る言語です。Befunge に近い2次元の言語ですが、スタックを何枚にも増やせる点が違います。実行して、ポインタの向きとスタックの中身をステップごとに見てみましょう。
Befunge に近い2次元の言語で、スタックを何枚にも増やせるのが特徴。実行・ステップ再生(ポインタの向きと複数のスタックを可視化)・3種のサンプルで、盤面を走る動きを確かめられます。
主な機能
- 実行とステップ再生(ポインタ・向き・複数スタック・レジスタの表示)
- 標準入力と、最初に積んでおく数を指定できる
- 全命令に対応( [ ] による複数スタックや g/p の書き換えも)
- Hello World・1から10まで数える・入力をそのまま出す、の3サンプル
- 無限ループは100万歩で止まる・送信ゼロ
よくある質問
Q. ><> はどう読みますか?
A. 「fish(フィッシュ)」と読みます。記号の並びが魚の形に見えることが名前の由来です(esolangs.org: Fish)。
Q. Befunge とどこが違いますか?
A. スタックを何枚にも増やせること、向きを曲げる鏡(/ と \)があること、割り算が小数のままであること、間違いがあるとエラーで止まることが主な違いです。
Q. エラーで「something smells fishy...」と出るのはなぜですか?
A. ><> のエラー表示は、どんな間違いでもこの1つだけです。0での割り算、空のスタックからの取り出し、存在しない命令に当たったときなどに出ます。
Q. 標準入力はどう使いますか?
A. 入力欄に書いた文字を、i 命令が1文字ずつ読みます。読み終えると -1 が積まれます。最初にスタックへ数を積んでおく欄もあり、これは公式のインタプリタが持つ「値を先に積む」機能に相当します。
Q. 公式のインタプリタと違う点はありますか?
A. 数は JavaScript の数値で、桁数に限りがあります。実行は100万歩、出力は20万文字で止まります。盤面への書き込み(p)は2000マス四方までです。命令の動き自体は esolangs.org の記述に合わせています。
入力値はURLの「#」以降に入るためサーバーには送信されません。リンクを開くと同じ状態を復元します。