// 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";
	"strconv";
	"strings";
	"os";
)

// An expr is the result of compiling an expression.  It stores the
// type of the expression and its evaluator function.
type expr struct {
	*exprInfo;
	t	Type;

	// Evaluate this node as the given type.
	eval	interface{};

	// Map index expressions permit special forms of assignment,
	// for which we need to know the Map and key.
	evalMapValue	func(t *Thread) (Map, interface{});

	// Evaluate to the "address of" this value; that is, the
	// settable Value object.  nil for expressions whose address
	// cannot be taken.
	evalAddr	func(t *Thread) Value;

	// Execute this expression as a statement.  Only expressions
	// that are valid expression statements should set this.
	exec	func(t *Thread);

	// If this expression is a type, this is its compiled type.
	// This is only permitted in the function position of a call
	// expression.  In this case, t should be nil.
	valType	Type;

	// A short string describing this expression for error
	// messages.
	desc	string;
}

// exprInfo stores information needed to compile any expression node.
// Each expr also stores its exprInfo so further expressions can be
// compiled from it.
type exprInfo struct {
	*compiler;
	pos	token.Position;
}

func (a *exprInfo) newExpr(t Type, desc string) *expr {
	return &expr{exprInfo: a, t: t, desc: desc}
}

func (a *exprInfo) diag(format string, args ...) {
	a.diagAt(&a.pos, format, args)
}

func (a *exprInfo) diagOpType(op token.Token, vt Type) {
	a.diag("illegal operand type for '%v' operator\n\t%v", op, vt)
}

func (a *exprInfo) diagOpTypes(op token.Token, lt Type, rt Type) {
	a.diag("illegal operand types for '%v' operator\n\t%v\n\t%v", op, lt, rt)
}

/*
 * Common expression manipulations
 */

// a.convertTo(t) converts the value of the analyzed expression a,
// which must be a constant, ideal number, to a new analyzed
// expression with a constant value of type t.
//
// TODO(austin) Rename to resolveIdeal or something?
func (a *expr) convertTo(t Type) *expr {
	if !a.t.isIdeal() {
		log.Crashf("attempted to convert from %v, expected ideal", a.t)
	}

	var rat *bignum.Rational;

	// XXX(Spec)  The spec says "It is erroneous".
	//
	// It is an error to assign a value with a non-zero fractional
	// part to an integer, or if the assignment would overflow or
	// underflow, or in general if the value cannot be represented
	// by the type of the variable.
	switch a.t {
	case IdealFloatType:
		rat = a.asIdealFloat()();
		if t.isInteger() && !rat.IsInt() {
			a.diag("constant %v truncated to integer", ratToString(rat));
			return nil;
		}
	case IdealIntType:
		i := a.asIdealInt()();
		rat = bignum.MakeRat(i, bignum.Nat(1));
	default:
		log.Crashf("unexpected ideal type %v", a.t)
	}

	// Check bounds
	if t, ok := t.lit().(BoundedType); ok {
		if rat.Cmp(t.minVal()) < 0 {
			a.diag("constant %v underflows %v", ratToString(rat), t);
			return nil;
		}
		if rat.Cmp(t.maxVal()) > 0 {
			a.diag("constant %v overflows %v", ratToString(rat), t);
			return nil;
		}
	}

	// Convert rat to type t.
	res := a.newExpr(t, a.desc);
	switch t := t.lit().(type) {
	case *uintType:
		n, d := rat.Value();
		f := n.Quo(bignum.MakeInt(false, d));
		v := f.Abs().Value();
		res.eval = func(*Thread) uint64 { return v };
	case *intType:
		n, d := rat.Value();
		f := n.Quo(bignum.MakeInt(false, d));
		v := f.Value();
		res.eval = func(*Thread) int64 { return v };
	case *idealIntType:
		n, d := rat.Value();
		f := n.Quo(bignum.MakeInt(false, d));
		res.eval = func() *bignum.Integer { return f };
	case *floatType:
		n, d := rat.Value();
		v := float64(n.Value()) / float64(d.Value());
		res.eval = func(*Thread) float64 { return v };
	case *idealFloatType:
		res.eval = func() *bignum.Rational { return rat }
	default:
		log.Crashf("cannot convert to type %T", t)
	}

	return res;
}

// convertToInt converts this expression to an integer, if possible,
// or produces an error if not.  This accepts ideal ints, uints, and
// ints.  If max is not -1, produces an error if possible if the value
// exceeds max.  If negErr is not "", produces an error if possible if
// the value is negative.
func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr {
	switch a.t.lit().(type) {
	case *idealIntType:
		val := a.asIdealInt()();
		if negErr != "" && val.IsNeg() {
			a.diag("negative %s: %s", negErr, val);
			return nil;
		}
		bound := max;
		if negErr == "slice" {
			bound++
		}
		if max != -1 && val.Cmp(bignum.Int(bound)) >= 0 {
			a.diag("index %s exceeds length %d", val, max);
			return nil;
		}
		return a.convertTo(IntType);

	case *uintType:
		// Convert to int
		na := a.newExpr(IntType, a.desc);
		af := a.asUint();
		na.eval = func(t *Thread) int64 { return int64(af(t)) };
		return na;

	case *intType:
		// Good as is
		return a
	}

	a.diag("illegal operand type for %s\n\t%v", errOp, a.t);
	return nil;
}

// derefArray returns an expression of array type if the given
// expression is a *array type.  Otherwise, returns the given
// expression.
func (a *expr) derefArray() *expr {
	if pt, ok := a.t.lit().(*PtrType); ok {
		if _, ok := pt.Elem.lit().(*ArrayType); ok {
			deref := a.compileStarExpr(a);
			if deref == nil {
				log.Crashf("failed to dereference *array")
			}
			return deref;
		}
	}
	return a;
}

/*
 * Assignments
 */

// An assignCompiler compiles assignment operations.  Anything other
// than short declarations should use the compileAssign wrapper.
//
// There are three valid types of assignment:
// 1) T = T
//    Assigning a single expression with single-valued type to a
//    single-valued type.
// 2) MT = T, T, ...
//    Assigning multiple expressions with single-valued types to a
//    multi-valued type.
// 3) MT = MT
//    Assigning a single expression with multi-valued type to a
//    multi-valued type.
type assignCompiler struct {
	*compiler;
	pos	token.Position;
	// The RHS expressions.  This may include nil's for
	// expressions that failed to compile.
	rs	[]*expr;
	// The (possibly unary) MultiType of the RHS.
	rmt	*MultiType;
	// Whether this is an unpack assignment (case 3).
	isUnpack	bool;
	// Whether map special assignment forms are allowed.
	allowMap	bool;
	// Whether this is a "r, ok = a[x]" assignment.
	isMapUnpack	bool;
	// The operation name to use in error messages, such as
	// "assignment" or "function call".
	errOp	string;
	// The name to use for positions in error messages, such as
	// "argument".
	errPosName	string;
}

// Type check the RHS of an assignment, returning a new assignCompiler
// and indicating if the type check succeeded.  This always returns an
// assignCompiler with rmt set, but if type checking fails, slots in
// the MultiType may be nil.  If rs contains nil's, type checking will
// fail and these expressions given a nil type.
func (a *compiler) checkAssign(pos token.Position, rs []*expr, errOp, errPosName string) (*assignCompiler, bool) {
	c := &assignCompiler{
		compiler: a,
		pos: pos,
		rs: rs,
		errOp: errOp,
		errPosName: errPosName,
	};

	// Is this an unpack?
	if len(rs) == 1 && rs[0] != nil {
		if rmt, isUnpack := rs[0].t.(*MultiType); isUnpack {
			c.rmt = rmt;
			c.isUnpack = true;
			return c, true;
		}
	}

	// Create MultiType for RHS and check that all RHS expressions
	// are single-valued.
	rts := make([]Type, len(rs));
	ok := true;
	for i, r := range rs {
		if r == nil {
			ok = false;
			continue;
		}

		if _, isMT := r.t.(*MultiType); isMT {
			r.diag("multi-valued expression not allowed in %s", errOp);
			ok = false;
			continue;
		}

		rts[i] = r.t;
	}

	c.rmt = NewMultiType(rts);
	return c, ok;
}

func (a *assignCompiler) allowMapForms(nls int) {
	a.allowMap = true;

	// Update unpacking info if this is r, ok = a[x]
	if nls == 2 && len(a.rs) == 1 && a.rs[0] != nil && a.rs[0].evalMapValue != nil {
		a.isUnpack = true;
		a.rmt = NewMultiType([]Type{a.rs[0].t, BoolType});
		a.isMapUnpack = true;
	}
}

// compile type checks and compiles an assignment operation, returning
// a function that expects an l-value and the frame in which to
// evaluate the RHS expressions.  The l-value must have exactly the
// type given by lt.  Returns nil if type checking fails.
func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {
	lmt, isMT := lt.(*MultiType);
	rmt, isUnpack := a.rmt, a.isUnpack;

	// Create unary MultiType for single LHS
	if !isMT {
		lmt = NewMultiType([]Type{lt})
	}

	// Check that the assignment count matches
	lcount := len(lmt.Elems);
	rcount := len(rmt.Elems);
	if lcount != rcount {
		msg := "not enough";
		pos := a.pos;
		if rcount > lcount {
			msg = "too many";
			if lcount > 0 {
				pos = a.rs[lcount-1].pos
			}
		}
		a.diagAt(&pos, "%s %ss for %s\n\t%s\n\t%s", msg, a.errPosName, a.errOp, lt, rmt);
		return nil;
	}

	bad := false;

	// If this is an unpack, create a temporary to store the
	// multi-value and replace the RHS with expressions to pull
	// out values from the temporary.  Technically, this is only
	// necessary when we need to perform assignment conversions.
	var effect func(*Thread);
	if isUnpack {
		// This leaks a slot, but is definitely safe.
		temp := b.DefineTemp(a.rmt);
		tempIdx := temp.Index;
		if tempIdx < 0 {
			panicln("tempidx", tempIdx)
		}
		if a.isMapUnpack {
			rf := a.rs[0].evalMapValue;
			vt := a.rmt.Elems[0];
			effect = func(t *Thread) {
				m, k := rf(t);
				v := m.Elem(t, k);
				found := boolV(true);
				if v == nil {
					found = boolV(false);
					v = vt.Zero();
				}
				t.f.Vars[tempIdx] = multiV([]Value{v, &found});
			};
		} else {
			rf := a.rs[0].asMulti();
			effect = func(t *Thread) { t.f.Vars[tempIdx] = multiV(rf(t)) };
		}
		orig := a.rs[0];
		a.rs = make([]*expr, len(a.rmt.Elems));
		for i, t := range a.rmt.Elems {
			if t.isIdeal() {
				log.Crashf("Right side of unpack contains ideal: %s", rmt)
			}
			a.rs[i] = orig.newExpr(t, orig.desc);
			index := i;
			a.rs[i].genValue(func(t *Thread) Value { return t.f.Vars[tempIdx].(multiV)[index] });
		}
	}
	// Now len(a.rs) == len(a.rmt) and we've reduced any unpacking
	// to multi-assignment.

	// TODO(austin) Deal with assignment special cases.

	// Values of any type may always be assigned to variables of
	// compatible static type.
	for i, lt := range lmt.Elems {
		rt := rmt.Elems[i];

		// When [an ideal is] (used in an expression) assigned
		// to a variable or typed constant, the destination
		// must be able to represent the assigned value.
		if rt.isIdeal() {
			a.rs[i] = a.rs[i].convertTo(lmt.Elems[i]);
			if a.rs[i] == nil {
				bad = true;
				continue;
			}
			rt = a.rs[i].t;
		}

		// A pointer p to an array can be assigned to a slice
		// variable v with compatible element type if the type
		// of p or v is unnamed.
		if rpt, ok := rt.lit().(*PtrType); ok {
			if at, ok := rpt.Elem.lit().(*ArrayType); ok {
				if lst, ok := lt.lit().(*SliceType); ok {
					if lst.Elem.compat(at.Elem, false) && (rt.lit() == Type(rt) || lt.lit() == Type(lt)) {
						rf := a.rs[i].asPtr();
						a.rs[i] = a.rs[i].newExpr(lt, a.rs[i].desc);
						len := at.Len;
						a.rs[i].eval = func(t *Thread) Slice { return Slice{rf(t).(ArrayValue), len, len} };
						rt = a.rs[i].t;
					}
				}
			}
		}

		if !lt.compat(rt, false) {
			if len(a.rs) == 1 {
				a.rs[0].diag("illegal operand types for %s\n\t%v\n\t%v", a.errOp, lt, rt)
			} else {
				a.rs[i].diag("illegal operand types in %s %d of %s\n\t%v\n\t%v", a.errPosName, i+1, a.errOp, lt, rt)
			}
			bad = true;
		}
	}
	if bad {
		return nil
	}

	// Compile
	if !isMT {
		// Case 1
		return genAssign(lt, a.rs[0])
	}
	// Case 2 or 3
	as := make([]func(lv Value, t *Thread), len(a.rs));
	for i, r := range a.rs {
		as[i] = genAssign(lmt.Elems[i], r)
	}
	return func(lv Value, t *Thread) {
		if effect != nil {
			effect(t)
		}
		lmv := lv.(multiV);
		for i, a := range as {
			a(lmv[i], t)
		}
	};
}

// compileAssign compiles an assignment operation without the full
// generality of an assignCompiler.  See assignCompiler for a
// description of the arguments.
func (a *compiler) compileAssign(pos token.Position, b *block, lt Type, rs []*expr, errOp, errPosName string) (func(Value, *Thread)) {
	ac, ok := a.checkAssign(pos, rs, errOp, errPosName);
	if !ok {
		return nil
	}
	return ac.compile(b, lt);
}

/*
 * Expression compiler
 */

// An exprCompiler stores information used throughout the compilation
// of a single expression.  It does not embed funcCompiler because
// expressions can appear at top level.
type exprCompiler struct {
	*compiler;
	// The block this expression is being compiled in.
	block	*block;
	// Whether this expression is used in a constant context.
	constant	bool;
}

// compile compiles an expression AST.  callCtx should be true if this
// AST is in the function position of a function call node; it allows
// the returned expression to be a type or a built-in function (which
// otherwise result in errors).
func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {
	ei := &exprInfo{a.compiler, x.Pos()};

	switch x := x.(type) {
	// Literals
	case *ast.BasicLit:
		switch x.Kind {
		case token.INT:
			return ei.compileIntLit(string(x.Value))
		case token.FLOAT:
			return ei.compileFloatLit(string(x.Value))
		case token.CHAR:
			return ei.compileCharLit(string(x.Value))
		case token.STRING:
			return ei.compileStringLit(string(x.Value))
		default:
			log.Crashf("unexpected basic literal type %v", x.Kind)
		}

	case *ast.CompositeLit:
		goto notimpl

	case *ast.FuncLit:
		decl := ei.compileFuncType(a.block, x.Type);
		if decl == nil {
			// TODO(austin) Try compiling the body,
			// perhaps with dummy argument definitions
			return nil
		}
		fn := ei.compileFunc(a.block, decl, x.Body);
		if fn == nil {
			return nil
		}
		if a.constant {
			a.diagAt(x, "function literal used in constant expression");
			return nil;
		}
		return ei.compileFuncLit(decl, fn);

	// Types
	case *ast.ArrayType:
		// TODO(austin) Use a multi-type case
		goto typeexpr

	case *ast.ChanType:
		goto typeexpr

	case *ast.Ellipsis:
		goto typeexpr

	case *ast.FuncType:
		goto typeexpr

	case *ast.InterfaceType:
		goto typeexpr

	case *ast.MapType:
		goto typeexpr

	// Remaining expressions
	case *ast.BadExpr:
		// Error already reported by parser
		a.silentErrors++;
		return nil;

	case *ast.BinaryExpr:
		l, r := a.compile(x.X, false), a.compile(x.Y, false);
		if l == nil || r == nil {
			return nil
		}
		return ei.compileBinaryExpr(x.Op, l, r);

	case *ast.CallExpr:
		l := a.compile(x.Fun, true);
		args := make([]*expr, len(x.Args));
		bad := false;
		for i, arg := range x.Args {
			if i == 0 && l != nil && (l.t == Type(makeType) || l.t == Type(newType)) {
				argei := &exprInfo{a.compiler, arg.Pos()};
				args[i] = argei.exprFromType(a.compileType(a.block, arg));
			} else {
				args[i] = a.compile(arg, false)
			}
			if args[i] == nil {
				bad = true
			}
		}
		if bad || l == nil {
			return nil
		}
		if a.constant {
			a.diagAt(x, "function call in constant context");
			return nil;
		}

		if l.valType != nil {
			a.diagAt(x, "type conversions not implemented");
			return nil;
		} else if ft, ok := l.t.(*FuncType); ok && ft.builtin != "" {
			return ei.compileBuiltinCallExpr(a.block, ft, args)
		} else {
			return ei.compileCallExpr(a.block, l, args)
		}

	case *ast.Ident:
		return ei.compileIdent(a.block, a.constant, callCtx, x.Value)

	case *ast.IndexExpr:
		if x.End != nil {
			arr := a.compile(x.X, false);
			lo := a.compile(x.Index, false);
			hi := a.compile(x.End, false);
			if arr == nil || lo == nil || hi == nil {
				return nil
			}
			return ei.compileSliceExpr(arr, lo, hi);
		}
		l, r := a.compile(x.X, false), a.compile(x.Index, false);
		if l == nil || r == nil {
			return nil
		}
		return ei.compileIndexExpr(l, r);

	case *ast.KeyValueExpr:
		goto notimpl

	case *ast.ParenExpr:
		return a.compile(x.X, callCtx)

	case *ast.SelectorExpr:
		v := a.compile(x.X, false);
		if v == nil {
			return nil
		}
		return ei.compileSelectorExpr(v, x.Sel.Value);

	case *ast.StarExpr:
		// We pass down our call context because this could be
		// a pointer type (and thus a type conversion)
		v := a.compile(x.X, callCtx);
		if v == nil {
			return nil
		}
		if v.valType != nil {
			// Turns out this was a pointer type, not a dereference
			return ei.exprFromType(NewPtrType(v.valType))
		}
		return ei.compileStarExpr(v);

	case *ast.StringList:
		strings := make([]*expr, len(x.Strings));
		bad := false;
		for i, s := range x.Strings {
			strings[i] = a.compile(s, false);
			if strings[i] == nil {
				bad = true
			}
		}
		if bad {
			return nil
		}
		return ei.compileStringList(strings);

	case *ast.StructType:
		goto notimpl

	case *ast.TypeAssertExpr:
		goto notimpl

	case *ast.UnaryExpr:
		v := a.compile(x.X, false);
		if v == nil {
			return nil
		}
		return ei.compileUnaryExpr(x.Op, v);
	}
	log.Crashf("unexpected ast node type %T", x);
	panic();

typeexpr:
	if !callCtx {
		a.diagAt(x, "type used as expression");
		return nil;
	}
	return ei.exprFromType(a.compileType(a.block, x));

notimpl:
	a.diagAt(x, "%T expression node not implemented", x);
	return nil;
}

func (a *exprInfo) exprFromType(t Type) *expr {
	if t == nil {
		return nil
	}
	expr := a.newExpr(nil, "type");
	expr.valType = t;
	return expr;
}

func (a *exprInfo) compileIdent(b *block, constant bool, callCtx bool, name string) *expr {
	bl, level, def := b.Lookup(name);
	if def == nil {
		a.diag("%s: undefined", name);
		return nil;
	}
	switch def := def.(type) {
	case *Constant:
		expr := a.newExpr(def.Type, "constant");
		if ft, ok := def.Type.(*FuncType); ok && ft.builtin != "" {
			// XXX(Spec) I don't think anything says that
			// built-in functions can't be used as values.
			if !callCtx {
				a.diag("built-in function %s cannot be used as a value", ft.builtin);
				return nil;
			}
			// Otherwise, we leave the evaluators empty
			// because this is handled specially
		} else {
			expr.genConstant(def.Value)
		}
		return expr;
	case *Variable:
		if constant {
			a.diag("variable %s used in constant expression", name);
			return nil;
		}
		if bl.global {
			return a.compileGlobalVariable(def)
		}
		return a.compileVariable(level, def);
	case Type:
		if callCtx {
			return a.exprFromType(def)
		}
		a.diag("type %v used as expression", name);
		return nil;
	}
	log.Crashf("name %s has unknown type %T", name, def);
	panic();
}

func (a *exprInfo) compileVariable(level int, v *Variable) *expr {
	if v.Type == nil {
		// Placeholder definition from an earlier error
		a.silentErrors++;
		return nil;
	}
	expr := a.newExpr(v.Type, "variable");
	expr.genIdentOp(level, v.Index);
	return expr;
}

func (a *exprInfo) compileGlobalVariable(v *Variable) *expr {
	if v.Type == nil {
		// Placeholder definition from an earlier error
		a.silentErrors++;
		return nil;
	}
	if v.Init == nil {
		v.Init = v.Type.Zero()
	}
	expr := a.newExpr(v.Type, "variable");
	val := v.Init;
	expr.genValue(func(t *Thread) Value { return val });
	return expr;
}

func (a *exprInfo) compileIdealInt(i *bignum.Integer, desc string) *expr {
	expr := a.newExpr(IdealIntType, desc);
	expr.eval = func() *bignum.Integer { return i };
	return expr;
}

func (a *exprInfo) compileIntLit(lit string) *expr {
	i, _, _ := bignum.IntFromString(lit, 0);
	return a.compileIdealInt(i, "integer literal");
}

func (a *exprInfo) compileCharLit(lit string) *expr {
	if lit[0] != '\'' {
		// Caught by parser
		a.silentErrors++;
		return nil;
	}
	v, _, tail, err := strconv.UnquoteChar(lit[1:len(lit)], '\'');
	if err != nil || tail != "'" {
		// Caught by parser
		a.silentErrors++;
		return nil;
	}
	return a.compileIdealInt(bignum.Int(int64(v)), "character literal");
}

func (a *exprInfo) compileFloatLit(lit string) *expr {
	f, _, n := bignum.RatFromString(lit, 0);
	if n != len(lit) {
		log.Crashf("malformed float literal %s at %v passed parser", lit, a.pos)
	}
	expr := a.newExpr(IdealFloatType, "float literal");
	expr.eval = func() *bignum.Rational { return f };
	return expr;
}

func (a *exprInfo) compileString(s string) *expr {
	// Ideal strings don't have a named type but they are
	// compatible with type string.

	// TODO(austin) Use unnamed string type.
	expr := a.newExpr(StringType, "string literal");
	expr.eval = func(*Thread) string { return s };
	return expr;
}

func (a *exprInfo) compileStringLit(lit string) *expr {
	s, err := strconv.Unquote(lit);
	if err != nil {
		a.diag("illegal string literal, %v", err);
		return nil;
	}
	return a.compileString(s);
}

func (a *exprInfo) compileStringList(list []*expr) *expr {
	ss := make([]string, len(list));
	for i, s := range list {
		ss[i] = s.asString()(nil)
	}
	return a.compileString(strings.Join(ss, ""));
}

func (a *exprInfo) compileFuncLit(decl *FuncDecl, fn func(*Thread) Func) *expr {
	expr := a.newExpr(decl.Type, "function literal");
	expr.eval = fn;
	return expr;
}

func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {
	// mark marks a field that matches the selector name.  It
	// tracks the best depth found so far and whether more than
	// one field has been found at that depth.
	bestDepth := -1;
	ambig := false;
	amberr := "";
	mark := func(depth int, pathName string) {
		switch {
		case bestDepth == -1 || depth < bestDepth:
			bestDepth = depth;
			ambig = false;
			amberr = "";

		case depth == bestDepth:
			ambig = true

		default:
			log.Crashf("Marked field at depth %d, but already found one at depth %d", depth, bestDepth)
		}
		amberr += "\n\t" + pathName[1:len(pathName)];
	};

	visited := make(map[Type]bool);

	// find recursively searches for the named field, starting at
	// type t.  If it finds the named field, it returns a function
	// which takes an expr that represents a value of type 't' and
	// returns an expr that retrieves the named field.  We delay
	// expr construction to avoid producing lots of useless expr's
	// as we search.
	//
	// TODO(austin) Now that the expression compiler works on
	// semantic values instead of AST's, there should be a much
	// better way of doing this.
	var find func(Type, int, string) (func(*expr) *expr);
	find = func(t Type, depth int, pathName string) (func(*expr) *expr) {
		// Don't bother looking if we've found something shallower
		if bestDepth != -1 && bestDepth < depth {
			return nil
		}

		// Don't check the same type twice and avoid loops
		if _, ok := visited[t]; ok {
			return nil
		}
		visited[t] = true;

		// Implicit dereference
		deref := false;
		if ti, ok := t.(*PtrType); ok {
			deref = true;
			t = ti.Elem;
		}

		// If it's a named type, look for methods
		if ti, ok := t.(*NamedType); ok {
			_, ok := ti.methods[name];
			if ok {
				mark(depth, pathName+"."+name);
				log.Crash("Methods not implemented");
			}
			t = ti.Def;
		}

		// If it's a struct type, check fields and embedded types
		var builder func(*expr) *expr;
		if t, ok := t.(*StructType); ok {
			for i, f := range t.Elems {
				var sub func(*expr) *expr;
				switch {
				case f.Name == name:
					mark(depth, pathName+"."+name);
					sub = func(e *expr) *expr { return e };

				case f.Anonymous:
					sub = find(f.Type, depth+1, pathName+"."+f.Name);
					if sub == nil {
						continue
					}

				default:
					continue
				}

				// We found something.  Create a
				// builder for accessing this field.
				ft := f.Type;
				index := i;
				builder = func(parent *expr) *expr {
					if deref {
						parent = a.compileStarExpr(parent)
					}
					expr := a.newExpr(ft, "selector expression");
					pf := parent.asStruct();
					evalAddr := func(t *Thread) Value { return pf(t).Field(t, index) };
					expr.genValue(evalAddr);
					return sub(expr);
				};
			}
		}

		return builder;
	};

	builder := find(v.t, 0, "");
	if builder == nil {
		a.diag("type %v has no field or method %s", v.t, name);
		return nil;
	}
	if ambig {
		a.diag("field %s is ambiguous in type %v%s", name, v.t, amberr);
		return nil;
	}

	return builder(v);
}

func (a *exprInfo) compileSliceExpr(arr, lo, hi *expr) *expr {
	// Type check object
	arr = arr.derefArray();

	var at Type;
	var maxIndex int64 = -1;

	switch lt := arr.t.lit().(type) {
	case *ArrayType:
		at = NewSliceType(lt.Elem);
		maxIndex = lt.Len;

	case *SliceType:
		at = lt

	case *stringType:
		at = lt

	default:
		a.diag("cannot slice %v", arr.t);
		return nil;
	}

	// Type check index and convert to int
	// XXX(Spec) It's unclear if ideal floats with no
	// fractional part are allowed here.  6g allows it.  I
	// believe that's wrong.
	lo = lo.convertToInt(maxIndex, "slice", "slice");
	hi = hi.convertToInt(maxIndex, "slice", "slice");
	if lo == nil || hi == nil {
		return nil
	}

	expr := a.newExpr(at, "slice expression");

	// Compile
	lof := lo.asInt();
	hif := hi.asInt();
	switch lt := arr.t.lit().(type) {
	case *ArrayType:
		arrf := arr.asArray();
		bound := lt.Len;
		expr.eval = func(t *Thread) Slice {
			arr, lo, hi := arrf(t), lof(t), hif(t);
			if lo > hi || hi > bound || lo < 0 {
				t.Abort(SliceError{lo, hi, bound})
			}
			return Slice{arr.Sub(lo, bound-lo), hi - lo, bound - lo};
		};

	case *SliceType:
		arrf := arr.asSlice();
		expr.eval = func(t *Thread) Slice {
			arr, lo, hi := arrf(t), lof(t), hif(t);
			if lo > hi || hi > arr.Cap || lo < 0 {
				t.Abort(SliceError{lo, hi, arr.Cap})
			}
			return Slice{arr.Base.Sub(lo, arr.Cap-lo), hi - lo, arr.Cap - lo};
		};

	case *stringType:
		arrf := arr.asString();
		// TODO(austin) This pulls over the whole string in a
		// remote setting, instead of creating a substring backed
		// by remote memory.
		expr.eval = func(t *Thread) string {
			arr, lo, hi := arrf(t), lof(t), hif(t);
			if lo > hi || hi > int64(len(arr)) || lo < 0 {
				t.Abort(SliceError{lo, hi, int64(len(arr))})
			}
			return arr[lo:hi];
		};

	default:
		log.Crashf("unexpected left operand type %T", arr.t.lit())
	}

	return expr;
}

func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {
	// Type check object
	l = l.derefArray();

	var at Type;
	intIndex := false;
	var maxIndex int64 = -1;

	switch lt := l.t.lit().(type) {
	case *ArrayType:
		at = lt.Elem;
		intIndex = true;
		maxIndex = lt.Len;

	case *SliceType:
		at = lt.Elem;
		intIndex = true;

	case *stringType:
		at = Uint8Type;
		intIndex = true;

	case *MapType:
		at = lt.Elem;
		if r.t.isIdeal() {
			r = r.convertTo(lt.Key);
			if r == nil {
				return nil
			}
		}
		if !lt.Key.compat(r.t, false) {
			a.diag("cannot use %s as index into %s", r.t, lt);
			return nil;
		}

	default:
		a.diag("cannot index into %v", l.t);
		return nil;
	}

	// Type check index and convert to int if necessary
	if intIndex {
		// XXX(Spec) It's unclear if ideal floats with no
		// fractional part are allowed here.  6g allows it.  I
		// believe that's wrong.
		r = r.convertToInt(maxIndex, "index", "index");
		if r == nil {
			return nil
		}
	}

	expr := a.newExpr(at, "index expression");

	// Compile
	switch lt := l.t.lit().(type) {
	case *ArrayType:
		lf := l.asArray();
		rf := r.asInt();
		bound := lt.Len;
		expr.genValue(func(t *Thread) Value {
			l, r := lf(t), rf(t);
			if r < 0 || r >= bound {
				t.Abort(IndexError{r, bound})
			}
			return l.Elem(t, r);
		});

	case *SliceType:
		lf := l.asSlice();
		rf := r.asInt();
		expr.genValue(func(t *Thread) Value {
			l, r := lf(t), rf(t);
			if l.Base == nil {
				t.Abort(NilPointerError{})
			}
			if r < 0 || r >= l.Len {
				t.Abort(IndexError{r, l.Len})
			}
			return l.Base.Elem(t, r);
		});

	case *stringType:
		lf := l.asString();
		rf := r.asInt();
		// TODO(austin) This pulls over the whole string in a
		// remote setting, instead of just the one character.
		expr.eval = func(t *Thread) uint64 {
			l, r := lf(t), rf(t);
			if r < 0 || r >= int64(len(l)) {
				t.Abort(IndexError{r, int64(len(l))})
			}
			return uint64(l[r]);
		};

	case *MapType:
		lf := l.asMap();
		rf := r.asInterface();
		expr.genValue(func(t *Thread) Value {
			m := lf(t);
			k := rf(t);
			if m == nil {
				t.Abort(NilPointerError{})
			}
			e := m.Elem(t, k);
			if e == nil {
				t.Abort(KeyError{k})
			}
			return e;
		});
		// genValue makes things addressable, but map values
		// aren't addressable.
		expr.evalAddr = nil;
		expr.evalMapValue = func(t *Thread) (Map, interface{}) {
			// TODO(austin) Key check?  nil check?
			return lf(t), rf(t)
		};

	default:
		log.Crashf("unexpected left operand type %T", l.t.lit())
	}

	return expr;
}

func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {
	// TODO(austin) Variadic functions.

	// Type check

	// XXX(Spec) Calling a named function type is okay.  I really
	// think there needs to be a general discussion of named
	// types.  A named type creates a new, distinct type, but the
	// type of that type is still whatever it's defined to.  Thus,
	// in "type Foo int", Foo is still an integer type and in
	// "type Foo func()", Foo is a function type.
	lt, ok := l.t.lit().(*FuncType);
	if !ok {
		a.diag("cannot call non-function type %v", l.t);
		return nil;
	}

	// The arguments must be single-valued expressions assignment
	// compatible with the parameters of F.
	//
	// XXX(Spec) The spec is wrong.  It can also be a single
	// multi-valued expression.
	nin := len(lt.In);
	assign := a.compileAssign(a.pos, b, NewMultiType(lt.In), as, "function call", "argument");
	if assign == nil {
		return nil
	}

	var t Type;
	nout := len(lt.Out);
	switch nout {
	case 0:
		t = EmptyType
	case 1:
		t = lt.Out[0]
	default:
		t = NewMultiType(lt.Out)
	}
	expr := a.newExpr(t, "function call");

	// Gather argument and out types to initialize frame variables
	vts := make([]Type, nin+nout);
	for i, t := range lt.In {
		vts[i] = t
	}
	for i, t := range lt.Out {
		vts[i+nin] = t
	}

	// Compile
	lf := l.asFunc();
	call := func(t *Thread) []Value {
		fun := lf(t);
		fr := fun.NewFrame();
		for i, t := range vts {
			fr.Vars[i] = t.Zero()
		}
		assign(multiV(fr.Vars[0:nin]), t);
		oldf := t.f;
		t.f = fr;
		fun.Call(t);
		t.f = oldf;
		return fr.Vars[nin : nin+nout];
	};
	expr.genFuncCall(call);

	return expr;
}

func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *expr {
	checkCount := func(min, max int) bool {
		if len(as) < min {
			a.diag("not enough arguments to %s", ft.builtin);
			return false;
		} else if len(as) > max {
			a.diag("too many arguments to %s", ft.builtin);
			return false;
		}
		return true;
	};

	switch ft {
	case capType:
		if !checkCount(1, 1) {
			return nil
		}
		arg := as[0].derefArray();
		expr := a.newExpr(IntType, "function call");
		switch t := arg.t.lit().(type) {
		case *ArrayType:
			// TODO(austin) It would be nice if this could
			// be a constant int.
			v := t.Len;
			expr.eval = func(t *Thread) int64 { return v };

		case *SliceType:
			vf := arg.asSlice();
			expr.eval = func(t *Thread) int64 { return vf(t).Cap };

		//case *ChanType:

		default:
			a.diag("illegal argument type for cap function\n\t%v", arg.t);
			return nil;
		}
		return expr;

	case lenType:
		if !checkCount(1, 1) {
			return nil
		}
		arg := as[0].derefArray();
		expr := a.newExpr(IntType, "function call");
		switch t := arg.t.lit().(type) {
		case *stringType:
			vf := arg.asString();
			expr.eval = func(t *Thread) int64 { return int64(len(vf(t))) };

		case *ArrayType:
			// TODO(austin) It would be nice if this could
			// be a constant int.
			v := t.Len;
			expr.eval = func(t *Thread) int64 { return v };

		case *SliceType:
			vf := arg.asSlice();
			expr.eval = func(t *Thread) int64 { return vf(t).Len };

		case *MapType:
			vf := arg.asMap();
			expr.eval = func(t *Thread) int64 {
				// XXX(Spec) What's the len of an
				// uninitialized map?
				m := vf(t);
				if m == nil {
					return 0
				}
				return m.Len(t);
			};

		//case *ChanType:

		default:
			a.diag("illegal argument type for len function\n\t%v", arg.t);
			return nil;
		}
		return expr;

	case makeType:
		if !checkCount(1, 3) {
			return nil
		}
		// XXX(Spec) What are the types of the
		// arguments?  Do they have to be ints?  6g
		// accepts any integral type.
		var lenexpr, capexpr *expr;
		var lenf, capf func(*Thread) int64;
		if len(as) > 1 {
			lenexpr = as[1].convertToInt(-1, "length", "make function");
			if lenexpr == nil {
				return nil
			}
			lenf = lenexpr.asInt();
		}
		if len(as) > 2 {
			capexpr = as[2].convertToInt(-1, "capacity", "make function");
			if capexpr == nil {
				return nil
			}
			capf = capexpr.asInt();
		}

		switch t := as[0].valType.lit().(type) {
		case *SliceType:
			// A new, initialized slice value for a given
			// element type T is made using the built-in
			// function make, which takes a slice type and
			// parameters specifying the length and
			// optionally the capacity.
			if !checkCount(2, 3) {
				return nil
			}
			et := t.Elem;
			expr := a.newExpr(t, "function call");
			expr.eval = func(t *Thread) Slice {
				l := lenf(t);
				// XXX(Spec) What if len or cap is
				// negative?  The runtime panics.
				if l < 0 {
					t.Abort(NegativeLengthError{l})
				}
				c := l;
				if capf != nil {
					c = capf(t);
					if c < 0 {
						t.Abort(NegativeCapacityError{c})
					}
					// XXX(Spec) What happens if
					// len > cap?  The runtime
					// sets cap to len.
					if l > c {
						c = l
					}
				}
				base := arrayV(make([]Value, c));
				for i := int64(0); i < c; i++ {
					base[i] = et.Zero()
				}
				return Slice{&base, l, c};
			};
			return expr;

		case *MapType:
			// A new, empty map value is made using the
			// built-in function make, which takes the map
			// type and an optional capacity hint as
			// arguments.
			if !checkCount(1, 2) {
				return nil
			}
			expr := a.newExpr(t, "function call");
			expr.eval = func(t *Thread) Map {
				if lenf == nil {
					return make(evalMap)
				}
				l := lenf(t);
				return make(evalMap, l);
			};
			return expr;

		//case *ChanType:

		default:
			a.diag("illegal argument type for make function\n\t%v", as[0].valType);
			return nil;
		}

	case closeType, closedType:
		a.diag("built-in function %s not implemented", ft.builtin);
		return nil;

	case newType:
		if !checkCount(1, 1) {
			return nil
		}

		t := as[0].valType;
		expr := a.newExpr(NewPtrType(t), "new");
		expr.eval = func(*Thread) Value { return t.Zero() };
		return expr;

	case panicType, paniclnType, printType, printlnType:
		evals := make([]func(*Thread) interface{}, len(as));
		for i, x := range as {
			evals[i] = x.asInterface()
		}
		spaces := ft == paniclnType || ft == printlnType;
		newline := ft != printType;
		printer := func(t *Thread) {
			for i, eval := range evals {
				if i > 0 && spaces {
					print(" ")
				}
				v := eval(t);
				type stringer interface {
					String() string;
				}
				switch v1 := v.(type) {
				case bool:
					print(v1)
				case uint64:
					print(v1)
				case int64:
					print(v1)
				case float64:
					print(v1)
				case string:
					print(v1)
				case stringer:
					print(v1.String())
				default:
					print("???")
				}
			}
			if newline {
				print("\n")
			}
		};
		expr := a.newExpr(EmptyType, "print");
		expr.exec = printer;
		if ft == panicType || ft == paniclnType {
			expr.exec = func(t *Thread) {
				printer(t);
				t.Abort(os.NewError("panic"));
			}
		}
		return expr;
	}

	log.Crashf("unexpected built-in function '%s'", ft.builtin);
	panic();
}

func (a *exprInfo) compileStarExpr(v *expr) *expr {
	switch vt := v.t.lit().(type) {
	case *PtrType:
		expr := a.newExpr(vt.Elem, "indirect expression");
		vf := v.asPtr();
		expr.genValue(func(t *Thread) Value {
			v := vf(t);
			if v == nil {
				t.Abort(NilPointerError{})
			}
			return v;
		});
		return expr;
	}

	a.diagOpType(token.MUL, v.t);
	return nil;
}

var unaryOpDescs = make(map[token.Token]string)

func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr {
	// Type check
	var t Type;
	switch op {
	case token.ADD, token.SUB:
		if !v.t.isInteger() && !v.t.isFloat() {
			a.diagOpType(op, v.t);
			return nil;
		}
		t = v.t;

	case token.NOT:
		if !v.t.isBoolean() {
			a.diagOpType(op, v.t);
			return nil;
		}
		t = BoolType;

	case token.XOR:
		if !v.t.isInteger() {
			a.diagOpType(op, v.t);
			return nil;
		}
		t = v.t;

	case token.AND:
		// The unary prefix address-of operator & generates
		// the address of its operand, which must be a
		// variable, pointer indirection, field selector, or
		// array or slice indexing operation.
		if v.evalAddr == nil {
			a.diag("cannot take the address of %s", v.desc);
			return nil;
		}

		// TODO(austin) Implement "It is illegal to take the
		// address of a function result variable" once I have
		// function result variables.

		t = NewPtrType(v.t);

	case token.ARROW:
		log.Crashf("Unary op %v not implemented", op)

	default:
		log.Crashf("unknown unary operator %v", op)
	}

	desc, ok := unaryOpDescs[op];
	if !ok {
		desc = "unary " + op.String() + " expression";
		unaryOpDescs[op] = desc;
	}

	// Compile
	expr := a.newExpr(t, desc);
	switch op {
	case token.ADD:
		// Just compile it out
		expr = v;
		expr.desc = desc;

	case token.SUB:
		expr.genUnaryOpNeg(v)

	case token.NOT:
		expr.genUnaryOpNot(v)

	case token.XOR:
		expr.genUnaryOpXor(v)

	case token.AND:
		vf := v.evalAddr;
		expr.eval = func(t *Thread) Value { return vf(t) };

	default:
		log.Crashf("Compilation of unary op %v not implemented", op)
	}

	return expr;
}

var binOpDescs = make(map[token.Token]string)

func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {
	// Save the original types of l.t and r.t for error messages.
	origlt := l.t;
	origrt := r.t;

	// XXX(Spec) What is the exact definition of a "named type"?

	// XXX(Spec) Arithmetic operators: "Integer types" apparently
	// means all types compatible with basic integer types, though
	// this is never explained.  Likewise for float types, etc.
	// This relates to the missing explanation of named types.

	// XXX(Spec) Operators: "If both operands are ideal numbers,
	// the conversion is to ideal floats if one of the operands is
	// an ideal float (relevant for / and %)."  How is that
	// relevant only for / and %?  If I add an ideal int and an
	// ideal float, I get an ideal float.

	if op != token.SHL && op != token.SHR {
		// Except in shift expressions, if one operand has
		// numeric type and the other operand is an ideal
		// number, the ideal number is converted to match the
		// type of the other operand.
		if (l.t.isInteger() || l.t.isFloat()) && !l.t.isIdeal() && r.t.isIdeal() {
			r = r.convertTo(l.t)
		} else if (r.t.isInteger() || r.t.isFloat()) && !r.t.isIdeal() && l.t.isIdeal() {
			l = l.convertTo(r.t)
		}
		if l == nil || r == nil {
			return nil
		}

		// Except in shift expressions, if both operands are
		// ideal numbers and one is an ideal float, the other
		// is converted to ideal float.
		if l.t.isIdeal() && r.t.isIdeal() {
			if l.t.isInteger() && r.t.isFloat() {
				l = l.convertTo(r.t)
			} else if l.t.isFloat() && r.t.isInteger() {
				r = r.convertTo(l.t)
			}
			if l == nil || r == nil {
				return nil
			}
		}
	}

	// Useful type predicates
	// TODO(austin) CL 33668 mandates identical types except for comparisons.
	compat := func() bool { return l.t.compat(r.t, false) };
	integers := func() bool { return l.t.isInteger() && r.t.isInteger() };
	floats := func() bool { return l.t.isFloat() && r.t.isFloat() };
	strings := func() bool {
		// TODO(austin) Deal with named types
		return l.t == StringType && r.t == StringType
	};
	booleans := func() bool { return l.t.isBoolean() && r.t.isBoolean() };

	// Type check
	var t Type;
	switch op {
	case token.ADD:
		if !compat() || (!integers() && !floats() && !strings()) {
			a.diagOpTypes(op, origlt, origrt);
			return nil;
		}
		t = l.t;

	case token.SUB, token.MUL, token.QUO:
		if !compat() || (!integers() && !floats()) {
			a.diagOpTypes(op, origlt, origrt);
			return nil;
		}
		t = l.t;

	case token.REM, token.AND, token.OR, token.XOR, token.AND_NOT:
		if !compat() || !integers() {
			a.diagOpTypes(op, origlt, origrt);
			return nil;
		}
		t = l.t;

	case token.SHL, token.SHR:
		// XXX(Spec) Is it okay for the right operand to be an
		// ideal float with no fractional part?  "The right
		// operand in a shift operation must be always be of
		// unsigned integer type or an ideal number that can
		// be safely converted into an unsigned integer type
		// (§Arithmetic operators)" suggests so and 6g agrees.

		if !l.t.isInteger() || !(r.t.isInteger() || r.t.isIdeal()) {
			a.diagOpTypes(op, origlt, origrt);
			return nil;
		}

		// The right operand in a shift operation must be
		// always be of unsigned integer type or an ideal
		// number that can be safely converted into an
		// unsigned integer type.
		if r.t.isIdeal() {
			r2 := r.convertTo(UintType);
			if r2 == nil {
				return nil
			}

			// If the left operand is not ideal, convert
			// the right to not ideal.
			if !l.t.isIdeal() {
				r = r2
			}

			// If both are ideal, but the right side isn't
			// an ideal int, convert it to simplify things.
			if l.t.isIdeal() && !r.t.isInteger() {
				r = r.convertTo(IdealIntType);
				if r == nil {
					log.Crashf("conversion to uintType succeeded, but conversion to idealIntType failed")
				}
			}
		} else if _, ok := r.t.lit().(*uintType); !ok {
			a.diag("right operand of shift must be unsigned");
			return nil;
		}

		if l.t.isIdeal() && !r.t.isIdeal() {
			// XXX(Spec) What is the meaning of "ideal >>
			// non-ideal"?  Russ says the ideal should be
			// converted to an int.  6g propagates the
			// type down from assignments as a hint.

			l = l.convertTo(IntType);
			if l == nil {
				return nil
			}
		}

		// At this point, we should have one of three cases:
		// 1) uint SHIFT uint
		// 2) int SHIFT uint
		// 3) ideal int SHIFT ideal int

		t = l.t;

	case token.LOR, token.LAND:
		if !booleans() {
			return nil
		}
		// XXX(Spec) There's no mention of *which* boolean
		// type the logical operators return.  From poking at
		// 6g, it appears to be the named boolean type, NOT
		// the type of the left operand, and NOT an unnamed
		// boolean type.

		t = BoolType;

	case token.ARROW:
		// The operands in channel sends differ in type: one
		// is always a channel and the other is a variable or
		// value of the channel's element type.
		log.Crash("Binary op <- not implemented");
		t = BoolType;

	case token.LSS, token.GTR, token.LEQ, token.GEQ:
		// XXX(Spec) It's really unclear what types which
		// comparison operators apply to.  I feel like the
		// text is trying to paint a Venn diagram for me,
		// which it's really pretty simple: <, <=, >, >= apply
		// only to numeric types and strings.  == and != apply
		// to everything except arrays and structs, and there
		// are some restrictions on when it applies to slices.

		if !compat() || (!integers() && !floats() && !strings()) {
			a.diagOpTypes(op, origlt, origrt);
			return nil;
		}
		t = BoolType;

	case token.EQL, token.NEQ:
		// XXX(Spec) The rules for type checking comparison
		// operators are spread across three places that all
		// partially overlap with each other: the Comparison
		// Compatibility section, the Operators section, and
		// the Comparison Operators section.  The Operators
		// section should just say that operators require
		// identical types (as it does currently) except that
		// there a few special cases for comparison, which are
		// described in section X.  Currently it includes just
		// one of the four special cases.  The Comparison
		// Compatibility section and the Comparison Operators
		// section should either be merged, or at least the
		// Comparison Compatibility section should be
		// exclusively about type checking and the Comparison
		// Operators section should be exclusively about
		// semantics.

		// XXX(Spec) Comparison operators: "All comparison
		// operators apply to basic types except bools."  This
		// is very difficult to parse.  It's explained much
		// better in the Comparison Compatibility section.

		// XXX(Spec) Comparison compatibility: "Function
		// values are equal if they refer to the same
		// function." is rather vague.  It should probably be
		// similar to the way the rule for map values is
		// written: Function values are equal if they were
		// created by the same execution of a function literal
		// or refer to the same function declaration.  This is
		// *almost* but not quite waht 6g implements.  If a
		// function literals does not capture any variables,
		// then multiple executions of it will result in the
		// same closure.  Russ says he'll change that.

		// TODO(austin) Deal with remaining special cases

		if !compat() {
			a.diagOpTypes(op, origlt, origrt);
			return nil;
		}
		// Arrays and structs may not be compared to anything.
		switch l.t.(type) {
		case *ArrayType, *StructType:
			a.diagOpTypes(op, origlt, origrt);
			return nil;
		}
		t = BoolType;

	default:
		log.Crashf("unknown binary operator %v", op)
	}

	desc, ok := binOpDescs[op];
	if !ok {
		desc = op.String() + " expression";
		binOpDescs[op] = desc;
	}

	// Check for ideal divide by zero
	switch op {
	case token.QUO, token.REM:
		if r.t.isIdeal() {
			if (r.t.isInteger() && r.asIdealInt()().IsZero()) ||
				(r.t.isFloat() && r.asIdealFloat()().IsZero()) {
				a.diag("divide by zero");
				return nil;
			}
		}
	}

	// Compile
	expr := a.newExpr(t, desc);
	switch op {
	case token.ADD:
		expr.genBinOpAdd(l, r)

	case token.SUB:
		expr.genBinOpSub(l, r)

	case token.MUL:
		expr.genBinOpMul(l, r)

	case token.QUO:
		expr.genBinOpQuo(l, r)

	case token.REM:
		expr.genBinOpRem(l, r)

	case token.AND:
		expr.genBinOpAnd(l, r)

	case token.OR:
		expr.genBinOpOr(l, r)

	case token.XOR:
		expr.genBinOpXor(l, r)

	case token.AND_NOT:
		expr.genBinOpAndNot(l, r)

	case token.SHL:
		if l.t.isIdeal() {
			lv := l.asIdealInt()();
			rv := r.asIdealInt()();
			const maxShift = 99999;
			if rv.Cmp(bignum.Int(maxShift)) > 0 {
				a.diag("left shift by %v; exceeds implementation limit of %v", rv, maxShift);
				expr.t = nil;
				return nil;
			}
			val := lv.Shl(uint(rv.Value()));
			expr.eval = func() *bignum.Integer { return val };
		} else {
			expr.genBinOpShl(l, r)
		}

	case token.SHR:
		if l.t.isIdeal() {
			lv := l.asIdealInt()();
			rv := r.asIdealInt()();
			val := lv.Shr(uint(rv.Value()));
			expr.eval = func() *bignum.Integer { return val };
		} else {
			expr.genBinOpShr(l, r)
		}

	case token.LSS:
		expr.genBinOpLss(l, r)

	case token.GTR:
		expr.genBinOpGtr(l, r)

	case token.LEQ:
		expr.genBinOpLeq(l, r)

	case token.GEQ:
		expr.genBinOpGeq(l, r)

	case token.EQL:
		expr.genBinOpEql(l, r)

	case token.NEQ:
		expr.genBinOpNeq(l, r)

	case token.LAND:
		expr.genBinOpLogAnd(l, r)

	case token.LOR:
		expr.genBinOpLogOr(l, r)

	default:
		log.Crashf("Compilation of binary op %v not implemented", op)
	}

	return expr;
}

// TODO(austin) This is a hack to eliminate a circular dependency
// between type.go and expr.go
func (a *compiler) compileArrayLen(b *block, expr ast.Expr) (int64, bool) {
	lenExpr := a.compileExpr(b, true, expr);
	if lenExpr == nil {
		return 0, false
	}

	// XXX(Spec) Are ideal floats with no fractional part okay?
	if lenExpr.t.isIdeal() {
		lenExpr = lenExpr.convertTo(IntType);
		if lenExpr == nil {
			return 0, false
		}
	}

	if !lenExpr.t.isInteger() {
		a.diagAt(expr, "array size must be an integer");
		return 0, false;
	}

	switch lenExpr.t.lit().(type) {
	case *intType:
		return lenExpr.asInt()(nil), true
	case *uintType:
		return int64(lenExpr.asUint()(nil)), true
	}
	log.Crashf("unexpected integer type %T", lenExpr.t);
	return 0, false;
}

func (a *compiler) compileExpr(b *block, constant bool, expr ast.Expr) *expr {
	ec := &exprCompiler{a, b, constant};
	nerr := a.numError();
	e := ec.compile(expr, false);
	if e == nil && nerr == a.numError() {
		log.Crashf("expression compilation failed without reporting errors")
	}
	return e;
}

// extractEffect separates out any effects that the expression may
// have, returning a function that will perform those effects and a
// new exprCompiler that is guaranteed to be side-effect free.  These
// are the moral equivalents of "temp := expr" and "temp" (or "temp :=
// &expr" and "*temp" for addressable exprs).  Because this creates a
// temporary variable, the caller should create a temporary block for
// the compilation of this expression and the evaluation of the
// results.
func (a *expr) extractEffect(b *block, errOp string) (func(*Thread), *expr) {
	// Create "&a" if a is addressable
	rhs := a;
	if a.evalAddr != nil {
		rhs = a.compileUnaryExpr(token.AND, rhs)
	}

	// Create temp
	ac, ok := a.checkAssign(a.pos, []*expr{rhs}, errOp, "");
	if !ok {
		return nil, nil
	}
	if len(ac.rmt.Elems) != 1 {
		a.diag("multi-valued expression not allowed in %s", errOp);
		return nil, nil;
	}
	tempType := ac.rmt.Elems[0];
	if tempType.isIdeal() {
		// It's too bad we have to duplicate this rule.
		switch {
		case tempType.isInteger():
			tempType = IntType
		case tempType.isFloat():
			tempType = FloatType
		default:
			log.Crashf("unexpected ideal type %v", tempType)
		}
	}
	temp := b.DefineTemp(tempType);
	tempIdx := temp.Index;

	// Create "temp := rhs"
	assign := ac.compile(b, tempType);
	if assign == nil {
		log.Crashf("compileAssign type check failed")
	}

	effect := func(t *Thread) {
		tempVal := tempType.Zero();
		t.f.Vars[tempIdx] = tempVal;
		assign(tempVal, t);
	};

	// Generate "temp" or "*temp"
	getTemp := a.compileVariable(0, temp);
	if a.evalAddr == nil {
		return effect, getTemp
	}

	deref := a.compileStarExpr(getTemp);
	if deref == nil {
		return nil, nil
	}
	return effect, deref;
}
