よくわかる Whitespace

ちょっと Whitespace インタプリタが欲しかったので書きました。

http://shinh.skr.jp/koneta/ws.c

さて、名前が語られることは多いけど、イマイチ仕様の説明の無い Whitespace ですが、これは誰がどう見ても言語というより VM です。機能も結構豊富というかかなり大きく、コンパイラ書けば普通になんか動かせるかと思います。 FORTH からのトランスレータなんかは割とすぐに書けそう。

以下にチュートリアルがあるのですが、

http://compsoc.dur.ac.uk/whitespace/tutorial.php

これをサックリ見てるとなんか命令長が可変だなぁと思うのですが、もう少しよく見ると、 3Byte の opcode と 0 or 1 or 可変長の operand に分解できるなぁと気付きます。

唯一 [Space][Space] の push だけが 2Byte 命令に見えますが、これは push の引数は数値なので、次の Byte が [Space] なら正数の push 、 [Tab] なら負数の push 、 [LF] なら不正な命令、として処理したらいいと思います。負数が影響してくるのはこの命令だけなので、実に好都合、というかそういうふうにデザインしてあるんでしょう。

数値が LF 終端で可変長なのは、たぶん、単に小さい値の push に 32Byte とか使いたくないということかなぁと思います。

あと 4Byte の命令もいくつかありますが、これらは operand を取らない命令なので、余った 1Byte を operand と考えればいいかと思います。

というわけで、上の C の実装は、単純に 3Byte の opcode は 3*3*3=27 パターンあるので、 5bit に収めておいて、 26bit くらいを operand の保存に使う、というような感じで、いったん 32bit 1命令の RISC ぽい命令列にしてから実行する感じになっています。というかラベルを貼る mark 命令は最初に検知しておかんといかんのでたぶん必然的に内部表現に翻訳しておく必要があります。ホント BF とは大違いですが、 RISC ぽい命令列になった状態で保存しちまえばそれはそれで普通に使えるかもしれんなぁとか思ったり思わなかったり。

あとラベルが可変長でサンプルのラベルがえらい長くてウザかったのですが、まぁ適当に小さい数値をあてる感じに。

あと以下のサイトに Ruby で書かれた処理系/アセンブラ/逆アセンブラがあるのでとても重宝します。

http://yagni.com/whitespace/index.html

まぁそんな感じで、 Whitespace は見た目以外はごく普通なのであまり面白くないという。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h