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