Parsec の練習のために、プログラム言語を作りました。今の流行りに乗って、 VM で動く言語です。 VM として、ポータビリティや命令のシンプルさを考慮して、 Brainf*ck を採用しました。
http://shinh.skr.jp/koneta/sbf.hs
以下のコードが
(let (x (getchar)) (while x (if (> x 64) (if (> 91 x) (+= x 32))) (putchar x) (= x (getchar)) ))
以下のように。
,[>++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]<<[->>+>> >>+<<<<<<]>>>>>>[-<<<<<<+>>>>>>][-]<<<[-]<<[->>+>>>+<<<<<]>>>>>[-<<<<<+>>>>>][-] <<<[<[->>+>+<<<]>>>[-<<<+>>>]<[[-]<<->>]<-]<<[-]>>>>>[-]<<<<[->>>>+<<<+<]>[-<+>] [-]>>>[[-]<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++<[-]>[-<+>>>>+<<<]>>>[-<<<+>>>][-]<<<<<[-]<<<[->>>+>>>>>+< <<<<<<<]>>>>>>>>[-<<<<<<<<+>>>>>>>>][-]<<<<<[>[->>+>+<<<]>>>[-<<<+>>>]<[[-]<<->> ]<<<-]>>[-]>[-]<<[->>+<<<+>]<[->+<][-]>>>[[-]>++++++++++++++++++++++++++++++++[- <<<<<<<+>>>>>>+>]<[->+<][-]>[-]<]<<[-]>>]<<<<[-]<<.>>>>>>,<<<<<<[-]>>>>>>[-<<<<< <+>>>+>>>]<<<[->>>+<<<][-]>>>[-]<<<<<<]
要するに大文字を小文字に変換しながらechoです。ネタ元は k.inaba さん。
http://www.kmonos.net/wlog/62.html#_0227060630
まぁはるかにパフォーマンスで負けています。 k.inaba さんより賢いコードを吐くコンパイラは書けなさそうな気がしますが、現状は色々ひどいというか途中で飽きてきたのでもういいかみたいな。なんというか破壊していいメモリ領域とダメな部分を区別して無駄なコピー減らせばずいぶんマシになると思います。
そもそもこの echo を書くための機能しか実装してません。気が向いたら命令増やします。たぶん増えません。使う人は自分で命令増やして下さい。
作った動機はなんか、俺も brainf*ck 書いてみよう、と思ったら頭悪いせいか全然書けなくて、くやしい思いをしたのでこんなもん機械に吐かせろ、と思ったとかそんな。
SBF は S式→BF とか、 SimplerBF とか。
S式なのはなんとなく。あえて言うならラクそうだったから。まぁλどころか関数すら実装してませんが。再帰とか大変そうな気がする。
Haskell はパーサ書くには偉いですね。はいはいえらいえらい。
でもなんていうかたぶん、数年後に見たら、昔の BASIC のコードを見た時のような気分になれる気がします。あの頃は若かった。若気の至りだ。みたいな。 emit ってなんなんやろ、とか思いながら書いてたし。
このへんが若気の至り。比較演算を丸パクリした部分。
return (cl++cr++(movePtr r "[")++(movePtr l ("[-"++(move$b1-l)++"+"++(move$b2-b1)++"+"++(move$l-b2)++"]"))++(movePtr b2 ("[-"++(move$l-b2)++"+"++(move$b2-l)++"]"))++(movePtr b1 ("[[-]"++(move$l-b1)++"-"++(move$b1-l)++"]"))++(movePtr r "-]"), l)
あー
と口走ったのが6月19日らしいのでなんか機動力落ちてるなぁ…若気とやらはどこにいった。ああこの発言受けてkonnさんは1日でHaskellインタプリタ書いたんだよな…何かがわかった気がした。