bf17 icon

BF Interpreter

bf17 | PRO | 02/01/22 12:10:22 PM UTC (Edited) | 0 ⭐ | 509 👁️ | Never ⏰ | []
Python |

4.95 KB

|

None

|

0 👍

/

0 👎

# 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