空白言語WhiteSpaceとは?Rubyで実装してみた
WhiteSpaceとは?
Whitespace(ホワイトスペース)は、プログラミング言語のひとつであり、またそれを動作させるインタプリタを指している。WhitespaceはGPLにより配布されている。実用言語ではない難解プログラミング言語のひとつ。
WhiteSpaceは空白に相当する文字のみで構成されたプログラミング言語です。
上記のものは空白やタブ、改行のみで構成されていますが、WhiteSpaceの場合これもコードです。
ちなみに処理としては1から10までの文字を出力するもので、実際に実行しても正常に動作していますね。
仕様
WhiteSpaceは下記3つの要素で構成されています。
- IMP
- コマンド
- パラメーター
IMPは一言で表すなら「どんな種類の処理をしたいか指定するもの」です。処理の種類は5つあり、どのIMPを指定するかによって選べるコマンドとパラメーターも決まってきます。
スタック操作
その名の通りスタックを操作するものです。IMPは[Space]
。
IMP | コマンド | パラメーター | 詳細 |
---|---|---|---|
[space] | [Space] | 数値 | パラメーターで指定した数値をスタックに積む |
[space] | [LF][Space] | - | スタックの一番上の値を複製する |
[space] | [LF][Tab] | - | スタックの上から2つの値を入れ替える |
[space] | [LF][LF] | - | スタックの一番上の値を削除する |
演算
スタックの上に積まれてる2つのリテラルを取り出しそれらで演算を行い、結果を再びスタックに積みます。IMPは[Tab][Space]
。
IMP | コマンド | パラメーター | 詳細 |
---|---|---|---|
[Tab][Space] | [Space][Space] | – | 足し算 |
[Tab][Space] | [Space][Tab] | – | 引き算 |
[Tab][Space] | [Space][LF] | – | 掛け算 |
[Tab][Space] | [Tab][Space] | – | 割り算 |
[Tab][Space] | [Tab][Tab] | – | 剰余 |
ヒープ操作
その名の通りヒープに値を保存したり取り出したりし、変数のような扱いができます。IMPは[Tab][Tab]
。
IMP | コマンド | パラメーター | 詳細 |
---|---|---|---|
[Tab][Tab] | [Space] | - | スタックの一番上を値としその次のものをアドレスとし、ヒープ上のそのアドレスに対応する位置にその値を保存する |
[Tab][Tab] | [Tab] | - | スタックの一番上をアドレスとし、ヒープ上のそのアドレスに対応する位置にある値をスタックに積む。 |
制御命令
指定した箇所にマークをつけるたりそこにジャンプしたりすることができます。これにより繰り返しなどが実現できます。IMPは[LF]
。
IMP | コマンド | パラメーター | 詳細 |
---|---|---|---|
[LF] | [Space][Space] | ラベル | マークする |
[LF] | [Space][Tab] | ラベル | 関数を呼ぶ |
[LF] | [Space][LF] | ラベル | パラメーターで指定したマークにジャンプする |
[LF] | [Tab][Space] | ラベル | スタックの一番上が0の場合にジャンプする |
[LF] | [Tab][Tab] | ラベル | スタックの一番上が負の値の場合にジャンプする |
[LF] | [Tab][LF] | - | 関数の実行を終了し呼び出し元に戻る |
[LF] | [LF][LF] | - | プログラムを終了する |
入出力
スタックの一番上の値を取り出し出力したり、スタックからアドレスを取り出しそのアドレスの位置に入力された文字を書き込んだりします。IMPは[Tab][LF]
。
IMP | コマンド | パラメーター | 詳細 |
---|---|---|---|
[Tab][LF] | [Space][Space] | - | スタックの一番上の値に等しい文字コードに対応する文字を出力する |
[Tab][LF] | [Space][Tab] | - | スタックの一番上の数値を文字列として出力する |
[Tab][LF] | [Tab][Space] | - | 入力された文字に対応するアヒープ上のドレスの位置に、スタックの一番上の値を積む |
[Tab][LF] | [Tab][Tab] | - | 入力された数値に対応するヒープ上のアドレスの位置に、スタックの一番上の値を積む |
大まかな概要はこんな感じ。詳細は公式のチュートリアルをご参照ください。
WhiteSpaceをRubyで実装してみる
1. 字句解析
まず字句解析をします。scan
メソッドはStringScanner
クラスのもので、eos?
メソッドを使ってトークンが最後尾まで達したかを判定しています。
2. 構文解析
そして構文解析。変数pc
はマークする際やジャンプする際に使用するカウンターのようなものです。
次にIMPそれぞれの操作を書いていきます。
3. スタック操作
4. 演算
5. ヒープ操作
6. 制御命令
7. 入出力
これでIMPそれぞれの処理は書けました。あとはtokenize
とevaluate
を呼び出してあげるだけです。
これで完成です 🎉