Wkikipediaの記事を読んだり,ダウンロードしたインタプリタをいじってるうちに,なんかちょっとできそうな気がしてきた。
目標は Hello world プログラムの実行だ。
まず,データを格納する配列(レジスタと呼ぶことにしよう)とポインタが必要だな。
data BrainF_ck = BF { bfPointer :: Int, bfRegister :: [Int] }
操作する命令をそれぞれ関数にする。こんな感じか。
命令 | 関数名 |
+ | bfIncrement |
- | bfDencrement |
> | bfShift |
< | bfUnshift |
. | bfPrint |
, | bfInput |
[ | bfGoto |
] | bfBack |
とりあえず簡単そうな「+」,「-」,「>」,「<」だけにしよう。
それから,BrainF_ck の初期値を設定する関数も要るな。レジスタがいくつ要るかわからないけど,10個あればいいか。
data BrainF_ck = BF { bfPointer :: Int, bfRegister :: [Int] } deriving (Show) bfInitial :: BrainF_ck bfInitial = BF { bfPointer = 0, bfRegister = [0,0,0,0,0,0,0,0,0,0] } bfValue :: BrainF_ck -> Int bfValue bf = (bfRegister bf) !! (bfPointer bf) bfIncrement :: BrainF_ck -> BrainF_ck bfIncrement (BF p v) = BF p ((take p v) ++ [(v !! p) + 1] ++ (tail $ drop p v)) bfDecrement :: BrainF_ck -> BrainF_ck bfDecrement (BF p v) = BF p ((take p v) ++ [(v !! p) - 1] ++ (tail $ drop p v)) bfShift :: BrainF_ck -> BrainF_ck bfShift (BF p v) = BF (p+1) v bfUnshift :: BrainF_ck -> BrainF_ck bfUnshift (BF p v) = BF (p-1) v
まずはここまででどうだ。
Prelude> :load hbf.hs Compiling Main ( hbf.hs, interpreted ) Ok, modules loaded: Main. *Main> bfInitial Loading package haskell98-1.0 ... linking ... done. BF {bfPointer = 0, bfRegister = [0,0,0,0,0,0,0,0,0,0]} *Main> bfIncrement $ bfInitial BF {bfPointer = 0, bfRegister = [1,0,0,0,0,0,0,0,0,0]} *Main> bfIncrement $ bfShift $ bfInitial BF {bfPointer = 1, bfRegister = [0,1,0,0,0,0,0,0,0,0]} *Main> bfUnshift $ bfIncrement $ bfShift $ bfInitial BF {bfPointer = 0, bfRegister = [0,1,0,0,0,0,0,0,0,0]}
おお,なんだかうまくいってるみたい。