# Pythonista 3.5 # brainfuck interpreter # latest update: 202202010710 from array import array p = 0 # data pointer high_p = 0 # highest value of p pc = 0 # program counter top = 0 # top of the stack tc = 0 # total command count steps = 0 # number of execution steps command_set = "<>+-,.[]!" prog_mem = "" data_mem = array('B') data_mem = [ 0 for i in range(65536)] stack = array('I') stack = [ 0 for i in range(32768)] open_bracket = array('I') open_bracket = [ 0 for i in range(32768)] close_bracket = array('I') close_bracket = [ 0 for i in range(32768)] bracket_check = "" bracket_counter = 0 bc_counter = 0 #bracket_check counter nesting_levels = 0 key_press = "" input_buffer = "" def printable(n): if((n>31 and n<127) or n == 10): return(True) else: return(False) # whole memory output from 0 to highest value of 'p' def dump(x): # x should only be current value of p format_count = 0 print() for i in range(high_p + 1): if(i == x): left_cc = "{" # put an indcator right_cc = "}" # around the current cell else: left_cc = " " right_cc = " " if(printable(data_mem[i])): print("|" + left_cc + "%05d" % i + chr(data_mem[i]) + "%03d" % data_mem[i], end = right_cc) format_count += 1 if(format_count % 8 == 0): print("|") else: print("|" + left_cc + "%05d" % i + " " + "%03d" % data_mem[i], end = right_cc) format_count += 1 if(format_count % 8 == 0): print("|") print("|") # load bf program into memory file = open(input("bf file: "), 'r') while True: nextch = file.read(1) if(not nextch): file.close() break if(nextch in command_set): prog_mem += (nextch) tc = len(prog_mem) # check bracket integrity ################################# for i in range(tc): if(prog_mem[i] == "[" or prog_mem[i] == "]"): bracket_check += prog_mem[i] for i in range(len(bracket_check)): if(bracket_check[i] == "["): bc_counter += 1 nesting_levels = max(bc_counter, nesting_levels) elif(bracket_check[i] == "]"): bc_counter -= 1 if(bc_counter < 0): print("mismatch") quit() if(bc_counter != 0): print("mismatch") quit() #########not THAT necessary to check bracket formatting### # calculate bracket locations, store in bracket stacks for i in range(tc): if(prog_mem[i] == '['): top += 1 stack[top] = i elif(prog_mem[i] == ']'): close_bracket[bracket_counter] = i open_bracket[bracket_counter] = stack[top] top -= 1 bracket_counter += 1 # run bf program while(pc < len(prog_mem)): if(prog_mem[pc] == "+"): data_mem[p] = (data_mem[p] + 1) % 256 pc += 1 steps += 1 # print("+", end = "") #expand brackets elif(prog_mem[pc] == "-"): data_mem[p] = (data_mem[p] - 1) % 256 pc += 1 steps += 1 # print("-", end = "") #expand brackets elif(prog_mem[pc] == ">"): p += 1 high_p = max(p, high_p) pc += 1 steps += 1 # print(">", end = "") #expand brackets # no checking is performed to catch p < 0 elif(prog_mem[pc] == "<"): p -= 1 pc += 1 steps += 1 # print("<", end = "") #expand brackets elif(prog_mem[pc] == "."): if(printable(data_mem[p])): print(chr(data_mem[p]), end = "") pc += 1 steps += 1 # print(".", end = "") #expand brackets # INPUT # enter one char at a time, or several # they will be used as needed # use one more prompt to enter (cr) for EOF elif(prog_mem[pc] == ","): if(input_buffer == ""): input_buffer = input(": ") if(input_buffer == ""): # still empty - (cr) entered data_mem[p] = 0 else: key_press = input_buffer[0] input_buffer = input_buffer[1:] data_mem[p] = ord(key_press) pc += 1 steps += 1 # print(",", end = "") #uncomment to expand brackets elif(prog_mem[pc] == "["): steps += 1 if(data_mem[p] == 0): pc = close_bracket[open_bracket.index(pc)] + 1 else: pc += 1 elif(prog_mem[pc] == "]"): # steps += 1 # close brackets not typically counted pc = open_bracket[close_bracket.index(pc)] elif(prog_mem[pc] == "!"): pc += 1 dump(p) # p simply marks position of data pointer # print out program data print("\n\n highest value of P: ", high_p) print("current location of P: ",p) print(" total commands: ", tc - prog_mem.count("!")) print(" total steps: ", steps) print(" nesting levels: ", nesting_levels) print(" total bracket pairs: ", bracket_counter) print()