Created
February 14, 2018 22:39
-
-
Save TapGhoul/5b807e936f25de8602317be33b2d2253 to your computer and use it in GitHub Desktop.
A brainfuck interpreter in golang. Because I was bored.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "fmt" | |
| "log" | |
| "os" | |
| ) | |
| func main() { | |
| if len(os.Args) == 1 { | |
| fmt.Printf("Usage: %s <brainfuck code>\n", os.Args[0]) | |
| os.Exit(1) | |
| } | |
| var ( | |
| code []byte | |
| memory [256]byte // Go auto-initializes this to all 0's | |
| memoryPtr byte | |
| codePtr int | |
| output = make([]byte, 0) | |
| ) | |
| code = []byte(os.Args[1]) | |
| for { | |
| if codePtr == len(code) { | |
| break | |
| } | |
| switch code[codePtr] { | |
| case '+': | |
| memory[memoryPtr]++ | |
| case '-': | |
| memory[memoryPtr]-- | |
| case '>': | |
| memoryPtr++ | |
| case '<': | |
| memoryPtr-- | |
| case '[': | |
| loopEntry := codePtr | |
| if memory[memoryPtr] == 0 { | |
| var loopCount = 1 | |
| for codePtr < len(code)-1 { | |
| codePtr++ | |
| if code[codePtr] == ']' { | |
| loopCount-- | |
| } else if code[codePtr] == '[' { | |
| loopCount++ | |
| } | |
| if loopCount == 0 { | |
| break | |
| } else if loopCount < 0 { | |
| log.Fatalf("Rogue ] at position %d\n", codePtr) | |
| } | |
| } | |
| if loopCount != 0 { | |
| log.Fatalf("Rogue [ at position %d\n", loopEntry) | |
| } | |
| } | |
| case ']': | |
| loopEntry := codePtr | |
| var loopCount = 1 | |
| for codePtr > 1 { | |
| codePtr-- | |
| if code[codePtr] == '[' { | |
| loopCount-- | |
| } else if code[codePtr] == ']' { | |
| loopCount++ | |
| } | |
| if loopCount == 0 { | |
| break | |
| } else if loopCount < 0 { | |
| log.Fatalf("Rogue [ at position %d\n", codePtr) | |
| } | |
| } | |
| if loopCount != 0 { | |
| log.Fatalf("Rogue ] at position %d\n", loopEntry) | |
| } | |
| continue | |
| case '.': | |
| output = append(output, memory[memoryPtr]) | |
| case ',': | |
| fmt.Fprintf(os.Stdout, "%d → 0x%x> ", codePtr, memoryPtr) | |
| os.Stdout.Sync() | |
| var char = []byte{0} | |
| os.Stdin.Read(char) | |
| if char[0] == '\n' { | |
| char[0] = 0 | |
| } | |
| memory[memoryPtr] = char[0] | |
| } | |
| codePtr++ | |
| } | |
| os.Stdout.Write(output) | |
| os.Stdout.Sync() | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment