4 回目の勉強会が開かれました.今日の勉強会は LT 枠のみということだったので,ネタとして Whitespace について発表してくるなどしました.
Whitespace は [space],[tab],[newline] の三種の文字のみを使って書く画期的,近未来的,イノベーティブなプログラミング言語です.本家サイトは http://compsoc.dur.ac.uk/whitespace/ なんですけど,今日はなぜか接続できないので,テキトウなことを書きます.
まず Whitespace では前述のように,プログラムを書くための文字としては 3 種類の文字しか使えません.ただ,そのわりには色んなことができたりします.関数呼び出しはサポートしてるわ,再帰関数は使えるわで,わりとやりたい放題できる.
アーキテクチャとしてはシンプルなスタックマシンを想像してもらえると良いのではないかと思います.各種の演算,命令は基本的にはスタックのトップに対して行われます.例えば Whitespace では 5 種の演算命令 (加減乗除に剰余を加えた 5 種) をサポートしていますが,それぞれの命令の演算対象はスタックのトップとその次の要素となります.1+2 をしたいときには,スタックに 1, 2 を PUSH してから加算命令を呼びだすといった感じですね.
また,スタック以外にヒープも記憶領域として使うことができます.アクセスしたいアドレスをスタックに PUSH しておいてロード命令を呼び出すと,ヒープ上でそのアドレスにある値がスタックトップに積まれます.
命令体系は http://jp.rubyist.net/magazine/?0022-Legwork にまとまっています (もちろん本家サイトにもありますが).アセンブラでプログラムを組んだことがある人には分かると思いますが,命令はアセンブラで登場する基本的な命令と酷似しており,ソースプログラム自身も (人間には"見えない"以外は) アセンブリプログラムとほぼ同じ構造を取ります.本家サイトにはサンプルとして hello world プログラムなどがアップされていますが,実際にこれをアセンブラ的なものにコンバートしてみた結果をエントリ末尾に示しますが,まさにアセンブリ言語のソースということが分かると思います.
言語としての仕様は固まっておらず,本家サイトにも Haskell で書かれた処理系と,「これを読んで仕様を理解しろ」ってことが書かれています.いろいろと独創的な言語です!
0000 PUSH 0 0001 PUSH 72 0002 STORE 0003 PUSH 1 0004 PUSH 101 0005 STORE 0006 PUSH 2 0007 PUSH 108 0008 STORE 0009 PUSH 3 0010 PUSH 108 0011 STORE 0012 PUSH 4 0013 PUSH 111 0014 STORE 0015 PUSH 5 0016 PUSH 44 0017 STORE 0018 PUSH 6 0019 PUSH 32 0020 STORE 0021 PUSH 7 0022 PUSH 119 0023 STORE 0024 PUSH 8 0025 PUSH 111 0026 STORE 0027 PUSH 9 0028 PUSH 114 0029 STORE 0030 PUSH 10 0031 PUSH 108 0032 STORE 0033 PUSH 11 0034 PUSH 100 0035 STORE 0036 PUSH 12 0037 PUSH 32 0038 STORE 0039 PUSH 13 0040 PUSH 111 0041 STORE 0042 PUSH 14 0043 PUSH 102 0044 STORE 0045 PUSH 15 0046 PUSH 32 0047 STORE 0048 PUSH 16 0049 PUSH 115 0050 STORE 0051 PUSH 17 0052 PUSH 112 0053 STORE 0054 PUSH 18 0055 PUSH 97 0056 STORE 0057 PUSH 19 0058 PUSH 99 0059 STORE 0060 PUSH 20 0061 PUSH 101 0062 STORE 0063 PUSH 21 0064 PUSH 115 0065 STORE 0066 PUSH 22 0067 PUSH 33 0068 STORE 0069 PUSH 23 0070 PUSH 0 0071 STORE 0072 PUSH 0 0073 CALL LABEL00 0074 CALL LABEL01 0075 EXIT MARK LABEL02 0076 ADD 0077 RET MARK LABEL00 0078 DUP 0079 LOAD 0080 DUP 0081 JPZ LABEL03 0082 PUTC 0083 PUSH 1 0084 ADD 0085 JMP LABEL00 MARK LABEL03 0086 DISC 0087 DISC 0088 RET MARK LABEL04 0089 DUP 0090 DUP 0091 GETC 0092 LOAD 0093 DUP 0094 PUSH 10 0095 SUB 0096 JPZ LABEL05 0097 DISC 0098 PUSH 1 0099 ADD 0100 JMP LABEL04 MARK LABEL05 0101 DISC 0102 PUSH 1 0103 ADD 0104 PUSH 0 0105 STORE 0106 RET MARK LABEL01 0107 PUSH 10 0108 PUSH 13 0109 PUTC 0110 PUTC 0111 RET