diff options
Diffstat (limited to 'src/pkg/exp/eval/expr.go')
| -rw-r--r-- | src/pkg/exp/eval/expr.go | 1088 | 
1 files changed, 544 insertions, 544 deletions
| diff --git a/src/pkg/exp/eval/expr.go b/src/pkg/exp/eval/expr.go index 1f1bf0634..8e161e522 100644 --- a/src/pkg/exp/eval/expr.go +++ b/src/pkg/exp/eval/expr.go @@ -5,53 +5,53 @@  package eval  import ( -	"bignum"; -	"go/ast"; -	"go/token"; -	"log"; -	"strconv"; -	"strings"; -	"os"; +	"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; +	*exprInfo +	t Type  	// Evaluate this node as the given type. -	eval	interface{}; +	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{}); +	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; +	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); +	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; +	valType Type  	// A short string describing this expression for error  	// messages. -	desc	string; +	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; +	*compiler +	pos token.Position  }  func (a *exprInfo) newExpr(t Type, desc string) *expr { @@ -84,7 +84,7 @@ func (a *expr) convertTo(t Type) *expr {  		log.Crashf("attempted to convert from %v, expected ideal", a.t)  	} -	var rat *bignum.Rational; +	var rat *bignum.Rational  	// XXX(Spec)  The spec says "It is erroneous".  	// @@ -94,14 +94,14 @@ func (a *expr) convertTo(t Type) *expr {  	// by the type of the variable.  	switch a.t {  	case IdealFloatType: -		rat = a.asIdealFloat()(); +		rat = a.asIdealFloat()()  		if t.isInteger() && !rat.IsInt() { -			a.diag("constant %v truncated to integer", ratToString(rat)); -			return nil; +			a.diag("constant %v truncated to integer", ratToString(rat)) +			return nil  		}  	case IdealIntType: -		i := a.asIdealInt()(); -		rat = bignum.MakeRat(i, bignum.Nat(1)); +		i := a.asIdealInt()() +		rat = bignum.MakeRat(i, bignum.Nat(1))  	default:  		log.Crashf("unexpected ideal type %v", a.t)  	} @@ -109,43 +109,43 @@ func (a *expr) convertTo(t Type) *expr {  	// 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; +			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; +			a.diag("constant %v overflows %v", ratToString(rat), t) +			return nil  		}  	}  	// Convert rat to type t. -	res := a.newExpr(t, a.desc); +	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 }; +		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 }; +		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 }; +		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 }; +		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; +	return res  }  // convertToInt converts this expression to an integer, if possible, @@ -156,35 +156,35 @@ func (a *expr) convertTo(t Type) *expr {  func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr {  	switch a.t.lit().(type) {  	case *idealIntType: -		val := a.asIdealInt()(); +		val := a.asIdealInt()()  		if negErr != "" && val.IsNeg() { -			a.diag("negative %s: %s", negErr, val); -			return nil; +			a.diag("negative %s: %s", negErr, val) +			return nil  		} -		bound := max; +		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; +			a.diag("index %s exceeds length %d", val, max) +			return nil  		} -		return a.convertTo(IntType); +		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; +		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; +	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 @@ -193,14 +193,14 @@ func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr {  func (a *expr) derefArray() *expr {  	if pt, ok := a.t.lit().(*PtrType); ok {  		if _, ok := pt.Elem.lit().(*ArrayType); ok { -			deref := a.compileStarExpr(a); +			deref := a.compileStarExpr(a)  			if deref == nil {  				log.Crashf("failed to dereference *array")  			} -			return deref; +			return deref  		}  	} -	return a; +	return a  }  /* @@ -221,25 +221,25 @@ func (a *expr) derefArray() *expr {  //    Assigning a single expression with multi-valued type to a  //    multi-valued type.  type assignCompiler struct { -	*compiler; -	pos	token.Position; +	*compiler +	pos token.Position  	// The RHS expressions.  This may include nil's for  	// expressions that failed to compile. -	rs	[]*expr; +	rs []*expr  	// The (possibly unary) MultiType of the RHS. -	rmt	*MultiType; +	rmt *MultiType  	// Whether this is an unpack assignment (case 3). -	isUnpack	bool; +	isUnpack bool  	// Whether map special assignment forms are allowed. -	allowMap	bool; +	allowMap bool  	// Whether this is a "r, ok = a[x]" assignment. -	isMapUnpack	bool; +	isMapUnpack bool  	// The operation name to use in error messages, such as  	// "assignment" or "function call". -	errOp	string; +	errOp string  	// The name to use for positions in error messages, such as  	// "argument". -	errPosName	string; +	errPosName string  }  // Type check the RHS of an assignment, returning a new assignCompiler @@ -254,48 +254,48 @@ func (a *compiler) checkAssign(pos token.Position, rs []*expr, errOp, errPosName  		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; +			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; +	rts := make([]Type, len(rs)) +	ok := true  	for i, r := range rs {  		if r == nil { -			ok = false; -			continue; +			ok = false +			continue  		}  		if _, isMT := r.t.(*MultiType); isMT { -			r.diag("multi-valued expression not allowed in %s", errOp); -			ok = false; -			continue; +			r.diag("multi-valued expression not allowed in %s", errOp) +			ok = false +			continue  		} -		rts[i] = r.t; +		rts[i] = r.t  	} -	c.rmt = NewMultiType(rts); -	return c, ok; +	c.rmt = NewMultiType(rts) +	return c, ok  }  func (a *assignCompiler) allowMapForms(nls int) { -	a.allowMap = true; +	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; +		a.isUnpack = true +		a.rmt = NewMultiType([]Type{a.rs[0].t, BoolType}) +		a.isMapUnpack = true  	}  } @@ -304,8 +304,8 @@ func (a *assignCompiler) allowMapForms(nls int) {  // 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; +	lmt, isMT := lt.(*MultiType) +	rmt, isUnpack := a.rmt, a.isUnpack  	// Create unary MultiType for single LHS  	if !isMT { @@ -313,61 +313,61 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {  	}  	// Check that the assignment count matches -	lcount := len(lmt.Elems); -	rcount := len(rmt.Elems); +	lcount := len(lmt.Elems) +	rcount := len(rmt.Elems)  	if lcount != rcount { -		msg := "not enough"; -		pos := a.pos; +		msg := "not enough" +		pos := a.pos  		if rcount > lcount { -			msg = "too many"; +			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; +		a.diagAt(&pos, "%s %ss for %s\n\t%s\n\t%s", msg, a.errPosName, a.errOp, lt, rmt) +		return nil  	} -	bad := false; +	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); +	var effect func(*Thread)  	if isUnpack {  		// This leaks a slot, but is definitely safe. -		temp := b.DefineTemp(a.rmt); -		tempIdx := temp.Index; +		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]; +			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); +				m, k := rf(t) +				v := m.Elem(t, k) +				found := boolV(true)  				if v == nil { -					found = boolV(false); -					v = vt.Zero(); +					found = boolV(false) +					v = vt.Zero()  				} -				t.f.Vars[tempIdx] = multiV([]Value{v, &found}); -			}; +				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)) }; +			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)); +		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] }); +			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 @@ -378,18 +378,18 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {  	// Values of any type may always be assigned to variables of  	// compatible static type.  	for i, lt := range lmt.Elems { -		rt := rmt.Elems[i]; +		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]); +			a.rs[i] = a.rs[i].convertTo(lmt.Elems[i])  			if a.rs[i] == nil { -				bad = true; -				continue; +				bad = true +				continue  			} -			rt = a.rs[i].t; +			rt = a.rs[i].t  		}  		// A pointer p to an array can be assigned to a slice @@ -399,11 +399,11 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {  			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; +						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  					}  				}  			} @@ -415,7 +415,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {  			} 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; +			bad = true  		}  	}  	if bad { @@ -428,7 +428,7 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {  		return genAssign(lt, a.rs[0])  	}  	// Case 2 or 3 -	as := make([]func(lv Value, t *Thread), len(a.rs)); +	as := make([]func(lv Value, t *Thread), len(a.rs))  	for i, r := range a.rs {  		as[i] = genAssign(lmt.Elems[i], r)  	} @@ -436,22 +436,22 @@ func (a *assignCompiler) compile(b *block, lt Type) (func(Value, *Thread)) {  		if effect != nil {  			effect(t)  		} -		lmv := lv.(multiV); +		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); +	ac, ok := a.checkAssign(pos, rs, errOp, errPosName)  	if !ok {  		return nil  	} -	return ac.compile(b, lt); +	return ac.compile(b, lt)  }  /* @@ -462,11 +462,11 @@ func (a *compiler) compileAssign(pos token.Position, b *block, lt Type, rs []*ex  // of a single expression.  It does not embed funcCompiler because  // expressions can appear at top level.  type exprCompiler struct { -	*compiler; +	*compiler  	// The block this expression is being compiled in. -	block	*block; +	block *block  	// Whether this expression is used in a constant context. -	constant	bool; +	constant bool  }  // compile compiles an expression AST.  callCtx should be true if this @@ -474,7 +474,7 @@ type exprCompiler struct {  // 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()}; +	ei := &exprInfo{a.compiler, x.Pos()}  	switch x := x.(type) {  	// Literals @@ -496,21 +496,21 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  		goto notimpl  	case *ast.FuncLit: -		decl := ei.compileFuncType(a.block, x.Type); +		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); +		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; +			a.diagAt(x, "function literal used in constant expression") +			return nil  		} -		return ei.compileFuncLit(decl, fn); +		return ei.compileFuncLit(decl, fn)  	// Types  	case *ast.ArrayType: @@ -535,24 +535,24 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  	// Remaining expressions  	case *ast.BadExpr:  		// Error already reported by parser -		a.silentErrors++; -		return nil; +		a.silentErrors++ +		return nil  	case *ast.BinaryExpr: -		l, r := a.compile(x.X, false), a.compile(x.Y, false); +		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); +		return ei.compileBinaryExpr(x.Op, l, r)  	case *ast.CallExpr: -		l := a.compile(x.Fun, true); -		args := make([]*expr, len(x.Args)); -		bad := false; +		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)); +				argei := &exprInfo{a.compiler, arg.Pos()} +				args[i] = argei.exprFromType(a.compileType(a.block, arg))  			} else {  				args[i] = a.compile(arg, false)  			} @@ -564,13 +564,13 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  			return nil  		}  		if a.constant { -			a.diagAt(x, "function call in constant context"); -			return nil; +			a.diagAt(x, "function call in constant context") +			return nil  		}  		if l.valType != nil { -			a.diagAt(x, "type conversions not implemented"); -			return 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 { @@ -581,25 +581,25 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  		return ei.compileIdent(a.block, a.constant, callCtx, x.Value)  	case *ast.IndexExpr: -		l, r := a.compile(x.X, false), a.compile(x.Index, false); +		l, r := a.compile(x.X, false), a.compile(x.Index, false)  		if l == nil || r == nil {  			return nil  		} -		return ei.compileIndexExpr(l, r); +		return ei.compileIndexExpr(l, r)  	case *ast.SliceExpr: -		end := x.End; +		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); +		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); +		return ei.compileSliceExpr(arr, lo, hi)  	case *ast.KeyValueExpr:  		goto notimpl @@ -608,16 +608,16 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  		return a.compile(x.X, callCtx)  	case *ast.SelectorExpr: -		v := a.compile(x.X, false); +		v := a.compile(x.X, false)  		if v == nil {  			return nil  		} -		return ei.compileSelectorExpr(v, x.Sel.Value); +		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); +		v := a.compile(x.X, callCtx)  		if v == nil {  			return nil  		} @@ -625,13 +625,13 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  			// Turns out this was a pointer type, not a dereference  			return ei.exprFromType(NewPtrType(v.valType))  		} -		return ei.compileStarExpr(v); +		return ei.compileStarExpr(v)  	case *ast.StringList: -		strings := make([]*expr, len(x.Strings)); -		bad := false; +		strings := make([]*expr, len(x.Strings)) +		bad := false  		for i, s := range x.Strings { -			strings[i] = a.compile(s, false); +			strings[i] = a.compile(s, false)  			if strings[i] == nil {  				bad = true  			} @@ -639,7 +639,7 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  		if bad {  			return nil  		} -		return ei.compileStringList(strings); +		return ei.compileStringList(strings)  	case *ast.StructType:  		goto notimpl @@ -648,138 +648,138 @@ func (a *exprCompiler) compile(x ast.Expr, callCtx bool) *expr {  		goto notimpl  	case *ast.UnaryExpr: -		v := a.compile(x.X, false); +		v := a.compile(x.X, false)  		if v == nil {  			return nil  		} -		return ei.compileUnaryExpr(x.Op, v); +		return ei.compileUnaryExpr(x.Op, v)  	} -	log.Crashf("unexpected ast node type %T", x); -	panic(); +	log.Crashf("unexpected ast node type %T", x) +	panic()  typeexpr:  	if !callCtx { -		a.diagAt(x, "type used as expression"); -		return nil; +		a.diagAt(x, "type used as expression") +		return nil  	} -	return ei.exprFromType(a.compileType(a.block, x)); +	return ei.exprFromType(a.compileType(a.block, x))  notimpl: -	a.diagAt(x, "%T expression node not implemented", x); -	return nil; +	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; +	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); +	bl, level, def := b.Lookup(name)  	if def == nil { -		a.diag("%s: undefined", name); -		return nil; +		a.diag("%s: undefined", name) +		return nil  	}  	switch def := def.(type) {  	case *Constant: -		expr := a.newExpr(def.Type, "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; +				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; +		return expr  	case *Variable:  		if constant { -			a.diag("variable %s used in constant expression", name); -			return nil; +			a.diag("variable %s used in constant expression", name) +			return nil  		}  		if bl.global {  			return a.compileGlobalVariable(def)  		} -		return a.compileVariable(level, def); +		return a.compileVariable(level, def)  	case Type:  		if callCtx {  			return a.exprFromType(def)  		} -		a.diag("type %v used as expression", name); -		return nil; +		a.diag("type %v used as expression", name) +		return nil  	} -	log.Crashf("name %s has unknown type %T", name, def); -	panic(); +	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; +		a.silentErrors++ +		return nil  	} -	expr := a.newExpr(v.Type, "variable"); -	expr.genIdentOp(level, v.Index); -	return expr; +	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; +		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; +	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; +	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"); +	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; +		a.silentErrors++ +		return nil  	} -	v, _, tail, err := strconv.UnquoteChar(lit[1:], '\''); +	v, _, tail, err := strconv.UnquoteChar(lit[1:], '\'')  	if err != nil || tail != "'" {  		// Caught by parser -		a.silentErrors++; -		return nil; +		a.silentErrors++ +		return nil  	} -	return a.compileIdealInt(bignum.Int(int64(v)), "character literal"); +	return a.compileIdealInt(bignum.Int(int64(v)), "character literal")  }  func (a *exprInfo) compileFloatLit(lit string) *expr { -	f, _, n := bignum.RatFromString(lit, 0); +	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; +	expr := a.newExpr(IdealFloatType, "float literal") +	expr.eval = func() *bignum.Rational { return f } +	return expr  }  func (a *exprInfo) compileString(s string) *expr { @@ -787,47 +787,47 @@ func (a *exprInfo) compileString(s string) *expr {  	// 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; +	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); +	s, err := strconv.Unquote(lit)  	if err != nil { -		a.diag("illegal string literal, %v", err); -		return nil; +		a.diag("illegal string literal, %v", err) +		return nil  	} -	return a.compileString(s); +	return a.compileString(s)  }  func (a *exprInfo) compileStringList(list []*expr) *expr { -	ss := make([]string, len(list)); +	ss := make([]string, len(list))  	for i, s := range list {  		ss[i] = s.asString()(nil)  	} -	return a.compileString(strings.Join(ss, "")); +	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; +	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 := ""; +	bestDepth := -1 +	ambig := false +	amberr := ""  	mark := func(depth int, pathName string) {  		switch {  		case bestDepth == -1 || depth < bestDepth: -			bestDepth = depth; -			ambig = false; -			amberr = ""; +			bestDepth = depth +			ambig = false +			amberr = ""  		case depth == bestDepth:  			ambig = true @@ -835,10 +835,10 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {  		default:  			log.Crashf("Marked field at depth %d, but already found one at depth %d", depth, bestDepth)  		} -		amberr += "\n\t" + pathName[1:]; -	}; +		amberr += "\n\t" + pathName[1:] +	} -	visited := make(map[Type]bool); +	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 @@ -850,7 +850,7 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {  	// 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); +	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 { @@ -861,37 +861,37 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {  		if _, ok := visited[t]; ok {  			return nil  		} -		visited[t] = true; +		visited[t] = true  		// Implicit dereference -		deref := false; +		deref := false  		if ti, ok := t.(*PtrType); ok { -			deref = true; -			t = ti.Elem; +			deref = true +			t = ti.Elem  		}  		// If it's a named type, look for methods  		if ti, ok := t.(*NamedType); ok { -			_, ok := ti.methods[name]; +			_, ok := ti.methods[name]  			if ok { -				mark(depth, pathName+"."+name); -				log.Crash("Methods not implemented"); +				mark(depth, pathName+"."+name) +				log.Crash("Methods not implemented")  			} -			t = ti.Def; +			t = ti.Def  		}  		// If it's a struct type, check fields and embedded types -		var builder func(*expr) *expr; +		var builder func(*expr) *expr  		if t, ok := t.(*StructType); ok {  			for i, f := range t.Elems { -				var sub func(*expr) *expr; +				var sub func(*expr) *expr  				switch {  				case f.Name == name: -					mark(depth, pathName+"."+name); -					sub = func(e *expr) *expr { return e }; +					mark(depth, pathName+"."+name) +					sub = func(e *expr) *expr { return e }  				case f.Anonymous: -					sub = find(f.Type, depth+1, pathName+"."+f.Name); +					sub = find(f.Type, depth+1, pathName+"."+f.Name)  					if sub == nil {  						continue  					} @@ -902,48 +902,48 @@ func (a *exprInfo) compileSelectorExpr(v *expr, name string) *expr {  				// We found something.  Create a  				// builder for accessing this field. -				ft := f.Type; -				index := i; +				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); -				}; +					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; -	}; +		return builder +	} -	builder := find(v.t, 0, ""); +	builder := find(v.t, 0, "")  	if builder == nil { -		a.diag("type %v has no field or method %s", v.t, name); -		return 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; +		a.diag("field %s is ambiguous in type %v%s", name, v.t, amberr) +		return nil  	} -	return builder(v); +	return builder(v)  }  func (a *exprInfo) compileSliceExpr(arr, lo, hi *expr) *expr {  	// Type check object -	arr = arr.derefArray(); +	arr = arr.derefArray() -	var at Type; -	var maxIndex int64 = -1; +	var at Type +	var maxIndex int64 = -1  	switch lt := arr.t.lit().(type) {  	case *ArrayType: -		at = NewSliceType(lt.Elem); -		maxIndex = lt.Len; +		at = NewSliceType(lt.Elem) +		maxIndex = lt.Len  	case *SliceType:  		at = lt @@ -952,105 +952,105 @@ func (a *exprInfo) compileSliceExpr(arr, lo, hi *expr) *expr {  		at = lt  	default: -		a.diag("cannot slice %v", arr.t); -		return nil; +		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"); +	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"); +	expr := a.newExpr(at, "slice expression")  	// Compile -	lof := lo.asInt(); -	hif := hi.asInt(); +	lof := lo.asInt() +	hif := hi.asInt()  	switch lt := arr.t.lit().(type) {  	case *ArrayType: -		arrf := arr.asArray(); -		bound := lt.Len; +		arrf := arr.asArray() +		bound := lt.Len  		expr.eval = func(t *Thread) Slice { -			arr, lo, hi := arrf(t), lof(t), hif(t); +			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}; -		}; +			return Slice{arr.Sub(lo, bound-lo), hi - lo, bound - lo} +		}  	case *SliceType: -		arrf := arr.asSlice(); +		arrf := arr.asSlice()  		expr.eval = func(t *Thread) Slice { -			arr, lo, hi := arrf(t), lof(t), hif(t); +			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}; -		}; +			return Slice{arr.Base.Sub(lo, arr.Cap-lo), hi - lo, arr.Cap - lo} +		}  	case *stringType: -		arrf := arr.asString(); +		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); +			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]; -		}; +			return arr[lo:hi] +		}  	default:  		log.Crashf("unexpected left operand type %T", arr.t.lit())  	} -	return expr; +	return expr  }  func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {  	// Type check object -	l = l.derefArray(); +	l = l.derefArray() -	var at Type; -	intIndex := false; -	var maxIndex int64 = -1; +	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; +		at = lt.Elem +		intIndex = true +		maxIndex = lt.Len  	case *SliceType: -		at = lt.Elem; -		intIndex = true; +		at = lt.Elem +		intIndex = true  	case *stringType: -		at = Uint8Type; -		intIndex = true; +		at = Uint8Type +		intIndex = true  	case *MapType: -		at = lt.Elem; +		at = lt.Elem  		if r.t.isIdeal() { -			r = r.convertTo(lt.Key); +			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; +			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; +		a.diag("cannot index into %v", l.t) +		return nil  	}  	// Type check index and convert to int if necessary @@ -1058,83 +1058,83 @@ func (a *exprInfo) compileIndexExpr(l, r *expr) *expr {  		// 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"); +		r = r.convertToInt(maxIndex, "index", "index")  		if r == nil {  			return nil  		}  	} -	expr := a.newExpr(at, "index expression"); +	expr := a.newExpr(at, "index expression")  	// Compile  	switch lt := l.t.lit().(type) {  	case *ArrayType: -		lf := l.asArray(); -		rf := r.asInt(); -		bound := lt.Len; +		lf := l.asArray() +		rf := r.asInt() +		bound := lt.Len  		expr.genValue(func(t *Thread) Value { -			l, r := lf(t), rf(t); +			l, r := lf(t), rf(t)  			if r < 0 || r >= bound {  				t.Abort(IndexError{r, bound})  			} -			return l.Elem(t, r); -		}); +			return l.Elem(t, r) +		})  	case *SliceType: -		lf := l.asSlice(); -		rf := r.asInt(); +		lf := l.asSlice() +		rf := r.asInt()  		expr.genValue(func(t *Thread) Value { -			l, r := lf(t), rf(t); +			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); -		}); +			return l.Base.Elem(t, r) +		})  	case *stringType: -		lf := l.asString(); -		rf := r.asInt(); +		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); +			l, r := lf(t), rf(t)  			if r < 0 || r >= int64(len(l)) {  				t.Abort(IndexError{r, int64(len(l))})  			} -			return uint64(l[r]); -		}; +			return uint64(l[r]) +		}  	case *MapType: -		lf := l.asMap(); -		rf := r.asInterface(); +		lf := l.asMap() +		rf := r.asInterface()  		expr.genValue(func(t *Thread) Value { -			m := lf(t); -			k := rf(t); +			m := lf(t) +			k := rf(t)  			if m == nil {  				t.Abort(NilPointerError{})  			} -			e := m.Elem(t, k); +			e := m.Elem(t, k)  			if e == nil {  				t.Abort(KeyError{k})  			} -			return e; -		}); +			return e +		})  		// genValue makes things addressable, but map values  		// aren't addressable. -		expr.evalAddr = nil; +		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; +	return expr  }  func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr { @@ -1148,10 +1148,10 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {  	// 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); +	lt, ok := l.t.lit().(*FuncType)  	if !ok { -		a.diag("cannot call non-function type %v", l.t); -		return nil; +		a.diag("cannot call non-function type %v", l.t) +		return nil  	}  	// The arguments must be single-valued expressions assignment @@ -1159,14 +1159,14 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {  	//  	// 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"); +	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); +	var t Type +	nout := len(lt.Out)  	switch nout {  	case 0:  		t = EmptyType @@ -1175,10 +1175,10 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {  	default:  		t = NewMultiType(lt.Out)  	} -	expr := a.newExpr(t, "function call"); +	expr := a.newExpr(t, "function call")  	// Gather argument and out types to initialize frame variables -	vts := make([]Type, nin+nout); +	vts := make([]Type, nin+nout)  	for i, t := range lt.In {  		vts[i] = t  	} @@ -1187,103 +1187,103 @@ func (a *exprInfo) compileCallExpr(b *block, l *expr, as []*expr) *expr {  	}  	// Compile -	lf := l.asFunc(); +	lf := l.asFunc()  	call := func(t *Thread) []Value { -		fun := lf(t); -		fr := fun.NewFrame(); +		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); +		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; +	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; +			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; +			a.diag("too many arguments to %s", ft.builtin) +			return false  		} -		return true; -	}; +		return true +	}  	switch ft {  	case capType:  		if !checkCount(1, 1) {  			return nil  		} -		arg := as[0].derefArray(); -		expr := a.newExpr(IntType, "function call"); +		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 }; +			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 }; +			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; +			a.diag("illegal argument type for cap function\n\t%v", arg.t) +			return nil  		} -		return expr; +		return expr  	case lenType:  		if !checkCount(1, 1) {  			return nil  		} -		arg := as[0].derefArray(); -		expr := a.newExpr(IntType, "function call"); +		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))) }; +			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 }; +			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 }; +			vf := arg.asSlice() +			expr.eval = func(t *Thread) int64 { return vf(t).Len }  		case *MapType: -			vf := arg.asMap(); +			vf := arg.asMap()  			expr.eval = func(t *Thread) int64 {  				// XXX(Spec) What's the len of an  				// uninitialized map? -				m := vf(t); +				m := vf(t)  				if m == nil {  					return 0  				} -				return m.Len(t); -			}; +				return m.Len(t) +			}  		//case *ChanType:  		default: -			a.diag("illegal argument type for len function\n\t%v", arg.t); -			return nil; +			a.diag("illegal argument type for len function\n\t%v", arg.t) +			return nil  		} -		return expr; +		return expr  	case makeType:  		if !checkCount(1, 3) { @@ -1292,21 +1292,21 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e  		// 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; +		var lenexpr, capexpr *expr +		var lenf, capf func(*Thread) int64  		if len(as) > 1 { -			lenexpr = as[1].convertToInt(-1, "length", "make function"); +			lenexpr = as[1].convertToInt(-1, "length", "make function")  			if lenexpr == nil {  				return nil  			} -			lenf = lenexpr.asInt(); +			lenf = lenexpr.asInt()  		}  		if len(as) > 2 { -			capexpr = as[2].convertToInt(-1, "capacity", "make function"); +			capexpr = as[2].convertToInt(-1, "capacity", "make function")  			if capexpr == nil {  				return nil  			} -			capf = capexpr.asInt(); +			capf = capexpr.asInt()  		}  		switch t := as[0].valType.lit().(type) { @@ -1319,18 +1319,18 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e  			if !checkCount(2, 3) {  				return nil  			} -			et := t.Elem; -			expr := a.newExpr(t, "function call"); +			et := t.Elem +			expr := a.newExpr(t, "function call")  			expr.eval = func(t *Thread) Slice { -				l := lenf(t); +				l := lenf(t)  				// XXX(Spec) What if len or cap is  				// negative?  The runtime panics.  				if l < 0 {  					t.Abort(NegativeLengthError{l})  				} -				c := l; +				c := l  				if capf != nil { -					c = capf(t); +					c = capf(t)  					if c < 0 {  						t.Abort(NegativeCapacityError{c})  					} @@ -1341,13 +1341,13 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e  						c = l  					}  				} -				base := arrayV(make([]Value, c)); +				base := arrayV(make([]Value, c))  				for i := int64(0); i < c; i++ {  					base[i] = et.Zero()  				} -				return Slice{&base, l, c}; -			}; -			return expr; +				return Slice{&base, l, c} +			} +			return expr  		case *MapType:  			// A new, empty map value is made using the @@ -1357,52 +1357,52 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e  			if !checkCount(1, 2) {  				return nil  			} -			expr := a.newExpr(t, "function call"); +			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; +				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; +			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; +		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; +		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)); +		evals := make([]func(*Thread) interface{}, len(as))  		for i, x := range as {  			evals[i] = x.asInterface()  		} -		spaces := ft == paniclnType || ft == printlnType; -		newline := ft != printType; +		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); +				v := eval(t)  				type stringer interface { -					String() string; +					String() string  				}  				switch v1 := v.(type) {  				case bool: @@ -1424,67 +1424,67 @@ func (a *exprInfo) compileBuiltinCallExpr(b *block, ft *FuncType, as []*expr) *e  			if newline {  				print("\n")  			} -		}; -		expr := a.newExpr(EmptyType, "print"); -		expr.exec = printer; +		} +		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")); +				printer(t) +				t.Abort(os.NewError("panic"))  			}  		} -		return expr; +		return expr  	} -	log.Crashf("unexpected built-in function '%s'", ft.builtin); -	panic(); +	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 := a.newExpr(vt.Elem, "indirect expression") +		vf := v.asPtr()  		expr.genValue(func(t *Thread) Value { -			v := vf(t); +			v := vf(t)  			if v == nil {  				t.Abort(NilPointerError{})  			} -			return v; -		}); -		return expr; +			return v +		}) +		return expr  	} -	a.diagOpType(token.MUL, v.t); -	return nil; +	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; +	var t Type  	switch op {  	case token.ADD, token.SUB:  		if !v.t.isInteger() && !v.t.isFloat() { -			a.diagOpType(op, v.t); -			return nil; +			a.diagOpType(op, v.t) +			return nil  		} -		t = v.t; +		t = v.t  	case token.NOT:  		if !v.t.isBoolean() { -			a.diagOpType(op, v.t); -			return nil; +			a.diagOpType(op, v.t) +			return nil  		} -		t = BoolType; +		t = BoolType  	case token.XOR:  		if !v.t.isInteger() { -			a.diagOpType(op, v.t); -			return nil; +			a.diagOpType(op, v.t) +			return nil  		} -		t = v.t; +		t = v.t  	case token.AND:  		// The unary prefix address-of operator & generates @@ -1492,15 +1492,15 @@ func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr {  		// 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; +			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); +		t = NewPtrType(v.t)  	case token.ARROW:  		log.Crashf("Unary op %v not implemented", op) @@ -1509,19 +1509,19 @@ func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr {  		log.Crashf("unknown unary operator %v", op)  	} -	desc, ok := unaryOpDescs[op]; +	desc, ok := unaryOpDescs[op]  	if !ok { -		desc = "unary " + op.String() + " expression"; -		unaryOpDescs[op] = desc; +		desc = "unary " + op.String() + " expression" +		unaryOpDescs[op] = desc  	}  	// Compile -	expr := a.newExpr(t, desc); +	expr := a.newExpr(t, desc)  	switch op {  	case token.ADD:  		// Just compile it out -		expr = v; -		expr.desc = desc; +		expr = v +		expr.desc = desc  	case token.SUB:  		expr.genUnaryOpNeg(v) @@ -1533,22 +1533,22 @@ func (a *exprInfo) compileUnaryExpr(op token.Token, v *expr) *expr {  		expr.genUnaryOpXor(v)  	case token.AND: -		vf := v.evalAddr; -		expr.eval = func(t *Thread) Value { return vf(t) }; +		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; +	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; +	origlt := l.t +	origrt := r.t  	// XXX(Spec) What is the exact definition of a "named type"? @@ -1594,38 +1594,38 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  	// 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() }; +	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() }; +	} +	booleans := func() bool { return l.t.isBoolean() && r.t.isBoolean() }  	// Type check -	var t Type; +	var t Type  	switch op {  	case token.ADD:  		if !compat() || (!integers() && !floats() && !strings()) { -			a.diagOpTypes(op, origlt, origrt); -			return nil; +			a.diagOpTypes(op, origlt, origrt) +			return nil  		} -		t = l.t; +		t = l.t  	case token.SUB, token.MUL, token.QUO:  		if !compat() || (!integers() && !floats()) { -			a.diagOpTypes(op, origlt, origrt); -			return nil; +			a.diagOpTypes(op, origlt, origrt) +			return nil  		} -		t = l.t; +		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; +			a.diagOpTypes(op, origlt, origrt) +			return nil  		} -		t = l.t; +		t = l.t  	case token.SHL, token.SHR:  		// XXX(Spec) Is it okay for the right operand to be an @@ -1636,8 +1636,8 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		// (§Arithmetic operators)" suggests so and 6g agrees.  		if !l.t.isInteger() || !(r.t.isInteger() || r.t.isIdeal()) { -			a.diagOpTypes(op, origlt, origrt); -			return nil; +			a.diagOpTypes(op, origlt, origrt) +			return nil  		}  		// The right operand in a shift operation must be @@ -1645,7 +1645,7 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		// number that can be safely converted into an  		// unsigned integer type.  		if r.t.isIdeal() { -			r2 := r.convertTo(UintType); +			r2 := r.convertTo(UintType)  			if r2 == nil {  				return nil  			} @@ -1659,14 +1659,14 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  			// 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); +				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; +			a.diag("right operand of shift must be unsigned") +			return nil  		}  		if l.t.isIdeal() && !r.t.isIdeal() { @@ -1675,7 +1675,7 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  			// converted to an int.  6g propagates the  			// type down from assignments as a hint. -			l = l.convertTo(IntType); +			l = l.convertTo(IntType)  			if l == nil {  				return nil  			} @@ -1686,7 +1686,7 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		// 2) int SHIFT uint  		// 3) ideal int SHIFT ideal int -		t = l.t; +		t = l.t  	case token.LOR, token.LAND:  		if !booleans() { @@ -1698,14 +1698,14 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		// the type of the left operand, and NOT an unnamed  		// boolean type. -		t = BoolType; +		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; +		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 @@ -1717,10 +1717,10 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		// are some restrictions on when it applies to slices.  		if !compat() || (!integers() && !floats() && !strings()) { -			a.diagOpTypes(op, origlt, origrt); -			return nil; +			a.diagOpTypes(op, origlt, origrt) +			return nil  		} -		t = BoolType; +		t = BoolType  	case token.EQL, token.NEQ:  		// XXX(Spec) The rules for type checking comparison @@ -1760,25 +1760,25 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		// TODO(austin) Deal with remaining special cases  		if !compat() { -			a.diagOpTypes(op, origlt, origrt); -			return nil; +			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; +			a.diagOpTypes(op, origlt, origrt) +			return nil  		} -		t = BoolType; +		t = BoolType  	default:  		log.Crashf("unknown binary operator %v", op)  	} -	desc, ok := binOpDescs[op]; +	desc, ok := binOpDescs[op]  	if !ok { -		desc = op.String() + " expression"; -		binOpDescs[op] = desc; +		desc = op.String() + " expression" +		binOpDescs[op] = desc  	}  	// Check for ideal divide by zero @@ -1787,14 +1787,14 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		if r.t.isIdeal() {  			if (r.t.isInteger() && r.asIdealInt()().IsZero()) ||  				(r.t.isFloat() && r.asIdealFloat()().IsZero()) { -				a.diag("divide by zero"); -				return nil; +				a.diag("divide by zero") +				return nil  			}  		}  	}  	// Compile -	expr := a.newExpr(t, desc); +	expr := a.newExpr(t, desc)  	switch op {  	case token.ADD:  		expr.genBinOpAdd(l, r) @@ -1825,26 +1825,26 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  	case token.SHL:  		if l.t.isIdeal() { -			lv := l.asIdealInt()(); -			rv := r.asIdealInt()(); -			const maxShift = 99999; +			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; +				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 }; +			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 }; +			lv := l.asIdealInt()() +			rv := r.asIdealInt()() +			val := lv.Shr(uint(rv.Value())) +			expr.eval = func() *bignum.Integer { return val }  		} else {  			expr.genBinOpShr(l, r)  		} @@ -1877,28 +1877,28 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr {  		log.Crashf("Compilation of binary op %v not implemented", op)  	} -	return expr; +	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); +	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); +		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; +		a.diagAt(expr, "array size must be an integer") +		return 0, false  	}  	switch lenExpr.t.lit().(type) { @@ -1907,18 +1907,18 @@ func (a *compiler) compileArrayLen(b *block, expr ast.Expr) (int64, bool) {  	case *uintType:  		return int64(lenExpr.asUint()(nil)), true  	} -	log.Crashf("unexpected integer type %T", lenExpr.t); -	return 0, false; +	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); +	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; +	return e  }  // extractEffect separates out any effects that the expression may @@ -1931,21 +1931,21 @@ func (a *compiler) compileExpr(b *block, constant bool, expr ast.Expr) *expr {  // results.  func (a *expr) extractEffect(b *block, errOp string) (func(*Thread), *expr) {  	// Create "&a" if a is addressable -	rhs := a; +	rhs := a  	if a.evalAddr != nil {  		rhs = a.compileUnaryExpr(token.AND, rhs)  	}  	// Create temp -	ac, ok := a.checkAssign(a.pos, []*expr{rhs}, errOp, ""); +	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; +		a.diag("multi-valued expression not allowed in %s", errOp) +		return nil, nil  	} -	tempType := ac.rmt.Elems[0]; +	tempType := ac.rmt.Elems[0]  	if tempType.isIdeal() {  		// It's too bad we have to duplicate this rule.  		switch { @@ -1957,30 +1957,30 @@ func (a *expr) extractEffect(b *block, errOp string) (func(*Thread), *expr) {  			log.Crashf("unexpected ideal type %v", tempType)  		}  	} -	temp := b.DefineTemp(tempType); -	tempIdx := temp.Index; +	temp := b.DefineTemp(tempType) +	tempIdx := temp.Index  	// Create "temp := rhs" -	assign := ac.compile(b, tempType); +	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); -	}; +		tempVal := tempType.Zero() +		t.f.Vars[tempIdx] = tempVal +		assign(tempVal, t) +	}  	// Generate "temp" or "*temp" -	getTemp := a.compileVariable(0, temp); +	getTemp := a.compileVariable(0, temp)  	if a.evalAddr == nil {  		return effect, getTemp  	} -	deref := a.compileStarExpr(getTemp); +	deref := a.compileStarExpr(getTemp)  	if deref == nil {  		return nil, nil  	} -	return effect, deref; +	return effect, deref  } | 
