A quick Python version (now tested):import sys
class _Getch: # A cross-platform method to read a single character, obtained from activestate.com def __init__(self): try: self.impl = _GetchWindows() except ImportError: self.impl = _GetchUnix() def __call__(self): return self.impl()
class _GetchUnix: def __init__(self): import tty, sys def __call__(self): import tty, sys, termios fd = sys.stdin.fileno() old_settings = termios.tcgetattr(fd) try: tty.setraw(sys.stdin.fileno()) ch = sys.stdin.read(1) finally: termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) return ch
class _GetchWindows: def __init__(self): import msvcrt
def __call__(self): import msvcrt return msvcrt.getch()
getch = _Getch()
if len(sys.argv) != 2: # If they didn't supply a file to parse... file = sys.stdin #...parse standard input. else: file = open(sys.argv[1], "r")
stack = [] data = [0] ptr = 0 skip = 0
while True: cur = file.read(1) if not cur: break # We hit the end of the file. elif not skip: if cur == ">": ptr += 1 if ptr >= len(data): data.append(0) elif cur == "<": if ptr > 0: ptr -= 1 else: data.insert(0, 0) elif cur == "+": data[ptr] += 1 elif cur == "-": data[ptr] -= 1 elif cur == ".": print(chr(data[ptr], end="") # Don't add a newline after printing. elif cur == ",": data[ptr] = ord(getch()) elif cur == "[": stack.append(file.tell()) if data[ptr] == 0: skip = len(stack) elif cur == "]": if data[ptr] == 0: stack.pop() else: file.seek(stack[-1] else: if cur == "[": stack.append(file.tell()) elif cur == "]": stack.pop() if skip > len(stack): skip = 0
EDIT: Fixed two bugs (the "extend data field rightwards" code needed to do a >= check, not a > check, and the file.seek() call popping the stack was causing an error when it ran into the closing bracket again) and successfully ran the following program (obtained from wikipedia):+++++ +++++ initialize counter (cell #0) to 10 [ use loop to set the next four cells to 70/100/30/10 > +++++ ++ add 7 to cell #1 > +++++ +++++ add 10 to cell #2 > +++ add 3 to cell #3 > + add 1 to cell #4 <<<< - decrement counter (cell #0) ] > ++ . print 'H' > + . print 'e' +++++ ++ . print 'l' . print 'l' +++ . print 'o' > ++ . print ' ' << +++++ +++++ +++++ . print 'W' > . print 'o' +++ . print 'r' ----- - . print 'l' ----- --- . print 'd' > + . print '!' > . print '\n'
|