Last active
May 31, 2016 13:34
-
-
Save ibigbug/822ede682f3504c2b31b to your computer and use it in GitHub Desktop.
brainfuck python implement
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
""" | |
A simple and powerful `Brainfuck` interpreter implementation in Python | |
Steal from: http://blog.csdn.net/redraiment/article/details/7483062 | |
""" | |
def _gen_array(length): | |
return [0 for i in range(0, length)] | |
TOKENS = ['<', '>', '+', '-', ',', '.', '[', ']'] | |
class VM(object): | |
cs = _gen_array(3000) # Code Segment | |
ip = 0 # Instructin Pointer | |
ss = _gen_array(3000) # Stack Segment, max stack depth 3000! | |
sp = 0 # Stack Pointer | |
ds = _gen_array(3000) # Data Segment | |
bp = 0 # Base Pointer | |
fn = {} | |
vm = VM() | |
def vm_forward(): | |
vm.bp += 1 | |
def vm_backward(): | |
vm.bp -= 1 | |
def vm_inc(): | |
vm.ds[vm.bp] += 1 | |
def vm_dec(): | |
vm.ds[vm.bp] -= 1 | |
def vm_input(): | |
vm.ds[vm.bp] = sys.stdin.read(1) | |
def vm_output(): | |
sys.stdout.write(chr(vm.ds[vm.bp])) | |
def vm_while_enter(): | |
if vm.ds[vm.bp]: | |
# Like function call, push the current ip into stack, aka *protect env* | |
# Each `while loop` becomes a new stack frame | |
vm.ss[vm.sp] = vm.ip - 1 | |
vm.sp += 1 | |
else: | |
m = 1 | |
vm.ip += 1 # to skip the enter TOKEN `[` | |
while vm.cs[vm.ip] and m: | |
vm.ip += 1 | |
if vm.cs[vm.ip] == '[': | |
m += 1 | |
elif vm.cs[vm.ip] == ']': | |
m -= 1 | |
def vm_while_leave(): | |
if vm.ds[vm.bp]: # why this `if`? | |
# pop stack frame | |
vm.sp -= 1 | |
vm.ip = vm.ss[vm.sp] | |
def setup(source): | |
vm.fn['>'] = vm_forward | |
vm.fn['<'] = vm_backward | |
vm.fn['+'] = vm_inc | |
vm.fn['-'] = vm_dec | |
vm.fn['.'] = vm_output | |
vm.fn[','] = vm_input | |
vm.fn['['] = vm_while_enter | |
vm.fn[']'] = vm_while_leave | |
i = 0 | |
for c in source: | |
if c in TOKENS: | |
vm.cs[i] = c | |
i += 1 | |
def run(): | |
while (vm.cs[vm.ip]): | |
vm.fn[vm.cs[vm.ip]]() | |
vm.ip += 1 | |
def main(): | |
if len(sys.argv) > 1: | |
f = open(sys.argv[1], 'rb') | |
source = f.read() | |
f.close() | |
setup(source) | |
run() | |
if __name__ == '__main__': | |
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
++++++++++[>+++++++>++++++++++>+++>+<<<<-] | |
>++.>+.+++++++..+++.>++.<<+++++++++++++++. | |
>.+++.------.--------.>+.>. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment