summaryrefslogtreecommitdiff
path: root/src/pkg/exp/eval/expr.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/exp/eval/expr.go')
-rw-r--r--src/pkg/exp/eval/expr.go1088
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
}