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