# 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()
Comments