github.com/classpythonaddike/brainfcompiler
Advanced tools
@@ -0,0 +0,0 @@ name: Go |
@@ -17,3 +17,3 @@ package brainfcompiler | ||
| Compile("mandelbrot.bf", "gcc", "cat.exe") | ||
| Compile("mandelbrot.bf", "gcc", "mandelbrot.exe") | ||
| } |
+29
-2
@@ -5,3 +5,3 @@ package brainfcompiler | ||
| "bufio" | ||
| "io/ioutil" | ||
| //"io/ioutil" | ||
| "log" | ||
@@ -41,3 +41,14 @@ "os" | ||
| log.Println("Done!") | ||
| } | ||
| func iscmd(cmd string) bool { | ||
| var allowed = [8]string{"[", "]", ".", ",", ">", "<", "+", "-"} | ||
| for _, char := range allowed { | ||
| if char == cmd { | ||
| return true | ||
| } | ||
| } | ||
| return false | ||
| } | ||
@@ -47,3 +58,4 @@ | ||
| data, err := ioutil.ReadFile(filename) | ||
| f, err := os.Open(filename) | ||
| data := "" | ||
@@ -54,2 +66,17 @@ if err != nil { | ||
| r := bufio.NewReader(f) | ||
| b := make([]byte, 1) | ||
| for { | ||
| n, err := r.Read(b) | ||
| if err != nil { | ||
| break | ||
| } | ||
| if iscmd(string(b[0:n])) { | ||
| data += string(b[0:n]) | ||
| } | ||
| } | ||
| return string(data) | ||
@@ -56,0 +83,0 @@ } |
+5
-16
@@ -21,14 +21,2 @@ package brainfcompiler | ||
| func TestLexerBasic(t *testing.T) { | ||
| fmt.Println("\n----- Test whether the lexer runs without errors -----") | ||
| code := "[+-<.>]" | ||
| result := formatcode(lex(code)) | ||
| want := "|[=1|+=1|-=1|<=1|.=1|>=1|]=1|" | ||
| if result != want { | ||
| t.Errorf("Got |%v|, want |%v|!", result, want) | ||
| } | ||
| } | ||
| func TestLexerShorten(t *testing.T) { | ||
@@ -59,9 +47,10 @@ fmt.Println("\n----- Test whether the lexer can shorten code -----") | ||
| func TestIgnoreCharacters(t *testing.T) { | ||
| fmt.Println("\n----- Test whether the lexer ignores characters that are not brainf commands -----") | ||
| func TestClearCommand(t *testing.T) { | ||
| fmt.Println("\n----- Test whether the lexer implements clear commands -----") | ||
| code := "..[--akdjfdk..///>><=--uieui]," | ||
| code := ">>>>>>[>>>>>>>[-]>>]<<<<<<" | ||
| result := formatcode(lex(code)) | ||
| want := "|.=2|[=1|-=2|.=2|>=2|<=1|-=2|]=1|,=1|" | ||
| want := "|>=6|[=1|>=7|c=1|>=2|]=1|<=6|" | ||
| if result != want { | ||
@@ -68,0 +57,0 @@ t.Errorf("Got %v, want %v !", result, want) |
+14
-25
| package brainfcompiler | ||
| import ( | ||
| // "fmt" | ||
| // "fmt" | ||
| "strings" | ||
| ) | ||
@@ -17,16 +18,7 @@ | ||
| func iscmd(cmd string) bool { | ||
| var allowed = [8]string{"[", "]", ".", ",", ">", "<", "+", "-"} | ||
| func lex(code string) []instruction { | ||
| for _, char := range allowed { | ||
| if char == cmd { | ||
| return true | ||
| } | ||
| } | ||
| code = strings.Replace(code, "[-]", "c", -1) | ||
| code = strings.Replace(code, "[+]", "c", -1) // Clear cell | ||
| return false | ||
| } | ||
| func lex(code string) []instruction { | ||
| currentinstruct := string(code[0]) | ||
@@ -42,16 +34,13 @@ magnitude := 1 | ||
| if iscmd(char) { | ||
| if char == currentinstruct && char != "[" && char != "]" && char != "c" { | ||
| // Increase the current magnitude, if the instruction is repeated | ||
| magnitude++ | ||
| if char == currentinstruct && char != "[" && char != "]" { | ||
| // Increase the current magnitude, if the instruction is repeated | ||
| magnitude++ | ||
| } else { | ||
| } else { | ||
| // Jump out of the current instruction, add it to the slice of instructions | ||
| instruct = makeInstruction(currentinstruct, magnitude) | ||
| instructionlist = append(instructionlist, instruct) | ||
| currentinstruct = char | ||
| magnitude = 1 | ||
| } | ||
| // Jump out of the current instruction, add it to the slice of instructions | ||
| instruct = makeInstruction(currentinstruct, magnitude) | ||
| instructionlist = append(instructionlist, instruct) | ||
| currentinstruct = char | ||
| magnitude = 1 | ||
| } | ||
@@ -58,0 +47,0 @@ } |
+8
-5
| # BrainF Compiler | ||
| This is a BrainF Compiler written in Golang. It converts BrainF code to C code, and then finally machine language, thus generating an executable. My aim is for it to be the fastest BrainF executor I've written yet. | ||
| This is a BrainF Compiler written in Golang. It converts BrainF code to C++ code, and then finally machine language, thus generating an executable. My aim is for it to be the fastest BrainF executor I've written yet. | ||
| As of now, this compiler is able to draw a mandelbrot set in 11 seconds. take a look at [mandelbrot.bf](/mandelbrot.bf) for the program | ||
| # Usage | ||
| ## Setup | ||
| 1. If you are on Windows or Debian, you can go to the Releases tab to download the latest release. | ||
| 1. If you are on Windows, Linux or a Mac, you can go to the Releases tab to download the latest release. | ||
| 2. If you are on a different operating system, you will need to compile it on your machine (hopefully I will be able to do it for you in a few days). Create a file named `main.go` and paste the following code into it: | ||
| 2. If you are on a different operating system, you will need to compile it on your machine. Create a file named `main.go` and paste the following code into it: | ||
| ```go | ||
@@ -42,2 +42,5 @@ package main | ||
| ``` | ||
| The compiler used by default is `gcc`. Supported compilers are `gcc` and `g++` | ||
| Where: | ||
| 1. `filename` is the brainf file you want to compile | ||
| 2. `out` is the output file you want. Remember, on Windows, it will need to have a suffix of `.exe`! | ||
| 3. `compiler` is the C compiler you want to use. This option is not compulsory. The compiler used by default is `gcc`. Supported compilers are `gcc` and `g++` |
@@ -0,0 +0,0 @@ package brainfcompiler |
+12
-16
@@ -5,11 +5,5 @@ package brainfcompiler | ||
| var template = ` | ||
| #include <stdio.h> | ||
| var template = `#include <stdio.h> | ||
| char m[30000]={0};int p=0;int o=30000;int main(){` | ||
| char memory_blocks[30000] = {0}; | ||
| int pointer = 0; | ||
| int main() { | ||
| ` | ||
| func transpile(code []instruction) string { | ||
@@ -28,21 +22,23 @@ | ||
| case ">": | ||
| output += fmt.Sprintf("pointer += %v;pointer = pointer", char.magnitude) + " % 30000;" | ||
| output += fmt.Sprintf("p+=%v;p=p", char.magnitude) + "%" + "o;" | ||
| case "<": | ||
| output += fmt.Sprintf("pointer -= %v;pointer = pointer", char.magnitude) + " % 30000;" | ||
| output += fmt.Sprintf("p-=%v;p=p", char.magnitude) + "%" + "o;" | ||
| case ".": | ||
| output += "putchar(memory_blocks[pointer]);" | ||
| output += "putchar(m[p]);" | ||
| case ",": | ||
| output += "memory_blocks[pointer]=getchar();" | ||
| output += "m[p]=getchar();" | ||
| case "+": | ||
| output += fmt.Sprintf("memory_blocks[pointer] += %v;", char.magnitude) | ||
| output += fmt.Sprintf("m[p]+=%v;", char.magnitude) | ||
| case "-": | ||
| output += fmt.Sprintf("memory_blocks[pointer] -= %v;", char.magnitude) | ||
| output += fmt.Sprintf("m[p]-=%v;", char.magnitude) | ||
| case "[": | ||
| output += "while (memory_blocks[pointer]){" | ||
| output += "while(m[p]){" | ||
| case "]": | ||
| output += "}" | ||
| case "c": | ||
| output += "m[p]=0;" | ||
| } | ||
| } | ||
| return template + output + "\n}" | ||
| return template + output + "}" | ||
| } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet