#python 3
# bitter - like brainfuck, only much, much, worse
# mathematically equivalent to Smallfuck
# Lineage:
# Brainfuck > Boolfuck > Smallfuck > Bitter
#set up variables, arrays
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(10000)]
stack = array('I')
stack = [ 0 for i in range(5000)]
open_paren = array('I')
open_paren = [ 0 for i in range(5000)]
close_paren = array('I')
close_paren = [ 0 for i in range(5000)]
paren_check = ""
paren_counter = 0
pch_counter = 0 #paren check counter
nesting_levels = 0
# load bitter program into memory
file = open(input("bitter file "), 'r')
while True:
nextch = file.read(1)
if(not nextch): break
if(nextch in command_set):
prog_mem += nextch
file.close()
tc = len(prog_mem)
# define functions
def find_open(x):
return(open_paren[close_paren.index(x)])
def find_close(x):
return(close_paren[open_paren.index(x)])
def flip(x): # x = data_mem[i]
return(abs(~x) % 2) # = not x
def dump(x):
format_count = 0
for i in range(high_p + 1):
if(i == x): cc = "#" # marks position of data pointer
else: cc = "-" # char in between address and bit
format_count += 1
print("%04d" % i + cc + str(data_mem[i]), end = "|")
if(format_count % 16 == 0): print(" ")
print()
# check parentheses integrity
for i in range(tc):
if(prog_mem[i] == "(" or prog_mem[i] == ")"):
paren_check += prog_mem[i]
for i in range(len(paren_check)):
if(paren_check[i] == "("):
pch_counter += 1
nesting_levels = max(pch_counter, nesting_levels)
elif(paren_check[i] == ")"):
pch_counter -= 1
if(pch_counter < 0):
print("mismatch")
quit()
if(pch_counter != 0):
print("mismatch")
quit()
# calculate parentheses locations
for i in range(tc):
if(prog_mem[i] == '('):
top += 1
stack[top] = i
elif(prog_mem[i] == ')'):
close_paren[paren_counter] = i
open_paren[paren_counter] = stack[top]
top -= 1
paren_counter += 1
# print out arrays of open/close parentheses (debugging)
'''
for i in range(paren_counter):
print("\n", i, ": ", open_paren[i], close_paren[i])
'''
# run program
while(pc < len(prog_mem)):
if(prog_mem[pc] == "+"):
pc += 1
steps += 1
p += 1
high_p = max(p, high_p)
data_mem[p] = flip(data_mem[p])
elif(prog_mem[pc] == "-"):
pc += 1
steps += 1
p -= 1
if(p < 0):
print("data pointer moved below zero")
dump(p)
quit()
else:
data_mem[p] = flip(data_mem[p])
elif(prog_mem[pc] == "("):
steps += 1
if(data_mem[p] == 0):
pc = close_paren[open_paren.index(pc)] + 1
else:
pc += 1
elif(prog_mem[pc] == ")"):
steps += 1
pc = open_paren[close_paren.index(pc)]
elif(prog_mem[pc] == "!"):
pc += 1
dump(p)
# print out program data
print()
print("\ntotal commands: ", tc - prog_mem.count("!"))
print("total steps: ", steps)
print("nesting levels: ", nesting_levels)
print("total paren pairs: ", paren_counter)
print()
Comments