もとのドキュメントのアドレスはhttp://catseye.mine.nu:8080/projects/befunge93/doc/befunge93.html
訳の間違い等があったらよろしく ina_job@hotmail.com
トップへ

Befunge-93 Documentation


伝統的なBrainf*ckやFalse言語の伝統をひん曲げてひねって作られた言語である

Translated by INA,May,2005

Chris Pressey, Cat's Eye Technologies
Original document September, 1993
Updated December, 1996
Updated Yet Again September, 2004

Befunge-93の基本

Befunge-93プログラミング特有の要素はそのプログラムカウンタにある(以下これをPCと表記する)。大抵のプログラミング言語においてPCは前に進み続け、時として他の場所にジャンプするといった物である。

しかしBefunge-93のPCは異なった動きをする。前に後ろに、そして左へ右へと移動するのである。Befunge-93のプログラムは80x25のASCIIテキストであり、PCの方向を変更する命令などが含まれている。通常PCは左上に位置し左から右へと向いている。

Befunge-93のどのコマンドも1文字で表現されている。(, as is the largest data unit that can be specified in the program source;Befunge-93 programs have a maximum size of 80x25 total commands and data bytes.  プログラムソースの中にデータを記録できると言いたい?)変数は存在せず、ただひとつのスタックが用意されている。Befunge-93のプログラムは自身の書き換えをすることが出来る。PCが2次元空間を動くためとても奇妙なソースを生み出すことになる。


スタック

ForthやPostScriptのようにBefunge-93はLIFOを扱える。符号付のlong integer型のスタックである。
スタックに値を載せることをPushという、そして値を取り出すことをPopと言う。0から9の数値は有効なBefunge-93の命令である、これはそれぞれの値をスタックにPushするための物である。"が出現するとstringモードとなり次の"に位置するまでセルに存在する文字のASCIIコードをスタックにPushする。

簡単な演算子

+ 加算
- 減算
/ 整数除算
* 積算
% 剰余
! 論理否定

これらはCommandセクションで詳細な解説を行う

9より大きい値をスタックに入れるには9以下の値を演算しなければならない。他の言語においてはこれは致命的な欠陥ある。Befunge-93においてはこれは喜びである。例えば123をスタックに入れたい場合、9をPushする、そして9を掛け算する。(81となる)さらに7をPushし6をPushし掛け算をする(81そして41がスタックにある)そこで加算をする(123が入った!)Befunge-93では以下のようになる


99*76*+
これはもちろんPCが左端の9から始まり右向きに進んでいく物と仮定している。このプログラムの断片が全体を現しているのならばこの過程は正しい。PCは左上に位置し右向きに移動する。

メモ:もしスタックが空の時に取り出そうとするとアンダーフローはおきません。それはただ単に0がPushされるでしょう(訳注popの間違いでは?)
上手く利用してください。

プログラムカウンタ(PC)についての詳細

プログラムカウンタを制御するのは5つのコマンドである。<,>,v,^,?先頭から順に左へ、右へ下へ上へランダムの方向へ、と言う意味である
以下の例は無限ループとなる
><

これも:
>v
^<

これも:
>v>v
>^
^ <
スペースは「何もしない」、という命令である。

PCがプログラムの淵に到達する場合、つまり以下のように実行しようとした場合、

<
これによりプログラムカウンタは向かい合う反対の淵へと移動する、よってこの例もまた無限ループとなる

意思決定(条件分岐)
Befunge-93において一般的な分岐命令は_と|である、どのように分岐させるかによってこれらを使い分けるのである。どちらもスタックからひとつPopしそれが真(0で無い)かどうかを見る、そして以下のようにプログラムカウンタの方向を変える。

_ は真であれば<のように振る舞い、偽の場合は>のように振舞う。
| は真であれば^のように振る舞い、偽の場合はvのように振舞う。

Whileループはifを含む無限ループで表現できる例えば以下のようである

>_@
(このプログラムはスタックの中の0で無い値をPopして始めの0が来たところで終了する。
(@は終了命令である。)

入力
&命令は数値を標準入力からひとつ得てスタックにPushする命令である。~は標準入力からひとつASCII文字のコードをスタックにpushする命令である。

たとえば

&,
もし65と言う入力があったならばAと出力する。

~.
もしAと言う入力があったなら65と表示する。

出力
.命令は値をスタックからpopし数値として出力しスペースを付加する命令である。,はスタックの値をASCIIコードとみなし文字を出力(こっちは続けてスペースが自動的に付加される事は無い)する命令である。

例えば

665+*1-,
ASCIIコードで65のAを表示

665+*1-.
65を表示

特別な命令
#は橋渡し命令である。これは次の命令を無視するという命令である。
例えば

>123...@
これは321を表示する、しかし

>123#...@
このようにすると32としか表示されない、.がひとつ無視されたからである。賢い#の利用はとてもおもしろいコードを生みます!

:は複製コマンドです。これはスタックの先頭の要素をコピーします。これは次のようなプログラムのデモに有効です

v.<>:| @
これはスタックにある値を複製し評価して0出なければ出力します。
(訳注 謎、これは何が実行される?
ひょっとしたらこうではないか?
v.<
>:| @ (スタックの中身を0が来るまで表示し尽す)


$は値をスタックからPopするだけのコマンドです、他には何もしません

123.$.@
結果は3 1となる(2は$命令により取り出された)

\はスタックの先頭の2つの要素を入れ替える命令です

123\...@
結果は2 3 1となる

`は大きいか?コマンドです、これはスタックに入っている2つの要素を比較しもし始めよりも次の物が大きい場合は1を返します。

65`.
これは1を返す

25`.
これは0を返す

自己変更
プログラムを保持している領域を変更する命令について説明する。プログラムが記録されているPlayFieldは1つのスタックだけでは満足できない場合の補助記憶として使うことが出来ます。しかしこの領域には実行中のプログラムがあることを覚えておく必要があります。

gコマンドはplayfieldを評価する、それはスタックのy位置,x位置を取り出し(この順番でPopする)、そしてx,yに位置する物が数値の場合スタックに入れる。(命令の場合はASCIIコードがスタックに入る。)

pコマンドはplayfield中のコマンドを変更する。スタックからy,xの順に値を取り出しそしてさらにもうひとつ値を取り出す。その値が(x,y)の値となる。もし、後にプログラムがそこを実行する際はp命令によって書き込んだASCIIコードの示す命令を実行することになる。

命令の概要
命令INITIAL STACK (bot->top)結果 (STACK)
+ (加算)
- (減算)
* (積算)
/ (整数除算)
% (剰余)
! (否定)
` (より大きい)
> (右へ)
< (左へ)
^ (上へ)
v (下へ)
? (ランダムへ)
_ (水平方向if)
| (垂直方向if)
" (文字モード)
: (複製)
\ (入れ替え)
$ (取り出し)
. (取り出し出力)
, (取り出し出力)
# (橋)

g (get 値取得)
p (put 値変更)
& (数値入力)
~ (文字入力)
@ (終了)
<value1> <value2>
<value1> <value2>
<value1> <value2>
<value1> <value2>
<value1> <value2>
<value>
<value1> <value2>





<boolean value>
<boolean value>

<value>
<value1> <value2>
<value>
<value>
<value>


<x> <y>
<value> <x> <y>



<value1 + value2>
<value1 - value2>
<value1 * value2>
<value1 / value2> (nb. integer)
<value1 mod value2>
<0 if value non-zero, 1 otherwise>
<1 if value1 > value2, 0 otherwise>
PC -> right
PC -> left
PC -> up
PC -> down
PC -> right? left? up? down? ???
PC->left if <value>, else PC->right
PC->up if <value>, else PC->down
Toggles 'stringmode'
lt;value> <value>
<value2> <value1>
pops <value> but does nothing
outputs <value> as integer
outputs <value> as ASCII
'jumps' PC one farther; skips
over next command
<value at (x,y)>
puts <value> at (x,y)
<value user entered>
<character user entered>
ends program


この夢を現実に変えるのを手伝ってくれた人たち。
Special thanks to Curtis Coleman, Jason Goga, Kalyna Zazelenchuk, Shawn Vincent, Mike Veroukis, Urban Mueller, and Wouter van Oortmerssen.