Created
May 12, 2024 11:17
-
-
Save ravener/e10492c85e86951e141c33a5d24be9f8 to your computer and use it in GitHub Desktop.
Brainfuck Interpreter in Python
This file contains 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
#!/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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.