WhiteSpaceアセンブラ・逆アセンブラの紹介

# はじめに
以前、WhiteSpaceを楽に書く/読むために、アセンブラ(兼実行環境)・逆アセンブラをバラバラに作成していたのですが、今回改めてRubyで作成し直したのでご紹介します。
※というより、2018年のアドベント・カレンダーのネタ用に引っ張り出したというのが正しいところですが

# WhiteSpaceとは
WhiteSpaceはesolangの一種で、通常は区切り文字以上の意味を持たない空白・タブ・改行のみが意味を持つプログラミング言語です。
※本家サイトが既にアクティブでないようなので、概要は[Webアーカイブ](https://web.archive.org/web/20170318183338/http://compsoc.dur.ac.uk/whitespace/tutorial.html)をご覧ください。

本家ではバージョン0.3までの言語仕様となっていますが、[Hackageのサイト](http://hackage.haskell.org/package/whitespace)では、ランダム操作が追加になったバージョン0.4が公開されています。

この言語は、ある特定の仮想的なハードウェアを操作する機械語のような構成をしています。そのハードウェアの特徴とは、以下のようになっています。

* 記憶領域としてスタックとヒープを持つ。
    * 条件判断・各種演算にはスタックのトップを使い、都度値を消費する。
    * ヒープはアドレスを指定して永続的な値の保存や、入力処理での値の保存に使える。
* データは全て整数 ( 任意精度 ) であり、整数としての加減乗除・剰余算が行える。
* 入出力はASCII文字あるいは整数値単位で行える。
* 分岐処理は静的で、ラベルを設定する命令でジャンプ先を登録する。関数コールも可能。

今回紹介するツールをアセンブラ・逆アセンブラと言っているのは、この機械語に対応するアセンブリ言語的な言語を定義し、それを操作するからです。

# このツールについて
ツール本体`whitespace.rb`は[githubのリポジトリ](https://github.com/angel-p57/whitespace/blob/master/whitespace.rb)で公開しています。

基本的に、WhiteSpaceとしての命令に1対1で、読み易いように言葉を割り振っているだけなのですが、直にWhiteSpaceを書くのに比べ更に以下のようなメリットがあります。

* 空白・タブ・改行の代わりに見易いように`s`,`t`,`n`をあてるフォーマットも使用可。
* 分岐命令のラベルを生データでなくシンボルとして書ける。( アセンブラが自動的に割り当てる ) 
* デバッグモードでのみ効果のある、( 主にダンプ処理を行う ) 専用命令を追加している。

サンプルである[hello.wss](https://github.com/angel-p57/whitespace/blob/master/sample/hello.wss)は次のようになります。
※出力する文字列の文字コードをスタックに積んでいき、ループで全て出力していくという単純な処理です。

```text
push -1   # end of string
push 10   # NL
push 33   # !
push 101  # e
push 99   # c
push 97   # a
push 112  # p
push 83   # S
push 101  # e
push 116  # t
push 105  # i
push 104  # h
push 87   # W
push 32   # SP
push 44   # ,
push 111  # o
push 108  # l
dup       # l
push 101  # e
push 72   # H
mark LOOP
 dup
 jneg LEND
 putc
 jump LOOP
mark LEND
end
```

これを実行する例は次の通りです。

```shell-session:実行とアセンブル
$ ruby -a whitespace.rb hello.wss  # hello.ws にWhiteSpaceコードを保存
Hello, WhiteSpace!
$ od -Ax -tx1 hello.ws
000000 20 20 09 09 0a 20 20 20 09 20 09 20 0a 20 20 20
000010 09 20 20 20 20 09 0a 20 20 20 09 09 20 20 09 20
000020 09 0a 20 20 20 09 09 20 20 20 09 09 0a 20 20 20
000030 09 09 20 20 20 20 09 0a 20 20 20 09 09 09 20 20
000040 20 20 0a 20 20 20 09 20 09 20 20 09 09 0a 20 20
000050 20 09 09 20 20 09 20 09 0a 20 20 20 09 09 09 20
000060 09 20 20 0a 20 20 20 09 09 20 09 20 20 09 0a 20
000070 20 20 09 09 20 09 20 20 20 0a 20 20 20 09 20 09
000080 20 09 09 09 0a 20 20 20 09 20 20 20 20 20 0a 20
000090 20 20 09 20 09 09 20 20 0a 20 20 20 09 09 20 09
0000a0 09 09 09 0a 20 20 20 09 09 20 09 09 20 20 0a 20
0000b0 0a 20 20 20 20 09 09 20 20 09 20 09 0a 20 20 20
0000c0 09 20 20 09 20 20 20 0a 0a 20 20 0a 20 0a 20 0a
0000d0 09 09 20 0a 09 0a 20 20 0a 20 0a 0a 0a 20 20 20
0000e0 0a 0a 0a 0a
0000e4
$ ruby whitespace.rb -a -T stn hello.wss  # hello.wsv にs,t,nでコードを保存
Hello, WhiteSpace!
$ more hello.wsv
ssttnssststsnssstsssstnsssttsststnsssttsssttnsssttsssstnssstttssssnssststssttnsssttsststnssstttstssn
sssttstsstnsssttstsssnssstststttnssstsssssnssststtssnsssttsttttnsssttsttssnsnssssttsststnssstsstsssn
nssnsnsnttsntnssnsnnnsssnnnn
```

使用できるオプションについては、`-h`オプションをつけて実行すると見られます。WhiteSpaceの各命令に対応する書き方は、ツール本体の`OPS`の内容そのままです。
※TODO: ドキュメントの整備

# 最後に
WhiteSpaceは、流石に空白文字であるため読み書きが大変ですが、このツールにより多少なりとも楽に扱えるようになることを期待しています。より良いWhiteSpaceライフ?を!!

おまけ1: なお、このツール自体がHelloサンプルになっています。

```shell-session:本体のサンプル実行
$ ruby whitespace.rb -t raw whitespace.rb
Hello, WhiteSpace!
```

おまけ2: このツールの前身の逆アセンブラは、以前ゴルフ場[http://golf.shinh.org](http://golf.shinh.org)に導入して頂いており、投稿されているWhiteSpaceコードを、本ツールで扱うのとほぼ同じ形式に変換したもので見ることができます。