August 22, 2011

Brainfuck

If you like programming and have looked around at various programming languages, then you've probably stumbled upon brainfuck at some point. For those unfamiliar with it, it is a non-practical, minimalistic language designed to amuse programmers.

Here's a "Hello World" program (source):



++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.


Yeah, check that shit out.  I can see you pissing your pants as I type this.  Here's a quick run down of what each character represents in brainfuck:


  • + means increment the current cell.
  • - means decrement the current cell.
  • > means shift the current cell to the right.
  • < means shift the current cell to the left.
  • [ means begin a loop.
  • ] means end of a loop, if the current cell  is not 0, jump to the beginning of the loop, else, continue (the [ and ] instructions can have a different meaning depending on the implementation, but they should behave the same way.
  • . means print out the ASCII representation of the current cell.
  • , means get an input and write it to the current cell.
As you can probably guess, writing in brainfuck is a bit of a ... brain fuck.  Programs are difficult to read for beginners, but with practice, it can be pretty easy to decipher brainfuck.  

Anyway, I decided to write my own brainfuck interpreter in python.  For any of you insane fucks interested, here is the source:

import sys

j=0
a = [0]
ptr = 0
loopbegin = 0
i = ""
x=0
while i !="`":
    try:
        x=0
        v = raw_input("\n~")
        while x < len(v):
            i = v[x]
            if i=='>':
                ptr+=1
                if  len(a) <= ptr:
                    a.append(0)
            elif i=='<':
                ptr-=1
            elif i=='+':
                a[ptr]+=1
            elif i=='-':
                a[ptr]-=1
            elif i==',':
                a[ptr] = ord(raw_input("~! "))
            elif i=='.':
                sys.stdout.write(chr(a[ptr]))
            elif i=='[':
                loopbegin = x
            elif i==']':
                if a[ptr] != 0:
                    x = loopbegin
            x+=1
    except:
        print("At char: %s: %s" %(i, ptr))
        print "Unexpected error:", sys.exc_info()[0]
        raise


I'm sure this can be optimized, and I think there is a bug with nested loops that I'm going ti work out tonight, but I don't really care that much since the language is not very useful anyway.  As for the specifics of my implementation:
  • This version uses a dynamic array of cells, which -- since I'm using python -- has a maximum size of 536,870,912 elements on a 32 bit system.
  • Since the array of cells is dynamic, its starting size is 1.  If the > operator is used, and the array is not large enough, it appends a new element to the end of the array.
  • The ` character is used to quit the application.
Anyway, if you don't have python, you can always use the javascript implementation of brainfuck here.

0 comments:

Post a Comment