Source code for fuckery.cli

"""
Module that contains the command line app.

Why does this file exist, and why not put this in __main__?

  You might be tempted to import things from __main__ later, but that will cause
  problems: the code will get executed twice:

  - When you run `python -mfuckery` python will execute
    ``__main__.py`` as a script. That means there won't be any
    ``fuckery.__main__`` in ``sys.modules``.
  - When you import __main__ it will get executed again (as a module) because
    there's no ``fuckery.__main__`` in ``sys.modules``.

  Also see (1) from http://click.pocoo.org/5/setuptools/#setuptools-integration
"""
import argparse
import logging
import os

from fuckery.constants import DEFAULT_MEMORY_SIZE
from fuckery.exc import ExitCondition
from fuckery.parser import parse_program
from fuckery.vm import VirtualMachine

log = logging.getLogger(__name__)


[docs]def main(options): if not options.verbose: # pragma: no cover logging.disable(logging.DEBUG) bn = os.path.basename(options.input) with open(options.input, 'rb') as f: buf = f.read() fn = os.path.basename(bn) log.info(f'Parsing {fn}') s = buf.decode() tree = parse_program(s=s) log.info(f'Executing {fn}') vm = VirtualMachine(memory_size=options.memory_size, loop_detection=options.loop_detection) try: vm.run(tree=tree) except ExitCondition as e: log.info(e) log.info('Done running program.')
[docs]def makeargpaser(): # pragma: no cover parser = argparse.ArgumentParser(description='Execute a brainfuck program.') parser.add_argument('-i', '--input', dest='input', action='store', type=str, required=True, help='.bf file to execute.') parser.add_argument('--loop-detection', dest='loop_detection', default=False, action='store_true', help='Enable loop detection (this has a significant performance impact with large memory).') parser.add_argument('--memory-size', dest='memory_size', default=DEFAULT_MEMORY_SIZE, type=int, action='store', help='Memory size to use. If set too low, programs may fail to run.') parser.add_argument('-v', '--verbose', dest='verbose', default=False, action='store_true', help='Enable verbose output.') return parser
def _main(): # pragma: no cover logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(levelname)s] %(message)s [%(filename)s:%(funcName)s]') p = makeargpaser() opts = p.parse_args() main(opts)