diff options
| author | Robert Griesemer <gri@golang.org> | 2009-12-15 15:27:16 -0800 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2009-12-15 15:27:16 -0800 |
| commit | 881d6064d23d9da5c7ff368bc7d41d271290deff (patch) | |
| tree | 44d5d948e3f27cc7eff15ec8cd7ee5165d9a7e90 /src/pkg/exp/eval/expr.go | |
| parent | d9dfea3ebd51cea89fef8afc6b2377c2958b24f1 (diff) | |
| download | golang-881d6064d23d9da5c7ff368bc7d41d271290deff.tar.gz | |
1) Change default gofmt default settings for
parsing and printing to new syntax.
Use -oldparser to parse the old syntax,
use -oldprinter to print the old syntax.
2) Change default gofmt formatting settings
to use tabs for indentation only and to use
spaces for alignment. This will make the code
alignment insensitive to an editor's tabwidth.
Use -spaces=false to use tabs for alignment.
3) Manually changed src/exp/parser/parser_test.go
so that it doesn't try to parse the parser's
source files using the old syntax (they have
new syntax now).
4) gofmt -w src misc test/bench
2nd set of files.
R=rsc
CC=golang-dev
http://codereview.appspot.com/179067
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 } |
