Skip to content

Instantly share code, notes, and snippets.

@controlflow
Created September 30, 2014 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save controlflow/b67376a4b7fda8a3be37 to your computer and use it in GitHub Desktop.
Save controlflow/b67376a4b7fda8a3be37 to your computer and use it in GitHub Desktop.
Simple BF interpreter in Haskell
import Data.Char(ord, chr)
data Tape = Tape [Int] Int [Int]
deriving Show
getTape :: [Int] -> Tape
getTape (x:xs) = Tape [] x xs
getTape [] = Tape [] 0 []
modify :: (Int -> Int) -> Tape -> Tape
modify f (Tape ls x rs) = Tape ls (f x) rs
moveRight :: Tape -> Tape
moveRight (Tape (l:ls) x rs) = Tape ls l (x:rs)
moveRight (Tape [] x rs) = Tape [] 0 (x:rs)
moveLeft :: Tape -> Tape
moveLeft (Tape ls x (r:rs)) = Tape (x:ls) r rs
moveLeft (Tape ls x [] ) = Tape (x:ls) 0 []
charOut :: Tape -> IO Tape
charOut t@(Tape _ x _) = (putChar $ chr x) >> return t
charIn :: Tape -> IO Tape
charIn (Tape ls _ rs) = getChar >>= return . tape'
where tape' x = Tape ls (ord x) rs
step :: Char -> (Tape -> IO Tape)
step '+' = return . modify (+ 1)
step '-' = return . modify (subtract 1)
step '<' = return . moveRight
step '>' = return . moveLeft
step '.' = charOut
step ',' = charIn
step _ = return . id
getLoop :: String -> String -> (String, String)
getLoop (']': tail) body = (reverse body, tail)
getLoop ( x : tail) body = getLoop tail (x:body)
getLoop _ _ = error "Disbalanced loop"
runLoop :: String -> Tape -> IO Tape
runLoop body t@(Tape _ 0 _) = return t
runLoop body t = (runBF body t) >>= runLoop body
runBF :: String -> Tape -> IO Tape
runBF ('[': code) t = (runLoop body t) >>= runBF tail
where (body, tail) = getLoop code []
runBF ( c : code) t = (step c t) >>= runBF code
runBF [] t = return t
src = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
main = do
_ <- runBF src $ getTape []
return ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment