Skip to content

Instantly share code, notes, and snippets.

@cleichner
Last active January 2, 2016 20:59
Show Gist options
  • Save cleichner/8360583 to your computer and use it in GitHub Desktop.
Save cleichner/8360583 to your computer and use it in GitHub Desktop.
The laziest high-performance bf compiler ever.
import Control.Monad
import Data.List
data BF a = Add a
| Move a
| StartLoop
| EndLoop
| Write
| Read
| Zero
| Copy a a
deriving (Show, Eq)
compact :: (Integral a) => [Char] -> [BF a]
compact [] = mzero
compact b@(c:_) | c == '>' = return $ Move repetition
| c == '<' = return $ Move (-repetition)
| c == '+' = return $ Add repetition
| c == '-' = return $ Add (-repetition)
| c == '[' = duplicate StartLoop
| c == ']' = duplicate EndLoop
| c == '.' = duplicate Write
| c == ',' = duplicate Read
| otherwise = mzero
where duplicate = replicate (fromIntegral repetition)
repetition = genericLength b
optimize :: (Num a, Eq a) => [BF a] -> [BF a]
optimize [] = []
optimize (StartLoop:Add (-1):EndLoop:xs) = Zero : optimize xs
-- add copy
optimize (x:xs) = x : optimize xs
generateC :: (Show a, Integral a) => BF a -> String
generateC Zero = "*p = 0;"
generateC (Copy n m) = unwords ["*(p + ", show n, ") = *(p + ", show m, ");"]
generateC (Move n) = unwords ["p += ", show n, ";"]
generateC (Add n) = unwords ["(*p) += ", show n, ";"]
generateC StartLoop = "while (*p) {"
generateC EndLoop = "}"
generateC Write = "putchar(*p);"
generateC Read = "*p = getchar();"
main :: IO ()
main = interact compile where
compile source = unlines $
[ "#include <stdio.h>"
, "#include <stdint.h>"
, "#include <stdlib.h>"
, ""
, "int main(void) {"
, "uint8_t* data = calloc(99999, 1);"
, "uint8_t* p=data;"
] ++ map generateC (optimize . abstract $ source)
++ ["}"]
abstract = concatMap compact . group . filter (`elem` "<>+-[].,")
#!/bin/sh
FILENAME=$(basename $1 .bf)
./cleichner < $1 > $FILENAME.c
cc -O2 $FILENAME.c -o $FILENAME
./$FILENAME
indent $FILENAME.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment