// Copyright 2011 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.

// This file implements operations on ideal constants.

package types

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

// TODO(gri) Consider changing the API so Const is an interface
//           and operations on consts don't have to type switch.

// A Const implements an ideal constant Value.
// The zero value z for a Const is not a valid constant value.
type Const struct {
	// representation of constant values:
	// ideal bool     ->  bool
	// ideal int      ->  *big.Int
	// ideal float    ->  *big.Rat
	// ideal complex  ->  cmplx
	// ideal string   ->  string
	val interface{}
}

// Representation of complex values.
type cmplx struct {
	re, im *big.Rat
}

func assert(cond bool) {
	if !cond {
		panic("go/types internal error: assertion failed")
	}
}

// MakeConst makes an ideal constant from a literal
// token and the corresponding literal string.
func MakeConst(tok token.Token, lit string) Const {
	switch tok {
	case token.INT:
		var x big.Int
		_, ok := x.SetString(lit, 0)
		assert(ok)
		return Const{&x}
	case token.FLOAT:
		var y big.Rat
		_, ok := y.SetString(lit)
		assert(ok)
		return Const{&y}
	case token.IMAG:
		assert(lit[len(lit)-1] == 'i')
		var im big.Rat
		_, ok := im.SetString(lit[0 : len(lit)-1])
		assert(ok)
		return Const{cmplx{big.NewRat(0, 1), &im}}
	case token.CHAR:
		assert(lit[0] == '\'' && lit[len(lit)-1] == '\'')
		code, _, _, err := strconv.UnquoteChar(lit[1:len(lit)-1], '\'')
		assert(err == nil)
		return Const{big.NewInt(int64(code))}
	case token.STRING:
		s, err := strconv.Unquote(lit)
		assert(err == nil)
		return Const{s}
	}
	panic("unreachable")
}

// MakeZero returns the zero constant for the given type.
func MakeZero(typ *Type) Const {
	// TODO(gri) fix this
	return Const{0}
}

// Match attempts to match the internal constant representations of x and y.
// If the attempt is successful, the result is the values of x and y,
// if necessary converted to have the same internal representation; otherwise
// the results are invalid.
func (x Const) Match(y Const) (u, v Const) {
	switch a := x.val.(type) {
	case bool:
		if _, ok := y.val.(bool); ok {
			u, v = x, y
		}
	case *big.Int:
		switch y.val.(type) {
		case *big.Int:
			u, v = x, y
		case *big.Rat:
			var z big.Rat
			z.SetInt(a)
			u, v = Const{&z}, y
		case cmplx:
			var z big.Rat
			z.SetInt(a)
			u, v = Const{cmplx{&z, big.NewRat(0, 1)}}, y
		}
	case *big.Rat:
		switch y.val.(type) {
		case *big.Int:
			v, u = y.Match(x)
		case *big.Rat:
			u, v = x, y
		case cmplx:
			u, v = Const{cmplx{a, big.NewRat(0, 0)}}, y
		}
	case cmplx:
		switch y.val.(type) {
		case *big.Int, *big.Rat:
			v, u = y.Match(x)
		case cmplx:
			u, v = x, y
		}
	case string:
		if _, ok := y.val.(string); ok {
			u, v = x, y
		}
	default:
		panic("unreachable")
	}
	return
}

// Convert attempts to convert the constant x to a given type.
// If the attempt is successful, the result is the new constant;
// otherwise the result is invalid.
func (x Const) Convert(typ *Type) Const {
	// TODO(gri) implement this
	switch x.val.(type) {
	case bool:
	case *big.Int:
	case *big.Rat:
	case cmplx:
	case string:
	}
	return x
}

func (x Const) String() string {
	switch x := x.val.(type) {
	case bool:
		if x {
			return "true"
		}
		return "false"
	case *big.Int:
		return x.String()
	case *big.Rat:
		return x.FloatString(10) // 10 digits of precision after decimal point seems fine
	case cmplx:
		// TODO(gri) don't print 0 components
		return x.re.FloatString(10) + " + " + x.im.FloatString(10) + "i"
	case string:
		return x
	}
	panic("unreachable")
}

func (x Const) UnaryOp(op token.Token) Const {
	panic("unimplemented")
}

func (x Const) BinaryOp(op token.Token, y Const) Const {
	var z interface{}
	switch x := x.val.(type) {
	case bool:
		z = binaryBoolOp(x, op, y.val.(bool))
	case *big.Int:
		z = binaryIntOp(x, op, y.val.(*big.Int))
	case *big.Rat:
		z = binaryFloatOp(x, op, y.val.(*big.Rat))
	case cmplx:
		z = binaryCmplxOp(x, op, y.val.(cmplx))
	case string:
		z = binaryStringOp(x, op, y.val.(string))
	default:
		panic("unreachable")
	}
	return Const{z}
}

func binaryBoolOp(x bool, op token.Token, y bool) interface{} {
	switch op {
	case token.EQL:
		return x == y
	case token.NEQ:
		return x != y
	}
	panic("unreachable")
}

func binaryIntOp(x *big.Int, op token.Token, y *big.Int) interface{} {
	var z big.Int
	switch op {
	case token.ADD:
		return z.Add(x, y)
	case token.SUB:
		return z.Sub(x, y)
	case token.MUL:
		return z.Mul(x, y)
	case token.QUO:
		return z.Quo(x, y)
	case token.REM:
		return z.Rem(x, y)
	case token.AND:
		return z.And(x, y)
	case token.OR:
		return z.Or(x, y)
	case token.XOR:
		return z.Xor(x, y)
	case token.AND_NOT:
		return z.AndNot(x, y)
	case token.SHL:
		panic("unimplemented")
	case token.SHR:
		panic("unimplemented")
	case token.EQL:
		return x.Cmp(y) == 0
	case token.NEQ:
		return x.Cmp(y) != 0
	case token.LSS:
		return x.Cmp(y) < 0
	case token.LEQ:
		return x.Cmp(y) <= 0
	case token.GTR:
		return x.Cmp(y) > 0
	case token.GEQ:
		return x.Cmp(y) >= 0
	}
	panic("unreachable")
}

func binaryFloatOp(x *big.Rat, op token.Token, y *big.Rat) interface{} {
	var z big.Rat
	switch op {
	case token.ADD:
		return z.Add(x, y)
	case token.SUB:
		return z.Sub(x, y)
	case token.MUL:
		return z.Mul(x, y)
	case token.QUO:
		return z.Quo(x, y)
	case token.EQL:
		return x.Cmp(y) == 0
	case token.NEQ:
		return x.Cmp(y) != 0
	case token.LSS:
		return x.Cmp(y) < 0
	case token.LEQ:
		return x.Cmp(y) <= 0
	case token.GTR:
		return x.Cmp(y) > 0
	case token.GEQ:
		return x.Cmp(y) >= 0
	}
	panic("unreachable")
}

func binaryCmplxOp(x cmplx, op token.Token, y cmplx) interface{} {
	a, b := x.re, x.im
	c, d := y.re, y.im
	switch op {
	case token.ADD:
		// (a+c) + i(b+d)
		var re, im big.Rat
		re.Add(a, c)
		im.Add(b, d)
		return cmplx{&re, &im}
	case token.SUB:
		// (a-c) + i(b-d)
		var re, im big.Rat
		re.Sub(a, c)
		im.Sub(b, d)
		return cmplx{&re, &im}
	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)
		var re, im big.Rat
		re.Sub(&ac, &bd)
		im.Add(&bc, &ad)
		return cmplx{&re, &im}
	case token.QUO:
		// (ac+bd)/s + i(bc-ad)/s, with s = cc + dd
		var ac, bd, bc, ad, s big.Rat
		ac.Mul(a, c)
		bd.Mul(b, d)
		bc.Mul(b, c)
		ad.Mul(a, d)
		s.Add(c.Mul(c, c), d.Mul(d, d))
		var re, im big.Rat
		re.Add(&ac, &bd)
		re.Quo(&re, &s)
		im.Sub(&bc, &ad)
		im.Quo(&im, &s)
		return cmplx{&re, &im}
	case token.EQL:
		return a.Cmp(c) == 0 && b.Cmp(d) == 0
	case token.NEQ:
		return a.Cmp(c) != 0 || b.Cmp(d) != 0
	}
	panic("unreachable")
}

func binaryStringOp(x string, op token.Token, y string) interface{} {
	switch op {
	case token.ADD:
		return x + y
	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("unreachable")
}
