1. #!/usr/bin/env python3
    
  2. import sys
    
  3. 
    
  4. TAPE_LEN = 30*1000
    
  5. def build_jumps(prog):
    
  6.     '''
    
  7.     build a pair of dicts from
    
  8.     a program.
    
  9.     returns (forward, backward)
    
  10.     forward maps forward->back
    
  11.     backward maps backward->forward
    
  12.     '''
    
  13.     forward = {}
    
  14.     backward = {}
    
  15.     stack = []
    
  16.     i = 0
    
  17.     while i < len(prog):
    
  18.         if prog[i] == '[':
    
  19.             stack.append(i)
    
  20.         elif prog[i] == ']':
    
  21.             match = stack.pop()
    
  22.             backward[i] = match
    
  23.             forward[match] = i
    
  24.         i += 1
    
  25.         pass
    
  26.     return (forward, backward)
    
  27. 
    
  28. def bf(prog):
    
  29.     tape = [0]*TAPE_LEN
    
  30.     (forward, backward) = build_jumps(prog)
    
  31.     ptr = 0
    
  32.     pc = 0
    
  33.     end = len(prog)
    
  34.     while pc < end:
    
  35.         c = prog[pc]
    
  36.         if c == '+':
    
  37.             tape[ptr] = (tape[ptr]+1) % 255
    
  38.         elif c == '-':
    
  39.             tape[ptr] = (tape[ptr]-1) % 255
    
  40.         elif c == '>':
    
  41.             ptr += 1
    
  42.         elif c == '<':
    
  43.             ptr -= 1
    
  44.         elif c =='[':
    
  45.             if tape[ptr] == 0:
    
  46.                 pc = forward[pc]
    
  47.         elif c == ']':
    
  48.             if tape[ptr] != 0:
    
  49.                 pc = backward[pc]
    
  50.         elif c == '.':
    
  51.             print(chr(tape[ptr]), end='')
    
  52.         elif c == ',':
    
  53.             print(", unimplemented")
    
  54.             sys.exit(1)
    
  55.         else:
    
  56.             print("unhandled instn: {}".format(c))
    
  57.             sys.exit(1)
    
  58.         pc += 1
    
  59. 
    
  60. def clean(lines):
    
  61.     data = ""
    
  62.     for line in lines:
    
  63.         if line.startswith(';'):
    
  64.             continue
    
  65.         else:
    
  66.             data += line
    
  67.     data = data.replace('\n', '')
    
  68.     data = data.replace(' ', '')
    
  69.     return data
    
  70.     
    
  71. if __name__ == "__main__":
    
  72.     with open(sys.argv[1]) as f:
    
  73.         lines = f.readlines()
    
  74.         bf(clean(lines))