Skip to content

Instantly share code, notes, and snippets.

@ravener
Created May 12, 2024 11:17
Show Gist options
  • Save ravener/e10492c85e86951e141c33a5d24be9f8 to your computer and use it in GitHub Desktop.
Save ravener/e10492c85e86951e141c33a5d24be9f8 to your computer and use it in GitHub Desktop.
Brainfuck Interpreter in Python
#!/usr/bin/python3
# -*- coding: utf8 -*-
import sys
from argparse import ArgumentParser
from pathlib import Path
def compute_jump_table(instructions: str) -> dict[int, int]:
"""
Computes a jump-table for associating the braces with their start and end positions.
So for example if [ is seen at position 47 and it's ending is seen at position 80,
the jump table will have { 47: 80, 80: 47 }, allowing either of them to know the position of the other end.
"""
bracemap = {}
stack = []
for index, char in enumerate(instructions):
if char == "[":
stack.append(index)
elif char == "]":
start = stack.pop()
bracemap[start] = index
bracemap[index] = start
return bracemap
def run(instructions: str):
jump_table = compute_jump_table(instructions)
cells = [0] * 30_000
pc = 0
cur_cell = 0
while pc != len(instructions):
command = instructions[pc]
match command:
case "+":
cells[cur_cell] += 1
case "-":
cells[cur_cell] -= 1
case "<":
cur_cell -= 1
case ">":
cur_cell += 1
case ",":
cells[cur_cell] = ord(sys.stdin.read(1))
case ".":
sys.stdout.write(chr(cells[cur_cell]))
case "[":
if cells[cur_cell] == 0:
pc = jump_table[pc]
case "]":
if cells[cur_cell] != 0:
pc = jump_table[pc]
pc += 1
if __name__ == "__main__":
parser = ArgumentParser(description="Interpret Brainfuck code")
parser.add_argument("input", help="Input file")
args = parser.parse_args()
file = Path(args.input).read_text()
run(file)
@ravener
Copy link
Author

ravener commented May 12, 2024

I've also written a blog post on this.

If licensing matters, I'm giving this away under Public Domain so feel free to do whatever.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment