https://www.ipa.go.jp/sec/reports/20180306.html
> brainfuckとかwhitespaceみたいな感じで改行文字のみで
> プログラミングする言語作ると生産性めっちゃあがるんじゃねーかな
みたいなことを某所に書いた。
そもそもWhitespaceのタブかスペースを"\r"に変えればよくね?
→_まずWhitespace作ってみよう
SS STSL # push 2 to stack LS # duplicate top of the stack TSSS # sum top 2 of the stack TLST # print top of the stack => 4
1. パーサ
ソースファイルを読み込んでバイトを1文字ずつ読み取り、命令オブジェクトの配列に変換
2. ランタイム
命令オブジェクトの配列を前から順に実行していく(巻き戻りあり)
まずパースする際は、コメントはすべて飛ばす。
空白、タブ、LFを除く全ての文字はコメントである。
Whitespaceのコードは命令と引数に大別される。
例えば
- SS => 引数をスタックにプッシュ
- SLS => スタックの一番上を複製する
などのように S(空白)、T(タブ)、L(ラインフィード)の組み合わせでそれぞれ命令を構成する
引数を取る命令に続く文字列は引数として解釈される。
引数の終わりはLFで、LFに達するまでのタブと空白がそれぞれ正負のビットとして解釈される。
つまり一つの引数はビット列である。
例:
TTTSSSL #=> [1,1,1,0,0,0]
引数は数値型かラベルである。
Whitespaceで扱える値は数値型のみである。
ラベルは命令の場所を覚えておくために使う(Goのラベルと同じ)
パーサは簡易的なステートマシンとして実装した。
type Command interface { AddBitToParam(bool) Exec(*Runtime) FinishReadParam() }
上記インターフェースを満たす構造体を命令ごとに作成した。
AddBitToParamとFinishReadParamは引数の読み取りに使う。
Execは命令ごとの処理をランタイムに対して行う。
ランタイムは以下の構造体である。
type Runtime struct { stdin *bufio.Reader stdout io.Writer stack Stack commands Program heap map[int]int labels map[int]int callstack []int index int }
github.com/minoritea/whitespace
github.com/technohippy/go-whitespace