Rubyist のための他言語探訪 【第 14 回】 Whitespace

著者:まつもとゆきひろ

Whitespace

今回は普段とは趣を変えて、実用性は全くないけれども話のネタとしては面白い言語「Whitespace」を紹介しましょう。

Whitespace は Durham 大学の Edwin Brady と Chris Morris によって開発され、2003 年 4 月 1 日にリリースされました。 つまり、エイプリルフールのジョークだったわけです。 しかし、Whitespace は単なるジョークではなく、(見かけはともかく) ちゃんと動作する言語です。 多くの言語 (Python などを除く) ではスペース、タブ、改行などの空白 (whitespace) を無視しますが、Whitespace では逆に空白以外の文字を無視します。 図 1 は Whitespace による Hello World プログラムです。 しかし、すべてが空白であるため、人間の目にはなんのことだかわかりません。

図 1 WhitespaceによるHello World

   	  	   
	
     		  	 	
	
     		 		  
	
     		 		  
	
     		 				
	
     	     
	
     	 	 			
	
     		 				
	
     			  	 
	
     		 		  
	
     		  	  
	
        	 	 
	
  

Whitespace の命令

人間に読めないプログラムを扱うのは難しいので、まず Whitespace の文法を紹介し、人間に読める形に置換してみましょう。 「異常な」外見を持つ Whitespace ですが、その構造は意外にストレートです。 Whitespace は単純なスタックベースのプログラミング言語です。 Whitespace の命令は「IMP (Instruction Modification Parameter)」、「コマンド」、「パラメータ」から構成されます。

IMP は命令の種類を決めるプレフィックスです。 スタック操作とフロー操作はもっとも頻繁に行われるので、1 バイトで表現されます。

表 1 IMP 一覧

種別 IMP
スタック操作 [space]
整数演算 [tab][space]
ヒープアクセス [tab][tab]
フロー制御 [newline]
入出力 [tab][newline]

パラメータは命令によってあったりなかったりします。 表 2 に Whitespace の命令一覧を示します。

表 2 Whitespace 命令セット

IMP コマンド パラメータ 意味
[space] [space] 数値1 数値をスタックにプッシュ
[space] [newline][space] - スタックトップを複製
[space] [newline][tab] - スタックの1番目と2番目を交換
[space] [newline][newline] - スタックトップを破棄
[tab][space] [space][space] - スタックの上から二つを足し算
[tab][space] [space][tab] - スタックの上から二つで引き算
[tab][space] [space][newline] - スタックの上から二つでかけ算
[tab][space] [tab][space] - スタックの上から二つで割り算
[tab][space] [tab][tab] - スタックの上から二つで剰余
[tab][tab] [space] - 値をアドレスに格納
[tab][tab] [tab] - アドレスから値をスタックに
[newline] [space][space] ラベル2 ラベル定義
[newline] [space][tab] ラベル サブルーチン呼び出し
[newline] [space][newline] ラベル 無条件ジャンプ
[newline] [tab][space] ラベル スタックトップがゼロならジャンプ
[newline] [tab][tab] ラベル スタックトップが負ならジャンプ
[newline] [tab][newline] - サブルーチン終了
[newline] [newline][newline] - プログラム終了
[tab][newline] [space][space] - スタックトップの文字を出力
[tab][newline] [space][tab] - スタックトップの数値を出力
[tab][newline] [tab][space] - 文字を読み込みアドレスに格納
[tab][newline] [tab][tab]3 - 数値を読み込みアドレスに格納

入出力 ([tab][newline])

図 2 はスペースを S、タブを T と置き換えた Hello World です。 これをさらにわかりやすい命令に逆アセンブルしたものを図 3 に示します。

図 2 置換を行った Hello World

SSSTSSTSSS
T
SSSSSTTSSTST
T
SSSSSTTSTTSS
T
SSSSSTTSTTSS
T
SSSSSTTSTTTT
T
SSSSSTSSSSS
T
SSSSSTSTSTTT
T
SSSSSTTSTTTT
T
SSSSSTTTSSTS
T
SSSSSTTSTTSS
T
SSSSSTTSSTSS
T
SSSSSSSSTSTS
T
SS

図 3 逆アセンブルした Hello World

PUSH "H"
PUTCHAR
PUSH "e"
PUTCHAR
PUSH "l"
PUTCHAR
PUSH "l"
PUTCHAR
PUSH "o"
PUTCHAR
PUSH " "
PUTCHAR
PUSH "W"
PUTCHAR
PUSH "o"
PUTCHAR
PUSH "r"
PUTCHAR
PUSH "l"
PUTCHAR
PUSH "d"
PUTCHAR
PUSH "\n"
PUTCHAR
FINISH

まとめ

今回はエイプリルフールのジョークから生まれた言語 Whitespace を紹介しました。 Whitespace は通常無視されがちな空白に対する「不公平を是正する」ために生まれたのだそうです。 ジョークとは言え、ちゃんと動作するプログラミング言語を一つ設計・実装してしまう パワーには脱帽します。

Whitespace に関する詳細な情報は本家サイト [英文] を参照してください。 Wikipedia にも情報があります。

著者について

matz.jpgまつもとゆきひろは自他ともに認める日本を代表する言語オタクです。 言語好きが昂じて自分の言語を設計してしまった大馬鹿者です。 が、オタクとかハッカーとか呼ばれる人種はみんな多かれ少なかれそんなものじゃないでしょうか。

バックナンバー


  1. 数値: 数値は二進数で表し、[space] が 0、[tab] が 1、[newline] が終端記号となる 

  2. ラベル: ラベルは [space] と [tab] の列で表現され、[newline] が終端記号となる 

  3. 修正: @pockeからの指摘で2019年5月5日に[tab][newline]から[tab][tab]に修正。詳細は指摘Issueを参照。