def quil_expression_to_sympy(expression: ParameterDesignator):
    """Convert a quil expression to a Sympy expression.

    Args:
        expression: A quil expression.

    Returns:
        The sympy form of the expression.

    Raises:
        ValueError: Connect convert unknown BinaryExp.
        ValueError: Unrecognized expression.
    """
    if type(expression) in {np.int_, np.float64, np.complex128, int, float, complex}:
        return expression
    elif isinstance(expression, Parameter):  # pragma: no cover
        return sympy.Symbol(expression.name)
    elif isinstance(expression, MemoryReference):
        return sympy.Symbol(expression.name + f"_{expression.offset}")
    elif isinstance(expression, Function):
        if expression.name == "SIN":  # pragma: no cover
            return sympy.sin(quil_expression_to_sympy(expression.expression))
        elif expression.name == "COS":
            return sympy.cos(quil_expression_to_sympy(expression.expression))
        elif expression.name == "SQRT":  # pragma: no cover
            return sympy.sqrt(quil_expression_to_sympy(expression.expression))
        elif expression.name == "EXP":
            return sympy.exp(quil_expression_to_sympy(expression.expression))
        elif expression.name == "CIS":  # pragma: no cover
            return sympy.exp(1j * quil_expression_to_sympy(expression.expression))
        else:  # pragma: no cover
            raise ValueError(f"Cannot convert unknown function: {expression}")

    elif isinstance(expression, BinaryExp):
        if isinstance(expression, Add):
            return quil_expression_to_sympy(expression.op1) + quil_expression_to_sympy(
                expression.op2
            )
        elif isinstance(expression, Sub):  # pragma: no cover
            return quil_expression_to_sympy(expression.op1) - quil_expression_to_sympy(
                expression.op2
            )
        elif isinstance(expression, Mul):
            return quil_expression_to_sympy(expression.op1) * quil_expression_to_sympy(
                expression.op2
            )
        elif isinstance(expression, Div):  # pragma: no cover
            return quil_expression_to_sympy(expression.op1) / quil_expression_to_sympy(
                expression.op2
            )
        elif isinstance(expression, Pow):  # pragma: no cover
            return quil_expression_to_sympy(expression.op1) ** quil_expression_to_sympy(
                expression.op2
            )
        else:  # pragma: no cover
            raise ValueError(f"Cannot convert unknown BinaryExp: {expression}")

    else:  # pragma: no cover
        raise ValueError(
            f"quil_expression_to_sympy failed to convert {expression} of type {type(expression)}"
        )
Convert a quil expression to a Sympy expression.

    Args:
        expression: A quil expression.

    Returns:
        The sympy form of the expression.

    Raises:
        ValueError: Connect convert unknown BinaryExp.
        ValueError: Unrecognized expression.
    
cirq-rigetti/cirq_rigetti/quil_input.py