// Copyright 2009 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 gc

import (
	"cmd/compile/internal/types"
	"cmd/internal/src"
	"fmt"
	"math/big"
	"strings"
)

// Ctype describes the constant kind of an "ideal" (untyped) constant.
type Ctype uint8

const (
	CTxxx Ctype = iota

	CTINT
	CTRUNE
	CTFLT
	CTCPLX
	CTSTR
	CTBOOL
	CTNIL
)

type Val struct {
	// U contains one of:
	// bool     bool when Ctype() == CTBOOL
	// *Mpint   int when Ctype() == CTINT, rune when Ctype() == CTRUNE
	// *Mpflt   float when Ctype() == CTFLT
	// *Mpcplx  pair of floats when Ctype() == CTCPLX
	// string   string when Ctype() == CTSTR
	// *Nilval  when Ctype() == CTNIL
	U interface{}
}

func (v Val) Ctype() Ctype {
	switch x := v.U.(type) {
	default:
		Fatalf("unexpected Ctype for %T", v.U)
		panic("unreachable")
	case nil:
		return 0
	case *NilVal:
		return CTNIL
	case bool:
		return CTBOOL
	case *Mpint:
		if x.Rune {
			return CTRUNE
		}
		return CTINT
	case *Mpflt:
		return CTFLT
	case *Mpcplx:
		return CTCPLX
	case string:
		return CTSTR
	}
}

func eqval(a, b Val) bool {
	if a.Ctype() != b.Ctype() {
		return false
	}
	switch x := a.U.(type) {
	default:
		Fatalf("unexpected Ctype for %T", a.U)
		panic("unreachable")
	case *NilVal:
		return true
	case bool:
		y := b.U.(bool)
		return x == y
	case *Mpint:
		y := b.U.(*Mpint)
		return x.Cmp(y) == 0
	case *Mpflt:
		y := b.U.(*Mpflt)
		return x.Cmp(y) == 0
	case *Mpcplx:
		y := b.U.(*Mpcplx)
		return x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
	case string:
		y := b.U.(string)
		return x == y
	}
}

// Interface returns the constant value stored in v as an interface{}.
// It returns int64s for ints and runes, float64s for floats,
// complex128s for complex values, and nil for constant nils.
func (v Val) Interface() interface{} {
	switch x := v.U.(type) {
	default:
		Fatalf("unexpected Interface for %T", v.U)
		panic("unreachable")
	case *NilVal:
		return nil
	case bool, string:
		return x
	case *Mpint:
		return x.Int64()
	case *Mpflt:
		return x.Float64()
	case *Mpcplx:
		return complex(x.Real.Float64(), x.Imag.Float64())
	}
}

type NilVal struct{}

// Int64 returns n as an int64.
// n must be an integer or rune constant.
func (n *Node) Int64() int64 {
	if !Isconst(n, CTINT) {
		Fatalf("Int64(%v)", n)
	}
	return n.Val().U.(*Mpint).Int64()
}

// CanInt64 reports whether it is safe to call Int64() on n.
func (n *Node) CanInt64() bool {
	if !Isconst(n, CTINT) {
		return false
	}

	// if the value inside n cannot be represented as an int64, the
	// return value of Int64 is undefined
	return n.Val().U.(*Mpint).CmpInt64(n.Int64()) == 0
}

// Bool returns n as a bool.
// n must be a boolean constant.
func (n *Node) Bool() bool {
	if !Isconst(n, CTBOOL) {
		Fatalf("Bool(%v)", n)
	}
	return n.Val().U.(bool)
}

// truncate float literal fv to 32-bit or 64-bit precision
// according to type; return truncated value.
func truncfltlit(oldv *Mpflt, t *types.Type) *Mpflt {
	if t == nil {
		return oldv
	}

	if overflow(Val{oldv}, t) {
		// If there was overflow, simply continuing would set the
		// value to Inf which in turn would lead to spurious follow-on
		// errors. Avoid this by returning the existing value.
		return oldv
	}

	fv := newMpflt()

	// convert large precision literal floating
	// into limited precision (float64 or float32)
	switch t.Etype {
	case types.TFLOAT32:
		fv.SetFloat64(oldv.Float32())
	case types.TFLOAT64:
		fv.SetFloat64(oldv.Float64())
	default:
		Fatalf("truncfltlit: unexpected Etype %v", t.Etype)
	}

	return fv
}

// truncate Real and Imag parts of Mpcplx to 32-bit or 64-bit
// precision, according to type; return truncated value. In case of
// overflow, calls yyerror but does not truncate the input value.
func trunccmplxlit(oldv *Mpcplx, t *types.Type) *Mpcplx {
	if t == nil {
		return oldv
	}

	if overflow(Val{oldv}, t) {
		// If there was overflow, simply continuing would set the
		// value to Inf which in turn would lead to spurious follow-on
		// errors. Avoid this by returning the existing value.
		return oldv
	}

	cv := newMpcmplx()

	switch t.Etype {
	case types.TCOMPLEX64:
		cv.Real.SetFloat64(oldv.Real.Float32())
		cv.Imag.SetFloat64(oldv.Imag.Float32())
	case types.TCOMPLEX128:
		cv.Real.SetFloat64(oldv.Real.Float64())
		cv.Imag.SetFloat64(oldv.Imag.Float64())
	default:
		Fatalf("trunccplxlit: unexpected Etype %v", t.Etype)
	}

	return cv
}

// canReuseNode indicates whether it is known to be safe
// to reuse a Node.
type canReuseNode bool

const (
	noReuse canReuseNode = false // not necessarily safe to reuse
	reuseOK canReuseNode = true  // safe to reuse
)

// convert n, if literal, to type t.
// implicit conversion.
// The result of convlit MUST be assigned back to n, e.g.
// 	n.Left = convlit(n.Left, t)
func convlit(n *Node, t *types.Type) *Node {
	return convlit1(n, t, false, noReuse)
}

// convlit1 converts n, if literal, to type t.
// It returns a new node if necessary.
// The result of convlit1 MUST be assigned back to n, e.g.
// 	n.Left = convlit1(n.Left, t, explicit, reuse)
func convlit1(n *Node, t *types.Type, explicit bool, reuse canReuseNode) *Node {
	if n == nil || t == nil || n.Type == nil || t.IsUntyped() || n.Type == t {
		return n
	}
	if !explicit && !n.Type.IsUntyped() {
		return n
	}

	if n.Op == OLITERAL && !reuse {
		// Can't always set n.Type directly on OLITERAL nodes.
		// See discussion on CL 20813.
		n = n.rawcopy()
		reuse = true
	}

	switch n.Op {
	default:
		if n.Type == types.Idealbool {
			if !t.IsBoolean() {
				t = types.Types[TBOOL]
			}
			switch n.Op {
			case ONOT:
				n.Left = convlit(n.Left, t)
			case OANDAND, OOROR:
				n.Left = convlit(n.Left, t)
				n.Right = convlit(n.Right, t)
			}
			n.Type = t
		}

		if n.Type.IsUntyped() {
			if t.IsInterface() {
				n.Left, n.Right = defaultlit2(n.Left, n.Right, true)
				n.Type = n.Left.Type // same as n.Right.Type per defaultlit2
			} else {
				n.Left = convlit(n.Left, t)
				n.Right = convlit(n.Right, t)
				n.Type = t
			}
		}

		return n

	// target is invalid type for a constant? leave alone.
	case OLITERAL:
		if !okforconst[t.Etype] && n.Type.Etype != TNIL {
			return defaultlitreuse(n, nil, reuse)
		}

	case OLSH, ORSH:
		n.Left = convlit1(n.Left, t, explicit && n.Left.Type.IsUntyped(), noReuse)
		t = n.Left.Type
		if t != nil && t.Etype == TIDEAL && n.Val().Ctype() != CTINT {
			n.SetVal(toint(n.Val()))
		}
		if t != nil && !t.IsInteger() {
			yyerror("invalid operation: %v (shift of type %v)", n, t)
			t = nil
		}

		n.Type = t
		return n

	case OCOMPLEX:
		if n.Type.Etype == TIDEAL {
			switch t.Etype {
			default:
				// If trying to convert to non-complex type,
				// leave as complex128 and let typechecker complain.
				t = types.Types[TCOMPLEX128]
				fallthrough
			case types.TCOMPLEX128:
				n.Type = t
				n.Left = convlit(n.Left, types.Types[TFLOAT64])
				n.Right = convlit(n.Right, types.Types[TFLOAT64])

			case TCOMPLEX64:
				n.Type = t
				n.Left = convlit(n.Left, types.Types[TFLOAT32])
				n.Right = convlit(n.Right, types.Types[TFLOAT32])
			}
		}

		return n
	}

	// avoid repeated calculations, errors
	if types.Identical(n.Type, t) {
		return n
	}

	ct := consttype(n)
	var et types.EType
	if ct == 0 {
		goto bad
	}

	et = t.Etype
	if et == TINTER {
		if ct == CTNIL && n.Type == types.Types[TNIL] {
			n.Type = t
			return n
		}
		return defaultlitreuse(n, nil, reuse)
	}

	switch ct {
	default:
		goto bad

	case CTNIL:
		switch et {
		default:
			n.Type = nil
			goto bad

			// let normal conversion code handle it
		case TSTRING:
			return n

		case TARRAY:
			goto bad

		case TPTR, TUNSAFEPTR:
			n.SetVal(Val{new(Mpint)})

		case TCHAN, TFUNC, TINTER, TMAP, TSLICE:
			break
		}

	case CTSTR, CTBOOL:
		if et != n.Type.Etype {
			goto bad
		}

	case CTINT, CTRUNE, CTFLT, CTCPLX:
		if n.Type.Etype == TUNSAFEPTR && t.Etype != TUINTPTR {
			goto bad
		}
		ct := n.Val().Ctype()
		if isInt[et] {
			switch ct {
			default:
				goto bad

			case CTCPLX, CTFLT, CTRUNE:
				n.SetVal(toint(n.Val()))
				fallthrough

			case CTINT:
				overflow(n.Val(), t)
			}
		} else if isFloat[et] {
			switch ct {
			default:
				goto bad

			case CTCPLX, CTINT, CTRUNE:
				n.SetVal(toflt(n.Val()))
				fallthrough

			case CTFLT:
				n.SetVal(Val{truncfltlit(n.Val().U.(*Mpflt), t)})
			}
		} else if isComplex[et] {
			switch ct {
			default:
				goto bad

			case CTFLT, CTINT, CTRUNE:
				n.SetVal(tocplx(n.Val()))
				fallthrough

			case CTCPLX:
				n.SetVal(Val{trunccmplxlit(n.Val().U.(*Mpcplx), t)})
			}
		} else if et == types.TSTRING && (ct == CTINT || ct == CTRUNE) && explicit {
			n.SetVal(tostr(n.Val()))
		} else {
			goto bad
		}
	}

	n.Type = t
	return n

bad:
	if !n.Diag() {
		if !t.Broke() {
			yyerror("cannot convert %L to type %v", n, t)
		}
		n.SetDiag(true)
	}

	if n.Type.IsUntyped() {
		n = defaultlitreuse(n, nil, reuse)
	}
	return n
}

func tocplx(v Val) Val {
	switch u := v.U.(type) {
	case *Mpint:
		c := newMpcmplx()
		c.Real.SetInt(u)
		c.Imag.SetFloat64(0.0)
		v.U = c

	case *Mpflt:
		c := newMpcmplx()
		c.Real.Set(u)
		c.Imag.SetFloat64(0.0)
		v.U = c
	}

	return v
}

func toflt(v Val) Val {
	switch u := v.U.(type) {
	case *Mpint:
		f := newMpflt()
		f.SetInt(u)
		v.U = f

	case *Mpcplx:
		f := newMpflt()
		f.Set(&u.Real)
		if u.Imag.CmpFloat64(0) != 0 {
			yyerror("constant %v truncated to real", u.GoString())
		}
		v.U = f
	}

	return v
}

func toint(v Val) Val {
	switch u := v.U.(type) {
	case *Mpint:
		if u.Rune {
			i := new(Mpint)
			i.Set(u)
			v.U = i
		}

	case *Mpflt:
		i := new(Mpint)
		if !i.SetFloat(u) {
			if i.checkOverflow(0) {
				yyerror("integer too large")
			} else {
				// The value of u cannot be represented as an integer;
				// so we need to print an error message.
				// Unfortunately some float values cannot be
				// reasonably formatted for inclusion in an error
				// message (example: 1 + 1e-100), so first we try to
				// format the float; if the truncation resulted in
				// something that looks like an integer we omit the
				// value from the error message.
				// (See issue #11371).
				var t big.Float
				t.Parse(u.GoString(), 10)
				if t.IsInt() {
					yyerror("constant truncated to integer")
				} else {
					yyerror("constant %v truncated to integer", u.GoString())
				}
			}
		}
		v.U = i

	case *Mpcplx:
		i := new(Mpint)
		if !i.SetFloat(&u.Real) || u.Imag.CmpFloat64(0) != 0 {
			yyerror("constant %v truncated to integer", u.GoString())
		}

		v.U = i
	}

	return v
}

func doesoverflow(v Val, t *types.Type) bool {
	switch u := v.U.(type) {
	case *Mpint:
		if !t.IsInteger() {
			Fatalf("overflow: %v integer constant", t)
		}
		return u.Cmp(minintval[t.Etype]) < 0 || u.Cmp(maxintval[t.Etype]) > 0

	case *Mpflt:
		if !t.IsFloat() {
			Fatalf("overflow: %v floating-point constant", t)
		}
		return u.Cmp(minfltval[t.Etype]) <= 0 || u.Cmp(maxfltval[t.Etype]) >= 0

	case *Mpcplx:
		if !t.IsComplex() {
			Fatalf("overflow: %v complex constant", t)
		}
		return u.Real.Cmp(minfltval[t.Etype]) <= 0 || u.Real.Cmp(maxfltval[t.Etype]) >= 0 ||
			u.Imag.Cmp(minfltval[t.Etype]) <= 0 || u.Imag.Cmp(maxfltval[t.Etype]) >= 0
	}

	return false
}

func overflow(v Val, t *types.Type) bool {
	// v has already been converted
	// to appropriate form for t.
	if t == nil || t.Etype == TIDEAL {
		return false
	}

	// Only uintptrs may be converted to pointers, which cannot overflow.
	if t.IsPtr() || t.IsUnsafePtr() {
		return false
	}

	if doesoverflow(v, t) {
		yyerror("constant %v overflows %v", v, t)
		return true
	}

	return false

}

func tostr(v Val) Val {
	switch u := v.U.(type) {
	case *Mpint:
		var i int64 = 0xFFFD
		if u.Cmp(minintval[TUINT32]) >= 0 && u.Cmp(maxintval[TUINT32]) <= 0 {
			i = u.Int64()
		}
		v.U = string(i)
	}

	return v
}

func consttype(n *Node) Ctype {
	if n == nil || n.Op != OLITERAL {
		return 0
	}
	return n.Val().Ctype()
}

func Isconst(n *Node, ct Ctype) bool {
	t := consttype(n)

	// If the caller is asking for CTINT, allow CTRUNE too.
	// Makes life easier for back ends.
	return t == ct || (ct == CTINT && t == CTRUNE)
}

// evconst rewrites constant expressions into OLITERAL nodes.
func evconst(n *Node) {
	nl, nr := n.Left, n.Right

	// Pick off just the opcodes that can be constant evaluated.
	switch op := n.Op; op {
	case OPLUS, ONEG, OBITNOT, ONOT:
		if nl.Op == OLITERAL {
			setconst(n, unaryOp(op, nl.Val(), n.Type))
		}

	case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND:
		if nl.Op == OLITERAL && nr.Op == OLITERAL {
			setconst(n, binaryOp(nl.Val(), op, nr.Val()))
		}

	case OEQ, ONE, OLT, OLE, OGT, OGE:
		if nl.Op == OLITERAL && nr.Op == OLITERAL {
			if nl.Type.IsInterface() != nr.Type.IsInterface() {
				// Mixed interface/non-interface
				// constant comparison means comparing
				// nil interface with some typed
				// constant, which is always unequal.
				// E.g., interface{}(nil) == (*int)(nil).
				setboolconst(n, op == ONE)
			} else {
				setboolconst(n, compareOp(nl.Val(), op, nr.Val()))
			}
		}

	case OLSH, ORSH:
		if nl.Op == OLITERAL && nr.Op == OLITERAL {
			setconst(n, shiftOp(nl.Val(), op, nr.Val()))
		}

	case OCONV:
		if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
			// TODO(mdempsky): There should be a convval function.
			setconst(n, convlit1(nl, n.Type, true, false).Val())
		}

	case OCONVNOP:
		if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
			// set so n.Orig gets OCONV instead of OCONVNOP
			n.Op = OCONV
			setconst(n, nl.Val())
		}

	case OADDSTR:
		// Merge adjacent constants in the argument list.
		s := n.List.Slice()
		for i1 := 0; i1 < len(s); i1++ {
			if Isconst(s[i1], CTSTR) && i1+1 < len(s) && Isconst(s[i1+1], CTSTR) {
				// merge from i1 up to but not including i2
				var strs []string
				i2 := i1
				for i2 < len(s) && Isconst(s[i2], CTSTR) {
					strs = append(strs, s[i2].Val().U.(string))
					i2++
				}

				nl := *s[i1]
				nl.Orig = &nl
				nl.SetVal(Val{strings.Join(strs, "")})
				s[i1] = &nl
				s = append(s[:i1+1], s[i2:]...)
			}
		}

		if len(s) == 1 && Isconst(s[0], CTSTR) {
			n.Op = OLITERAL
			n.SetVal(s[0].Val())
		} else {
			n.List.Set(s)
		}

	case OCAP, OLEN:
		switch nl.Type.Etype {
		case TSTRING:
			if Isconst(nl, CTSTR) {
				setintconst(n, int64(len(nl.Val().U.(string))))
			}
		case TARRAY:
			if !hascallchan(nl) {
				setintconst(n, nl.Type.NumElem())
			}
		}

	case OALIGNOF, OOFFSETOF, OSIZEOF:
		setintconst(n, evalunsafe(n))

	case OREAL, OIMAG:
		if nl.Op == OLITERAL {
			var re, im *Mpflt
			switch u := nl.Val().U.(type) {
			case *Mpint:
				re = newMpflt()
				re.SetInt(u)
				// im = 0
			case *Mpflt:
				re = u
				// im = 0
			case *Mpcplx:
				re = &u.Real
				im = &u.Imag
			default:
				Fatalf("impossible")
			}
			if n.Op == OIMAG {
				if im == nil {
					im = newMpflt()
				}
				re = im
			}
			setconst(n, Val{re})
		}

	case OCOMPLEX:
		if nl == nil || nr == nil {
			// TODO(mdempsky): Remove after early OAS2FUNC rewrite CL lands.
			break
		}
		if nl.Op == OLITERAL && nr.Op == OLITERAL {
			// make it a complex literal
			c := newMpcmplx()
			c.Real.Set(toflt(nl.Val()).U.(*Mpflt))
			c.Imag.Set(toflt(nr.Val()).U.(*Mpflt))
			setconst(n, Val{c})
		}
	}
}

func match(x, y Val) (Val, Val) {
	switch {
	case x.Ctype() == CTCPLX || y.Ctype() == CTCPLX:
		return tocplx(x), tocplx(y)
	case x.Ctype() == CTFLT || y.Ctype() == CTFLT:
		return toflt(x), toflt(y)
	}

	// Mixed int/rune are fine.
	return x, y
}

func compareOp(x Val, op Op, y Val) bool {
	x, y = match(x, y)

	switch x.Ctype() {
	case CTNIL:
		_, _ = x.U.(*NilVal), y.U.(*NilVal) // assert dynamic types match
		switch op {
		case OEQ:
			return true
		case ONE:
			return false
		}

	case CTBOOL:
		x, y := x.U.(bool), y.U.(bool)
		switch op {
		case OEQ:
			return x == y
		case ONE:
			return x != y
		}

	case CTINT, CTRUNE:
		x, y := x.U.(*Mpint), y.U.(*Mpint)
		return cmpZero(x.Cmp(y), op)

	case CTFLT:
		x, y := x.U.(*Mpflt), y.U.(*Mpflt)
		return cmpZero(x.Cmp(y), op)

	case CTCPLX:
		x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)
		eq := x.Real.Cmp(&y.Real) == 0 && x.Imag.Cmp(&y.Imag) == 0
		switch op {
		case OEQ:
			return eq
		case ONE:
			return !eq
		}

	case CTSTR:
		x, y := x.U.(string), y.U.(string)
		switch op {
		case OEQ:
			return x == y
		case ONE:
			return x != y
		case OLT:
			return x < y
		case OLE:
			return x <= y
		case OGT:
			return x > y
		case OGE:
			return x >= y
		}
	}

	Fatalf("compareOp: bad comparison: %v %v %v", x, op, y)
	panic("unreachable")
}

func cmpZero(x int, op Op) bool {
	switch op {
	case OEQ:
		return x == 0
	case ONE:
		return x != 0
	case OLT:
		return x < 0
	case OLE:
		return x <= 0
	case OGT:
		return x > 0
	case OGE:
		return x >= 0
	}

	Fatalf("cmpZero: want comparison operator, got %v", op)
	panic("unreachable")
}

func binaryOp(x Val, op Op, y Val) Val {
	x, y = match(x, y)

Outer:
	switch x.Ctype() {
	case CTBOOL:
		x, y := x.U.(bool), y.U.(bool)
		switch op {
		case OANDAND:
			return Val{U: x && y}
		case OOROR:
			return Val{U: x || y}
		}

	case CTINT, CTRUNE:
		x, y := x.U.(*Mpint), y.U.(*Mpint)

		u := new(Mpint)
		u.Rune = x.Rune || y.Rune
		u.Set(x)
		switch op {
		case OADD:
			u.Add(y)
		case OSUB:
			u.Sub(y)
		case OMUL:
			u.Mul(y)
		case ODIV:
			if y.CmpInt64(0) == 0 {
				yyerror("division by zero")
				return Val{}
			}
			u.Quo(y)
		case OMOD:
			if y.CmpInt64(0) == 0 {
				yyerror("division by zero")
				return Val{}
			}
			u.Rem(y)
		case OOR:
			u.Or(y)
		case OAND:
			u.And(y)
		case OANDNOT:
			u.AndNot(y)
		case OXOR:
			u.Xor(y)
		default:
			break Outer
		}
		return Val{U: u}

	case CTFLT:
		x, y := x.U.(*Mpflt), y.U.(*Mpflt)

		u := newMpflt()
		u.Set(x)
		switch op {
		case OADD:
			u.Add(y)
		case OSUB:
			u.Sub(y)
		case OMUL:
			u.Mul(y)
		case ODIV:
			if y.CmpFloat64(0) == 0 {
				yyerror("division by zero")
				return Val{}
			}
			u.Quo(y)
		case OMOD, OOR, OAND, OANDNOT, OXOR:
			// TODO(mdempsky): Move to typecheck; see #31060.
			yyerror("invalid operation: operator %v not defined on untyped float", op)
			return Val{}
		default:
			break Outer
		}
		return Val{U: u}

	case CTCPLX:
		x, y := x.U.(*Mpcplx), y.U.(*Mpcplx)

		u := newMpcmplx()
		u.Real.Set(&x.Real)
		u.Imag.Set(&x.Imag)
		switch op {
		case OADD:
			u.Real.Add(&y.Real)
			u.Imag.Add(&y.Imag)
		case OSUB:
			u.Real.Sub(&y.Real)
			u.Imag.Sub(&y.Imag)
		case OMUL:
			u.Mul(y)
		case ODIV:
			if !u.Div(y) {
				yyerror("complex division by zero")
				return Val{}
			}
		case OMOD, OOR, OAND, OANDNOT, OXOR:
			// TODO(mdempsky): Move to typecheck; see #31060.
			yyerror("invalid operation: operator %v not defined on untyped complex", op)
			return Val{}
		default:
			break Outer
		}
		return Val{U: u}
	}

	Fatalf("binaryOp: bad operation: %v %v %v", x, op, y)
	panic("unreachable")
}

func unaryOp(op Op, x Val, t *types.Type) Val {
	switch op {
	case OPLUS:
		switch x.Ctype() {
		case CTINT, CTRUNE, CTFLT, CTCPLX:
			return x
		}

	case ONEG:
		switch x.Ctype() {
		case CTINT, CTRUNE:
			x := x.U.(*Mpint)
			u := new(Mpint)
			u.Rune = x.Rune
			u.Set(x)
			u.Neg()
			return Val{U: u}

		case CTFLT:
			x := x.U.(*Mpflt)
			u := newMpflt()
			u.Set(x)
			u.Neg()
			return Val{U: u}

		case CTCPLX:
			x := x.U.(*Mpcplx)
			u := newMpcmplx()
			u.Real.Set(&x.Real)
			u.Imag.Set(&x.Imag)
			u.Real.Neg()
			u.Imag.Neg()
			return Val{U: u}
		}

	case OBITNOT:
		switch x.Ctype() {
		case CTINT, CTRUNE:
			x := x.U.(*Mpint)

			u := new(Mpint)
			u.Rune = x.Rune
			if t.IsSigned() || t.IsUntyped() {
				// Signed values change sign.
				u.SetInt64(-1)
			} else {
				// Unsigned values invert their bits.
				u.Set(maxintval[t.Etype])
			}
			u.Xor(x)
			return Val{U: u}

		case CTFLT:
			// TODO(mdempsky): Move to typecheck; see #31060.
			yyerror("invalid operation: operator %v not defined on untyped float", op)
			return Val{}
		case CTCPLX:
			// TODO(mdempsky): Move to typecheck; see #31060.
			yyerror("invalid operation: operator %v not defined on untyped complex", op)
			return Val{}
		}

	case ONOT:
		return Val{U: !x.U.(bool)}
	}

	Fatalf("unaryOp: bad operation: %v %v", op, x)
	panic("unreachable")
}

func shiftOp(x Val, op Op, y Val) Val {
	if x.Ctype() != CTRUNE {
		x = toint(x)
	}
	y = toint(y)

	u := new(Mpint)
	u.Set(x.U.(*Mpint))
	u.Rune = x.U.(*Mpint).Rune
	switch op {
	case OLSH:
		u.Lsh(y.U.(*Mpint))
	case ORSH:
		u.Rsh(y.U.(*Mpint))
	default:
		Fatalf("shiftOp: bad operator: %v", op)
		panic("unreachable")
	}
	return Val{U: u}
}

// setconst rewrites n as an OLITERAL with value v.
func setconst(n *Node, v Val) {
	// If constant folding failed, mark n as broken and give up.
	if v.U == nil {
		n.Type = nil
		return
	}

	// Ensure n.Orig still points to a semantically-equivalent
	// expression after we rewrite n into a constant.
	if n.Orig == n {
		n.Orig = n.sepcopy()
	}

	*n = Node{
		Op:      OLITERAL,
		Pos:     n.Pos,
		Orig:    n.Orig,
		Type:    n.Type,
		Xoffset: BADWIDTH,
	}
	n.SetVal(v)

	// Check range.
	lno := setlineno(n)
	overflow(v, n.Type)
	lineno = lno

	if !n.Type.IsUntyped() {
		switch v.Ctype() {
		// Truncate precision for non-ideal float.
		case CTFLT:
			n.SetVal(Val{truncfltlit(v.U.(*Mpflt), n.Type)})
		// Truncate precision for non-ideal complex.
		case CTCPLX:
			n.SetVal(Val{trunccmplxlit(v.U.(*Mpcplx), n.Type)})
		}
	}
}

func setboolconst(n *Node, v bool) {
	setconst(n, Val{U: v})
}

func setintconst(n *Node, v int64) {
	u := new(Mpint)
	u.SetInt64(v)
	setconst(n, Val{u})
}

// nodlit returns a new untyped constant with value v.
func nodlit(v Val) *Node {
	n := nod(OLITERAL, nil, nil)
	n.SetVal(v)
	switch v.Ctype() {
	default:
		Fatalf("nodlit ctype %d", v.Ctype())

	case CTSTR:
		n.Type = types.Idealstring

	case CTBOOL:
		n.Type = types.Idealbool

	case CTINT, CTRUNE, CTFLT, CTCPLX:
		n.Type = types.Types[TIDEAL]

	case CTNIL:
		n.Type = types.Types[TNIL]
	}

	return n
}

// idealkind returns a constant kind like consttype
// but for an arbitrary "ideal" (untyped constant) expression.
func idealkind(n *Node) Ctype {
	if n == nil || !n.Type.IsUntyped() {
		return CTxxx
	}

	switch n.Op {
	default:
		return CTxxx

	case OLITERAL:
		return n.Val().Ctype()

		// numeric kinds.
	case OADD,
		OAND,
		OANDNOT,
		OBITNOT,
		ODIV,
		ONEG,
		OMOD,
		OMUL,
		OSUB,
		OXOR,
		OOR,
		OPLUS:
		k1 := idealkind(n.Left)
		k2 := idealkind(n.Right)
		if k1 > k2 {
			return k1
		} else {
			return k2
		}

	case OREAL, OIMAG:
		return CTFLT

	case OCOMPLEX:
		return CTCPLX

	case OADDSTR:
		return CTSTR

	case OANDAND,
		OEQ,
		OGE,
		OGT,
		OLE,
		OLT,
		ONE,
		ONOT,
		OOROR:
		return CTBOOL

		// shifts (beware!).
	case OLSH, ORSH:
		return idealkind(n.Left)
	}
}

// The result of defaultlit MUST be assigned back to n, e.g.
// 	n.Left = defaultlit(n.Left, t)
func defaultlit(n *Node, t *types.Type) *Node {
	return defaultlitreuse(n, t, noReuse)
}

// The result of defaultlitreuse MUST be assigned back to n, e.g.
// 	n.Left = defaultlitreuse(n.Left, t, reuse)
func defaultlitreuse(n *Node, t *types.Type, reuse canReuseNode) *Node {
	if n == nil || !n.Type.IsUntyped() {
		return n
	}

	if n.Op == OLITERAL && !reuse {
		n = n.rawcopy()
		reuse = true
	}

	lno := setlineno(n)
	ctype := idealkind(n)
	var t1 *types.Type
	switch ctype {
	default:
		if t != nil {
			return convlit(n, t)
		}

		switch n.Val().Ctype() {
		case CTNIL:
			lineno = lno
			if !n.Diag() {
				yyerror("use of untyped nil")
				n.SetDiag(true)
			}

			n.Type = nil
		case CTSTR:
			t1 := types.Types[TSTRING]
			n = convlit1(n, t1, false, reuse)
		default:
			yyerror("defaultlit: unknown literal: %v", n)
		}
		lineno = lno
		return n

	case CTxxx:
		Fatalf("defaultlit: idealkind is CTxxx: %+v", n)

	case CTBOOL:
		t1 := types.Types[TBOOL]
		if t != nil && t.IsBoolean() {
			t1 = t
		}
		n = convlit1(n, t1, false, reuse)
		lineno = lno
		return n

	case CTINT:
		t1 = types.Types[TINT]
	case CTRUNE:
		t1 = types.Runetype
	case CTFLT:
		t1 = types.Types[TFLOAT64]
	case CTCPLX:
		t1 = types.Types[TCOMPLEX128]
	}

	// Note: n.Val().Ctype() can be CTxxx (not a constant) here
	// in the case of an untyped non-constant value, like 1<<i.
	v1 := n.Val()
	if t != nil {
		if t.IsInteger() {
			t1 = t
			v1 = toint(n.Val())
		} else if t.IsFloat() {
			t1 = t
			v1 = toflt(n.Val())
		} else if t.IsComplex() {
			t1 = t
			v1 = tocplx(n.Val())
		}
		if n.Val().Ctype() != CTxxx {
			n.SetVal(v1)
		}
	}

	if n.Val().Ctype() != CTxxx {
		overflow(n.Val(), t1)
	}
	n = convlit1(n, t1, false, reuse)
	lineno = lno
	return n
}

// defaultlit on both nodes simultaneously;
// if they're both ideal going in they better
// get the same type going out.
// force means must assign concrete (non-ideal) type.
// The results of defaultlit2 MUST be assigned back to l and r, e.g.
// 	n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
	if l.Type == nil || r.Type == nil {
		return l, r
	}
	if !l.Type.IsUntyped() {
		r = convlit(r, l.Type)
		return l, r
	}

	if !r.Type.IsUntyped() {
		l = convlit(l, r.Type)
		return l, r
	}

	if !force {
		return l, r
	}

	if l.Type.IsBoolean() {
		l = convlit(l, types.Types[TBOOL])
		r = convlit(r, types.Types[TBOOL])
	}

	lkind := idealkind(l)
	rkind := idealkind(r)
	if lkind == CTCPLX || rkind == CTCPLX {
		l = convlit(l, types.Types[TCOMPLEX128])
		r = convlit(r, types.Types[TCOMPLEX128])
		return l, r
	}

	if lkind == CTFLT || rkind == CTFLT {
		l = convlit(l, types.Types[TFLOAT64])
		r = convlit(r, types.Types[TFLOAT64])
		return l, r
	}

	if lkind == CTRUNE || rkind == CTRUNE {
		l = convlit(l, types.Runetype)
		r = convlit(r, types.Runetype)
		return l, r
	}

	l = convlit(l, types.Types[TINT])
	r = convlit(r, types.Types[TINT])

	return l, r
}

// strlit returns the value of a literal string Node as a string.
func strlit(n *Node) string {
	return n.Val().U.(string)
}

// TODO(gri) smallintconst is only used in one place - can we used indexconst?
func smallintconst(n *Node) bool {
	if n.Op == OLITERAL && Isconst(n, CTINT) && n.Type != nil {
		switch simtype[n.Type.Etype] {
		case TINT8,
			TUINT8,
			TINT16,
			TUINT16,
			TINT32,
			TUINT32,
			TBOOL:
			return true

		case TIDEAL, TINT64, TUINT64, TPTR:
			v, ok := n.Val().U.(*Mpint)
			if ok && v.Cmp(minintval[TINT32]) >= 0 && v.Cmp(maxintval[TINT32]) <= 0 {
				return true
			}
		}
	}

	return false
}

// indexconst checks if Node n contains a constant expression
// representable as a non-negative int and returns its value.
// If n is not a constant expression, not representable as an
// integer, or negative, it returns -1. If n is too large, it
// returns -2.
func indexconst(n *Node) int64 {
	if n.Op != OLITERAL {
		return -1
	}

	v := toint(n.Val()) // toint returns argument unchanged if not representable as an *Mpint
	vi, ok := v.U.(*Mpint)
	if !ok || vi.CmpInt64(0) < 0 {
		return -1
	}
	if vi.Cmp(maxintval[TINT]) > 0 {
		return -2
	}

	return vi.Int64()
}

// isGoConst reports whether n is a Go language constant (as opposed to a
// compile-time constant).
//
// Expressions derived from nil, like string([]byte(nil)), while they
// may be known at compile time, are not Go language constants.
func (n *Node) isGoConst() bool {
	return n.Op == OLITERAL && n.Val().Ctype() != CTNIL
}

func hascallchan(n *Node) bool {
	if n == nil {
		return false
	}
	switch n.Op {
	case OAPPEND,
		OCALL,
		OCALLFUNC,
		OCALLINTER,
		OCALLMETH,
		OCAP,
		OCLOSE,
		OCOMPLEX,
		OCOPY,
		ODELETE,
		OIMAG,
		OLEN,
		OMAKE,
		ONEW,
		OPANIC,
		OPRINT,
		OPRINTN,
		OREAL,
		ORECOVER,
		ORECV:
		return true
	}

	if hascallchan(n.Left) || hascallchan(n.Right) {
		return true
	}
	for _, n1 := range n.List.Slice() {
		if hascallchan(n1) {
			return true
		}
	}
	for _, n2 := range n.Rlist.Slice() {
		if hascallchan(n2) {
			return true
		}
	}

	return false
}

// A constSet represents a set of Go constant expressions.
type constSet struct {
	m map[constSetKey]src.XPos
}

type constSetKey struct {
	typ *types.Type
	val interface{}
}

// add adds constant expression n to s. If a constant expression of
// equal value and identical type has already been added, then add
// reports an error about the duplicate value.
//
// pos provides position information for where expression n occured
// (in case n does not have its own position information). what and
// where are used in the error message.
//
// n must not be an untyped constant.
func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
	if n.Op == OCONVIFACE && n.Implicit() {
		n = n.Left
	}

	if !n.isGoConst() {
		return
	}
	if n.Type.IsUntyped() {
		Fatalf("%v is untyped", n)
	}

	// Consts are only duplicates if they have the same value and
	// identical types.
	//
	// In general, we have to use types.Identical to test type
	// identity, because == gives false negatives for anonymous
	// types and the byte/uint8 and rune/int32 builtin type
	// aliases.  However, this is not a problem here, because
	// constant expressions are always untyped or have a named
	// type, and we explicitly handle the builtin type aliases
	// below.
	//
	// This approach may need to be revisited though if we fix
	// #21866 by treating all type aliases like byte/uint8 and
	// rune/int32.

	typ := n.Type
	switch typ {
	case types.Bytetype:
		typ = types.Types[TUINT8]
	case types.Runetype:
		typ = types.Types[TINT32]
	}
	k := constSetKey{typ, n.Val().Interface()}

	if hasUniquePos(n) {
		pos = n.Pos
	}

	if s.m == nil {
		s.m = make(map[constSetKey]src.XPos)
	}

	if prevPos, isDup := s.m[k]; isDup {
		yyerrorl(pos, "duplicate %s %s in %s\n\tprevious %s at %v",
			what, nodeAndVal(n), where,
			what, linestr(prevPos))
	} else {
		s.m[k] = pos
	}
}

// nodeAndVal reports both an expression and its constant value, if
// the latter is non-obvious.
//
// TODO(mdempsky): This could probably be a fmt.go flag.
func nodeAndVal(n *Node) string {
	show := n.String()
	val := n.Val().Interface()
	if s := fmt.Sprintf("%#v", val); show != s {
		show += " (value " + s + ")"
	}
	return show
}
