Created
January 23, 2017 11:05
-
-
Save justinfay/1144c56eacbfb982777225f23a2f80ff to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Taken from: https://learnxinyminutes.com/docs/brainfuck/ | |
| There are eight commands: | |
| + : Increments the value at the current cell by one. | |
| - : Decrements the value at the current cell by one. | |
| > : Moves the data pointer to the next cell (cell on the right). | |
| < : Moves the data pointer to the previous cell (cell on the left). | |
| . : Prints the ASCII value at the current cell (i.e. 65 = 'A'). | |
| , : Reads a single input character into the current cell. | |
| [ : If the value at the current cell is zero, skips to the corresponding ] . | |
| Otherwise, move to the next instruction. | |
| ] : If the value at the current cell is zero, move to the next instruction. | |
| Otherwise, move backwards in the instructions to the corresponding [ . | |
| [ and ] form a while loop. Obviously, they must be balanced. | |
| """ | |
| import sys | |
| INCREMENT = '+' | |
| DECREMENT = '-' | |
| MOVER = '>' | |
| MOVEL = '<' | |
| PRINT = '.' | |
| READ = ',' | |
| WHILE_START = '[' | |
| WHILE_END = ']' | |
| OPERATIONS = ( | |
| INCREMENT, | |
| DECREMENT, | |
| MOVER, | |
| MOVEL, | |
| PRINT, | |
| READ, | |
| WHILE_START, | |
| WHILE_END) | |
| TAPE = [0]*30000 | |
| def lex(stream): | |
| return [char for char in stream if char in OPERATIONS] | |
| def parse(tokens): | |
| index = 0 | |
| # A stack of executed instructions. | |
| stack = [] | |
| while True: | |
| try: | |
| next_ = tokens.pop(0) | |
| except IndexError: | |
| break | |
| else: | |
| stack.append(next_) | |
| if next_ == INCREMENT: | |
| TAPE[index] += 1 | |
| elif next_ == DECREMENT: | |
| TAPE[index] -= 1 | |
| elif next_ == MOVER: | |
| index += 1 | |
| elif next_ == MOVEL: | |
| if index == 0: | |
| raise RuntimeError() | |
| index -= 1 | |
| elif next_ == PRINT: | |
| print(chr(TAPE[index]), end='') | |
| elif next_ == READ: | |
| TAPE[index] = ord(sys.stdin.read(1)) | |
| elif next_ == WHILE_START: | |
| if TAPE[index] == 0: | |
| # Skip to matching ']'. | |
| while True: | |
| n = tokens.pop(0) | |
| if n == WHILE_END: | |
| tokens.insert(0, n) | |
| break | |
| stack.append(n) | |
| elif next_ == WHILE_END: | |
| if TAPE[index] != 0: | |
| # Go back to opening '['. | |
| while True: | |
| n = stack.pop() | |
| tokens.insert(0, n) | |
| if n == WHILE_START: | |
| break | |
| def read_file(path): | |
| with open(path) as fh: | |
| return fh.read() | |
| if __name__ == "__main__": | |
| path = sys.argv[1] | |
| parse(lex(read_file(path))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment