// 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].Value + " "
		}
		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.Value
	}
	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);
}
