Compare commits
4 Commits
9fde7bb543
...
ecc172527a
Author | SHA1 | Date | |
---|---|---|---|
|
ecc172527a | ||
|
cb90f6b4a0 | ||
|
d7e57cfa9c | ||
|
0042a1d999 |
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
bf
|
||||
bf.asm
|
||||
bf.o
|
||||
main
|
||||
main.o
|
||||
main.hi
|
15
README.md
15
README.md
@ -1,3 +1,14 @@
|
||||
# bfhaskell
|
||||
# Brainfuck compiler In Haskell
|
||||
*ts sucks but i love it*
|
||||
|
||||
Brainfuck compiler in haskell
|
||||
# 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
|
49
main.hs
Normal file
49
main.hs
Normal file
@ -0,0 +1,49 @@
|
||||
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
|
3
test/test.bf
Normal file
3
test/test.bf
Normal file
@ -0,0 +1,3 @@
|
||||
>++++++++[<+++++++++>-]<.>++++[<+++++++>-]<+.+++++++..+++.>>++++++[<+++++++>-]<+
|
||||
+.------------.>++++++[<+++++++++>-]<+.<.+++.------.--------.>>>++++[<++++++++>-
|
||||
]<+.
|
2
test/test1.bf
Normal file
2
test/test1.bf
Normal file
@ -0,0 +1,2 @@
|
||||
++++++ 6
|
||||
[->++++++++++<]>+++++. 65
|
1
test/test2.bf
Normal file
1
test/test2.bf
Normal file
@ -0,0 +1 @@
|
||||
,+++.
|
Loading…
x
Reference in New Issue
Block a user