Decorator to enable a more convenient syntax for writing quil programs. With this decorator there is no need to
    keep track of a Program object and regular Python if/else branches can be used for classical control flow.

    Example usage:

        @magicquil
        def fast_reset(q1):
            reg1 = MEASURE(q1, None)
            if reg1:
                X(q1)
            else:
                I(q1)

        my_program = fast_reset(0)  # this will be a Program object

def magicquil(f):
    """
    Decorator to enable a more convenient syntax for writing quil programs. With this decorator there is no need to
    keep track of a Program object and regular Python if/else branches can be used for classical control flow.

    Example usage:

        @magicquil
        def fast_reset(q1):
            reg1 = MEASURE(q1, None)
            if reg1:
                X(q1)
            else:
                I(q1)

        my_program = fast_reset(0)  # this will be a Program object
    """
    rewritten_function = _rewrite_function(f)

    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        if _program_context.get(None) is not None:
            rewritten_function(*args, **kwargs)
            program = _program_context.get()
        else:
            token = _program_context.set(Program())
            rewritten_function(*args, **kwargs)
            program = _program_context.get()
            _program_context.reset(token)
        return program

    return wrapper