import System.Environment import System.IO template = "global _start\n\nSECTION .data\n\nSECTION .bss\ntape resb 255\nbuf resb 1\n\nSECTION .text\n_start:" left_arrow = "\n\tsub rax, 1\n\tand rax, 0x00000000000000FF" right_arrow = "\n\tadd rax, 1\n\tand rax, 0x00000000000000FF" add_bf = "\n\tmov bl, [tape+rax]\n\tadd bl, 1\n\tmov [tape+rax], bl" sub_bf = "\n\tmov bl, [tape+rax]\n\tsub bl, 1\n\tmov [tape+rax], bl" dot = "\n\tpush rax\n\tpush qword [tape+rax]\n\tmov rax, 1\n\tmov rdi, 1,\n\tmov rsi, rsp\n\tmov rdx, 1\n\tsyscall\n\tpop rax\n\tpop rax" comma = "\n\tpush rax\n\tmov rax, 0\n\tmov rdi, 0\n\tmov rsi, buf\n\tmov rdx, 1\n\tsyscall\n\tpop rax\n\tmov rbx, [buf]\n\tmov [tape+rax], bl" end = "\n\n\n\tmov rdi, [tape+rax]\n\tmov rax, 60\n\tsyscall" opbrack = ":\n\tcmp byte [tape+rax], 0\n\tje close_" closbrack = ":\n\tcmp byte [tape+rax], 0\n\tjne open_" append :: [Int] -> Int -> [Int] append stack val = stack ++ [val] parse_other :: Char -> String parse_other char | char == '>' = right_arrow | char == '<' = left_arrow | char == '+' = add_bf | char == '-' = sub_bf | char == '.' = dot | char == ',' = comma | otherwise = "" parse_bracket :: Char -> Int -> String parse_bracket char index | char == '[' = "\nopen_" ++ show index ++ opbrack ++ show index | char == ']' = "\nclose_" ++ show index ++ closbrack ++ show index | otherwise = "" -- never parse :: String -> Int -> [Int] -> String -- the stack contains positions parse file index brackstack | index == (length file) = "" | file!!index == '[' = parse_bracket (file!!index) index ++ (parse file (index+1) (append brackstack index)) | file!!index == ']' = parse_bracket (file!!index) (last brackstack) ++ (parse file (index+1) (init brackstack)) | otherwise = (parse_other $ file!!index) ++ parse file (index+1) brackstack main :: IO() main = do -- let file = "/home/coderlol/code/bfhaskell/test/test.bf" args <- getArgs print("Compiling " ++ (args!!0) ++ "...") content <- readFile(args!!0) let stuff = template ++ (parse content 0 []) ++ end writeFile "./bf.asm" stuff