Skip to content

Instantly share code, notes, and snippets.

@Bruntaz
Created November 13, 2016 18:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Bruntaz/c90d94d94836f7f565c0b502d3bd0544 to your computer and use it in GitHub Desktop.
Save Bruntaz/c90d94d94836f7f565c0b502d3bd0544 to your computer and use it in GitHub Desktop.
A first pass at a brainfuck implementation written in Python. It could easily be made more efficient (by removing unnecessary characters before executing etc.) but the code is pretty clean.
def executeBrainfuck(brainfuckCode):
valueList = [0]
listPointer = 0
programCounter = 0
programStack = []
while programCounter < len(brainfuckCode):
instruction = brainfuckCode[programCounter]
if instruction == ">": # Increment pointer
# If list isn't long enough, increase length
if listPointer + 1 == len(valueList):
valueList.append(0)
listPointer += 1
elif instruction == "<": # Decrement pointer
listPointer -= 1
if listPointer < 0: # Pointer out of range
raise Exception("listPointer is negative")
elif instruction == "+": # Increment value
valueList[listPointer] += 1
elif instruction == "-": # Decrement value
valueList[listPointer] -= 1
elif instruction == ".": # Print value
print(chr(valueList[listPointer]), end='')
elif instruction == ",": # Input character
# Ensure a character is inputted
userInput = ""
while userInput == "":
userInput = input()
# Add first inputted character's ASCII value
valueList[listPointer] = ord(userInput[0])
elif instruction == "[": # Start loop
if valueList[listPointer] == 0:
unequalBrackets = 1
# Jump to the end of the loop
while unequalBrackets > 0:
programCounter += 1
# Crash if no closing bracket is found
if programCounter >= len(brainfuckCode):
raise Exception("Unequal brackets in loop. There are " + str(unequalBrackets) + " brackets still open.")
if brainfuckCode[programCounter] == "[":
unequalBrackets += 1
elif brainfuckCode[programCounter] == "]":
unequalBrackets -= 1
else:
programStack.append(programCounter)
elif instruction == "]": # End loop
# Loop must be balanced
if len(programStack) == 0:
raise Exception("programStack is empty")
# If value is 0 continue execution, otherwise loop
if valueList[listPointer] == 0:
programStack.pop()
else:
programCounter = programStack[-1]
else: # If invalid character, ignore it
pass
programCounter += 1
# Example brainfuck code
brainfuckCode = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>."
executeBrainfuck(brainfuckCode)
@b8horpet
Copy link

b8horpet commented Nov 13, 2016

in brainfuck you can go left from the starting point
also values are stored as bytes so they wrap around when incremented or decremented

@bragr
Copy link

bragr commented Nov 15, 2016

@b8horpet Neither of those are strictly true. There is no formal language spec, so most of this is a matter of debate.

I looked at few implementations real quick for reference. It seems that various implementations use different sized cells anywhere from 8-64 bits, or even a few with unlimited size. It also looks like most implementations do not allow you to move left of cell 0, although some do.

Since any BF programs that relies on over/under flow, or moving left of cell 0, can be rewritten to work without it, I don't think this is a big deal. If one wants to write "portable" BF, you should avoid these anyways.

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