スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

HaskellでBrainfuckインタプリタ

> Haskell Brainfuck の検索結果 約 56,600 件中 1 - 10 件目 (0.16 秒)
…まあ気にしない。もう書いちゃったし。

BF的な仕様
  • 入力が無くなった場合はポインタの指す値を変更しない
  • mod 256

処理系の仕様
  • 入出力はIntのリストで
  • 遅延評価

使い方
interpretBF "コード" [入力...] → [出力...]

ghciでの実行例(ghciで)
*Main> interpretBF "+++." []
[3]
*Main> interpretBF ",.,.,." [1,2,3]
[1,2,3]
*Main> take 10 $ interpretBF "+[.+]" [1,2,3]
[1,2,3,4,5,6,7,8,9,10]
*Main> interpretBF "<<<" [1,2,3]
[]
*Main> interpretBF "<<<." [1,2,3]
[*** Exception: Prelude.(!!): negative index


実装

data Op = Val Int | Ptr Int | Get | Put | While [Op]
parseBF :: String -> ([Op],String)
evalBF :: [Op] -> (Int,[Int]) -> [Int] -> (((Int,[Int]),[Int]),[Int])
interpretBF :: String -> [Int] -> [Int]

interpretBF c = let (o,[]) = parseBF c in snd . evalBF o (0,[0,0..])

parseBF [] = ([],[])
parseBF ('[':xs) = let (o,']':t) = parseBF xs; (p,u) = parseBF t in (While o:p,u)
parseBF xs@(']':_) = ([],xs)
parseBF (x:xs) = (p,t) where
(o,t) = parseBF xs
p = case x of
'+' -> Val 1 : o
'-' -> Val (-1) : o
'>' -> Ptr 1 : o
'<' -> Ptr (-1) : o
',' -> Get : o
'.' -> Put : o
_ -> o

changeAt n arr newval = (take n arr)++newval:(drop (n+1) arr)

evalBF [] s i = ((s,i),[])
evalBF (Val k:cs) (p,a) i = evalBF cs (p,changeAt p a $ k + a!!p `mod` 256) i
evalBF (Ptr k:cs) (p,a) i = evalBF cs (p+k,a) i
evalBF (Get:cs) (p,a) (x:xs) = evalBF cs (p,changeAt p a x) xs
evalBF (Get:cs) s i@[] = evalBF cs s i
evalBF (Put:cs) s0@(p,a) i0 = let (si1,o1) = evalBF cs s0 i0 in (si1,(a!!p):o1)
evalBF cs0@(While cs1:cs2) s0@(p,a) i0 | a!!p == 0 = evalBF cs2 s0 i0
| otherwise = let ((s1,i1),o1) = evalBF cs1 s0 i0;
(si2,o2) = evalBF cs0 s1 i1 in
(si2,o1++o2)
スポンサーサイト

テーマ : プログラミング | ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

minoki

Author:minoki
好きなプログラミング言語:
Haskell,Lua
GitHubアカウント
Twitter

最新記事
月別アーカイブ
カテゴリ
検索フォーム
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。