def repl(input_: str = ''): print(""" ______ _ __ _ | ___ \ (_) / _| | | | |_/ /_ __ __ _ _ _ __ | |_ _ _ ___| | __ _ __ _ _ | ___ \ '__/ _` | | '_ \| _| | | |/ __| |/ / | '_ \| | | | | |_/ / | | (_| | | | | | | | |_| | (__| < _| |_) | |_| | \____/|_| \__,_|_|_| |_|_| \__,_|\___|_|\_(_) .__/ \__, | | | __/ | |_| |___/ Welcome to the Brainfuck interpreter :) Written in Python 3 by @franciscocid (on Github!) Repo: https://github.com/franciscocid/brainfuckpy """) while True: try: repl_code = input('Input: ') brain = Brainfuck() result = brain.run(repl_code, input_) print('Output:', result) except (EOFError, KeyboardInterrupt): print("...Exiting...") exit(0) except Exception as e: print(e) raise e
class TestInterpreter(TestCase): def setUp(self): self.bf = Brainfuck() def test_multiple_programs_and_their_outputs(self): with open('test/res/lorem_ipsun.txt', 'r') as f: lorem_ipsun = f.read() cases = [ ('print_input.b', 'hello world', 'hello world'), ('test.b', '', 'i\'m a test'), ('not_really_long.b', '', 'Well, that\'s a really and really long and massive bit of text, well, not much actually, but it\'s a nice way to see if things are going as they should.'), ('lorem_ipsun.b', '', lorem_ipsun), ] for file, args, output in cases: path: str = os.path.join('test', 'programs', file) with open(path, 'r') as code_file: code: str = code_file.read() self.assertEqual(self.bf.run(code, args), output)
def fetch(self, var): """ Fetch a variable by copying it to two locations on the stack, then poping one back and saving it in memory. """ return self._sp() + \ self._set_zero() + \ var + \ '[-' + self._sp() + '+' + '>+' + var + ']' + \ self._sp() + \ self._widen() + \ self._widen() + \ self.store(var) def store(self, var): """ Store the value currently on the stack to some var. """ return self._squeeze() + \ var + \ self._set_zero() + \ self._sp() + \ '[-' + var + '+' + self._sp() + ']' s = Stack() code = s.push_const(2) + s.push_const(6) + s.subtract() compiled = cmpl(code) print code print compiled b = Brainfuck(compiled) b.run(print_state=True, sleep_time=0.01)
if args.log: if args.log == LOG_TO_STDOUT: logging.basicConfig(stream=sys.stdout, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.INFO) else: logging.basicConfig(filename='{}'.format(args.log), filemode='w', format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.INFO) if not args.file: brainfuck = Brainfuck() while True: instructions = input('> ') brainfuck.interpret(instructions) print(brainfuck.memory) if args.file: brainfuck = Brainfuck( "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>123+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." ) try: brainfuck.run() except KeyboardInterrupt: pass
from brainfuck import Brainfuck from util.logger import setup_logs from repl import repl import argparse, logging arg_parser = argparse.ArgumentParser(prog='bf', description='Brainfuck VM') arg_parser.add_argument('source', nargs='?', help='Source file') arg_parser.add_argument('--input', nargs='*', help='Input text') arg_parser.add_argument('--log', action='store_true', help='Display logs on stdout') args = arg_parser.parse_args() if args.log: setup_logs() input_: str = ' '.join(args.input) if args.input else '' if args.source: logging.info('Loading from source: ' + args.source) brain = Brainfuck() with open(args.source, 'r') as f: result = brain.run(f.read(), input_=input_) print(result) else: logging.info('Setting up REPL...') repl(input_=input_)