新言語 neko mimi Fu**♥をHaskellで実装してみた(私じゃないです)
neko mimi mode.の歌詞でコーディングするBrainFuckの方バリエーションが
http://www.aichi-pu.ac.jp/ist/~ohkubo/sb/log/eid3.html
↑で紹介されていたので、先輩に教えたところ帰る前にHaskellで実装を済ませていたという話。
↓こいつをコンパイルして、bf.exeを作って
import Data.Char import Data.List import System import System.IO main = do as <- getArgs if length as >= 1 then do cmd <- readFile "command.list" src <- readFile (as!!0) bfstart (lines cmd) src else putStr "usage:\n\tbf [sourcefilepath]\n\t.\\command.list ... command definition file." -- '>' Greater Then -- gt = 0 -- '<' Less Then -- lt = 1 -- '+' PLus sign -- pl = 2 -- '-' MInus sign -- mi = 3 -- '.' PEriod -- pe = 4 -- ',' COmma -- co = 5 -- '[' Left Bracket -- lb = 6 -- ']' Right Bracket -- rb = 7 bfstart :: [String] -> String -> IO () bfstart= \ cmds code -> bf (normalize cmds code) 0 iniMem 0 where -- initialized memory -- iniMem = 0:iniMem -- brainfuck core -- bf :: [Int] -> Int -> [Int] -> Int -> IO () bf code cp memory mp -- end of code -- |length code <= cp = return () -- '>' -- |get code cp == gt = bf code (inc cp) memory (inc mp) -- '<' -- |get code cp == lt = bf code (inc cp) memory (dec mp) -- '+' -- |get code cp == pl = bf code (inc cp) (dataInc memory mp) mp -- '-' -- |get code cp == mi = bf code (inc cp) (dataDec memory mp) mp -- '.' -- |get code cp == pe = do putChar $ chr $ get memory mp bf code (inc cp) memory mp -- ',' -- |get code cp == co = do c <- hGetChar stdin bf code (inc cp) (put memory mp $ ord c) mp -- '[' && mem == 0 -- |get code cp == lb && get memory mp == 0 = bf code (next code $ inc cp) memory mp -- ']' && mem /= 0 -- |get code cp == rb && get memory mp /= 0 = bf code (prev code $ dec cp) memory mp -- other characters -- |otherwise = bf code (inc cp) memory mp where get :: [a] -> Int -> a get = (!!) put :: [a] -> Int -> a -> [a] put xs p y = take p xs ++ y : drop (inc p) xs inc :: Int -> Int inc = (+1) dec :: Int -> Int dec = \ n -> n - 1 dataInc :: [Int] -> Int -> [Int] dataInc = \ d p -> put d p $ inc $ get d p dataDec :: [Int] -> Int -> [Int] dataDec = \ d p -> put d p $ dec $ get d p next :: [Int] -> Int -> Int next ns p | get ns p == rb = p | get ns p == lb = next ns $ inc $ next ns $ inc p | otherwise = next ns $ inc p prev :: [Int] -> Int -> Int prev ns p | get ns p == lb = p | get ns p == rb = prev ns $ dec $ prev ns $ dec p | otherwise = prev ns $ dec p -- normalize -- normalize :: [String] -> String -> [Int] normalize cmds cs |cs == [] = [] |isPrefixOf (cmds !! gt) cs = gt:(normalize cmds $ drop (length $ cmds !! gt) cs) |isPrefixOf (cmds !! lt) cs = lt:(normalize cmds $ drop (length $ cmds !! lt) cs) |isPrefixOf (cmds !! pl) cs = pl:(normalize cmds $ drop (length $ cmds !! pl) cs) |isPrefixOf (cmds !! mi) cs = mi:(normalize cmds $ drop (length $ cmds !! mi) cs) |isPrefixOf (cmds !! pe) cs = pe:(normalize cmds $ drop (length $ cmds !! pe) cs) |isPrefixOf (cmds !! co) cs = co:(normalize cmds $ drop (length $ cmds !! co) cs) |isPrefixOf (cmds !! lb) cs = lb:(normalize cmds $ drop (length $ cmds !! lb) cs) |isPrefixOf (cmds !! rb) cs = rb:(normalize cmds $ drop (length $ cmds !! rb) cs) |otherwise = normalize cmds $ tail cs
同じディレクトリに↓のcommand.listを置く
ネコミミ! ネコミミモード おにいさま 私のしもべー や・く・そ・く・よ フルフルフルムーン キスキス… キス…したくなっちゃった…
neko mimi Fu**♥のソースファイル名を第一引数として、
bf.exeを実行すればおk。
bf hello.bf
…確認のしようもないな。
確認できました。バンザーイ。
command.listさえ差し替えれば、本家BrainFuckも含めていくらでもバリエーションを作れます。
2007/10/16追記
無駄が多かったので直したとのことなので、
掲載したソースを差し替えておきました。