#! python 2.7
"""
V: 0.7
Brainf**k Compiler
bfInterpreter06.py
Last edit was Tuesday, November 14th, 2017
Jacob DiDiodato
An interpreter for the brainf**k language written by Urban Muller
Supports the basic instructions for brainf**k as well as a few instructions I have implemented
Program size has been reduced by ~12 times from version 0.0
This interpreter should not be used when time is tight as it does take a long time to execute most instructions
If you find any bugs with this interpreter please PM me with the error message and steps to recreate the problem
----------------V0.7 PATCHNOTES----------------
Made the program slightly more efficient by precalculating upper and lower bounds on tape increments.
-> Takes slightly more time to compile
Ascii mandelbrot fractal took 286.495 seconds as opposed to 294.403 that it took with the last version
-----------------------------------------------
Note: This program relies on you having and using Python 2.7. It is almost certain that this won't work on Python 3.X. If you are using Python 3.X and refuse/don't understand how to change Python versions then consider using 2to3 which is a Python program that will change the Python 2.X semantics to Python 3.X, also be aware that is is UB in terms of my program so I can't guarantee that will work either. Just change to Python 2.7 :P
My apologies if I forgot to censor a f**k, I checked through this document a few times and it is written uncensored.
--SYMBOLS IN BRAINF**K--
> - Move the tape pointer over 1 cell towards positive direction
< - Move the tape pointer over 1 cell towards negative direction
+ - Increments the current unit of tape by 1
- - Decrements the current unit of tape by 1
. - Prints the value of the current tape
, - Takes an input from stdio and reads the decimal value into the current cell
[ - If the cell under the tape pointer is pointing to zero (or less?) then jump to (and pass) the matching square bracket
] - Jump back to the matching square bracket unless the cell that the tape pointer is pointing to is zero (or less?)
------------------------
-----EXTRA SYMBOLS-----
/ - Clears the current unit of tape (i.e sets it to zero)
* - Sets the current unit of tape to 255
| - Sets the current unit of tape to 128
{ - If the cell that the tape pointer is pointing to is zero (or less?) then jump to (and pass) the matching curly bracket
} - Required to end the conditional block
------------------------
"""
import os, sys
def checkClosed(srcText):
stack = []
i = 0
numInstructions = len(srcText)
while i < numInstructions:
try:
if (srcText[i] == "[" or srcText[i] == "{"):
stack.append(srcText[i])
elif (srcText[i] == "]" or srcText[i] == "}") and srcText[i] == chr(ord(stack.pop())):
return -1
except IndexError:
print "Error: Forgot to open loop or conditional."
return -1
i += 1
return 0
def interpret(srcText):
runningTab = ""
repeat = 1
i = 0
open("pySrc.py", "w").close()
pySrc = open("pySrc.py", "a")
pySrc.write("#! python 2.7\nfrom __future__ import print_function\n\ntape = [0] * 30000\ncurrentCell = 15000\n\n")
numInstructions = len(srcText)
while i < numInstructions:
if srcText[i] == ">":
try:
while srcText[i + 1] == ">":
repeat += 1
i += 1
except IndexError:
pass
upperBound = 29999 - repeat
pySrc.write(runningTab + "if (currentCell <= " + str(upperBound) + "):\n")
pySrc.write(runningTab + "\tcurrentCell += " + str(repeat) + "\n")
elif srcText[i] == "<":
try:
while srcText[i + 1] == "<":
repeat += 1
i += 1
except IndexError:
pass
lowerBound = 0 + repeat
pySrc.write(runningTab + "if (currentCell >= " + str(lowerBound) + "):\n")
pySrc.write(runningTab + "\tcurrentCell -= " + str(repeat) + "\n")
elif srcText[i] == "+":
try:
while srcText[i + 1] == "+":
repeat += 1
i += 1
except IndexError:
pass
pySrc.write(runningTab + "tape[currentCell] += " + str(repeat) + "\n")
elif srcText[i] == "-":
try:
while srcText[i + 1] == "-":
repeat += 1
i += 1
except IndexError:
pass
pySrc.write(runningTab + "tape[currentCell] -= " + str(repeat) + "\n")
elif srcText[i] == ".":
pySrc.write(runningTab + "print(chr(tape[currentCell]), end = '')\n")
elif srcText[i] == ",":
pySrc.write(runningTab + "userInput = raw_input('')\n" + runningTab + "for i in range(len(userInput)):\n" + runningTab + "\ttape[currentCell] = ord(userInput[i])\n" + runningTab + "\tcurrentCell += 1\n")
elif srcText[i] == "[":
pySrc.write(runningTab + "while tape[currentCell] > 0:\n")
runningTab += "\t"
try:
if srcText[i + 1] == "]":
pySrc.write(runningTab + "pass\n")
except IndexError:
print "Error: Forgot to close loop."
pySrc.close()
os.remove("pySrc.py")
raise SystemExit
elif srcText[i] == "]":
runningTab = runningTab[0:len(runningTab) - 1]
elif srcText[i] == "{":
pySrc.write(runningTab + "if tape[currentCell] > 0:\n")
runningTab += "\t"
try:
if srcText[i + 1] == "}":
pySrc.write(runningTab + "pass\n")
except IndexError:
print "Error: Forgot to close conditional."
pySrc.close()
os.remove("pySrc.py")
raise SystemExit
elif srcText[i] == "}":
runningTab = runningTab[0:len(runningTab) - 1]
elif srcText[i] == "/":
pySrc.write(runningTab + "tape[currentCell] = 0\n")
elif srcText[i] == "*":
pySrc.write(runningTab + "tape[currentCell] = 255\n")
elif srcText[i] == "|":
pySrc.write(runningTab + "tape[currentCell] = 128\n")
repeat = 1
i += 1
pySrc.close()
os.system("python pySrc.py")
os.remove("pySrc.py")
def main():
#Get the filename from the cmd arguments
try:
filename = str(sys.argv[1])
except:
print "Usage: python " + sys.argv[0] + " <filename>"
else:
#check if the file exists
try:
#Open the file
src = open(filename, "r")
except IOError:
#Give an English definition of the error
print "The file \"" + filename + "\" does not exist."
else:
retval = checkClosed(src.read())
if (retval == 0):
src.seek(0)
interpret(src.read())
if __name__ == "__main__":
main()
Comments
0 B
|👍
/👎