// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package opconst defines the representation and operations for VDL constants.
package opconst

import (
	"errors"
	"fmt"
	"math"
	"math/big"
	"strconv"

	"v.io/v23/vdl"
)

var (
	bigIntZero     = new(big.Int)
	bigRatZero     = new(big.Rat)
	bigIntOne      = big.NewInt(1)
	bigRatAbsMin32 = new(big.Rat).SetFloat64(math.SmallestNonzeroFloat32)
	bigRatAbsMax32 = new(big.Rat).SetFloat64(math.MaxFloat32)
	bigRatAbsMin64 = new(big.Rat).SetFloat64(math.SmallestNonzeroFloat64)
	bigRatAbsMax64 = new(big.Rat).SetFloat64(math.MaxFloat64)
	maxShiftSize   = big.NewInt(2000) // arbitrary large value

	errInvalidConst = errors.New("invalid const")
	errConvertNil   = errors.New("invalid conversion to untyped const")
	errDivZero      = errors.New("divide by zero")
)

// Const represents a constant value, similar in spirit to Go constants.  Consts
// may be typed or untyped.  Typed consts represent unchanging Values; all
// Values may be converted into valid typed consts, and all typed consts may be
// converted into valid Values.  Untyped consts belong to one of the following
// categories:
//   untyped boolean
//   untyped string
//   untyped integer
//   untyped rational
// Literal consts are untyped, as are expressions only containing untyped
// consts.  The result of comparison operations is untyped boolean.
//
// Operations are represented by UnaryOp and BinaryOp, and are supported on
// Consts, but not Values.  We support common logical, bitwise, comparison and
// arithmetic operations.  Not all operations are supported on all consts.
//
// Binary ops where both sides are typed consts return errors on type
// mismatches; e.g. uint32(1) + uint64(1) is an invalid binary add.  Ops on
// typed consts also return errors on loss of precision; e.g. uint32(1.1)
// returns an error.
//
// Binary ops where one or both sides are untyped consts perform implicit type
// conversion.  E.g. uint32(1) + 1 is a valid binary add, where the
// right-hand-side is the untyped integer const 1, which is coerced to the
// uint32 type before the op is performed.  Operations only containing untyped
// consts are performed with "infinite" precision.
//
// The zero Const is invalid.
type Const struct {
	// rep holds the underlying representation, it may be one of:
	//   bool        - Represents typed and untyped boolean constants.
	//   string      - Represents typed and untyped string constants.
	//   *big.Int    - Represents typed and untyped integer constants.
	//   *big.Rat    - Represents typed and untyped rational constants.
	//   *Value      - Represents all other typed constants.
	rep interface{}

	// repType holds the type of rep.  If repType is nil the constant is untyped,
	// otherwise the constant is typed, and rep must match the kind of repType.
	// If rep is a *Value, repType is always non-nil.
	repType *vdl.Type
}

// Boolean returns an untyped boolean Const.
func Boolean(x bool) Const { return Const{x, nil} }

// String returns an untyped string Const.
func String(x string) Const { return Const{x, nil} }

// Integer returns an untyped integer Const.
func Integer(x *big.Int) Const { return Const{x, nil} }

// Rational returns an untyped rational Const.
func Rational(x *big.Rat) Const { return Const{x, nil} }

// TODO(toddw): Use big.Float to represent floating point, rather than big.Rat.
// We'll still use big.Rat to represent rationals, e.g. integer division.

// FromValue returns a typed Const based on value v.
func FromValue(v *vdl.Value) Const {
	if v.Type().IsBytes() {
		// Represent []byte and [N]byte as a string, so that conversions are easy.
		return Const{string(v.Bytes()), v.Type()}
	}
	switch v.Kind() {
	case vdl.Bool:
		if v.Type() == vdl.BoolType { // Treat unnamed bool as untyped bool.
			return Boolean(v.Bool())
		}
		return Const{v.Bool(), v.Type()}
	case vdl.String:
		if v.Type() == vdl.StringType { // Treat unnamed string as untyped string.
			return String(v.RawString())
		}
		return Const{v.RawString(), v.Type()}
	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64:
		return Const{new(big.Int).SetUint64(v.Uint()), v.Type()}
	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
		return Const{new(big.Int).SetInt64(v.Int()), v.Type()}
	case vdl.Float32, vdl.Float64:
		return Const{new(big.Rat).SetFloat64(v.Float()), v.Type()}
	default:
		return Const{v, v.Type()}
	}
}

// IsValid returns true iff the c represents a const; it returns false for the
// zero Const.
func (c Const) IsValid() bool {
	return c.rep != nil
}

// Type returns the type of c.  Nil indicates c is an untyped const.
func (c Const) Type() *vdl.Type {
	return c.repType
}

// Convert converts c to the target type t, and returns the resulting const.
// Returns an error if t is nil; you're not allowed to convert into an untyped
// const.
func (c Const) Convert(t *vdl.Type) (Const, error) {
	if t == nil {
		return Const{}, errConvertNil
	}
	// If we're trying to convert to Any or Union, or if c is already a vdl.Value,
	// use vdl.Convert to convert as a vdl.Value.
	_, isValue := c.rep.(*vdl.Value)
	if isValue || t.Kind() == vdl.Any || t.Kind() == vdl.Union {
		src, err := c.ToValue()
		if err != nil {
			return Const{}, err
		}
		dst := vdl.ZeroValue(t)
		if err := vdl.Convert(dst, src); err != nil {
			return Const{}, err
		}
		return FromValue(dst), nil
	}
	// Otherwise use makeConst to convert as a Const.
	return makeConst(c.rep, t)
}

func (c Const) String() string {
	if !c.IsValid() {
		return "invalid"
	}
	if v, ok := c.rep.(*vdl.Value); ok {
		return v.String()
	}
	if c.repType == nil {
		// E.g. 12345
		return cRepString(c.rep)
	}
	// E.g. int32(12345)
	return c.typeString() + "(" + cRepString(c.rep) + ")"
}

func (c Const) typeString() string {
	return cRepTypeString(c.rep, c.repType)
}

// cRepString returns a human-readable string representing the const value.
func cRepString(rep interface{}) string {
	switch trep := rep.(type) {
	case nil:
		return "" // invalid const
	case bool:
		if trep {
			return "true"
		}
		return "false"
	case string:
		return strconv.Quote(trep)
	case *big.Int:
		return trep.String()
	case *big.Rat:
		if trep.IsInt() {
			return trep.Num().String() + ".0"
		}
		frep, _ := trep.Float64()
		return strconv.FormatFloat(frep, 'g', -1, 64)
	case *vdl.Value:
		return trep.String()
	default:
		panic(fmt.Errorf("val: unhandled const type %T value %v", rep, rep))
	}
}

// cRepTypeString returns a human-readable string representing the type of
// the const value.
func cRepTypeString(rep interface{}, t *vdl.Type) string {
	if t != nil {
		return t.String()
	}
	switch rep.(type) {
	case nil:
		return "invalid"
	case bool:
		return "untyped boolean"
	case string:
		return "untyped string"
	case *big.Int:
		return "untyped integer"
	case *big.Rat:
		return "untyped rational"
	default:
		panic(fmt.Errorf("val: unhandled const type %T value %v", rep, rep))
	}
}

// ToValue converts Const c to a Value.
func (c Const) ToValue() (*vdl.Value, error) {
	if c.rep == nil {
		return nil, errInvalidConst
	}
	// All const defs must have a type.  We implicitly assign bool and string, but
	// the user must explicitly assign a type for numeric consts.
	if c.repType == nil {
		switch c.rep.(type) {
		case bool:
			c.repType = vdl.BoolType
		case string:
			c.repType = vdl.StringType
		default:
			return nil, fmt.Errorf("%s must be assigned a type", c)
		}
	}
	// Create a value of the appropriate type.
	vx := vdl.ZeroValue(c.repType)
	switch trep := c.rep.(type) {
	case bool:
		switch vx.Kind() {
		case vdl.Bool:
			vx.AssignBool(trep)
			return vx, nil
		}
	case string:
		switch {
		case vx.Kind() == vdl.String:
			vx.AssignString(trep)
			return vx, nil
		case vx.Type().IsBytes():
			if vx.Kind() == vdl.Array {
				if vx.Len() != len(trep) {
					return nil, fmt.Errorf("%s has a different length than %v", c, vx.Type())
				}
			}
			vx.AssignBytes([]byte(trep))
			return vx, nil
		}
	case *big.Int:
		switch vx.Kind() {
		case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64:
			vx.AssignUint(trep.Uint64())
			return vx, nil
		case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
			vx.AssignInt(trep.Int64())
			return vx, nil
		}
	case *big.Rat:
		switch vx.Kind() {
		case vdl.Float32, vdl.Float64:
			f64, _ := trep.Float64()
			vx.AssignFloat(f64)
			return vx, nil
		}
	case *vdl.Value:
		return trep, nil
	}
	// Type mismatches shouldn't occur, since makeConst always ensures the rep and
	// repType are in sync.  If something's wrong we want to know about it.
	panic(fmt.Errorf("val: mismatched const rep type for %v", c))
}

func errNotSupported(rep interface{}, t *vdl.Type) error {
	return fmt.Errorf("%s not supported", cRepTypeString(rep, t))
}

// EvalUnary returns the result of evaluating (op x).
func EvalUnary(op UnaryOp, x Const) (Const, error) {
	if x.rep == nil {
		return Const{}, errInvalidConst
	}
	if _, ok := x.rep.(*vdl.Value); ok {
		// There are no valid unary ops on *Value consts.
		return Const{}, errNotSupported(x.rep, x.repType)
	}
	switch op {
	case LogicNot:
		switch tx := x.rep.(type) {
		case bool:
			return makeConst(!tx, x.repType)
		}
	case Pos:
		switch x.rep.(type) {
		case *big.Int, *big.Rat:
			return x, nil
		}
	case Neg:
		switch tx := x.rep.(type) {
		case *big.Int:
			return makeConst(new(big.Int).Neg(tx), x.repType)
		case *big.Rat:
			return makeConst(new(big.Rat).Neg(tx), x.repType)
		}
	case BitNot:
		ix, err := constToInt(x)
		if err != nil {
			return Const{}, err
		}
		// big.Int.Not implements bit-not for signed integers, but we need to
		// special-case unsigned integers.  E.g. ^int8(1)=-2, ^uint8(1)=254
		not := new(big.Int)
		switch {
		case x.repType != nil && x.repType.Kind() == vdl.Byte:
			not.SetUint64(uint64(^uint8(ix.Uint64())))
		case x.repType != nil && x.repType.Kind() == vdl.Uint16:
			not.SetUint64(uint64(^uint16(ix.Uint64())))
		case x.repType != nil && x.repType.Kind() == vdl.Uint32:
			not.SetUint64(uint64(^uint32(ix.Uint64())))
		case x.repType != nil && x.repType.Kind() == vdl.Uint64:
			not.SetUint64(^ix.Uint64())
		default:
			not.Not(ix)
		}
		return makeConst(not, x.repType)
	}
	return Const{}, errNotSupported(x.rep, x.repType)
}

// EvalBinary returns the result of evaluating (x op y).
func EvalBinary(op BinaryOp, x, y Const) (Const, error) {
	if x.rep == nil || y.rep == nil {
		return Const{}, errInvalidConst
	}
	switch op {
	case LeftShift, RightShift:
		// Shift ops are special since they require an integer lhs and unsigned rhs.
		return evalShift(op, x, y)
	}
	// All other binary ops behave similarly.  First we perform implicit
	// conversion of x and y.  If either side is untyped, we may need to
	// implicitly convert it to the type of the other side.  If both sides are
	// typed they need to match.  The resulting tx and ty are guaranteed to have
	// the same type, and resType tells us which type we need to convert the
	// result into when we're done.
	cx, cy, resType, err := coerceConsts(x, y)
	if err != nil {
		return Const{}, err
	}
	// Now we perform the actual binary op.
	var res interface{}
	switch op {
	case LogicOr, LogicAnd:
		res, err = opLogic(op, cx, cy, resType)
	case EQ, NE, LT, LE, GT, GE:
		res, err = opComp(op, cx, cy, resType)
		resType = nil // comparisons always result in untyped bool.
	case Add, Sub, Mul, Div:
		res, err = opArith(op, cx, cy, resType)
	case Mod, BitAnd, BitOr, BitXor:
		res, err = opIntArith(op, cx, cy, resType)
	default:
		err = errNotSupported(cx, resType)
	}
	if err != nil {
		return Const{}, err
	}
	// As a final step we convert to the result type.
	return makeConst(res, resType)
}

func opLogic(op BinaryOp, x, y interface{}, resType *vdl.Type) (interface{}, error) {
	switch tx := x.(type) {
	case bool:
		switch op {
		case LogicOr:
			return tx || y.(bool), nil
		case LogicAnd:
			return tx && y.(bool), nil
		}
	}
	return nil, errNotSupported(x, resType)
}

func opComp(op BinaryOp, x, y interface{}, resType *vdl.Type) (interface{}, error) {
	switch tx := x.(type) {
	case bool:
		switch op {
		case EQ:
			return tx == y.(bool), nil
		case NE:
			return tx != y.(bool), nil
		}
	case string:
		return compString(op, tx, y.(string)), nil
	case *big.Int:
		return opCmpToBool(op, tx.Cmp(y.(*big.Int))), nil
	case *big.Rat:
		return opCmpToBool(op, tx.Cmp(y.(*big.Rat))), nil
	case *vdl.Value:
		switch op {
		case EQ:
			return vdl.EqualValue(tx, y.(*vdl.Value)), nil
		case NE:
			return !vdl.EqualValue(tx, y.(*vdl.Value)), nil
		}
	}
	return nil, errNotSupported(x, resType)
}

func opArith(op BinaryOp, x, y interface{}, resType *vdl.Type) (interface{}, error) {
	switch tx := x.(type) {
	case string:
		if op == Add {
			return tx + y.(string), nil
		}
	case *big.Int:
		return arithBigInt(op, tx, y.(*big.Int))
	case *big.Rat:
		return arithBigRat(op, tx, y.(*big.Rat))
	}
	return nil, errNotSupported(x, resType)
}

func opIntArith(op BinaryOp, x, y interface{}, resType *vdl.Type) (interface{}, error) {
	ix, err := constToInt(Const{x, resType})
	if err != nil {
		return nil, err
	}
	iy, err := constToInt(Const{y, resType})
	if err != nil {
		return nil, err
	}
	return arithBigInt(op, ix, iy)
}

func evalShift(op BinaryOp, x, y Const) (Const, error) {
	// lhs must be an integer.
	ix, err := constToInt(x)
	if err != nil {
		return Const{}, err
	}
	// rhs must be a small unsigned integer.
	iy, err := constToInt(y)
	if err != nil {
		return Const{}, err
	}
	if iy.Sign() < 0 {
		return Const{}, fmt.Errorf("shift amount %v isn't unsigned", cRepString(iy))
	}
	if iy.Cmp(maxShiftSize) > 0 {
		return Const{}, fmt.Errorf("shift amount %v greater than max allowed %v", cRepString(iy), cRepString(maxShiftSize))
	}
	// Perform the shift and convert it back to the lhs type.
	return makeConst(shiftBigInt(op, ix, uint(iy.Uint64())), x.repType)
}

// bigRatToInt converts rational to integer values as long as there isn't any
// loss in precision, checking resType to make sure the conversion is allowed.
func bigRatToInt(rat *big.Rat, resType *vdl.Type) (*big.Int, error) {
	// As a special-case we allow untyped rat consts to be converted to integers,
	// as long as they can do so without loss of precision.  This is safe since
	// untyped rat consts have "unbounded" precision.  Typed float consts may have
	// been rounded at some point, so we don't allow this.  This is the same
	// behavior as Go.
	if resType != nil {
		return nil, fmt.Errorf("can't convert typed %s to integer", cRepTypeString(rat, resType))
	}
	if !rat.IsInt() {
		return nil, fmt.Errorf("converting %s %s to integer loses precision", cRepTypeString(rat, resType), cRepString(rat))
	}
	return new(big.Int).Set(rat.Num()), nil
}

// constToInt converts x to an integer value as long as there isn't any loss in
// precision.
func constToInt(x Const) (*big.Int, error) {
	switch tx := x.rep.(type) {
	case *big.Int:
		return tx, nil
	case *big.Rat:
		return bigRatToInt(tx, x.repType)
	}
	return nil, fmt.Errorf("can't convert %s to integer", x.typeString())
}

// makeConst creates a Const with value rep and type totype, performing overflow
// and conversion checks on numeric values.  If totype is nil the resulting
// const is untyped.
//
// TODO(toddw): Update to handle conversions to optional types.
func makeConst(rep interface{}, totype *vdl.Type) (Const, error) {
	if rep == nil {
		return Const{}, errInvalidConst
	}
	if totype == nil {
		if v, ok := rep.(*vdl.Value); ok {
			return Const{}, fmt.Errorf("can't make typed value %s untyped", v.Type())
		}
		return Const{rep, nil}, nil
	}
	switch trep := rep.(type) {
	case bool:
		if totype.Kind() == vdl.Bool {
			return Const{trep, totype}, nil
		}
	case string:
		if totype.Kind() == vdl.String || totype.IsBytes() {
			return Const{trep, totype}, nil
		}
	case *big.Int:
		switch totype.Kind() {
		case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
			if err := checkOverflowInt(trep, totype.Kind()); err != nil {
				return Const{}, err
			}
			return Const{trep, totype}, nil
		case vdl.Float32, vdl.Float64:
			return makeConst(new(big.Rat).SetInt(trep), totype)
		}
	case *big.Rat:
		switch totype.Kind() {
		case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64, vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
			// The only way we reach this conversion from big.Rat to a typed integer
			// is for explicit type conversions.  We pass a nil Type to bigRatToInt
			// indicating trep is untyped, to allow all conversions from float to int
			// as long as trep is actually an integer.
			irep, err := bigRatToInt(trep, nil)
			if err != nil {
				return Const{}, err
			}
			return makeConst(irep, totype)
		case vdl.Float32, vdl.Float64:
			frep, err := convertTypedRat(trep, totype.Kind())
			if err != nil {
				return Const{}, err
			}
			return Const{frep, totype}, nil
		}
	}
	return Const{}, fmt.Errorf("can't convert %s to %v", cRepString(rep), cRepTypeString(rep, totype))
}

func bitLenInt(kind vdl.Kind) int {
	switch kind {
	case vdl.Byte, vdl.Int8:
		return 8
	case vdl.Uint16, vdl.Int16:
		return 16
	case vdl.Uint32, vdl.Int32:
		return 32
	case vdl.Uint64, vdl.Int64:
		return 64
	default:
		panic(fmt.Errorf("val: bitLen unhandled kind %v", kind))
	}
}

// checkOverflowInt returns an error iff converting b to the typed integer will
// cause overflow.
func checkOverflowInt(b *big.Int, kind vdl.Kind) error {
	switch bitlen := bitLenInt(kind); kind {
	case vdl.Byte, vdl.Uint16, vdl.Uint32, vdl.Uint64:
		if b.Sign() < 0 || b.BitLen() > bitlen {
			return fmt.Errorf("const %v overflows uint%d", cRepString(b), bitlen)
		}
	case vdl.Int8, vdl.Int16, vdl.Int32, vdl.Int64:
		// Account for two's complement, where e.g. int8 ranges from -128 to 127
		if b.Sign() >= 0 {
			// Positives and 0 - just check bitlen, accounting for the sign bit.
			if b.BitLen() >= bitlen {
				return fmt.Errorf("const %v overflows int%d", cRepString(b), bitlen)
			}
		} else {
			// Negatives need to take an extra value into account (e.g. -128 for int8)
			bplus1 := new(big.Int).Add(b, bigIntOne)
			if bplus1.BitLen() >= bitlen {
				return fmt.Errorf("const %v overflows int%d", cRepString(b), bitlen)
			}
		}
	default:
		panic(fmt.Errorf("val: checkOverflowInt unhandled kind %v", kind))
	}
	return nil
}

// checkOverflowRat returns an error iff converting b to the typed rat will
// cause overflow or underflow.
func checkOverflowRat(b *big.Rat, kind vdl.Kind) error {
	// Exact zero is special cased in ieee754.
	if b.Cmp(bigRatZero) == 0 {
		return nil
	}
	// TODO(toddw): perhaps allow slightly smaller and larger values, to account
	// for ieee754 round-to-even rules.
	switch abs := new(big.Rat).Abs(b); kind {
	case vdl.Float32:
		if abs.Cmp(bigRatAbsMin32) < 0 {
			return fmt.Errorf("const %v underflows float32", cRepString(b))
		}
		if abs.Cmp(bigRatAbsMax32) > 0 {
			return fmt.Errorf("const %v overflows float32", cRepString(b))
		}
	case vdl.Float64:
		if abs.Cmp(bigRatAbsMin64) < 0 {
			return fmt.Errorf("const %v underflows float64", cRepString(b))
		}
		if abs.Cmp(bigRatAbsMax64) > 0 {
			return fmt.Errorf("const %v overflows float64", cRepString(b))
		}
	default:
		panic(fmt.Errorf("val: checkOverflowRat unhandled kind %v", kind))
	}
	return nil
}

// convertTypedRat converts b to the typed rat, rounding as necessary.
func convertTypedRat(b *big.Rat, kind vdl.Kind) (*big.Rat, error) {
	if err := checkOverflowRat(b, kind); err != nil {
		return nil, err
	}
	switch f64, _ := b.Float64(); kind {
	case vdl.Float32:
		return new(big.Rat).SetFloat64(float64(float32(f64))), nil
	case vdl.Float64:
		return new(big.Rat).SetFloat64(f64), nil
	default:
		panic(fmt.Errorf("val: convertTypedRat unhandled kind %v", kind))
	}
}

// coerceConsts performs implicit conversion of cl and cr based on their
// respective types.  Returns the converted values vl and vr which are
// guaranteed to be of the same type represented by the returned Type, which may
// be nil if both consts are untyped.
func coerceConsts(cl, cr Const) (interface{}, interface{}, *vdl.Type, error) {
	var err error
	if cl.repType != nil && cr.repType != nil {
		// Both consts are typed - their types must match (no implicit conversion).
		if cl.repType != cr.repType {
			return nil, nil, nil, fmt.Errorf("type mismatch %v and %v", cl.typeString(), cr.typeString())
		}
		return cl.rep, cr.rep, cl.repType, nil
	}
	if cl.repType != nil {
		// Convert rhs to the type of the lhs.
		cr, err = makeConst(cr.rep, cl.repType)
		if err != nil {
			return nil, nil, nil, err
		}
		return cl.rep, cr.rep, cl.repType, nil
	}
	if cr.repType != nil {
		// Convert lhs to the type of the rhs.
		cl, err = makeConst(cl.rep, cr.repType)
		if err != nil {
			return nil, nil, nil, err
		}
		return cl.rep, cr.rep, cr.repType, nil
	}
	// Both consts are untyped, might need to implicitly promote untyped consts.
	switch vl := cl.rep.(type) {
	case bool:
		switch vr := cr.rep.(type) {
		case bool:
			return vl, vr, nil, nil
		}
	case string:
		switch vr := cr.rep.(type) {
		case string:
			return vl, vr, nil, nil
		}
	case *big.Int:
		switch vr := cr.rep.(type) {
		case *big.Int:
			return vl, vr, nil, nil
		case *big.Rat:
			// Promote lhs to rat
			return new(big.Rat).SetInt(vl), vr, nil, nil
		}
	case *big.Rat:
		switch vr := cr.rep.(type) {
		case *big.Int:
			// Promote rhs to rat
			return vl, new(big.Rat).SetInt(vr), nil, nil
		case *big.Rat:
			return vl, vr, nil, nil
		}
	}
	return nil, nil, nil, fmt.Errorf("mismatched %s and %s", cl.typeString(), cr.typeString())
}

func compString(op BinaryOp, l, r string) bool {
	switch op {
	case EQ:
		return l == r
	case NE:
		return l != r
	case LT:
		return l < r
	case LE:
		return l <= r
	case GT:
		return l > r
	case GE:
		return l >= r
	default:
		panic(fmt.Errorf("val: unhandled op %q", op))
	}
}

func opCmpToBool(op BinaryOp, cmp int) bool {
	switch op {
	case EQ:
		return cmp == 0
	case NE:
		return cmp != 0
	case LT:
		return cmp < 0
	case LE:
		return cmp <= 0
	case GT:
		return cmp > 0
	case GE:
		return cmp >= 0
	default:
		panic(fmt.Errorf("val: unhandled op %q", op))
	}
}

func arithBigInt(op BinaryOp, l, r *big.Int) (*big.Int, error) {
	switch op {
	case Add:
		return new(big.Int).Add(l, r), nil
	case Sub:
		return new(big.Int).Sub(l, r), nil
	case Mul:
		return new(big.Int).Mul(l, r), nil
	case Div:
		if r.Cmp(bigIntZero) == 0 {
			return nil, errDivZero
		}
		return new(big.Int).Quo(l, r), nil
	case Mod:
		if r.Cmp(bigIntZero) == 0 {
			return nil, errDivZero
		}
		return new(big.Int).Rem(l, r), nil
	case BitAnd:
		return new(big.Int).And(l, r), nil
	case BitOr:
		return new(big.Int).Or(l, r), nil
	case BitXor:
		return new(big.Int).Xor(l, r), nil
	default:
		panic(fmt.Errorf("val: unhandled op %q", op))
	}
}

func arithBigRat(op BinaryOp, l, r *big.Rat) (*big.Rat, error) {
	switch op {
	case Add:
		return new(big.Rat).Add(l, r), nil
	case Sub:
		return new(big.Rat).Sub(l, r), nil
	case Mul:
		return new(big.Rat).Mul(l, r), nil
	case Div:
		if r.Cmp(bigRatZero) == 0 {
			return nil, errDivZero
		}
		inv := new(big.Rat).Inv(r)
		return inv.Mul(inv, l), nil
	default:
		panic(fmt.Errorf("val: unhandled op %q", op))
	}
}

func shiftBigInt(op BinaryOp, l *big.Int, n uint) *big.Int {
	switch op {
	case LeftShift:
		return new(big.Int).Lsh(l, n)
	case RightShift:
		return new(big.Int).Rsh(l, n)
	default:
		panic(fmt.Errorf("val: unhandled op %q", op))
	}
}
