Advertisement
bf17

Bitter Interpreter

May 12th, 2017
448
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.25 KB | None | 0 0
  1. #python 3
  2. # bitter - like brainfuck, only much, much, worse
  3. # mathematically equivalent to Smallfuck
  4. # Lineage:
  5. #   Brainfuck > Boolfuck > Smallfuck > Bitter
  6.  
  7. #set up variables, arrays
  8. from array import array
  9.  
  10. p = 0       # data pointer
  11. high_p = 0  # highest value of p
  12. pc = 0      # program counter
  13. top = 0     # top of the stack
  14. tc = 0      # total command count
  15. steps = 0   # number of execution steps
  16. command_set = "+-()!"
  17.  
  18. prog_mem = ""
  19. data_mem =       array('B')
  20. data_mem =       [ 0 for i in range(10000)]
  21. stack =          array('I')
  22. stack =          [ 0 for i in range(5000)]
  23. open_paren =     array('I')
  24. open_paren =     [ 0 for i in range(5000)]
  25. close_paren =    array('I')
  26. close_paren =    [ 0 for i in range(5000)]
  27. paren_check =    ""
  28. paren_counter =  0
  29. pch_counter =    0   #paren check counter
  30. nesting_levels = 0
  31.  
  32. # load bitter program into memory
  33. file = open(input("bitter file "), 'r')
  34. while True:
  35.     nextch = file.read(1)
  36.     if(not nextch): break
  37.    
  38.     if(nextch in command_set):
  39.         prog_mem += nextch
  40.  
  41. file.close()
  42.  
  43. tc = len(prog_mem)
  44.  
  45. # define functions
  46. def find_open(x):
  47.     return(open_paren[close_paren.index(x)])
  48.  
  49. def find_close(x):
  50.     return(close_paren[open_paren.index(x)])
  51.  
  52. def flip(x):              # x = data_mem[i]
  53.     return(abs(~x) % 2)   # = not x
  54.  
  55. def dump(x):
  56.     format_count = 0
  57.     for i in range(high_p + 1):
  58.         if(i == x): cc = "#"  # marks position of data pointer
  59.         else: cc = "-"  # char in between address and bit
  60.         format_count += 1
  61.         print("%04d" % i + cc + str(data_mem[i]), end = "|")
  62.         if(format_count % 16 == 0): print(" ")
  63.     print()
  64.  
  65. # check parentheses integrity
  66. for i in range(tc):
  67.     if(prog_mem[i] == "(" or prog_mem[i] == ")"):
  68.         paren_check += prog_mem[i]
  69.  
  70. for i in range(len(paren_check)):
  71.     if(paren_check[i] == "("):
  72.         pch_counter += 1
  73.         nesting_levels = max(pch_counter, nesting_levels)
  74.  
  75.     elif(paren_check[i] == ")"):
  76.         pch_counter -= 1
  77.         if(pch_counter < 0):
  78.             print("mismatch")
  79.             quit()
  80.  
  81. if(pch_counter != 0):
  82.     print("mismatch")
  83.     quit()
  84.    
  85. # calculate parentheses locations
  86. for i in range(tc):
  87.     if(prog_mem[i] == '('):
  88.         top += 1
  89.         stack[top] = i
  90.     elif(prog_mem[i] == ')'):
  91.         close_paren[paren_counter] = i
  92.         open_paren[paren_counter] = stack[top]
  93.         top -= 1
  94.         paren_counter += 1
  95.  
  96. # print out arrays of open/close parentheses (debugging)
  97. '''
  98. for i in range(paren_counter):
  99.     print("\n", i, ": ", open_paren[i], close_paren[i])
  100. '''
  101. # run program
  102. while(pc < len(prog_mem)):
  103.     if(prog_mem[pc] == "+"):
  104.         pc += 1
  105.         steps += 1
  106.         p += 1
  107.         high_p = max(p, high_p)
  108.         data_mem[p] = flip(data_mem[p])
  109.    
  110.     elif(prog_mem[pc] == "-"):
  111.         pc += 1
  112.         steps += 1
  113.         p -= 1
  114.         if(p < 0):
  115.             print("data pointer moved below zero")
  116.             dump(p)
  117.             quit()
  118.         else:
  119.             data_mem[p] = flip(data_mem[p])
  120.  
  121.     elif(prog_mem[pc] == "("):
  122.         steps += 1
  123.         if(data_mem[p] == 0):
  124.             pc = close_paren[open_paren.index(pc)] + 1
  125.         else:
  126.             pc += 1
  127.  
  128.     elif(prog_mem[pc] == ")"):
  129.         steps += 1
  130.         pc = open_paren[close_paren.index(pc)]
  131.    
  132.     elif(prog_mem[pc] == "!"):
  133.         pc += 1
  134.         dump(p)
  135.  
  136. # print out program data
  137. print()
  138. print("\ntotal commands: ", tc - prog_mem.count("!"))
  139. print("total steps: ", steps)
  140. print("nesting levels: ", nesting_levels)
  141. print("total paren pairs: ", paren_counter)
  142. print()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement