// 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 eval

import (
	"bignum"
	"go/ast"
	"go/token"
	"log"
	"reflect"
	"sort"
	"unsafe" // For Sizeof
)


// XXX(Spec) The type compatibility section is very confusing because
// it makes it seem like there are three distinct types of
// compatibility: plain compatibility, assignment compatibility, and
// comparison compatibility.  As I understand it, there's really only
// assignment compatibility and comparison and conversion have some
// restrictions and have special meaning in some cases where the types
// are not otherwise assignment compatible.  The comparison
// compatibility section is almost all about the semantics of
// comparison, not the type checking of it, so it would make much more
// sense in the comparison operators section.  The compatibility and
// assignment compatibility sections should be rolled into one.

type Type interface {
	// compat returns whether this type is compatible with another
	// type.  If conv is false, this is normal compatibility,
	// where two named types are compatible only if they are the
	// same named type.  If conv if true, this is conversion
	// compatibility, where two named types are conversion
	// compatible if their definitions are conversion compatible.
	//
	// TODO(austin) Deal with recursive types
	compat(o Type, conv bool) bool
	// lit returns this type's literal.  If this is a named type,
	// this is the unnamed underlying type.  Otherwise, this is an
	// identity operation.
	lit() Type
	// isBoolean returns true if this is a boolean type.
	isBoolean() bool
	// isInteger returns true if this is an integer type.
	isInteger() bool
	// isFloat returns true if this is a floating type.
	isFloat() bool
	// isIdeal returns true if this is an ideal int or float.
	isIdeal() bool
	// Zero returns a new zero value of this type.
	Zero() Value
	// String returns the string representation of this type.
	String() string
	// The position where this type was defined, if any.
	Pos() token.Position
}

type BoundedType interface {
	Type
	// minVal returns the smallest value of this type.
	minVal() *bignum.Rational
	// maxVal returns the largest value of this type.
	maxVal() *bignum.Rational
}

var universePos = token.Position{"<universe>", 0, 0, 0}

/*
 * Type array maps.  These are used to memoize composite types.
 */

type typeArrayMapEntry struct {
	key  []Type
	v    interface{}
	next *typeArrayMapEntry
}

type typeArrayMap map[uintptr]*typeArrayMapEntry

func hashTypeArray(key []Type) uintptr {
	hash := uintptr(0)
	for _, t := range key {
		hash = hash * 33
		if t == nil {
			continue
		}
		addr := reflect.NewValue(t).(*reflect.PtrValue).Get()
		hash ^= addr
	}
	return hash
}

func newTypeArrayMap() typeArrayMap { return make(map[uintptr]*typeArrayMapEntry) }

func (m typeArrayMap) Get(key []Type) interface{} {
	ent, ok := m[hashTypeArray(key)]
	if !ok {
		return nil
	}

nextEnt:
	for ; ent != nil; ent = ent.next {
		if len(key) != len(ent.key) {
			continue
		}
		for i := 0; i < len(key); i++ {
			if key[i] != ent.key[i] {
				continue nextEnt
			}
		}
		// Found it
		return ent.v
	}

	return nil
}

func (m typeArrayMap) Put(key []Type, v interface{}) interface{} {
	hash := hashTypeArray(key)
	ent, _ := m[hash]

	new := &typeArrayMapEntry{key, v, ent}
	m[hash] = new
	return v
}

/*
 * Common type
 */

type commonType struct{}

func (commonType) isBoolean() bool { return false }

func (commonType) isInteger() bool { return false }

func (commonType) isFloat() bool { return false }

func (commonType) isIdeal() bool { return false }

func (commonType) Pos() token.Position { return token.Position{} }

/*
 * Bool
 */

type boolType struct {
	commonType
}

var BoolType = universe.DefineType("bool", universePos, &boolType{})

func (t *boolType) compat(o Type, conv bool) bool {
	_, ok := o.lit().(*boolType)
	return ok
}

func (t *boolType) lit() Type { return t }

func (t *boolType) isBoolean() bool { return true }

func (boolType) String() string {
	// Use angle brackets as a convention for printing the
	// underlying, unnamed type.  This should only show up in
	// debug output.
	return "<bool>"
}

func (t *boolType) Zero() Value {
	res := boolV(false)
	return &res
}

/*
 * Uint
 */

type uintType struct {
	commonType

	// 0 for architecture-dependent types
	Bits uint
	// true for uintptr, false for all others
	Ptr  bool
	name string
}

var (
	Uint8Type  = universe.DefineType("uint8", universePos, &uintType{commonType{}, 8, false, "uint8"})
	Uint16Type = universe.DefineType("uint16", universePos, &uintType{commonType{}, 16, false, "uint16"})
	Uint32Type = universe.DefineType("uint32", universePos, &uintType{commonType{}, 32, false, "uint32"})
	Uint64Type = universe.DefineType("uint64", universePos, &uintType{commonType{}, 64, false, "uint64"})

	UintType    = universe.DefineType("uint", universePos, &uintType{commonType{}, 0, false, "uint"})
	UintptrType = universe.DefineType("uintptr", universePos, &uintType{commonType{}, 0, true, "uintptr"})
)

func (t *uintType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*uintType)
	return ok && t == t2
}

func (t *uintType) lit() Type { return t }

func (t *uintType) isInteger() bool { return true }

func (t *uintType) String() string { return "<" + t.name + ">" }

func (t *uintType) Zero() Value {
	switch t.Bits {
	case 0:
		if t.Ptr {
			res := uintptrV(0)
			return &res
		} else {
			res := uintV(0)
			return &res
		}
	case 8:
		res := uint8V(0)
		return &res
	case 16:
		res := uint16V(0)
		return &res
	case 32:
		res := uint32V(0)
		return &res
	case 64:
		res := uint64V(0)
		return &res
	}
	panic("unexpected uint bit count: ", t.Bits)
}

func (t *uintType) minVal() *bignum.Rational { return bignum.Rat(0, 1) }

func (t *uintType) maxVal() *bignum.Rational {
	bits := t.Bits
	if bits == 0 {
		if t.Ptr {
			bits = uint(8 * unsafe.Sizeof(uintptr(0)))
		} else {
			bits = uint(8 * unsafe.Sizeof(uint(0)))
		}
	}
	return bignum.MakeRat(bignum.Int(1).Shl(bits).Add(bignum.Int(-1)), bignum.Nat(1))
}

/*
 * Int
 */

type intType struct {
	commonType

	// XXX(Spec) Numeric types: "There is also a set of
	// architecture-independent basic numeric types whose size
	// depends on the architecture."  Should that be
	// architecture-dependent?

	// 0 for architecture-dependent types
	Bits uint
	name string
}

var (
	Int8Type  = universe.DefineType("int8", universePos, &intType{commonType{}, 8, "int8"})
	Int16Type = universe.DefineType("int16", universePos, &intType{commonType{}, 16, "int16"})
	Int32Type = universe.DefineType("int32", universePos, &intType{commonType{}, 32, "int32"})
	Int64Type = universe.DefineType("int64", universePos, &intType{commonType{}, 64, "int64"})

	IntType = universe.DefineType("int", universePos, &intType{commonType{}, 0, "int"})
)

func (t *intType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*intType)
	return ok && t == t2
}

func (t *intType) lit() Type { return t }

func (t *intType) isInteger() bool { return true }

func (t *intType) String() string { return "<" + t.name + ">" }

func (t *intType) Zero() Value {
	switch t.Bits {
	case 8:
		res := int8V(0)
		return &res
	case 16:
		res := int16V(0)
		return &res
	case 32:
		res := int32V(0)
		return &res
	case 64:
		res := int64V(0)
		return &res

	case 0:
		res := intV(0)
		return &res
	}
	panic("unexpected int bit count: ", t.Bits)
}

func (t *intType) minVal() *bignum.Rational {
	bits := t.Bits
	if bits == 0 {
		bits = uint(8 * unsafe.Sizeof(int(0)))
	}
	return bignum.MakeRat(bignum.Int(-1).Shl(bits-1), bignum.Nat(1))
}

func (t *intType) maxVal() *bignum.Rational {
	bits := t.Bits
	if bits == 0 {
		bits = uint(8 * unsafe.Sizeof(int(0)))
	}
	return bignum.MakeRat(bignum.Int(1).Shl(bits-1).Add(bignum.Int(-1)), bignum.Nat(1))
}

/*
 * Ideal int
 */

type idealIntType struct {
	commonType
}

var IdealIntType Type = &idealIntType{}

func (t *idealIntType) compat(o Type, conv bool) bool {
	_, ok := o.lit().(*idealIntType)
	return ok
}

func (t *idealIntType) lit() Type { return t }

func (t *idealIntType) isInteger() bool { return true }

func (t *idealIntType) isIdeal() bool { return true }

func (t *idealIntType) String() string { return "ideal integer" }

func (t *idealIntType) Zero() Value { return &idealIntV{bignum.Int(0)} }

/*
 * Float
 */

type floatType struct {
	commonType

	// 0 for architecture-dependent type
	Bits uint

	name string
}

var (
	Float32Type = universe.DefineType("float32", universePos, &floatType{commonType{}, 32, "float32"})
	Float64Type = universe.DefineType("float64", universePos, &floatType{commonType{}, 64, "float64"})
	FloatType   = universe.DefineType("float", universePos, &floatType{commonType{}, 0, "float"})
)

func (t *floatType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*floatType)
	return ok && t == t2
}

func (t *floatType) lit() Type { return t }

func (t *floatType) isFloat() bool { return true }

func (t *floatType) String() string { return "<" + t.name + ">" }

func (t *floatType) Zero() Value {
	switch t.Bits {
	case 32:
		res := float32V(0)
		return &res
	case 64:
		res := float64V(0)
		return &res
	case 0:
		res := floatV(0)
		return &res
	}
	panic("unexpected float bit count: ", t.Bits)
}

var maxFloat32Val = bignum.MakeRat(bignum.Int(0xffffff).Shl(127-23), bignum.Nat(1))
var maxFloat64Val = bignum.MakeRat(bignum.Int(0x1fffffffffffff).Shl(1023-52), bignum.Nat(1))
var minFloat32Val = maxFloat32Val.Neg()
var minFloat64Val = maxFloat64Val.Neg()

func (t *floatType) minVal() *bignum.Rational {
	bits := t.Bits
	if bits == 0 {
		bits = uint(8 * unsafe.Sizeof(float(0)))
	}
	switch bits {
	case 32:
		return minFloat32Val
	case 64:
		return minFloat64Val
	}
	log.Crashf("unexpected floating point bit count: %d", bits)
	panic()
}

func (t *floatType) maxVal() *bignum.Rational {
	bits := t.Bits
	if bits == 0 {
		bits = uint(8 * unsafe.Sizeof(float(0)))
	}
	switch bits {
	case 32:
		return maxFloat32Val
	case 64:
		return maxFloat64Val
	}
	log.Crashf("unexpected floating point bit count: %d", bits)
	panic()
}

/*
 * Ideal float
 */

type idealFloatType struct {
	commonType
}

var IdealFloatType Type = &idealFloatType{}

func (t *idealFloatType) compat(o Type, conv bool) bool {
	_, ok := o.lit().(*idealFloatType)
	return ok
}

func (t *idealFloatType) lit() Type { return t }

func (t *idealFloatType) isFloat() bool { return true }

func (t *idealFloatType) isIdeal() bool { return true }

func (t *idealFloatType) String() string { return "ideal float" }

func (t *idealFloatType) Zero() Value { return &idealFloatV{bignum.Rat(1, 0)} }

/*
 * String
 */

type stringType struct {
	commonType
}

var StringType = universe.DefineType("string", universePos, &stringType{})

func (t *stringType) compat(o Type, conv bool) bool {
	_, ok := o.lit().(*stringType)
	return ok
}

func (t *stringType) lit() Type { return t }

func (t *stringType) String() string { return "<string>" }

func (t *stringType) Zero() Value {
	res := stringV("")
	return &res
}

/*
 * Array
 */

type ArrayType struct {
	commonType
	Len  int64
	Elem Type
}

var arrayTypes = make(map[int64]map[Type]*ArrayType)

// Two array types are identical if they have identical element types
// and the same array length.

func NewArrayType(len int64, elem Type) *ArrayType {
	ts, ok := arrayTypes[len]
	if !ok {
		ts = make(map[Type]*ArrayType)
		arrayTypes[len] = ts
	}
	t, ok := ts[elem]
	if !ok {
		t = &ArrayType{commonType{}, len, elem}
		ts[elem] = t
	}
	return t
}

func (t *ArrayType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*ArrayType)
	if !ok {
		return false
	}
	return t.Len == t2.Len && t.Elem.compat(t2.Elem, conv)
}

func (t *ArrayType) lit() Type { return t }

func (t *ArrayType) String() string { return "[]" + t.Elem.String() }

func (t *ArrayType) Zero() Value {
	res := arrayV(make([]Value, t.Len))
	// TODO(austin) It's unfortunate that each element is
	// separately heap allocated.  We could add ZeroArray to
	// everything, though that doesn't help with multidimensional
	// arrays.  Or we could do something unsafe.  We'll have this
	// same problem with structs.
	for i := int64(0); i < t.Len; i++ {
		res[i] = t.Elem.Zero()
	}
	return &res
}

/*
 * Struct
 */

type StructField struct {
	Name      string
	Type      Type
	Anonymous bool
}

type StructType struct {
	commonType
	Elems []StructField
}

var structTypes = newTypeArrayMap()

// Two struct types are identical if they have the same sequence of
// fields, and if corresponding fields have the same names and
// identical types. Two anonymous fields are considered to have the
// same name.

func NewStructType(fields []StructField) *StructType {
	// Start by looking up just the types
	fts := make([]Type, len(fields))
	for i, f := range fields {
		fts[i] = f.Type
	}
	tMapI := structTypes.Get(fts)
	if tMapI == nil {
		tMapI = structTypes.Put(fts, make(map[string]*StructType))
	}
	tMap := tMapI.(map[string]*StructType)

	// Construct key for field names
	key := ""
	for _, f := range fields {
		// XXX(Spec) It's not clear if struct { T } and struct
		// { T T } are either identical or compatible.  The
		// "Struct Types" section says that the name of that
		// field is "T", which suggests that they are
		// identical, but it really means that it's the name
		// for the purpose of selector expressions and nothing
		// else.  We decided that they should be neither
		// identical or compatible.
		if f.Anonymous {
			key += "!"
		}
		key += f.Name + " "
	}

	// XXX(Spec) Do the tags also have to be identical for the
	// types to be identical?  I certainly hope so, because
	// otherwise, this is the only case where two distinct type
	// objects can represent identical types.

	t, ok := tMap[key]
	if !ok {
		// Create new struct type
		t = &StructType{commonType{}, fields}
		tMap[key] = t
	}
	return t
}

func (t *StructType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*StructType)
	if !ok {
		return false
	}
	if len(t.Elems) != len(t2.Elems) {
		return false
	}
	for i, e := range t.Elems {
		e2 := t2.Elems[i]
		// XXX(Spec) An anonymous and a non-anonymous field
		// are neither identical nor compatible.
		if e.Anonymous != e2.Anonymous ||
			(!e.Anonymous && e.Name != e2.Name) ||
			!e.Type.compat(e2.Type, conv) {
			return false
		}
	}
	return true
}

func (t *StructType) lit() Type { return t }

func (t *StructType) String() string {
	s := "struct {"
	for i, f := range t.Elems {
		if i > 0 {
			s += "; "
		}
		if !f.Anonymous {
			s += f.Name + " "
		}
		s += f.Type.String()
	}
	return s + "}"
}

func (t *StructType) Zero() Value {
	res := structV(make([]Value, len(t.Elems)))
	for i, f := range t.Elems {
		res[i] = f.Type.Zero()
	}
	return &res
}

/*
 * Pointer
 */

type PtrType struct {
	commonType
	Elem Type
}

var ptrTypes = make(map[Type]*PtrType)

// Two pointer types are identical if they have identical base types.

func NewPtrType(elem Type) *PtrType {
	t, ok := ptrTypes[elem]
	if !ok {
		t = &PtrType{commonType{}, elem}
		ptrTypes[elem] = t
	}
	return t
}

func (t *PtrType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*PtrType)
	if !ok {
		return false
	}
	return t.Elem.compat(t2.Elem, conv)
}

func (t *PtrType) lit() Type { return t }

func (t *PtrType) String() string { return "*" + t.Elem.String() }

func (t *PtrType) Zero() Value { return &ptrV{nil} }

/*
 * Function
 */

type FuncType struct {
	commonType
	// TODO(austin) Separate receiver Type for methods?
	In       []Type
	Variadic bool
	Out      []Type
	builtin  string
}

var funcTypes = newTypeArrayMap()
var variadicFuncTypes = newTypeArrayMap()

// Create singleton function types for magic built-in functions
var (
	capType     = &FuncType{builtin: "cap"}
	closeType   = &FuncType{builtin: "close"}
	closedType  = &FuncType{builtin: "closed"}
	lenType     = &FuncType{builtin: "len"}
	makeType    = &FuncType{builtin: "make"}
	newType     = &FuncType{builtin: "new"}
	panicType   = &FuncType{builtin: "panic"}
	paniclnType = &FuncType{builtin: "panicln"}
	printType   = &FuncType{builtin: "print"}
	printlnType = &FuncType{builtin: "println"}
)

// Two function types are identical if they have the same number of
// parameters and result values and if corresponding parameter and
// result types are identical. All "..." parameters have identical
// type. Parameter and result names are not required to match.

func NewFuncType(in []Type, variadic bool, out []Type) *FuncType {
	inMap := funcTypes
	if variadic {
		inMap = variadicFuncTypes
	}

	outMapI := inMap.Get(in)
	if outMapI == nil {
		outMapI = inMap.Put(in, newTypeArrayMap())
	}
	outMap := outMapI.(typeArrayMap)

	tI := outMap.Get(out)
	if tI != nil {
		return tI.(*FuncType)
	}

	t := &FuncType{commonType{}, in, variadic, out, ""}
	outMap.Put(out, t)
	return t
}

func (t *FuncType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*FuncType)
	if !ok {
		return false
	}
	if len(t.In) != len(t2.In) || t.Variadic != t2.Variadic || len(t.Out) != len(t2.Out) {
		return false
	}
	for i := range t.In {
		if !t.In[i].compat(t2.In[i], conv) {
			return false
		}
	}
	for i := range t.Out {
		if !t.Out[i].compat(t2.Out[i], conv) {
			return false
		}
	}
	return true
}

func (t *FuncType) lit() Type { return t }

func typeListString(ts []Type, ns []*ast.Ident) string {
	s := ""
	for i, t := range ts {
		if i > 0 {
			s += ", "
		}
		if ns != nil && ns[i] != nil {
			s += ns[i].Name() + " "
		}
		if t == nil {
			// Some places use nil types to represent errors
			s += "<none>"
		} else {
			s += t.String()
		}
	}
	return s
}

func (t *FuncType) String() string {
	if t.builtin != "" {
		return "built-in function " + t.builtin
	}
	args := typeListString(t.In, nil)
	if t.Variadic {
		if len(args) > 0 {
			args += ", "
		}
		args += "..."
	}
	s := "func(" + args + ")"
	if len(t.Out) > 0 {
		s += " (" + typeListString(t.Out, nil) + ")"
	}
	return s
}

func (t *FuncType) Zero() Value { return &funcV{nil} }

type FuncDecl struct {
	Type *FuncType
	Name *ast.Ident // nil for function literals
	// InNames will be one longer than Type.In if this function is
	// variadic.
	InNames  []*ast.Ident
	OutNames []*ast.Ident
}

func (t *FuncDecl) String() string {
	s := "func"
	if t.Name != nil {
		s += " " + t.Name.Name()
	}
	s += funcTypeString(t.Type, t.InNames, t.OutNames)
	return s
}

func funcTypeString(ft *FuncType, ins []*ast.Ident, outs []*ast.Ident) string {
	s := "("
	s += typeListString(ft.In, ins)
	if ft.Variadic {
		if len(ft.In) > 0 {
			s += ", "
		}
		s += "..."
	}
	s += ")"
	if len(ft.Out) > 0 {
		s += " (" + typeListString(ft.Out, outs) + ")"
	}
	return s
}

/*
 * Interface
 */

// TODO(austin) Interface values, types, and type compilation are
// implemented, but none of the type checking or semantics of
// interfaces are.

type InterfaceType struct {
	commonType
	// TODO(austin) This should be a map from names to
	// *FuncType's.  We only need the sorted list for generating
	// the type map key.  It's detrimental for everything else.
	methods []IMethod
}

type IMethod struct {
	Name string
	Type *FuncType
}

var interfaceTypes = newTypeArrayMap()

func NewInterfaceType(methods []IMethod, embeds []*InterfaceType) *InterfaceType {
	// Count methods of embedded interfaces
	nMethods := len(methods)
	for _, e := range embeds {
		nMethods += len(e.methods)
	}

	// Combine methods
	allMethods := make([]IMethod, nMethods)
	for i, m := range methods {
		allMethods[i] = m
	}
	n := len(methods)
	for _, e := range embeds {
		for _, m := range e.methods {
			allMethods[n] = m
			n++
		}
	}

	// Sort methods
	sort.Sort(iMethodSorter(allMethods))

	mts := make([]Type, len(allMethods))
	for i, m := range methods {
		mts[i] = m.Type
	}
	tMapI := interfaceTypes.Get(mts)
	if tMapI == nil {
		tMapI = interfaceTypes.Put(mts, make(map[string]*InterfaceType))
	}
	tMap := tMapI.(map[string]*InterfaceType)

	key := ""
	for _, m := range allMethods {
		key += m.Name + " "
	}

	t, ok := tMap[key]
	if !ok {
		t = &InterfaceType{commonType{}, allMethods}
		tMap[key] = t
	}
	return t
}

type iMethodSorter []IMethod

func (s iMethodSorter) Less(a, b int) bool { return s[a].Name < s[b].Name }

func (s iMethodSorter) Swap(a, b int) { s[a], s[b] = s[b], s[a] }

func (s iMethodSorter) Len() int { return len(s) }

func (t *InterfaceType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*InterfaceType)
	if !ok {
		return false
	}
	if len(t.methods) != len(t2.methods) {
		return false
	}
	for i, e := range t.methods {
		e2 := t2.methods[i]
		if e.Name != e2.Name || !e.Type.compat(e2.Type, conv) {
			return false
		}
	}
	return true
}

func (t *InterfaceType) lit() Type { return t }

func (t *InterfaceType) String() string {
	// TODO(austin) Instead of showing embedded interfaces, this
	// shows their methods.
	s := "interface {"
	for i, m := range t.methods {
		if i > 0 {
			s += "; "
		}
		s += m.Name + funcTypeString(m.Type, nil, nil)
	}
	return s + "}"
}

// implementedBy tests if o implements t, returning nil, true if it does.
// Otherwise, it returns a method of t that o is missing and false.
func (t *InterfaceType) implementedBy(o Type) (*IMethod, bool) {
	if len(t.methods) == 0 {
		return nil, true
	}

	// The methods of a named interface types are those of the
	// underlying type.
	if it, ok := o.lit().(*InterfaceType); ok {
		o = it
	}

	// XXX(Spec) Interface types: "A type implements any interface
	// comprising any subset of its methods" It's unclear if
	// methods must have identical or compatible types.  6g
	// requires identical types.

	switch o := o.(type) {
	case *NamedType:
		for _, tm := range t.methods {
			sm, ok := o.methods[tm.Name]
			if !ok || sm.decl.Type != tm.Type {
				return &tm, false
			}
		}
		return nil, true

	case *InterfaceType:
		var ti, oi int
		for ti < len(t.methods) && oi < len(o.methods) {
			tm, om := &t.methods[ti], &o.methods[oi]
			switch {
			case tm.Name == om.Name:
				if tm.Type != om.Type {
					return tm, false
				}
				ti++
				oi++
			case tm.Name > om.Name:
				oi++
			default:
				return tm, false
			}
		}
		if ti < len(t.methods) {
			return &t.methods[ti], false
		}
		return nil, true
	}

	return &t.methods[0], false
}

func (t *InterfaceType) Zero() Value { return &interfaceV{} }

/*
 * Slice
 */

type SliceType struct {
	commonType
	Elem Type
}

var sliceTypes = make(map[Type]*SliceType)

// Two slice types are identical if they have identical element types.

func NewSliceType(elem Type) *SliceType {
	t, ok := sliceTypes[elem]
	if !ok {
		t = &SliceType{commonType{}, elem}
		sliceTypes[elem] = t
	}
	return t
}

func (t *SliceType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*SliceType)
	if !ok {
		return false
	}
	return t.Elem.compat(t2.Elem, conv)
}

func (t *SliceType) lit() Type { return t }

func (t *SliceType) String() string { return "[]" + t.Elem.String() }

func (t *SliceType) Zero() Value {
	// The value of an uninitialized slice is nil. The length and
	// capacity of a nil slice are 0.
	return &sliceV{Slice{nil, 0, 0}}
}

/*
 * Map type
 */

type MapType struct {
	commonType
	Key  Type
	Elem Type
}

var mapTypes = make(map[Type]map[Type]*MapType)

func NewMapType(key Type, elem Type) *MapType {
	ts, ok := mapTypes[key]
	if !ok {
		ts = make(map[Type]*MapType)
		mapTypes[key] = ts
	}
	t, ok := ts[elem]
	if !ok {
		t = &MapType{commonType{}, key, elem}
		ts[elem] = t
	}
	return t
}

func (t *MapType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*MapType)
	if !ok {
		return false
	}
	return t.Elem.compat(t2.Elem, conv) && t.Key.compat(t2.Key, conv)
}

func (t *MapType) lit() Type { return t }

func (t *MapType) String() string { return "map[" + t.Key.String() + "] " + t.Elem.String() }

func (t *MapType) Zero() Value {
	// The value of an uninitialized map is nil.
	return &mapV{nil}
}

/*
type ChanType struct {
	// TODO(austin)
}
*/

/*
 * Named types
 */

type Method struct {
	decl *FuncDecl
	fn   Func
}

type NamedType struct {
	token.Position
	Name string
	// Underlying type.  If incomplete is true, this will be nil.
	// If incomplete is false and this is still nil, then this is
	// a placeholder type representing an error.
	Def Type
	// True while this type is being defined.
	incomplete bool
	methods    map[string]Method
}

// TODO(austin) This is temporarily needed by the debugger's remote
// type parser.  This should only be possible with block.DefineType.
func NewNamedType(name string) *NamedType {
	return &NamedType{token.Position{}, name, nil, true, make(map[string]Method)}
}

func (t *NamedType) Complete(def Type) {
	if !t.incomplete {
		log.Crashf("cannot complete already completed NamedType %+v", *t)
	}
	// We strip the name from def because multiple levels of
	// naming are useless.
	if ndef, ok := def.(*NamedType); ok {
		def = ndef.Def
	}
	t.Def = def
	t.incomplete = false
}

func (t *NamedType) compat(o Type, conv bool) bool {
	t2, ok := o.(*NamedType)
	if ok {
		if conv {
			// Two named types are conversion compatible
			// if their literals are conversion
			// compatible.
			return t.Def.compat(t2.Def, conv)
		} else {
			// Two named types are compatible if their
			// type names originate in the same type
			// declaration.
			return t == t2
		}
	}
	// A named and an unnamed type are compatible if the
	// respective type literals are compatible.
	return o.compat(t.Def, conv)
}

func (t *NamedType) lit() Type { return t.Def.lit() }

func (t *NamedType) isBoolean() bool { return t.Def.isBoolean() }

func (t *NamedType) isInteger() bool { return t.Def.isInteger() }

func (t *NamedType) isFloat() bool { return t.Def.isFloat() }

func (t *NamedType) isIdeal() bool { return false }

func (t *NamedType) String() string { return t.Name }

func (t *NamedType) Zero() Value { return t.Def.Zero() }

/*
 * Multi-valued type
 */

// MultiType is a special type used for multi-valued expressions, akin
// to a tuple type.  It's not generally accessible within the
// language.
type MultiType struct {
	commonType
	Elems []Type
}

var multiTypes = newTypeArrayMap()

func NewMultiType(elems []Type) *MultiType {
	if t := multiTypes.Get(elems); t != nil {
		return t.(*MultiType)
	}

	t := &MultiType{commonType{}, elems}
	multiTypes.Put(elems, t)
	return t
}

func (t *MultiType) compat(o Type, conv bool) bool {
	t2, ok := o.lit().(*MultiType)
	if !ok {
		return false
	}
	if len(t.Elems) != len(t2.Elems) {
		return false
	}
	for i := range t.Elems {
		if !t.Elems[i].compat(t2.Elems[i], conv) {
			return false
		}
	}
	return true
}

var EmptyType Type = NewMultiType([]Type{})

func (t *MultiType) lit() Type { return t }

func (t *MultiType) String() string {
	if len(t.Elems) == 0 {
		return "<none>"
	}
	return typeListString(t.Elems, nil)
}

func (t *MultiType) Zero() Value {
	res := make([]Value, len(t.Elems))
	for i, t := range t.Elems {
		res[i] = t.Zero()
	}
	return multiV(res)
}

/*
 * Initialize the universe
 */

func init() {
	// To avoid portability issues all numeric types are distinct
	// except byte, which is an alias for uint8.

	// Make byte an alias for the named type uint8.  Type aliases
	// are otherwise impossible in Go, so just hack it here.
	universe.defs["byte"] = universe.defs["uint8"]

	// Built-in functions
	universe.DefineConst("cap", universePos, capType, nil)
	universe.DefineConst("close", universePos, closeType, nil)
	universe.DefineConst("closed", universePos, closedType, nil)
	universe.DefineConst("len", universePos, lenType, nil)
	universe.DefineConst("make", universePos, makeType, nil)
	universe.DefineConst("new", universePos, newType, nil)
	universe.DefineConst("panic", universePos, panicType, nil)
	universe.DefineConst("panicln", universePos, paniclnType, nil)
	universe.DefineConst("print", universePos, printType, nil)
	universe.DefineConst("println", universePos, printlnType, nil)
}
