ページへ戻る
印刷
HOSINO/efg01上で動くプログラムの作り方
をテンプレートにして作成 ::
OSASK計画
osaskwiki
:HOSINO/efg01上で動くプログラムの作り方 をテンプレートにして作成
開始行:
**この講座について
星野が作ったインタプリタ(ip.g01)の上で動くプログラムを作...
そのインタプリタはefg01で動くので、結局作ったアプリも(間...
ちゃんとしたチュートリアルはそのうちhideyosiさんが作られ...
また、K-tanさんも以前にGUIGUI01/memoシリーズでC言語やアセ...
インタプリタ上で動くプログラムなんか興味無い!という方はぜ...
**開発環境の作り方
efg01とip.g01を手に入れてください。~
ip.g01はhttp://osask.net/w/513.htmlから入手できます。~
後はip.g01とefg01を同じフォルダに入れておいてください。~
*efg01上で動くプログラムの作り方講座(1)
**HQ9+でプログラミング
まずはじめに、初心者向けのHQ9+という言語でのプログラミン...
***Hello, world!プログラムを作る!
古今東西、いかなるプログラミング言語であっても伝統的に入...
この講座でもその伝統に従って、最初はHello, world!と表示す...
H
上のような内容にしたテキストファイルをhello.txtという名前...
このプログラムを実行したいときは、コンソールを開いて次の...
プロンプト>efg01 ip02 file:hello.txt type:10
これで無事にHello, world!プログラムを作ることが出来ました...
もし、上のように打ち込んでもHello, world!と表示されなけれ...
もうお分かりかもしれませんが、HQ9+でHello, world!と表示す...
このように初心者に非常に分かりやすく、覚えやすい文法を採...
なお、もしHello, world!と二回表示するプログラムを作りたけ...
HH
という内容のファイルを実行させます。~
***プログラムが書いてあるファイルの中身を表示させる!
Hello, world!と表示するだけでは飽きてしまったと思いますの...
まずは、プログラムを以下に示します。~
Q
これを実行させると、確かにQと表示されます。~
HQ9+では、自分自身のファイルをオープンして内容を読み込み...
これがQという命令で、もし仮に二回HQ9+のプログラムが書かれ...
QQ
と書かれたファイルを実行します。~
これでは、「QQ」というファイルの中身を二回表示するので、~
QQ
QQ
と表示されます。~
***英語の歌の歌詞を表示させる!
これまで作ってきたプログラムはどれも実用的とは言えません...
そこで、今回は99 Bottles of Beerという英語の歌の歌詞を表...
これが有れば、何かの機会に99 Bottles of Beerを歌わないと...
では、今回のプログラムです。~
9
これを実行すると、かなり長い歌詞が表示されます。~
このように、HQ9+では9という命令を実行させることで、99 Bot...
***変数を使ってみる!
これまで見てきたように、HQ9+は非常にシンプルで覚えやすい...
この言語の特徴は変数、という物の扱いにも現れています。~
変数とは、簡単にいえば色々な物を入れておく箱の事ですが、H...
つまり、最初から0で初期化された変数が一つ用意されているわ...
この変数の値を1増加させるときには、+という命令を使います。~
+++
上のようなHQ9+プログラムは、最初から用意されている変数に1...
***色々なHQ9+プログラムを書く!
まずは、次のようなプログラムを実行させてみます。~
This is HQ9+ program !
これを実行すると、~
Hello, world!
This is HQ9+ program !
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on ...
(中略)
No more bottles of beer on the wall, no more bottles of ...
Go to the store and buy some more, 99 bottles of beer on...
と表示されます。(もしかしたら長すぎて上のほうがこうンソー...
HQ9+では、H、Q、9、+、以外の全ての文字がコメントとして無...
よって、上のプログラムは~
HQ9+
という内容とみなされて実行されます。~
勿論、HQ9+でも一つのプログラムの中で複数の種類の命令を使...
最後に、もうひとつプログラムを紹介します。~
#include<stdio.h>
void main(void){
printf("Hello,world!");
return;
}
このプログラムも、コメントの部分を無視すると以下のように...
H
よって、このプログラムはHello, world!と表示します。~
**HQ9++でプログラミング
HQ9++とは、C言語に対するC++のように、HQ9+と互換性を保ちな...
新たに++という命令が追加されています。~
この命令は、変数に2を足し、さらにオブジェクトのインスタン...
HQ9++で書かれたプログラムをip01.g01で実行するときは、~
プロンプト>efg01 ip02 file:ファイル名 type:11
とコマンドプロンプトに打ち込みます。
HQ9++
というプログラムを実行すると、~
Hello, world!
HQ9++
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on ...
(中略)
No more bottles of beer on the wall, no more bottles of ...
Go to the store and buy some more, 99 bottles of beer on...
と表示され、プログラム終了時の変数の値は2で、オブジェクト...
ただし、情報隠蔽の原理に従って、このオブジェクトへのアク...
**HQ9F+でプログラミング
HQ9F+も、HQ9+と互換性のある言語のひとつです。~
HQ9F+で書かれたプログラムをip02.g01で実行するときは、~
プロンプト>efg01 ip02 file:ファイル名 type:12
とコマンドプロンプトに打ち込みます。~
新たにFという命令が加えられています。~
この命令は、0から命令が実行された時の変数の値の数まで、一...
具体的には、~
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
F
というプログラムは、~
Fizz Buzz
1
2
Fizz
4
Buzz
(中略)
Fizz
97
98
Fizz
Buzz
と表示されます。~
また、お分かりだと思いますが、HQ9F+では、Fもコメントでは...
*efg01上で動くプログラムの作り方講座(2)
前回はHQ9+系統のプログラミング言語を使ってプログラムを作...
しかし、HQ9+は初心者用の言語なので、コンピュータが本来処...
これに対して、今回扱うBrainf*ck系統のプログラミング言語は...
最初のうちはちょっと難しく感じるかもしれませんが、頑張っ...
**Brainf*ckでプログラミング
Brainf*ckのプログラムをip02.g01で実行する際は、~
プロンプト>efg01 ip02 file:ファイル名 type:0
と打ち込みます。~
***まずはHello, world!
伝統は大切にするべきなので、いきなりですがHello, world!と...
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++. ++++++++++ ++++++++++
+++++++++. +++++++. . +++. ----------
---------- ---------- ---------- ---------- ----------
-------. ---------- --. ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +++++++. --------. +++. ------.
--------. ---------- ---------- ---------- ----------
---------- ---------- -------.
かなり意味不明だと思いますが、これから少しずつ説明します...
***Brainf*ckの基本仕様を知る!
Brainf*ckは仮想的なコンピュータの機械語、ととらえることが...
しかも、機械語としては非常に高い可読性を持っています。~
その仮想機械は一つのレジスタと、1024バイトのメモリを持っ...
(この1024という数字は星野が勝手に決めた物であり、処理系に...
レジスタもメモリも最初は0で初期化されています。~
機械語は全部で8種類あります。~
+ レジスタが指しているメモリのアドレスにある値を1増加さ...
- レジスタが指しているメモリのアドレスにある値を1減少さ...
> レジスタの値を1増加させます。
< レジスタの値を1減少させます。
[ レジスタが指しているメモリのアドレスにある値が0なら、...
] レジスタが指しているメモリのアドレスにある値が0以外な...
. レジスタが指しているメモリのアドレスにある値を、文字...
, レジスタが指しているメモリのアドレスに、入力された文...
上記以外の文字はコメントとみなされて全て無視されます。~
***Hello, world!を読み解く!
まず、先にあげたソースの解説をしようと思います。~
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++. ++++++++++ ++++++++++
+++++++++. +++++++. . +++. ----------
---------- ---------- ---------- ---------- ----------
-------. ---------- --. ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +++++++. --------. +++. ------.
--------. ---------- ---------- ---------- ----------
---------- ---------- -------.
1~2行目の3番目のブロックまででメモリの0番地の値を72にし...
この72はHの文字コードです。~
3行目の1番目のブロックまでで、メモリの0番地の値にさらに29...
(中略)~
9行目の3番目のブロックまでで、メモリの0番地の値から67を引...
ただ、このやり方はかなりカッコ悪いので、もう少し短いソー...
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++. ++++++++++ ++++++++++
+++++++++. +++++++. . +++.> ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++. ----------
--.< ++++++++. --------. +++. ------.
--------.> +.
前のソースが373文字(スペース、改行を除く)だったのに対して...
(それでもHQ9+の1文字には全然届きませんが…)~
3行目の4番目のブロックまでは前回と同じです。~
ここで、>命令が実行されています。~
これによって、レジスタはメモリの1番地をさすようになります...
メモリの1番地の値はこのとき0ですが、これを4行目の4番目の...
5行目の1番目のブロックでスペースを出力した後、レジスタの...
これで再びレジスタはメモリの0番地をさすようになり、そこに...
今度はそれをいじって文字を出力していき、最後にもう一回1番...
少しはましになりましたが、まだまだカッコイイとは言えない...
もうちょっと工夫を加えてみます。~
+++++++ [>++++++++++<-] >++.
++++++++++ ++++++++++ +++++++++. +++++++. . +++.>
++++ [>++++++++++<-] >++++.
---------- --.<<
++++++++. --------. +++. ------. --------.>>
+.
これで152文字にまで減らすことが出来ました。~
ソース自体も、[や]が加わったことでBrainf*ckらしいカッコよ...
今までは72を作るときに、1+1+1+1+(中略)+1=72と考えていまし...
この考えを捨てて、10*7+2=(1+1+1+1+1+1+1+1+1+1)*(1+1+1+1+1...
まず最初に、0番地の値を7にします。~
0番地の値は7なので[は素通りして、>でレジスタは1番地をさし...
1番地の値に10を足した後、<で0番地へもどり、1を引きます。~
それでもまだ値は6なので[へもどり、さらに1番地に10を足しま...
また、0番地の値を1減らしますが、まだ5なので[へもどります。~
これを繰り返すと、1番地の値が70になったときに0番地の値が0...
それに2を足すので72になり、無事にHが出力されます。~
2行目の最後でoを出力した後も、同じ要領で4回ループさせ、3...
それに4を足して44にし、,を出力します。~
4行目と5行目の最後が<<と>>になっているのは、2回目のループ...
最後に、Brainf*ckのカッコよさが最大限に発揮されたHello, w...
+++++++++
[>++++++++>+++++++++++>+++++<<<-]
>.
>++.+++++++..+++.
>-.------------.
<++++++++.--------.+++.------.--------.
>+.
119文字、という事は、最初のプログラムの1/3以下という事で...
簡単に解説すると、最初に0番地をカウンタにして9回ループさ...
このループで1番地が72、2番地が99、3番地が45になります。~
後は、1番地を使ってHを、2番地を使って、e、l、l、o、w、o、...
***echoプログラムを作る!
g01アプリをabcdwを使って学んだ人なら誰でも知っているecho...
とはいいつつも、ものすごく簡単なので説明は省きます。~
+[>,.<]
これさえあれば、一時的にコンソールにメモをすることが出来...
***charsプログラムを作る!
同じくabcdwでおなじみのcharsプログラムです。~
0x20~0x7eの文字コードを持つ文字を出力させます。~
これも、最終段階のHello, world!が理解できた人なら難なく理...
+++++++++
[>++++++++++>++++<<-]
>+++++
>----<
[>.+<-]
色々と最適化の余地があるので、考えてみてください。~
***1~10の合計を数える!
K-tanさんがGUIGUI01/memoシリーズで作ったプログラムの一つ...
++++++++++ +++++++++ ++++++++ +++++++ ++++++
+++++ ++++ +++ ++ +
.
これは誰でも思いつくと思います。~
これを実行すると、7と表示されます。7の文字コードは55なの...
しかし、この方法だと55回+を打ち込まないとこのプログラムは...
それはBrainf*ck的には勿論のこと、一般常識に照らし合わせて...
++++++++++
[[>+>+<<-]>-[<+>-]<]
>>.
ちょっと複雑なループですが、要は1~10の合計を数えさせてい...
さきほどのプログラムに比べればだいぶ良くなりましたが、答...
しかし、Brainf*ckで55と表示させるのはかなり難しいので、1...
ただ、文字コードを全て暗記している人にとっては、わざわざ1...
++++++++++
[[>+>+<<-]>-[<+>-]<]
>>.
>++++++++++.++++++++++++++++++++++.---------------------...
[>+>+++++++<<-]
<
[>>?>.<<<-]
>++++++++++.
>>>>+++++
[>++++++++++>++++++<<-]
>--
>++
>++++++++++
[><<<.+>>>+++++++++[><<<.>>><-]<-]
かなり汚いプログラムですいません。~
書いているときは全く問題なかったのですが、今改めて見ると...
しかし、それがBrainf*ckの醍醐味だと思うので気にしないこと...
なお、プログラム中の?を.に変えれば、一部のOSでは1~10の合...
うるさくしても問題ない環境で試してみてください。~
最後に、これまでの集大成として、1~10の合計を文字コードと...
これでいきなり7と表示されても戸惑う事が少なくなるはずです...
++++++++++
[>++++++>++++++++>++++++++++>+++++++++++<<<<-]
>+++++.>+++.<++.++++++..>>-.>+.<+.+.>>
++++++++++
[[>+>+<<-]>-[<+>-]<]
>>.
>++++++++++.++++++++++++++++++++++.---------------------...
[>+>+++++++<<-]
<
[>>?>.<<<-]
>++++++++++.
>>>>+++++
[>++++++++++>++++++<<-]
>--
>++
>++++++++++
[><<<.+>>>+++++++++[><<<.>>><-]<-]
?を.に変えると音が鳴るのは今回も変わりません。~
このレベルのプログラムが問題なく読めて、作れるようであれ...
**MONAmonaでプログラミング
MONAmonaはBrainf*ck系統の言語です。~
ip02.g01でMONAmonaで書かれたプログラムを実行するには、~
プロンプト>efg01 ip02 file:ファイル名 type:1
と入力します。~
MONAmonaでは>、<、+、-、,、.、[、]、がそれぞれM、O、N、A...
つまり、~
M ポインタを1進める
O ポインタを1戻す
N ポインタの指す所の値を1増やす
A ポインタの指す所の値を1減らす
m ポインタの指す所へ値を入力
o ポインタの指す所の値を出力
n ポインタの指す所の値が0だったら対応するaまでジャンプ
a ポインタの指す所の値が0でなかったら対応するnまでジャンプ
となります。~
MONAmonaでは、M、O、N、A、m、o、n、a、以外の文字は全てコ...
以下に、MONAmonaでのHello, world!を示します。~
NNNNNNNNN +++++++++
nMNNNNNNNNMNNNNNNNNNNNMNNNNNOOOAa [>++++++++>++++...
Mo >.
MNNoNNNNNNNooNNNo >++.+++++++..+++.
MAoAAAAAAAAAAAAo >-.------------.
ONNNNNNNNoAAAAAAAAoNNNoAAAAAAoAAAAAAAAo <++++++++.-----...
MNo >+.
勿論右側は無視されます。~
**BrainCrashでプログラミング
BrainCrashはBrainf*ckを拡張した言語です。~
新たにビット演算を行う命令が加えられました。~
また、0バイトでHello, world!プログラムが書ける言語として...
ip02.g01でBrainCrashで書かれたプログラムを実行するには、~
プロンプト>efg01 ip02 file:ファイル名 type:2
と入力します。~
以下に、BrainCrashの追加機能を示します。~
追加命令~
| レジスタが指しているメモリのアドレスにある値と、その...
レジスタが指しているアドレスの次のアドレスに値を入れ...
また、レジスタの値は一つ進められます。
& レジスタが指しているメモリのアドレスにある値と、その...
レジスタが指しているアドレスの次のアドレスに値を入れ...
また、レジスタの値は一つ進められます。
~ レジスタが指しているメモリのアドレスにある値をビット...
レジスタの値は変化しません。
^ レジスタが指しているメモリのアドレスにある値と、その...
レジスタが指しているアドレスの次のアドレスに値を入れ...
また、レジスタの値は一つ進められます。
開始、終了時の挙動~
処理開始時、メモリにはHello, world!に相当する72,101,108,...
終了時、現在レジスタが指し示すアドレスの値が0になるまで...
よって、BrainCrashでHello, worldを書くと、以下のようにな...
Let us write Hello world !
何かしら英文が書かれていますが、全部コメントなので無視さ...
これを実行すると、まずメモリにHello, world!に当たる文字コ...
そして、プログラムが何も書かれていないので、このまま終了...
!に当たる33を出力し、レジスタの値が1増加すると、レジスタ...
BrainCrashのインタプリタでBrainf*ckのプログラムを動かす際...
[>]
Brainf*ckのプログラム
[>]
とします。~
ただし、ip.g01ではtypeの値を0にすればBrainf*ckのプログラ...
*efg01上で動くプログラムの作り方講座(3)
前回までは、難解プログラミング言語と呼ばれる言語でプログ...
やはりそれらの言語では実用性が高いとは言えません。~
今回扱うeasy Forthは立派な実用言語であるForthを少し変更を...
これでip.g01でのプログラミングもかなり楽になるはずです。~
ちなみに、easy Forthの「easy」は処理系にとって処理しやす...
Forth自体が十分簡単な言語ですので、お間違えの無いように。~
**easy Forthでプログラミング
ip02.g01でeasy Forthのプログラムを実行するには~
プロンプト>efg01 ip02 file:ファイル名 type:20
と入力します。~
***基本はHello, world!!
今回もHello, world!と表示するプログラムから解説していきま...
: main
"!" "d" "l" "r" "o" "w" " " "," "o" "l" "l" "e" "H"
PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT
;
以上を実行すると、Hello, world!と表示されます。~
easy Forthでは、プログラムはワードと呼ばれる物の集まりで...
このプログラムでは「:」「main」「"!"」「PUT」「;」などが...
ワードとワードの間は一つ以上のスペースか改行で区切られて...
最初の「:」というワードは新たに自分でワードを定義すること...
このように、easy Forthでは、最初から定義されているワード...
「:」の次にワードが新たに定義するワードの名前となり、「;...
ここでは、mainというワードを定義していますが、インタプリ...
そのため、easy Forthでは、必ずmainというワードを定義する...
さて、ワードの中身ですが、二行目に"!"、"d"、"l"…というワ...
easy Forthでは、スタックと呼ばれる靴下のような物を使って...
つまり、二行目が終わった段階で靴下の中身は以下のようにな...
(左側が靴下の口です。)~
------------------------------+
H e l l o , w o r l d ! |
------------------------------+
Hello, world!を逆の順番でスタックに入れていったので、スタ...
三行目のPUTというワードは、スタックから一つデータを取り出...
勿論靴下は物を入れたり出したりする穴は一つしかないので、...
このようにして、mainはHello, world!を出力するワードとして...
しかし、いちいちこんな書き方をしていたのでは、めんどくさ...
以下に、ちょっとめんどくさくなくなったHello, world!を示し...
: main "!dlrow ,olleH" PUT PUT PUT PUT PUT PUT PUT PUT P...
PUTの連続がカッコ悪いのは変わりませんが、だいぶんまともに...
easy Forthでは、もし"と"の間の文字が二つ以上なら、一つ一...
そのため、最初の"!dlrow ,olleH"は"!" "d" "l" "r" "o" "w" ...
つぎに、PUTの連続を何とかしたいと思います。~
: main 0 "!dlrow ,olleH" print ;
: print BGN DUP WHL PUT RPT DRP ;
mainの次に、0というワードが有ります。~
これは、スタックに0を積むワードです。~
また、"!dlrow ,olleH"の次にprintというワードが有ります。~
これは、最初から定義されているワードではなく、二行目で定...
ここで、処理が二行目に移ります。~
二行目では、C言語で言うところのwhile文が使われています。~
easy Forthでの繰り返し処理は、以下のように書きます。~
BGN ワード列(1) WHL ワード列(2) RPT
まず、ワード列(1)が実行されて、WHLに到達した時点でスタッ...
そのデータが0ならRPTの次まで処理をジャンプします。~
そのデータが0以外ならばワード列(2)を実行し、BGNに戻り、以...
今回ワード列(1)のところにあるのはDUPだけです。~
このDUPはスタックから一つデータを取り出し、それを二回スタ...
つまり、スタックの一番上のデータを複製します。~
最後のDRPは、スタックから一つデータを取り出し、それを捨て...
では、print全体の処理を見てみます。~
まず最初にワード列(1)のDUPで、スタックの一番上にあるHが複...
次にWHLで複製されたHが取り出されます。~
Hの文字コードは72なので、0以外である為、ワード列(2)のPUT...
PUTは、スタックからHを取り出し、表示します。~
もう一度BGNの次のDUPが行われてeが複製され、0以外なので、...
これを繰り返して、!まで無事表示されます。~
!を表示してBGNに戻ると、DUPで今度は0が複製されます。~
そして、WHLで0が取り出され、0なのでPUTを行わずにRPTの次へ...
スタックの中に残った0をDRPで掃除します。~
次は、ワードの定義が終了した事を示す;が有るので、printワ...
これでだいぶんカッコ良くなりましたが、Hello, world!が逆向...
: main 0 "Hello, world!" print ;
: print invert BGN DUP WHL PUT RPT DRP ;
: invert
VAR pointer VAR256 words
0 pointer !
256 BGN DUP WHL
1 - DUP words + 0 SWP !
RPT DRP
BGN DUP WHL
words pointer @ + !
pointer @ 1 + pointer !
RPT
0 words pointer @ + !
0 pointer !
BGN words pointer @ + @ WHL
words pointer @ + @
pointer @ 1 + pointer !
RPT
;
とりあえず、Hello, world!は正しい向きになりました。~
色々と新しいワードが出ていますが、これを今説明するのは難...
とりあえずこれで、printとinvertをきちんと定義すれば、0 "...
***計算をする!
いきなりですが、easy Forthを使って計算をさせて見たいと思...
: main
0 "11 + 3 = " print 11 3 + . "\n" PUT
0 "11 - 3 = " print 11 3 - . "\n" PUT
0 "11 * 3 = " print 11 3 * . "\n" PUT
0 "11 / 3 = " print 11 3 / . "\n" PUT
0 "11 % 3 = " print 11 3 % . "\n" PUT
;
: print invert BGN DUP WHL PUT RPT DRP ;
: invert VAR pointer VAR256 words 0 pointer ! 256 BGN DU...
BGN DUP WHL words pointer @ + ! pointer @ 1 + pointer ...
BGN words pointer @ + @ WHL words pointer @ + @ pointe...
これを実行すると、11+3、11-3、11*3、11/3、11%3の結果がそ...
(*は掛け算、/は小数点以下切り捨ての割り算、%は割り算の余...
まず、0 "11 + 3 = " printのところは前回までの内容なのでい...
invertの中身は今回も説明しません。もう少し待って下さい。~
2~6行目の最後の"\n" PUTはちょっと変に思われた方もいるか...
\nというのは改行を表す特別な文字で、この二文字で一文字と...
そのため、PUT一回で出力することが出来、これが出力されると...
さて、最後に残ったprintと"\n"の間の説明です。~
代表して、2行目で説明します。~
まず、11というワードが実行され、スタックに11が積まれます。~
次に、3というワードが実行され、スタックに3が積まれます。~
そして、+というワードでは、スタックから二つデータを取り出...
これで、11+3の答えである14がスタックに積まれるわけです。~
最後に、.というワードは、スタックから一つデータを取り出し...
ここでは、14が出力されます。~
3~6行もほぼ同じです。割る方、割られる方、引く方、引かれ...
スタックの一番上のデータで(を)、二番目のデータを(から)割...
***if文を使う!
easy Forthでは、勿論if文も使う事が出来ます。~
以下にサンプルを示します。~
: main
100 RND DUP . 0 " + " print 100 RND DUP . 0 " = " prin...
= IF 0 "That's true !" print ELS 0 "That's false !" pr...
;
: print invert BGN DUP WHL PUT RPT DRP ;
: invert VAR pointer VAR256 words 0 pointer ! 256 BGN DU...
BGN DUP WHL words pointer @ + ! pointer @ 1 + pointer ...
BGN words pointer @ + @ WHL words pointer @ + @ pointe...
これを実行すると、足し算の問題が出題されます。~
これに、正しい答えを入力してEnterを押すとThat's true !と...
では、プログラムを見ていきます。~
2行目にRNDというワードが二回出ています。~
このワードは、スタックから一つデータを取り出し、0~取り出...
今回はどちらも100が直前に積まれているので、0~99の間で、...
(ちなみに、このランダムな数の事を乱数と言います。)~
それらの数はそれぞれDUPで複製され、片方は.でそれぞれ出力...
" = "が出力された後、二つの乱数は足されています。~
そして、,というワードがきます。~
このワードは、このプログラムを実行している人に数字を入力...
Enterで入力を終了します。~
数字以外はもちろん入力できず、入力された物は数字として処...
今回はこのワードで、それまでに表示した足し算の式の答えを...
2行目が終わった時点で、スタックの中には、一番上に入力して...
3行目では、いきなり=というワードが実行されます。~
このワードはスタックから値を二つ取り出し、その二つの値が...
ここでは、足し算の答えと入力された答えが同じなら1が、違え...
そしてついにIFです。~
easy Forthでは、IFというワードは以下のように使います。~
IF ワード列(1) ELS ワード列(2) THN
IFというワードが実行されるとスタックからデータが一つ取り...
もし、値が0の時何もしないのであれば、~
IF ワード列(1) THN
とすることもできます。~
今回は、答えが正解ならワード列(1)が、不正解ならワード列(2...
最後に、=と似たような意味を持つワード群を書いておきます。~
= スタックの1番目のデータが2番目のデータと等しければ1...
< スタックの1番目のデータが2番目のデータより小さければ...
> スタックの1番目のデータが2番目のデータより大きければ...
<= スタックの1番目のデータが2番目のデータより小さいか等...
>= スタックの1番目のデータが2番目のデータより大きいか等...
<> スタックの1番目のデータが2番目のデータと等しくなけれ...
***変数を使う!
~
~
~
~
''工事中!''~
終了行:
**この講座について
星野が作ったインタプリタ(ip.g01)の上で動くプログラムを作...
そのインタプリタはefg01で動くので、結局作ったアプリも(間...
ちゃんとしたチュートリアルはそのうちhideyosiさんが作られ...
また、K-tanさんも以前にGUIGUI01/memoシリーズでC言語やアセ...
インタプリタ上で動くプログラムなんか興味無い!という方はぜ...
**開発環境の作り方
efg01とip.g01を手に入れてください。~
ip.g01はhttp://osask.net/w/513.htmlから入手できます。~
後はip.g01とefg01を同じフォルダに入れておいてください。~
*efg01上で動くプログラムの作り方講座(1)
**HQ9+でプログラミング
まずはじめに、初心者向けのHQ9+という言語でのプログラミン...
***Hello, world!プログラムを作る!
古今東西、いかなるプログラミング言語であっても伝統的に入...
この講座でもその伝統に従って、最初はHello, world!と表示す...
H
上のような内容にしたテキストファイルをhello.txtという名前...
このプログラムを実行したいときは、コンソールを開いて次の...
プロンプト>efg01 ip02 file:hello.txt type:10
これで無事にHello, world!プログラムを作ることが出来ました...
もし、上のように打ち込んでもHello, world!と表示されなけれ...
もうお分かりかもしれませんが、HQ9+でHello, world!と表示す...
このように初心者に非常に分かりやすく、覚えやすい文法を採...
なお、もしHello, world!と二回表示するプログラムを作りたけ...
HH
という内容のファイルを実行させます。~
***プログラムが書いてあるファイルの中身を表示させる!
Hello, world!と表示するだけでは飽きてしまったと思いますの...
まずは、プログラムを以下に示します。~
Q
これを実行させると、確かにQと表示されます。~
HQ9+では、自分自身のファイルをオープンして内容を読み込み...
これがQという命令で、もし仮に二回HQ9+のプログラムが書かれ...
QQ
と書かれたファイルを実行します。~
これでは、「QQ」というファイルの中身を二回表示するので、~
QQ
QQ
と表示されます。~
***英語の歌の歌詞を表示させる!
これまで作ってきたプログラムはどれも実用的とは言えません...
そこで、今回は99 Bottles of Beerという英語の歌の歌詞を表...
これが有れば、何かの機会に99 Bottles of Beerを歌わないと...
では、今回のプログラムです。~
9
これを実行すると、かなり長い歌詞が表示されます。~
このように、HQ9+では9という命令を実行させることで、99 Bot...
***変数を使ってみる!
これまで見てきたように、HQ9+は非常にシンプルで覚えやすい...
この言語の特徴は変数、という物の扱いにも現れています。~
変数とは、簡単にいえば色々な物を入れておく箱の事ですが、H...
つまり、最初から0で初期化された変数が一つ用意されているわ...
この変数の値を1増加させるときには、+という命令を使います。~
+++
上のようなHQ9+プログラムは、最初から用意されている変数に1...
***色々なHQ9+プログラムを書く!
まずは、次のようなプログラムを実行させてみます。~
This is HQ9+ program !
これを実行すると、~
Hello, world!
This is HQ9+ program !
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on ...
(中略)
No more bottles of beer on the wall, no more bottles of ...
Go to the store and buy some more, 99 bottles of beer on...
と表示されます。(もしかしたら長すぎて上のほうがこうンソー...
HQ9+では、H、Q、9、+、以外の全ての文字がコメントとして無...
よって、上のプログラムは~
HQ9+
という内容とみなされて実行されます。~
勿論、HQ9+でも一つのプログラムの中で複数の種類の命令を使...
最後に、もうひとつプログラムを紹介します。~
#include<stdio.h>
void main(void){
printf("Hello,world!");
return;
}
このプログラムも、コメントの部分を無視すると以下のように...
H
よって、このプログラムはHello, world!と表示します。~
**HQ9++でプログラミング
HQ9++とは、C言語に対するC++のように、HQ9+と互換性を保ちな...
新たに++という命令が追加されています。~
この命令は、変数に2を足し、さらにオブジェクトのインスタン...
HQ9++で書かれたプログラムをip01.g01で実行するときは、~
プロンプト>efg01 ip02 file:ファイル名 type:11
とコマンドプロンプトに打ち込みます。
HQ9++
というプログラムを実行すると、~
Hello, world!
HQ9++
99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on ...
(中略)
No more bottles of beer on the wall, no more bottles of ...
Go to the store and buy some more, 99 bottles of beer on...
と表示され、プログラム終了時の変数の値は2で、オブジェクト...
ただし、情報隠蔽の原理に従って、このオブジェクトへのアク...
**HQ9F+でプログラミング
HQ9F+も、HQ9+と互換性のある言語のひとつです。~
HQ9F+で書かれたプログラムをip02.g01で実行するときは、~
プロンプト>efg01 ip02 file:ファイル名 type:12
とコマンドプロンプトに打ち込みます。~
新たにFという命令が加えられています。~
この命令は、0から命令が実行された時の変数の値の数まで、一...
具体的には、~
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
F
というプログラムは、~
Fizz Buzz
1
2
Fizz
4
Buzz
(中略)
Fizz
97
98
Fizz
Buzz
と表示されます。~
また、お分かりだと思いますが、HQ9F+では、Fもコメントでは...
*efg01上で動くプログラムの作り方講座(2)
前回はHQ9+系統のプログラミング言語を使ってプログラムを作...
しかし、HQ9+は初心者用の言語なので、コンピュータが本来処...
これに対して、今回扱うBrainf*ck系統のプログラミング言語は...
最初のうちはちょっと難しく感じるかもしれませんが、頑張っ...
**Brainf*ckでプログラミング
Brainf*ckのプログラムをip02.g01で実行する際は、~
プロンプト>efg01 ip02 file:ファイル名 type:0
と打ち込みます。~
***まずはHello, world!
伝統は大切にするべきなので、いきなりですがHello, world!と...
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++. ++++++++++ ++++++++++
+++++++++. +++++++. . +++. ----------
---------- ---------- ---------- ---------- ----------
-------. ---------- --. ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +++++++. --------. +++. ------.
--------. ---------- ---------- ---------- ----------
---------- ---------- -------.
かなり意味不明だと思いますが、これから少しずつ説明します...
***Brainf*ckの基本仕様を知る!
Brainf*ckは仮想的なコンピュータの機械語、ととらえることが...
しかも、機械語としては非常に高い可読性を持っています。~
その仮想機械は一つのレジスタと、1024バイトのメモリを持っ...
(この1024という数字は星野が勝手に決めた物であり、処理系に...
レジスタもメモリも最初は0で初期化されています。~
機械語は全部で8種類あります。~
+ レジスタが指しているメモリのアドレスにある値を1増加さ...
- レジスタが指しているメモリのアドレスにある値を1減少さ...
> レジスタの値を1増加させます。
< レジスタの値を1減少させます。
[ レジスタが指しているメモリのアドレスにある値が0なら、...
] レジスタが指しているメモリのアドレスにある値が0以外な...
. レジスタが指しているメモリのアドレスにある値を、文字...
, レジスタが指しているメモリのアドレスに、入力された文...
上記以外の文字はコメントとみなされて全て無視されます。~
***Hello, world!を読み解く!
まず、先にあげたソースの解説をしようと思います。~
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++. ++++++++++ ++++++++++
+++++++++. +++++++. . +++. ----------
---------- ---------- ---------- ---------- ----------
-------. ---------- --. ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +++++++. --------. +++. ------.
--------. ---------- ---------- ---------- ----------
---------- ---------- -------.
1~2行目の3番目のブロックまででメモリの0番地の値を72にし...
この72はHの文字コードです。~
3行目の1番目のブロックまでで、メモリの0番地の値にさらに29...
(中略)~
9行目の3番目のブロックまでで、メモリの0番地の値から67を引...
ただ、このやり方はかなりカッコ悪いので、もう少し短いソー...
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++. ++++++++++ ++++++++++
+++++++++. +++++++. . +++.> ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++. ----------
--.< ++++++++. --------. +++. ------.
--------.> +.
前のソースが373文字(スペース、改行を除く)だったのに対して...
(それでもHQ9+の1文字には全然届きませんが…)~
3行目の4番目のブロックまでは前回と同じです。~
ここで、>命令が実行されています。~
これによって、レジスタはメモリの1番地をさすようになります...
メモリの1番地の値はこのとき0ですが、これを4行目の4番目の...
5行目の1番目のブロックでスペースを出力した後、レジスタの...
これで再びレジスタはメモリの0番地をさすようになり、そこに...
今度はそれをいじって文字を出力していき、最後にもう一回1番...
少しはましになりましたが、まだまだカッコイイとは言えない...
もうちょっと工夫を加えてみます。~
+++++++ [>++++++++++<-] >++.
++++++++++ ++++++++++ +++++++++. +++++++. . +++.>
++++ [>++++++++++<-] >++++.
---------- --.<<
++++++++. --------. +++. ------. --------.>>
+.
これで152文字にまで減らすことが出来ました。~
ソース自体も、[や]が加わったことでBrainf*ckらしいカッコよ...
今までは72を作るときに、1+1+1+1+(中略)+1=72と考えていまし...
この考えを捨てて、10*7+2=(1+1+1+1+1+1+1+1+1+1)*(1+1+1+1+1...
まず最初に、0番地の値を7にします。~
0番地の値は7なので[は素通りして、>でレジスタは1番地をさし...
1番地の値に10を足した後、<で0番地へもどり、1を引きます。~
それでもまだ値は6なので[へもどり、さらに1番地に10を足しま...
また、0番地の値を1減らしますが、まだ5なので[へもどります。~
これを繰り返すと、1番地の値が70になったときに0番地の値が0...
それに2を足すので72になり、無事にHが出力されます。~
2行目の最後でoを出力した後も、同じ要領で4回ループさせ、3...
それに4を足して44にし、,を出力します。~
4行目と5行目の最後が<<と>>になっているのは、2回目のループ...
最後に、Brainf*ckのカッコよさが最大限に発揮されたHello, w...
+++++++++
[>++++++++>+++++++++++>+++++<<<-]
>.
>++.+++++++..+++.
>-.------------.
<++++++++.--------.+++.------.--------.
>+.
119文字、という事は、最初のプログラムの1/3以下という事で...
簡単に解説すると、最初に0番地をカウンタにして9回ループさ...
このループで1番地が72、2番地が99、3番地が45になります。~
後は、1番地を使ってHを、2番地を使って、e、l、l、o、w、o、...
***echoプログラムを作る!
g01アプリをabcdwを使って学んだ人なら誰でも知っているecho...
とはいいつつも、ものすごく簡単なので説明は省きます。~
+[>,.<]
これさえあれば、一時的にコンソールにメモをすることが出来...
***charsプログラムを作る!
同じくabcdwでおなじみのcharsプログラムです。~
0x20~0x7eの文字コードを持つ文字を出力させます。~
これも、最終段階のHello, world!が理解できた人なら難なく理...
+++++++++
[>++++++++++>++++<<-]
>+++++
>----<
[>.+<-]
色々と最適化の余地があるので、考えてみてください。~
***1~10の合計を数える!
K-tanさんがGUIGUI01/memoシリーズで作ったプログラムの一つ...
++++++++++ +++++++++ ++++++++ +++++++ ++++++
+++++ ++++ +++ ++ +
.
これは誰でも思いつくと思います。~
これを実行すると、7と表示されます。7の文字コードは55なの...
しかし、この方法だと55回+を打ち込まないとこのプログラムは...
それはBrainf*ck的には勿論のこと、一般常識に照らし合わせて...
++++++++++
[[>+>+<<-]>-[<+>-]<]
>>.
ちょっと複雑なループですが、要は1~10の合計を数えさせてい...
さきほどのプログラムに比べればだいぶ良くなりましたが、答...
しかし、Brainf*ckで55と表示させるのはかなり難しいので、1...
ただ、文字コードを全て暗記している人にとっては、わざわざ1...
++++++++++
[[>+>+<<-]>-[<+>-]<]
>>.
>++++++++++.++++++++++++++++++++++.---------------------...
[>+>+++++++<<-]
<
[>>?>.<<<-]
>++++++++++.
>>>>+++++
[>++++++++++>++++++<<-]
>--
>++
>++++++++++
[><<<.+>>>+++++++++[><<<.>>><-]<-]
かなり汚いプログラムですいません。~
書いているときは全く問題なかったのですが、今改めて見ると...
しかし、それがBrainf*ckの醍醐味だと思うので気にしないこと...
なお、プログラム中の?を.に変えれば、一部のOSでは1~10の合...
うるさくしても問題ない環境で試してみてください。~
最後に、これまでの集大成として、1~10の合計を文字コードと...
これでいきなり7と表示されても戸惑う事が少なくなるはずです...
++++++++++
[>++++++>++++++++>++++++++++>+++++++++++<<<<-]
>+++++.>+++.<++.++++++..>>-.>+.<+.+.>>
++++++++++
[[>+>+<<-]>-[<+>-]<]
>>.
>++++++++++.++++++++++++++++++++++.---------------------...
[>+>+++++++<<-]
<
[>>?>.<<<-]
>++++++++++.
>>>>+++++
[>++++++++++>++++++<<-]
>--
>++
>++++++++++
[><<<.+>>>+++++++++[><<<.>>><-]<-]
?を.に変えると音が鳴るのは今回も変わりません。~
このレベルのプログラムが問題なく読めて、作れるようであれ...
**MONAmonaでプログラミング
MONAmonaはBrainf*ck系統の言語です。~
ip02.g01でMONAmonaで書かれたプログラムを実行するには、~
プロンプト>efg01 ip02 file:ファイル名 type:1
と入力します。~
MONAmonaでは>、<、+、-、,、.、[、]、がそれぞれM、O、N、A...
つまり、~
M ポインタを1進める
O ポインタを1戻す
N ポインタの指す所の値を1増やす
A ポインタの指す所の値を1減らす
m ポインタの指す所へ値を入力
o ポインタの指す所の値を出力
n ポインタの指す所の値が0だったら対応するaまでジャンプ
a ポインタの指す所の値が0でなかったら対応するnまでジャンプ
となります。~
MONAmonaでは、M、O、N、A、m、o、n、a、以外の文字は全てコ...
以下に、MONAmonaでのHello, world!を示します。~
NNNNNNNNN +++++++++
nMNNNNNNNNMNNNNNNNNNNNMNNNNNOOOAa [>++++++++>++++...
Mo >.
MNNoNNNNNNNooNNNo >++.+++++++..+++.
MAoAAAAAAAAAAAAo >-.------------.
ONNNNNNNNoAAAAAAAAoNNNoAAAAAAoAAAAAAAAo <++++++++.-----...
MNo >+.
勿論右側は無視されます。~
**BrainCrashでプログラミング
BrainCrashはBrainf*ckを拡張した言語です。~
新たにビット演算を行う命令が加えられました。~
また、0バイトでHello, world!プログラムが書ける言語として...
ip02.g01でBrainCrashで書かれたプログラムを実行するには、~
プロンプト>efg01 ip02 file:ファイル名 type:2
と入力します。~
以下に、BrainCrashの追加機能を示します。~
追加命令~
| レジスタが指しているメモリのアドレスにある値と、その...
レジスタが指しているアドレスの次のアドレスに値を入れ...
また、レジスタの値は一つ進められます。
& レジスタが指しているメモリのアドレスにある値と、その...
レジスタが指しているアドレスの次のアドレスに値を入れ...
また、レジスタの値は一つ進められます。
~ レジスタが指しているメモリのアドレスにある値をビット...
レジスタの値は変化しません。
^ レジスタが指しているメモリのアドレスにある値と、その...
レジスタが指しているアドレスの次のアドレスに値を入れ...
また、レジスタの値は一つ進められます。
開始、終了時の挙動~
処理開始時、メモリにはHello, world!に相当する72,101,108,...
終了時、現在レジスタが指し示すアドレスの値が0になるまで...
よって、BrainCrashでHello, worldを書くと、以下のようにな...
Let us write Hello world !
何かしら英文が書かれていますが、全部コメントなので無視さ...
これを実行すると、まずメモリにHello, world!に当たる文字コ...
そして、プログラムが何も書かれていないので、このまま終了...
!に当たる33を出力し、レジスタの値が1増加すると、レジスタ...
BrainCrashのインタプリタでBrainf*ckのプログラムを動かす際...
[>]
Brainf*ckのプログラム
[>]
とします。~
ただし、ip.g01ではtypeの値を0にすればBrainf*ckのプログラ...
*efg01上で動くプログラムの作り方講座(3)
前回までは、難解プログラミング言語と呼ばれる言語でプログ...
やはりそれらの言語では実用性が高いとは言えません。~
今回扱うeasy Forthは立派な実用言語であるForthを少し変更を...
これでip.g01でのプログラミングもかなり楽になるはずです。~
ちなみに、easy Forthの「easy」は処理系にとって処理しやす...
Forth自体が十分簡単な言語ですので、お間違えの無いように。~
**easy Forthでプログラミング
ip02.g01でeasy Forthのプログラムを実行するには~
プロンプト>efg01 ip02 file:ファイル名 type:20
と入力します。~
***基本はHello, world!!
今回もHello, world!と表示するプログラムから解説していきま...
: main
"!" "d" "l" "r" "o" "w" " " "," "o" "l" "l" "e" "H"
PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT PUT
;
以上を実行すると、Hello, world!と表示されます。~
easy Forthでは、プログラムはワードと呼ばれる物の集まりで...
このプログラムでは「:」「main」「"!"」「PUT」「;」などが...
ワードとワードの間は一つ以上のスペースか改行で区切られて...
最初の「:」というワードは新たに自分でワードを定義すること...
このように、easy Forthでは、最初から定義されているワード...
「:」の次にワードが新たに定義するワードの名前となり、「;...
ここでは、mainというワードを定義していますが、インタプリ...
そのため、easy Forthでは、必ずmainというワードを定義する...
さて、ワードの中身ですが、二行目に"!"、"d"、"l"…というワ...
easy Forthでは、スタックと呼ばれる靴下のような物を使って...
つまり、二行目が終わった段階で靴下の中身は以下のようにな...
(左側が靴下の口です。)~
------------------------------+
H e l l o , w o r l d ! |
------------------------------+
Hello, world!を逆の順番でスタックに入れていったので、スタ...
三行目のPUTというワードは、スタックから一つデータを取り出...
勿論靴下は物を入れたり出したりする穴は一つしかないので、...
このようにして、mainはHello, world!を出力するワードとして...
しかし、いちいちこんな書き方をしていたのでは、めんどくさ...
以下に、ちょっとめんどくさくなくなったHello, world!を示し...
: main "!dlrow ,olleH" PUT PUT PUT PUT PUT PUT PUT PUT P...
PUTの連続がカッコ悪いのは変わりませんが、だいぶんまともに...
easy Forthでは、もし"と"の間の文字が二つ以上なら、一つ一...
そのため、最初の"!dlrow ,olleH"は"!" "d" "l" "r" "o" "w" ...
つぎに、PUTの連続を何とかしたいと思います。~
: main 0 "!dlrow ,olleH" print ;
: print BGN DUP WHL PUT RPT DRP ;
mainの次に、0というワードが有ります。~
これは、スタックに0を積むワードです。~
また、"!dlrow ,olleH"の次にprintというワードが有ります。~
これは、最初から定義されているワードではなく、二行目で定...
ここで、処理が二行目に移ります。~
二行目では、C言語で言うところのwhile文が使われています。~
easy Forthでの繰り返し処理は、以下のように書きます。~
BGN ワード列(1) WHL ワード列(2) RPT
まず、ワード列(1)が実行されて、WHLに到達した時点でスタッ...
そのデータが0ならRPTの次まで処理をジャンプします。~
そのデータが0以外ならばワード列(2)を実行し、BGNに戻り、以...
今回ワード列(1)のところにあるのはDUPだけです。~
このDUPはスタックから一つデータを取り出し、それを二回スタ...
つまり、スタックの一番上のデータを複製します。~
最後のDRPは、スタックから一つデータを取り出し、それを捨て...
では、print全体の処理を見てみます。~
まず最初にワード列(1)のDUPで、スタックの一番上にあるHが複...
次にWHLで複製されたHが取り出されます。~
Hの文字コードは72なので、0以外である為、ワード列(2)のPUT...
PUTは、スタックからHを取り出し、表示します。~
もう一度BGNの次のDUPが行われてeが複製され、0以外なので、...
これを繰り返して、!まで無事表示されます。~
!を表示してBGNに戻ると、DUPで今度は0が複製されます。~
そして、WHLで0が取り出され、0なのでPUTを行わずにRPTの次へ...
スタックの中に残った0をDRPで掃除します。~
次は、ワードの定義が終了した事を示す;が有るので、printワ...
これでだいぶんカッコ良くなりましたが、Hello, world!が逆向...
: main 0 "Hello, world!" print ;
: print invert BGN DUP WHL PUT RPT DRP ;
: invert
VAR pointer VAR256 words
0 pointer !
256 BGN DUP WHL
1 - DUP words + 0 SWP !
RPT DRP
BGN DUP WHL
words pointer @ + !
pointer @ 1 + pointer !
RPT
0 words pointer @ + !
0 pointer !
BGN words pointer @ + @ WHL
words pointer @ + @
pointer @ 1 + pointer !
RPT
;
とりあえず、Hello, world!は正しい向きになりました。~
色々と新しいワードが出ていますが、これを今説明するのは難...
とりあえずこれで、printとinvertをきちんと定義すれば、0 "...
***計算をする!
いきなりですが、easy Forthを使って計算をさせて見たいと思...
: main
0 "11 + 3 = " print 11 3 + . "\n" PUT
0 "11 - 3 = " print 11 3 - . "\n" PUT
0 "11 * 3 = " print 11 3 * . "\n" PUT
0 "11 / 3 = " print 11 3 / . "\n" PUT
0 "11 % 3 = " print 11 3 % . "\n" PUT
;
: print invert BGN DUP WHL PUT RPT DRP ;
: invert VAR pointer VAR256 words 0 pointer ! 256 BGN DU...
BGN DUP WHL words pointer @ + ! pointer @ 1 + pointer ...
BGN words pointer @ + @ WHL words pointer @ + @ pointe...
これを実行すると、11+3、11-3、11*3、11/3、11%3の結果がそ...
(*は掛け算、/は小数点以下切り捨ての割り算、%は割り算の余...
まず、0 "11 + 3 = " printのところは前回までの内容なのでい...
invertの中身は今回も説明しません。もう少し待って下さい。~
2~6行目の最後の"\n" PUTはちょっと変に思われた方もいるか...
\nというのは改行を表す特別な文字で、この二文字で一文字と...
そのため、PUT一回で出力することが出来、これが出力されると...
さて、最後に残ったprintと"\n"の間の説明です。~
代表して、2行目で説明します。~
まず、11というワードが実行され、スタックに11が積まれます。~
次に、3というワードが実行され、スタックに3が積まれます。~
そして、+というワードでは、スタックから二つデータを取り出...
これで、11+3の答えである14がスタックに積まれるわけです。~
最後に、.というワードは、スタックから一つデータを取り出し...
ここでは、14が出力されます。~
3~6行もほぼ同じです。割る方、割られる方、引く方、引かれ...
スタックの一番上のデータで(を)、二番目のデータを(から)割...
***if文を使う!
easy Forthでは、勿論if文も使う事が出来ます。~
以下にサンプルを示します。~
: main
100 RND DUP . 0 " + " print 100 RND DUP . 0 " = " prin...
= IF 0 "That's true !" print ELS 0 "That's false !" pr...
;
: print invert BGN DUP WHL PUT RPT DRP ;
: invert VAR pointer VAR256 words 0 pointer ! 256 BGN DU...
BGN DUP WHL words pointer @ + ! pointer @ 1 + pointer ...
BGN words pointer @ + @ WHL words pointer @ + @ pointe...
これを実行すると、足し算の問題が出題されます。~
これに、正しい答えを入力してEnterを押すとThat's true !と...
では、プログラムを見ていきます。~
2行目にRNDというワードが二回出ています。~
このワードは、スタックから一つデータを取り出し、0~取り出...
今回はどちらも100が直前に積まれているので、0~99の間で、...
(ちなみに、このランダムな数の事を乱数と言います。)~
それらの数はそれぞれDUPで複製され、片方は.でそれぞれ出力...
" = "が出力された後、二つの乱数は足されています。~
そして、,というワードがきます。~
このワードは、このプログラムを実行している人に数字を入力...
Enterで入力を終了します。~
数字以外はもちろん入力できず、入力された物は数字として処...
今回はこのワードで、それまでに表示した足し算の式の答えを...
2行目が終わった時点で、スタックの中には、一番上に入力して...
3行目では、いきなり=というワードが実行されます。~
このワードはスタックから値を二つ取り出し、その二つの値が...
ここでは、足し算の答えと入力された答えが同じなら1が、違え...
そしてついにIFです。~
easy Forthでは、IFというワードは以下のように使います。~
IF ワード列(1) ELS ワード列(2) THN
IFというワードが実行されるとスタックからデータが一つ取り...
もし、値が0の時何もしないのであれば、~
IF ワード列(1) THN
とすることもできます。~
今回は、答えが正解ならワード列(1)が、不正解ならワード列(2...
最後に、=と似たような意味を持つワード群を書いておきます。~
= スタックの1番目のデータが2番目のデータと等しければ1...
< スタックの1番目のデータが2番目のデータより小さければ...
> スタックの1番目のデータが2番目のデータより大きければ...
<= スタックの1番目のデータが2番目のデータより小さいか等...
>= スタックの1番目のデータが2番目のデータより大きいか等...
<> スタックの1番目のデータが2番目のデータと等しくなけれ...
***変数を使う!
~
~
~
~
''工事中!''~
ページ名: