// Copyright 2013 The Go 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 constant implements Values representing untyped
// Go constants and the corresponding operations. Values
// and operations may have arbitrary or unlimited precision.
//
// A special Unknown value may be used when a value
// is unknown due to an error. Operations on unknown
// values produce unknown values unless specified
// otherwise.
//
package constant // import "go/constant"

import (
	"fmt"
	"go/token"
	"math/big"
	"strconv"
)

// Kind specifies the kind of value represented by a Value.
type Kind int

// Implementation note: Kinds must be enumerated in
// order of increasing "complexity" (used by match).

const (
	// unknown values
	Unknown Kind = iota

	// non-numeric values
	Bool
	String

	// numeric values
	Int
	Float
	Complex
)

// A Value represents a mathematically exact value of a given Kind.
type Value interface {
	// Kind returns the value kind; it is always the smallest
	// kind in which the value can be represented exactly.
	Kind() Kind

	// String returns a human-readable form of the value.
	String() string

	// Prevent external implementations.
	implementsValue()
}

// ----------------------------------------------------------------------------
// Implementations

type (
	unknownVal struct{}
	boolVal    bool
	stringVal  string
	int64Val   int64
	intVal     struct{ val *big.Int }
	floatVal   struct{ val *big.Rat }
	complexVal struct{ re, im *big.Rat }
)

func (unknownVal) Kind() Kind { return Unknown }
func (boolVal) Kind() Kind    { return Bool }
func (stringVal) Kind() Kind  { return String }
func (int64Val) Kind() Kind   { return Int }
func (intVal) Kind() Kind     { return Int }
func (floatVal) Kind() Kind   { return Float }
func (complexVal) Kind() Kind { return Complex }

func (unknownVal) String() string   { return "unknown" }
func (x boolVal) String() string    { return fmt.Sprintf("%v", bool(x)) }
func (x stringVal) String() string  { return strconv.Quote(string(x)) }
func (x int64Val) String() string   { return strconv.FormatInt(int64(x), 10) }
func (x intVal) String() string     { return x.val.String() }
func (x floatVal) String() string   { return x.val.String() }
func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }

func (unknownVal) implementsValue() {}
func (boolVal) implementsValue()    {}
func (stringVal) implementsValue()  {}
func (int64Val) implementsValue()   {}
func (intVal) implementsValue()     {}
func (floatVal) implementsValue()   {}
func (complexVal) implementsValue() {}

// int64 bounds
var (
	minInt64 = big.NewInt(-1 << 63)
	maxInt64 = big.NewInt(1<<63 - 1)
)

func normInt(x *big.Int) Value {
	if minInt64.Cmp(x) <= 0 && x.Cmp(maxInt64) <= 0 {
		return int64Val(x.Int64())
	}
	return intVal{x}
}

func normFloat(x *big.Rat) Value {
	if x.IsInt() {
		return normInt(x.Num())
	}
	return floatVal{x}
}

func normComplex(re, im *big.Rat) Value {
	if im.Sign() == 0 {
		return normFloat(re)
	}
	return complexVal{re, im}
}

// ----------------------------------------------------------------------------
// Factories

// MakeUnknown returns the Unknown value.
func MakeUnknown() Value { return unknownVal{} }

// MakeBool returns the Bool value for x.
func MakeBool(b bool) Value { return boolVal(b) }

// MakeString returns the String value for x.
func MakeString(s string) Value { return stringVal(s) }

// MakeInt64 returns the Int value for x.
func MakeInt64(x int64) Value { return int64Val(x) }

// MakeUint64 returns the Int value for x.
func MakeUint64(x uint64) Value { return normInt(new(big.Int).SetUint64(x)) }

// MakeFloat64 returns the numeric value for x.
// If x is not finite, the result is unknown.
func MakeFloat64(x float64) Value {
	if f := new(big.Rat).SetFloat64(x); f != nil {
		return normFloat(f)
	}
	return unknownVal{}
}

// MakeFromLiteral returns the corresponding integer, floating-point,
// imaginary, character, or string value for a Go literal string.
// If prec > 0, prec specifies an upper limit for the precision of
// a numeric value. If the literal string is invalid, the result is
// nil.
// BUG(gri) Only prec == 0 is supported at the moment.
func MakeFromLiteral(lit string, tok token.Token, prec uint) Value {
	if prec != 0 {
		panic("limited precision not supported")
	}
	switch tok {
	case token.INT:
		if x, err := strconv.ParseInt(lit, 0, 64); err == nil {
			return int64Val(x)
		}
		if x, ok := new(big.Int).SetString(lit, 0); ok {
			return intVal{x}
		}

	case token.FLOAT:
		if x, ok := new(big.Rat).SetString(lit); ok {
			return normFloat(x)
		}

	case token.IMAG:
		if n := len(lit); n > 0 && lit[n-1] == 'i' {
			if im, ok := new(big.Rat).SetString(lit[0 : n-1]); ok {
				return normComplex(big.NewRat(0, 1), im)
			}
		}

	case token.CHAR:
		if n := len(lit); n >= 2 {
			if code, _, _, err := strconv.UnquoteChar(lit[1:n-1], '\''); err == nil {
				return int64Val(code)
			}
		}

	case token.STRING:
		if s, err := strconv.Unquote(lit); err == nil {
			return stringVal(s)
		}
	}

	return nil
}

// ----------------------------------------------------------------------------
// Accessors
//
// For unknown arguments the result is the zero value for the respective
// accessor type, except for Sign, where the result is 1.

// BoolVal returns the Go boolean value of x, which must be a Bool or an Unknown.
// If x is Unknown, the result is false.
func BoolVal(x Value) bool {
	switch x := x.(type) {
	case boolVal:
		return bool(x)
	case unknownVal:
		return false
	}
	panic(fmt.Sprintf("%v not a Bool", x))
}

// StringVal returns the Go string value of x, which must be a String or an Unknown.
// If x is Unknown, the result is "".
func StringVal(x Value) string {
	switch x := x.(type) {
	case stringVal:
		return string(x)
	case unknownVal:
		return ""
	}
	panic(fmt.Sprintf("%v not a String", x))
}

// Int64Val returns the Go int64 value of x and whether the result is exact;
// x must be an Int or an Unknown. If the result is not exact, its value is undefined.
// If x is Unknown, the result is (0, false).
func Int64Val(x Value) (int64, bool) {
	switch x := x.(type) {
	case int64Val:
		return int64(x), true
	case intVal:
		return x.val.Int64(), x.val.BitLen() <= 63
	case unknownVal:
		return 0, false
	}
	panic(fmt.Sprintf("%v not an Int", x))
}

// Uint64Val returns the Go uint64 value of x and whether the result is exact;
// x must be an Int or an Unknown. If the result is not exact, its value is undefined.
// If x is Unknown, the result is (0, false).
func Uint64Val(x Value) (uint64, bool) {
	switch x := x.(type) {
	case int64Val:
		return uint64(x), x >= 0
	case intVal:
		return x.val.Uint64(), x.val.Sign() >= 0 && x.val.BitLen() <= 64
	case unknownVal:
		return 0, false
	}
	panic(fmt.Sprintf("%v not an Int", x))
}

// Float32Val is like Float64Val but for float32 instead of float64.
func Float32Val(x Value) (float32, bool) {
	switch x := x.(type) {
	case int64Val:
		f := float32(x)
		return f, int64Val(f) == x
	case intVal:
		return ratToFloat32(new(big.Rat).SetFrac(x.val, int1))
	case floatVal:
		return ratToFloat32(x.val)
	case unknownVal:
		return 0, false
	}
	panic(fmt.Sprintf("%v not a Float", x))
}

// Float64Val returns the nearest Go float64 value of x and whether the result is exact;
// x must be numeric but not Complex, or Unknown. For values too small (too close to 0)
// to represent as float64, Float64Val silently underflows to 0. The result sign always
// matches the sign of x, even for 0.
// If x is Unknown, the result is (0, false).
func Float64Val(x Value) (float64, bool) {
	switch x := x.(type) {
	case int64Val:
		f := float64(int64(x))
		return f, int64Val(f) == x
	case intVal:
		return new(big.Rat).SetFrac(x.val, int1).Float64()
	case floatVal:
		return x.val.Float64()
	case unknownVal:
		return 0, false
	}
	panic(fmt.Sprintf("%v not a Float", x))
}

// BitLen returns the number of bits required to represent
// the absolute value x in binary representation; x must be an Int or an Unknown.
// If x is Unknown, the result is 0.
func BitLen(x Value) int {
	switch x := x.(type) {
	case int64Val:
		return new(big.Int).SetInt64(int64(x)).BitLen()
	case intVal:
		return x.val.BitLen()
	case unknownVal:
		return 0
	}
	panic(fmt.Sprintf("%v not an Int", x))
}

// Sign returns -1, 0, or 1 depending on whether x < 0, x == 0, or x > 0;
// x must be numeric or Unknown. For complex values x, the sign is 0 if x == 0,
// otherwise it is != 0. If x is Unknown, the result is 1.
func Sign(x Value) int {
	switch x := x.(type) {
	case int64Val:
		switch {
		case x < 0:
			return -1
		case x > 0:
			return 1
		}
		return 0
	case intVal:
		return x.val.Sign()
	case floatVal:
		return x.val.Sign()
	case complexVal:
		return x.re.Sign() | x.im.Sign()
	case unknownVal:
		return 1 // avoid spurious division by zero errors
	}
	panic(fmt.Sprintf("%v not numeric", x))
}

// ----------------------------------------------------------------------------
// Support for serializing/deserializing integers

const (
	// Compute the size of a Word in bytes.
	_m       = ^big.Word(0)
	_log     = _m>>8&1 + _m>>16&1 + _m>>32&1
	wordSize = 1 << _log
)

// Bytes returns the bytes for the absolute value of x in little-
// endian binary representation; x must be an Int.
func Bytes(x Value) []byte {
	var val *big.Int
	switch x := x.(type) {
	case int64Val:
		val = new(big.Int).SetInt64(int64(x))
	case intVal:
		val = x.val
	default:
		panic(fmt.Sprintf("%v not an Int", x))
	}

	words := val.Bits()
	bytes := make([]byte, len(words)*wordSize)

	i := 0
	for _, w := range words {
		for j := 0; j < wordSize; j++ {
			bytes[i] = byte(w)
			w >>= 8
			i++
		}
	}
	// remove leading 0's
	for i > 0 && bytes[i-1] == 0 {
		i--
	}

	return bytes[:i]
}

// MakeFromBytes returns the Int value given the bytes of its little-endian
// binary representation. An empty byte slice argument represents 0.
func MakeFromBytes(bytes []byte) Value {
	words := make([]big.Word, (len(bytes)+(wordSize-1))/wordSize)

	i := 0
	var w big.Word
	var s uint
	for _, b := range bytes {
		w |= big.Word(b) << s
		if s += 8; s == wordSize*8 {
			words[i] = w
			i++
			w = 0
			s = 0
		}
	}
	// store last word
	if i < len(words) {
		words[i] = w
		i++
	}
	// remove leading 0's
	for i > 0 && words[i-1] == 0 {
		i--
	}

	return normInt(new(big.Int).SetBits(words[:i]))
}

// ----------------------------------------------------------------------------
// Support for disassembling fractions

// Num returns the numerator of x; x must be Int, Float, or Unknown.
// If x is Unknown, the result is Unknown, otherwise it is an Int
// with the same sign as x.
func Num(x Value) Value {
	switch x := x.(type) {
	case unknownVal, int64Val, intVal:
		return x
	case floatVal:
		return normInt(x.val.Num())
	}
	panic(fmt.Sprintf("%v not Int or Float", x))
}

// Denom returns the denominator of x; x must be Int, Float, or Unknown.
// If x is Unknown, the result is Unknown, otherwise it is an Int >= 1.
func Denom(x Value) Value {
	switch x := x.(type) {
	case unknownVal:
		return x
	case int64Val, intVal:
		return int64Val(1)
	case floatVal:
		return normInt(x.val.Denom())
	}
	panic(fmt.Sprintf("%v not Int or Float", x))
}

// ----------------------------------------------------------------------------
// Support for assembling/disassembling complex numbers

// MakeImag returns the numeric value x*i (possibly 0);
// x must be Int, Float, or Unknown.
// If x is Unknown, the result is Unknown.
func MakeImag(x Value) Value {
	var im *big.Rat
	switch x := x.(type) {
	case unknownVal:
		return x
	case int64Val:
		im = big.NewRat(int64(x), 1)
	case intVal:
		im = new(big.Rat).SetFrac(x.val, int1)
	case floatVal:
		im = x.val
	default:
		panic(fmt.Sprintf("%v not Int or Float", x))
	}
	return normComplex(rat0, im)
}

// Real returns the real part of x, which must be a numeric or unknown value.
// If x is Unknown, the result is Unknown.
func Real(x Value) Value {
	switch x := x.(type) {
	case unknownVal, int64Val, intVal, floatVal:
		return x
	case complexVal:
		return normFloat(x.re)
	}
	panic(fmt.Sprintf("%v not numeric", x))
}

// Imag returns the imaginary part of x, which must be a numeric or unknown value.
// If x is Unknown, the result is Unknown.
func Imag(x Value) Value {
	switch x := x.(type) {
	case unknownVal:
		return x
	case int64Val, intVal, floatVal:
		return int64Val(0)
	case complexVal:
		return normFloat(x.im)
	}
	panic(fmt.Sprintf("%v not numeric", x))
}

// ----------------------------------------------------------------------------
// Operations

// is32bit reports whether x can be represented using 32 bits.
func is32bit(x int64) bool {
	const s = 32
	return -1<<(s-1) <= x && x <= 1<<(s-1)-1
}

// is63bit reports whether x can be represented using 63 bits.
func is63bit(x int64) bool {
	const s = 63
	return -1<<(s-1) <= x && x <= 1<<(s-1)-1
}

// UnaryOp returns the result of the unary expression op y.
// The operation must be defined for the operand.
// If prec > 0 it specifies the ^ (xor) result size in bits.
// If y is Unknown, the result is Unknown.
//
func UnaryOp(op token.Token, y Value, prec uint) Value {
	switch op {
	case token.ADD:
		switch y.(type) {
		case unknownVal, int64Val, intVal, floatVal, complexVal:
			return y
		}

	case token.SUB:
		switch y := y.(type) {
		case unknownVal:
			return y
		case int64Val:
			if z := -y; z != y {
				return z // no overflow
			}
			return normInt(new(big.Int).Neg(big.NewInt(int64(y))))
		case intVal:
			return normInt(new(big.Int).Neg(y.val))
		case floatVal:
			return normFloat(new(big.Rat).Neg(y.val))
		case complexVal:
			return normComplex(new(big.Rat).Neg(y.re), new(big.Rat).Neg(y.im))
		}

	case token.XOR:
		var z big.Int
		switch y := y.(type) {
		case unknownVal:
			return y
		case int64Val:
			z.Not(big.NewInt(int64(y)))
		case intVal:
			z.Not(y.val)
		default:
			goto Error
		}
		// For unsigned types, the result will be negative and
		// thus "too large": We must limit the result precision
		// to the type's precision.
		if prec > 0 {
			z.AndNot(&z, new(big.Int).Lsh(big.NewInt(-1), prec)) // z &^= (-1)<<prec
		}
		return normInt(&z)

	case token.NOT:
		switch y := y.(type) {
		case unknownVal:
			return y
		case boolVal:
			return !y
		}
	}

Error:
	panic(fmt.Sprintf("invalid unary operation %s%v", op, y))
}

var (
	int1 = big.NewInt(1)
	rat0 = big.NewRat(0, 1)
)

func ord(x Value) int {
	switch x.(type) {
	default:
		return 0
	case boolVal, stringVal:
		return 1
	case int64Val:
		return 2
	case intVal:
		return 3
	case floatVal:
		return 4
	case complexVal:
		return 5
	}
}

// match returns the matching representation (same type) with the
// smallest complexity for two values x and y. If one of them is
// numeric, both of them must be numeric. If one of them is Unknown,
// both results are Unknown.
//
func match(x, y Value) (_, _ Value) {
	if ord(x) > ord(y) {
		y, x = match(y, x)
		return x, y
	}
	// ord(x) <= ord(y)

	switch x := x.(type) {
	case unknownVal:
		return x, x

	case boolVal, stringVal, complexVal:
		return x, y

	case int64Val:
		switch y := y.(type) {
		case int64Val:
			return x, y
		case intVal:
			return intVal{big.NewInt(int64(x))}, y
		case floatVal:
			return floatVal{big.NewRat(int64(x), 1)}, y
		case complexVal:
			return complexVal{big.NewRat(int64(x), 1), rat0}, y
		}

	case intVal:
		switch y := y.(type) {
		case intVal:
			return x, y
		case floatVal:
			return floatVal{new(big.Rat).SetFrac(x.val, int1)}, y
		case complexVal:
			return complexVal{new(big.Rat).SetFrac(x.val, int1), rat0}, y
		}

	case floatVal:
		switch y := y.(type) {
		case floatVal:
			return x, y
		case complexVal:
			return complexVal{x.val, rat0}, y
		}
	}

	panic("unreachable")
}

// BinaryOp returns the result of the binary expression x op y.
// The operation must be defined for the operands. If one of the
// operands is Unknown, the result is Unknown.
// To force integer division of Int operands, use op == token.QUO_ASSIGN
// instead of token.QUO; the result is guaranteed to be Int in this case.
// Division by zero leads to a run-time panic.
//
func BinaryOp(x Value, op token.Token, y Value) Value {
	x, y = match(x, y)

	switch x := x.(type) {
	case unknownVal:
		return x

	case boolVal:
		y := y.(boolVal)
		switch op {
		case token.LAND:
			return x && y
		case token.LOR:
			return x || y
		}

	case int64Val:
		a := int64(x)
		b := int64(y.(int64Val))
		var c int64
		switch op {
		case token.ADD:
			if !is63bit(a) || !is63bit(b) {
				return normInt(new(big.Int).Add(big.NewInt(a), big.NewInt(b)))
			}
			c = a + b
		case token.SUB:
			if !is63bit(a) || !is63bit(b) {
				return normInt(new(big.Int).Sub(big.NewInt(a), big.NewInt(b)))
			}
			c = a - b
		case token.MUL:
			if !is32bit(a) || !is32bit(b) {
				return normInt(new(big.Int).Mul(big.NewInt(a), big.NewInt(b)))
			}
			c = a * b
		case token.QUO:
			return normFloat(new(big.Rat).SetFrac(big.NewInt(a), big.NewInt(b)))
		case token.QUO_ASSIGN: // force integer division
			c = a / b
		case token.REM:
			c = a % b
		case token.AND:
			c = a & b
		case token.OR:
			c = a | b
		case token.XOR:
			c = a ^ b
		case token.AND_NOT:
			c = a &^ b
		default:
			goto Error
		}
		return int64Val(c)

	case intVal:
		a := x.val
		b := y.(intVal).val
		var c big.Int
		switch op {
		case token.ADD:
			c.Add(a, b)
		case token.SUB:
			c.Sub(a, b)
		case token.MUL:
			c.Mul(a, b)
		case token.QUO:
			return normFloat(new(big.Rat).SetFrac(a, b))
		case token.QUO_ASSIGN: // force integer division
			c.Quo(a, b)
		case token.REM:
			c.Rem(a, b)
		case token.AND:
			c.And(a, b)
		case token.OR:
			c.Or(a, b)
		case token.XOR:
			c.Xor(a, b)
		case token.AND_NOT:
			c.AndNot(a, b)
		default:
			goto Error
		}
		return normInt(&c)

	case floatVal:
		a := x.val
		b := y.(floatVal).val
		var c big.Rat
		switch op {
		case token.ADD:
			c.Add(a, b)
		case token.SUB:
			c.Sub(a, b)
		case token.MUL:
			c.Mul(a, b)
		case token.QUO:
			c.Quo(a, b)
		default:
			goto Error
		}
		return normFloat(&c)

	case complexVal:
		y := y.(complexVal)
		a, b := x.re, x.im
		c, d := y.re, y.im
		var re, im big.Rat
		switch op {
		case token.ADD:
			// (a+c) + i(b+d)
			re.Add(a, c)
			im.Add(b, d)
		case token.SUB:
			// (a-c) + i(b-d)
			re.Sub(a, c)
			im.Sub(b, d)
		case token.MUL:
			// (ac-bd) + i(bc+ad)
			var ac, bd, bc, ad big.Rat
			ac.Mul(a, c)
			bd.Mul(b, d)
			bc.Mul(b, c)
			ad.Mul(a, d)
			re.Sub(&ac, &bd)
			im.Add(&bc, &ad)
		case token.QUO:
			// (ac+bd)/s + i(bc-ad)/s, with s = cc + dd
			var ac, bd, bc, ad, s, cc, dd big.Rat
			ac.Mul(a, c)
			bd.Mul(b, d)
			bc.Mul(b, c)
			ad.Mul(a, d)
			cc.Mul(c, c)
			dd.Mul(d, d)
			s.Add(&cc, &dd)
			re.Add(&ac, &bd)
			re.Quo(&re, &s)
			im.Sub(&bc, &ad)
			im.Quo(&im, &s)
		default:
			goto Error
		}
		return normComplex(&re, &im)

	case stringVal:
		if op == token.ADD {
			return x + y.(stringVal)
		}
	}

Error:
	panic(fmt.Sprintf("invalid binary operation %v %s %v", x, op, y))
}

// Shift returns the result of the shift expression x op s
// with op == token.SHL or token.SHR (<< or >>). x must be
// an Int or an Unknown. If x is Unknown, the result is x.
//
func Shift(x Value, op token.Token, s uint) Value {
	switch x := x.(type) {
	case unknownVal:
		return x

	case int64Val:
		if s == 0 {
			return x
		}
		switch op {
		case token.SHL:
			z := big.NewInt(int64(x))
			return normInt(z.Lsh(z, s))
		case token.SHR:
			return x >> s
		}

	case intVal:
		if s == 0 {
			return x
		}
		var z big.Int
		switch op {
		case token.SHL:
			return normInt(z.Lsh(x.val, s))
		case token.SHR:
			return normInt(z.Rsh(x.val, s))
		}
	}

	panic(fmt.Sprintf("invalid shift %v %s %d", x, op, s))
}

func cmpZero(x int, op token.Token) bool {
	switch op {
	case token.EQL:
		return x == 0
	case token.NEQ:
		return x != 0
	case token.LSS:
		return x < 0
	case token.LEQ:
		return x <= 0
	case token.GTR:
		return x > 0
	case token.GEQ:
		return x >= 0
	}
	panic("unreachable")
}

// Compare returns the result of the comparison x op y.
// The comparison must be defined for the operands.
// If one of the operands is Unknown, the result is
// false.
//
func Compare(x Value, op token.Token, y Value) bool {
	x, y = match(x, y)

	switch x := x.(type) {
	case unknownVal:
		return false

	case boolVal:
		y := y.(boolVal)
		switch op {
		case token.EQL:
			return x == y
		case token.NEQ:
			return x != y
		}

	case int64Val:
		y := y.(int64Val)
		switch op {
		case token.EQL:
			return x == y
		case token.NEQ:
			return x != y
		case token.LSS:
			return x < y
		case token.LEQ:
			return x <= y
		case token.GTR:
			return x > y
		case token.GEQ:
			return x >= y
		}

	case intVal:
		return cmpZero(x.val.Cmp(y.(intVal).val), op)

	case floatVal:
		return cmpZero(x.val.Cmp(y.(floatVal).val), op)

	case complexVal:
		y := y.(complexVal)
		re := x.re.Cmp(y.re)
		im := x.im.Cmp(y.im)
		switch op {
		case token.EQL:
			return re == 0 && im == 0
		case token.NEQ:
			return re != 0 || im != 0
		}

	case stringVal:
		y := y.(stringVal)
		switch op {
		case token.EQL:
			return x == y
		case token.NEQ:
			return x != y
		case token.LSS:
			return x < y
		case token.LEQ:
			return x <= y
		case token.GTR:
			return x > y
		case token.GEQ:
			return x >= y
		}
	}

	panic(fmt.Sprintf("invalid comparison %v %s %v", x, op, y))
}
