Compare commits
No commits in common. "ecc172527a863b4dc4e955c911711850c142286d" and "9fde7bb543a1db0e6513345915584685452baa62" have entirely different histories.
ecc172527a
...
9fde7bb543
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,6 +0,0 @@
|
||||
bf
|
||||
bf.asm
|
||||
bf.o
|
||||
main
|
||||
main.o
|
||||
main.hi
|
15
README.md
15
README.md
@ -1,14 +1,3 @@
|
||||
# Brainfuck compiler In Haskell
|
||||
*ts sucks but i love it*
|
||||
# bfhaskell
|
||||
|
||||
# what you need
|
||||
- GHC (to compile the haskell code)
|
||||
- Nasm (to assemble the generated assembly)
|
||||
- ld (to link it and stuff, should already be installed tho)
|
||||
|
||||
# how to use
|
||||
run `ghc main.hs`
|
||||
|
||||
do `./main <path to bf>` to generate the assembly (you need to assemble it yourself by doing nasm -felf64 -o bf.o bf.asm && ld -o bf bf.o, you may need to do some linking shenanigans depending on your distro)
|
||||
|
||||
# linux only
|
||||
Brainfuck compiler in haskell
|
49
main.hs
49
main.hs
@ -1,49 +0,0 @@
|
||||
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, 0\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
|
@ -1,3 +0,0 @@
|
||||
>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<+
|
||||
+.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-
|
||||
]<+.
|
@ -1,2 +0,0 @@
|
||||
++++++ 6
|
||||
[->++++++++++<]>+++++. 65
|
@ -1 +0,0 @@
|
||||
,+++.
|
Loading…
x
Reference in New Issue
Block a user