bf17 icon

Bitter Interpreter

bf17 | PRO | 05/13/17 04:30:58 AM UTC | 0 ⭐ | 872 👁️ | Never ⏰ | []
Python |

3.25 KB

|

None

|

0 👍

/

0 👎

#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