Jacob_DiDiodato icon

Brainf**k Interpreter [V0.7]

Jacob_DiDiodato | PRO | 11/15/17 02:41:18 PM UTC | 0 ⭐ | 238 👁️ | Never ⏰ | []
Python |

6.18 KB

|

None

|

0 👍

/

0 👎

#! 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

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎