// 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 ...interface{}) {
	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.Name())

	case *ast.IndexExpr:
		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.SliceExpr:
		end := x.End
		if end == nil {
			// TODO: set end to len(x.X)
			panic("unimplemented")
		}
		arr := a.compile(x.X, false)
		lo := a.compile(x.Index, false)
		hi := a.compile(end, false)
		if arr == nil || lo == nil || hi == nil {
			return nil
		}
		return ei.compileSliceExpr(arr, lo, hi)

	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.Name())

	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.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:], '\'')
	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:]
	}

	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
}
