def main() -> None:
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('infile', type=Path)
    arg_parser.add_argument('-o', '--outfile', type=Path)
    arg_parser.add_argument('--valgrind', default='')
    arg_parser.add_argument('-v', '--verbose', action='store_true')
    (compiler_args, program_args) = arg_parser.parse_known_args()
    try:
        cache_dir = (compiler_args.infile.parent / '.oomph-cache')
        cache_dir.mkdir(exist_ok=True)
    except OSError:
        cache_dir = (Path.cwd() / '.oomph-cache')
        cache_dir.mkdir(exist_ok=True)
    session = c_output.Session(get_compilation_dir(cache_dir, (compiler_args.infile.stem + '_compilation')))
    dependency_graph = compute_dependency_graph(session, compiler_args.infile.absolute(), compiler_args.verbose)
    compilation_order = compute_compilation_order(compiler_args.verbose, dependency_graph)
    for unit in compilation_order:
        if compiler_args.verbose:
            print('Creating C code:', unit.source_path)
        unit.create_c_code(session.symbols)
    c_paths = session.write_everything((project_root / 'builtins.oomph'))
    exe_path = (session.compilation_dir / compiler_args.infile.stem)
    (command, human_readable_command) = get_c_compiler_command(c_paths, exe_path)
    result = run(command, compiler_args.verbose, human_readable_command)
    if (result != 0):
        sys.exit(result)
    if (compiler_args.outfile is not None):
        assert (not compiler_args.outfile.is_dir())
        shutil.move(str(exe_path), str(compiler_args.outfile))
        if compiler_args.verbose:
            print('Moved executable to', compiler_args.outfile)
        return
    command = ((shlex.split(compiler_args.valgrind) + [str(exe_path)]) + program_args)
    result = run(command, compiler_args.verbose)
    if (result < 0):
        message = f'Program killed by signal {abs(result)}'
        try:
            message += f' ({signal.Signals(abs(result)).name})'
        except ValueError:
            pass
        print(message, file=sys.stderr)
    elif (result > 0):
        print(f'Program exited with status {result}', file=sys.stderr)
    sys.exit(result)
def main() -> None:
    arg_parser = argparse.ArgumentParser()
    arg_parser.add_argument('infile', type=Path)
    arg_parser.add_argument('-o', '--outfile', type=Path)
    arg_parser.add_argument('--valgrind', default=)
    arg_parser.add_argument('-v', '--verbose', action='store_true')
    (compiler_args, program_args) = arg_parser.parse_known_args()
    try:
        cache_dir = (compiler_args.infile.parent / '.oomph-cache')
        cache_dir.mkdir(exist_ok=True)
    except OSError:
        cache_dir = (Path.cwd() / '.oomph-cache')
        cache_dir.mkdir(exist_ok=True)
    session = c_output.Session(get_compilation_dir(cache_dir, (compiler_args.infile.stem + '_compilation')))
    dependency_graph = compute_dependency_graph(session, compiler_args.infile.absolute(), compiler_args.verbose)
    compilation_order = compute_compilation_order(compiler_args.verbose, dependency_graph)
    for unit in compilation_order:
        if compiler_args.verbose:
            print('Creating C code:', unit.source_path)
        unit.create_c_code(session.symbols)
    c_paths = session.write_everything((project_root / 'builtins.oomph'))
    exe_path = (session.compilation_dir / compiler_args.infile.stem)
    (command, human_readable_command) = get_c_compiler_command(c_paths, exe_path)
    result = run(command, compiler_args.verbose, human_readable_command)
    if (result != 0):
        sys.exit(result)
    if (compiler_args.outfile is not None):
        assert (not compiler_args.outfile.is_dir())
        shutil.move(str(exe_path), str(compiler_args.outfile))
        if compiler_args.verbose:
            print('Moved executable to', compiler_args.outfile)
        return
    command = ((shlex.split(compiler_args.valgrind) + [str(exe_path)]) + program_args)
    result = run(command, compiler_args.verbose)
    if (result < 0):
        message = f'Program killed by signal {abs(result)}'
        try:
            message += f' ({signal.Signals(abs(result)).name})'
        except ValueError:
            pass
        print(message, file=sys.stderr)
    elif (result > 0):
        print(f'Program exited with status {result}', file=sys.stderr)
    sys.exit(result)