Skip to content

Instantly share code, notes, and snippets.

@TapGhoul
Created February 14, 2018 22:39
Show Gist options
  • Select an option

  • Save TapGhoul/5b807e936f25de8602317be33b2d2253 to your computer and use it in GitHub Desktop.

Select an option

Save TapGhoul/5b807e936f25de8602317be33b2d2253 to your computer and use it in GitHub Desktop.
A brainfuck interpreter in golang. Because I was bored.
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