Skip to content

Instantly share code, notes, and snippets.

@Alpha59
Last active October 24, 2017 15:16
Show Gist options
  • Save Alpha59/b7a6322d21151075aa487ffa70eb0bc9 to your computer and use it in GitHub Desktop.
Save Alpha59/b7a6322d21151075aa487ffa70eb0bc9 to your computer and use it in GitHub Desktop.
A very simple python implementation of a BrainF*** style language using nibbles (4-bits strings)
class Stack:
import sys
import re
chunks = []
heap = []
index = 0
stackIndex = 0
stack = []
ptrRight = "0000"
ptrLeft = "0001"
ptrAdd = "0010"
ptrSub = "0011"
printState = "0100"
readState = "0101"
loopStart = "0110"
loopEnd = "0111"
ptrRight10 = "1000"
ptrLeft10 = "1001"
ptrAdd10 = "1010"
ptrSub10 = "1011"
ifState = "1100"
ifNotState = "1101"
endIf = "1110"
breakState = "1111"
bytes = {
">": { "byte": ptrRight,
"F": (lambda stack: setattr(stack, "index", stack.index+1))},
"<": { "byte": ptrLeft,
"F": (lambda stack: setattr(stack, "index", stack.index-1))},
"+": { "byte": ptrAdd,
"F": (lambda stack: stack.updateIndex(1))},
"-": { "byte": ptrSub,
"F": (lambda stack: stack.updateIndex(-1))},
".": { "byte": printState,
"F": (lambda stack: Stack.sys.stdout.write(chr(stack.heap[stack.index])))},
",": { "byte": readState,
"F": (lambda stack: stack.index)}, # Eh, deal with this later.
"[": { "byte": loopStart,
"F": (lambda stack: stack.ExecuteLoop())},
"]": { "byte": loopEnd,
"F": (lambda stack: stack.ExecuteLoop())},
"$": { "byte": ptrRight10,
"F": (lambda stack: setattr(stack, "index", stack.index+10))},
"^": { "byte": ptrLeft10,
"F": (lambda stack: setattr(stack, "index", stack.index-10))},
"#": { "byte": ptrAdd10,
"F": (lambda stack: stack.updateIndex(10))},
"*": { "byte": ptrSub10,
"F": (lambda stack: stack.updateIndex(-10))},
"?": { "byte": ifState,
"F": (lambda stack: stack.ExecuteIf(True))},
"!": { "byte": ifNotState,
"F": (lambda stack: stack.ExecuteIf(False))},
"}": { "byte": endIf,
"F": (lambda stack: stack.ExecuteContinue())},
"|": { "byte": breakState,
"F": (lambda stack: stack.ExecuteBreak())}
}
def ensureLength(self):
while self.index > len(self.heap) - 1:
self.heap.append(0)
def ExecuteLoop(self):
if (self.chunks[self.stackIndex] == self.loopStart):
self.stack.append(self.stackIndex)
elif(self.chunks[self.stackIndex] == self.loopEnd):
if ( self.heap[self.index] < 1 ):
self.stack.pop()
else:
self.stackIndex = self.stack[-1]
def ExecuteIf(self, bitwise):
if ( self.heap[self.index] == bitwise):
#self.stackIndex += 1
pass
else:
while self.chunks[self.stackIndex] != self.endIf:
self.stackIndex += 1
def ExecuteContinue(self):
pass
def ExecuteBreak(self):
self.stackIndex = len(self.chunks) + 1
def updateIndex(self, val, set=False):
self.ensureLength()
if set:
self.heap[self.index] = val
else:
self.heap[self.index] += val
def showHeap(self):
print([[self.heap[i]] if self.index == i else self.heap[i] for i in range(len(self.heap))])
@staticmethod
def execute(biteme):
stack = Stack()
stack.chunks = Stack.chunkstring(biteme)
while stack.stackIndex < len(stack.chunks):
chunk = stack.chunks[stack.stackIndex]
f = [Stack.bytes[k]["F"] for k in Stack.bytes if Stack.bytes[k]["byte"] == chunk][0]
stack.ensureLength()
f(stack)
stack.stackIndex += 1
print("")
#stack.showHeap()
@staticmethod
def convert2Bytes(bf):
bf = Stack.re.sub(r'[^\>\<\+\-\.\,\[\]\$\^\#\*\?\!\|}]','',bf)
for k in Stack.bytes.iterkeys():
bf = bf.replace(k, Stack.bytes[k]['byte'])
return bf
@staticmethod
def chunkstring(string):
length = len(Stack.ptrRight)
return [string[0+i:length+i] for i in range(0, len(string), length)]# Sample Program to output something.
""" BrainF*** implementation
>+>######+++++>##########--->#->+>#>++++>[<]>?->[->>+<<]}>[>>[+>][<]>-]>>-<<[>.]
"""
""" Binary implementation
00000010000010101010101010101010101000100010001000100010000010101010101010101010101010101010101010100011001100110000101000110000001000001010000000100010001000100000011000010111000011000011000001100011000000000010000100010111111000000110000000000110001000000111011000010111000000110111000000000011000100010110000001000111
"""
@Alpha59
Copy link
Author

Alpha59 commented Oct 23, 2017

Originally everything was in bytes - but i changed them to nibbles without refactoring.

@Alpha59
Copy link
Author

Alpha59 commented Oct 24, 2017

The BrainF*** implementation adds a few extra elements to make it a little easier to work with...

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