Skip to content

Instantly share code, notes, and snippets.

@banacorn

banacorn/README.md

Created Apr 28, 2012
Embed
What would you like to do?
HaskellFuck

HaskellFuck

Compile

ghc bf.hs

Hello World

cat hello | ./a.out
import Data.Char
class Mem a where
empty :: a
instance Mem Int where empty = 0
instance Mem Char where empty = ' '
data (Mem a) => Tape a = Tape Int [a] deriving (Show)
get (Tape 0 (x:_)) = x
get (Tape i (x:xs)) = get $ Tape (i - 1) xs
set (Tape i xs) n = Tape i $ a ++ (n:b)
where a = fst tape
b = tail $ snd tape
tape = splitAt i xs
next (Tape i xs)
| i < length xs - 1 = Tape (i + 1) xs
| otherwise = Tape (i + 1) (xs ++ [empty])
prev (Tape i xs)
| i < 1 = Tape i (empty:xs)
| otherwise = Tape (i - 1) xs
incr tape = set tape $ (get tape) + 1
decr tape = set tape $ (get tape) - 1
exec instruction memory
| command == '>' = exec (next instruction) (next memory)
| command == '<' = exec (next instruction) (prev memory)
| command == '+' = exec (next instruction) (incr memory)
| command == '-' = exec (next instruction) (decr memory)
| command == '.' = do
putChar $ (chr value)
exec (next instruction) memory
| command == ',' = do
c <- getChar
exec (next instruction) (set memory $ ord c)
| command == '[' && value == 0 = exec (jumpTo instruction) memory
| command == '[' && value /= 0 = exec (next instruction) memory
| command == ']' && value /= 0 = exec (jumpBack instruction) memory
| command == ']' && value == 0 = exec (next instruction) memory
| otherwise = return ()
where command = get instruction
value = get memory
jumpTo tape
| get tape == ']' = next tape
| otherwise = jumpTo $ next tape
jumpBack tape
| get tape == '[' = next tape
| otherwise = jumpBack $ prev tape
main = do
inst <- getLine
exec (Tape 0 inst) (Tape 0 [0])
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment