Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #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()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement