diff options
author | Evan Shaw <chickencha@gmail.com> | 2010-07-14 09:39:59 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2010-07-14 09:39:59 -0700 |
commit | b97292791b0f5cca6b9b52b1f03631e70fff75b2 (patch) | |
tree | e7b90457af8bbbff83fdd0fdcd63f0418f789bb5 | |
parent | c9406f930d7fbd7e4d1ec2eaf3d0e47e5bfab402 (diff) | |
download | go-b97292791b0f5cca6b9b52b1f03631e70fff75b2.tar.gz go-b97292791b0f5cca6b9b52b1f03631e70fff75b2.zip |
exp/eval: Converted from bignum to big
Also in this CL:
* Removed util.go, as its functionality is in big
* Removed some semicolons from the code generated by gen.go
* Added a generate target to Makefile
* Removed an outdated TODO from value.go
R=gri
CC=golang-dev
https://golang.org/cl/1780042
-rw-r--r-- | src/pkg/exp/eval/Makefile | 10 | ||||
-rw-r--r-- | src/pkg/exp/eval/eval_test.go | 8 | ||||
-rw-r--r-- | src/pkg/exp/eval/expr.go | 74 | ||||
-rwxr-xr-x[-rw-r--r--] | src/pkg/exp/eval/expr1.go | 94 | ||||
-rw-r--r-- | src/pkg/exp/eval/expr_test.go | 91 | ||||
-rw-r--r-- | src/pkg/exp/eval/gen.go | 102 | ||||
-rw-r--r-- | src/pkg/exp/eval/stmt.go | 4 | ||||
-rw-r--r-- | src/pkg/exp/eval/type.go | 53 | ||||
-rw-r--r-- | src/pkg/exp/eval/util.go | 39 | ||||
-rw-r--r-- | src/pkg/exp/eval/value.go | 18 |
10 files changed, 241 insertions, 252 deletions
diff --git a/src/pkg/exp/eval/Makefile b/src/pkg/exp/eval/Makefile index eac844f1ed..4accbb26da 100644 --- a/src/pkg/exp/eval/Makefile +++ b/src/pkg/exp/eval/Makefile @@ -16,7 +16,6 @@ GOFILES=\ stmt.go\ type.go\ typec.go\ - util.go\ value.go\ world.go\ @@ -27,3 +26,12 @@ main.$O: main.go $(pkgdir)/$(TARG).a eval: main.$O $(QUOTED_GOBIN)/$(LD) -o $@ $< + +gen.$O: gen.go + $(QUOTED_GOBIN)/$(GC) $< + +expr1.go: gen.$O + $(QUOTED_GOBIN)/$(LD) -o generate $<;\ + ./generate > expr1.go;\ + gofmt -w expr1.go + diff --git a/src/pkg/exp/eval/eval_test.go b/src/pkg/exp/eval/eval_test.go index 1dfdfe1fd6..cd4bbbbb0a 100644 --- a/src/pkg/exp/eval/eval_test.go +++ b/src/pkg/exp/eval/eval_test.go @@ -5,7 +5,7 @@ package eval import ( - "exp/bignum" + "big" "flag" "fmt" "log" @@ -166,12 +166,12 @@ func toValue(val interface{}) Value { case int: r := intV(val) return &r - case *bignum.Integer: + case *big.Int: return &idealIntV{val} case float: r := floatV(val) return &r - case *bignum.Rational: + case *big.Rat: return &idealFloatV{val} case string: r := stringV(val) @@ -235,7 +235,7 @@ func newTestWorld() *World { def := func(name string, t Type, val interface{}) { w.DefineVar(name, t, toValue(val)) } - w.DefineConst("c", IdealIntType, toValue(bignum.Int(1))) + w.DefineConst("c", IdealIntType, toValue(big.NewInt(1))) def("i", IntType, 1) def("i2", IntType, 2) def("u", UintType, uint(1)) diff --git a/src/pkg/exp/eval/expr.go b/src/pkg/exp/eval/expr.go index ea8117d065..9d4fdd84b7 100644 --- a/src/pkg/exp/eval/expr.go +++ b/src/pkg/exp/eval/expr.go @@ -5,7 +5,7 @@ package eval import ( - "exp/bignum" + "big" "fmt" "go/ast" "go/token" @@ -15,6 +15,11 @@ import ( "os" ) +var ( + idealZero = big.NewInt(0) + idealOne = big.NewInt(1) +) + // An expr is the result of compiling an expression. It stores the // type of the expression and its evaluator function. type expr struct { @@ -85,7 +90,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 *big.Rat // XXX(Spec) The spec says "It is erroneous". // @@ -97,12 +102,12 @@ func (a *expr) convertTo(t Type) *expr { case IdealFloatType: rat = a.asIdealFloat()() if t.isInteger() && !rat.IsInt() { - a.diag("constant %v truncated to integer", ratToString(rat)) + a.diag("constant %v truncated to integer", rat.FloatString(6)) return nil } case IdealIntType: i := a.asIdealInt()() - rat = bignum.MakeRat(i, bignum.Nat(1)) + rat = new(big.Rat).SetInt(i) default: log.Crashf("unexpected ideal type %v", a.t) } @@ -110,11 +115,11 @@ 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) + a.diag("constant %v underflows %v", rat.FloatString(6), t) return nil } if rat.Cmp(t.maxVal()) > 0 { - a.diag("constant %v overflows %v", ratToString(rat), t) + a.diag("constant %v overflows %v", rat.FloatString(6), t) return nil } } @@ -123,25 +128,26 @@ func (a *expr) convertTo(t Type) *expr { 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() + n, d := rat.Num(), rat.Denom() + f := new(big.Int).Quo(n, d) + f = f.Abs(f) + v := uint64(f.Int64()) res.eval = func(*Thread) uint64 { return v } case *intType: - n, d := rat.Value() - f := n.Quo(bignum.MakeInt(false, d)) - v := f.Value() + n, d := rat.Num(), rat.Denom() + f := new(big.Int).Quo(n, d) + v := f.Int64() 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.Num(), rat.Denom() + f := new(big.Int).Quo(n, d) + res.eval = func() *big.Int { return f } case *floatType: - n, d := rat.Value() - v := float64(n.Value()) / float64(d.Value()) + n, d := rat.Num(), rat.Denom() + v := float64(n.Int64()) / float64(d.Int64()) res.eval = func(*Thread) float64 { return v } case *idealFloatType: - res.eval = func() *bignum.Rational { return rat } + res.eval = func() *big.Rat { return rat } default: log.Crashf("cannot convert to type %T", t) } @@ -158,7 +164,7 @@ func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr { switch a.t.lit().(type) { case *idealIntType: val := a.asIdealInt()() - if negErr != "" && val.IsNeg() { + if negErr != "" && val.Sign() < 0 { a.diag("negative %s: %s", negErr, val) return nil } @@ -166,7 +172,7 @@ func (a *expr) convertToInt(max int64, negErr string, errOp string) *expr { if negErr == "slice" { bound++ } - if max != -1 && val.Cmp(bignum.Int(bound)) >= 0 { + if max != -1 && val.Cmp(big.NewInt(bound)) >= 0 { a.diag("index %s exceeds length %d", val, max) return nil } @@ -735,14 +741,14 @@ func (a *exprInfo) compileGlobalVariable(v *Variable) *expr { return expr } -func (a *exprInfo) compileIdealInt(i *bignum.Integer, desc string) *expr { +func (a *exprInfo) compileIdealInt(i *big.Int, desc string) *expr { expr := a.newExpr(IdealIntType, desc) - expr.eval = func() *bignum.Integer { return i } + expr.eval = func() *big.Int { return i } return expr } func (a *exprInfo) compileIntLit(lit string) *expr { - i, _, _ := bignum.IntFromString(lit, 0) + i, _ := new(big.Int).SetString(lit, 0) return a.compileIdealInt(i, "integer literal") } @@ -758,16 +764,16 @@ func (a *exprInfo) compileCharLit(lit string) *expr { a.silentErrors++ return nil } - return a.compileIdealInt(bignum.Int(int64(v)), "character literal") + return a.compileIdealInt(big.NewInt(int64(v)), "character literal") } func (a *exprInfo) compileFloatLit(lit string) *expr { - f, _, n := bignum.RatFromString(lit, 10) - if n != len(lit) { + f, ok := new(big.Rat).SetString(lit) + if !ok { 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 } + expr.eval = func() *big.Rat { return f } return expr } @@ -1774,8 +1780,8 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr { switch op { case token.QUO, token.REM: if r.t.isIdeal() { - if (r.t.isInteger() && r.asIdealInt()().IsZero()) || - (r.t.isFloat() && r.asIdealFloat()().IsZero()) { + if (r.t.isInteger() && r.asIdealInt()().Sign() == 0) || + (r.t.isFloat() && r.asIdealFloat()().Sign() == 0) { a.diag("divide by zero") return nil } @@ -1817,13 +1823,13 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr { lv := l.asIdealInt()() rv := r.asIdealInt()() const maxShift = 99999 - if rv.Cmp(bignum.Int(maxShift)) > 0 { + if rv.Cmp(big.NewInt(maxShift)) > 0 { a.diag("left shift by %v; exceeds implementation limit of %v", rv, maxShift) expr.t = nil return nil } - val := lv.Shl(uint(rv.Value())) - expr.eval = func() *bignum.Integer { return val } + val := new(big.Int).Lsh(lv, uint(rv.Int64())) + expr.eval = func() *big.Int { return val } } else { expr.genBinOpShl(l, r) } @@ -1832,8 +1838,8 @@ func (a *exprInfo) compileBinaryExpr(op token.Token, l, r *expr) *expr { if l.t.isIdeal() { lv := l.asIdealInt()() rv := r.asIdealInt()() - val := lv.Shr(uint(rv.Value())) - expr.eval = func() *bignum.Integer { return val } + val := new(big.Int).Rsh(lv, uint(rv.Int64())) + expr.eval = func() *big.Int { return val } } else { expr.genBinOpShr(l, r) } diff --git a/src/pkg/exp/eval/expr1.go b/src/pkg/exp/eval/expr1.go index f0a78ac4d6..81bc3a2202 100644..100755 --- a/src/pkg/exp/eval/expr1.go +++ b/src/pkg/exp/eval/expr1.go @@ -4,13 +4,13 @@ package eval import ( - "exp/bignum" + "big" "log" ) /* - * "As" functions. These retrieve evaluator functions from an - * expr, panicking if the requested evaluator has the wrong type. +* "As" functions. These retrieve evaluator functions from an +* expr, panicking if the requested evaluator has the wrong type. */ func (a *expr) asBool() func(*Thread) bool { return a.eval.(func(*Thread) bool) @@ -21,14 +21,14 @@ func (a *expr) asUint() func(*Thread) uint64 { func (a *expr) asInt() func(*Thread) int64 { return a.eval.(func(*Thread) int64) } -func (a *expr) asIdealInt() func() *bignum.Integer { - return a.eval.(func() *bignum.Integer) +func (a *expr) asIdealInt() func() *big.Int { + return a.eval.(func() *big.Int) } func (a *expr) asFloat() func(*Thread) float64 { return a.eval.(func(*Thread) float64) } -func (a *expr) asIdealFloat() func() *bignum.Rational { - return a.eval.(func() *bignum.Rational) +func (a *expr) asIdealFloat() func() *big.Rat { + return a.eval.(func() *big.Rat) } func (a *expr) asString() func(*Thread) string { return a.eval.(func(*Thread) string) @@ -63,11 +63,11 @@ func (a *expr) asInterface() func(*Thread) interface{} { return func(t *Thread) interface{} { return sf(t) } case func(t *Thread) int64: return func(t *Thread) interface{} { return sf(t) } - case func() *bignum.Integer: + case func() *big.Int: return func(*Thread) interface{} { return sf() } case func(t *Thread) float64: return func(t *Thread) interface{} { return sf(t) } - case func() *bignum.Rational: + case func() *big.Rat: return func(*Thread) interface{} { return sf() } case func(t *Thread) string: return func(t *Thread) interface{} { return sf(t) } @@ -90,7 +90,7 @@ func (a *expr) asInterface() func(*Thread) interface{} { } /* - * Operator generators. +* Operator generators. */ func (a *expr) genConstant(v Value) { @@ -103,12 +103,12 @@ func (a *expr) genConstant(v Value) { a.eval = func(t *Thread) int64 { return v.(IntValue).Get(t) } case *idealIntType: val := v.(IdealIntValue).Get() - a.eval = func() *bignum.Integer { return val } + a.eval = func() *big.Int { return val } case *floatType: a.eval = func(t *Thread) float64 { return v.(FloatValue).Get(t) } case *idealFloatType: val := v.(IdealFloatValue).Get() - a.eval = func() *bignum.Rational { return val } + a.eval = func() *big.Rat { return val } case *stringType: a.eval = func(t *Thread) string { return v.(StringValue).Get(t) } case *ArrayType: @@ -229,16 +229,16 @@ func (a *expr) genUnaryOpNeg(v *expr) { vf := v.asInt() a.eval = func(t *Thread) int64 { v := vf(t); return -v } case *idealIntType: - v := v.asIdealInt()() - val := v.Neg() - a.eval = func() *bignum.Integer { return val } + val := v.asIdealInt()() + val.Neg(val) + a.eval = func() *big.Int { return val } case *floatType: vf := v.asFloat() a.eval = func(t *Thread) float64 { v := vf(t); return -v } case *idealFloatType: - v := v.asIdealFloat()() - val := v.Neg() - a.eval = func() *bignum.Rational { return val } + val := v.asIdealFloat()() + val.Neg(val) + a.eval = func() *big.Rat { return val } default: log.Crashf("unexpected type %v at %v", a.t, a.pos) } @@ -263,9 +263,9 @@ func (a *expr) genUnaryOpXor(v *expr) { vf := v.asInt() a.eval = func(t *Thread) int64 { v := vf(t); return ^v } case *idealIntType: - v := v.asIdealInt()() - val := v.Neg().Sub(bignum.Int(1)) - a.eval = func() *bignum.Integer { return val } + val := v.asIdealInt()() + val.Not(val) + a.eval = func() *big.Int { return val } default: log.Crashf("unexpected type %v at %v", a.t, a.pos) } @@ -372,8 +372,8 @@ func (a *expr) genBinOpAdd(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.Add(r) - a.eval = func() *bignum.Integer { return val } + val := l.Add(l, r) + a.eval = func() *big.Int { return val } case *floatType: lf := l.asFloat() rf := r.asFloat() @@ -405,8 +405,8 @@ func (a *expr) genBinOpAdd(l, r *expr) { case *idealFloatType: l := l.asIdealFloat()() r := r.asIdealFloat()() - val := l.Add(r) - a.eval = func() *bignum.Rational { return val } + val := l.Add(l, r) + a.eval = func() *big.Rat { return val } case *stringType: lf := l.asString() rf := r.asString() @@ -508,8 +508,8 @@ func (a *expr) genBinOpSub(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.Sub(r) - a.eval = func() *bignum.Integer { return val } + val := l.Sub(l, r) + a.eval = func() *big.Int { return val } case *floatType: lf := l.asFloat() rf := r.asFloat() @@ -541,8 +541,8 @@ func (a *expr) genBinOpSub(l, r *expr) { case *idealFloatType: l := l.asIdealFloat()() r := r.asIdealFloat()() - val := l.Sub(r) - a.eval = func() *bignum.Rational { return val } + val := l.Sub(l, r) + a.eval = func() *big.Rat { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } @@ -637,8 +637,8 @@ func (a *expr) genBinOpMul(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.Mul(r) - a.eval = func() *bignum.Integer { return val } + val := l.Mul(l, r) + a.eval = func() *big.Int { return val } case *floatType: lf := l.asFloat() rf := r.asFloat() @@ -670,8 +670,8 @@ func (a *expr) genBinOpMul(l, r *expr) { case *idealFloatType: l := l.asIdealFloat()() r := r.asIdealFloat()() - val := l.Mul(r) - a.eval = func() *bignum.Rational { return val } + val := l.Mul(l, r) + a.eval = func() *big.Rat { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } @@ -796,8 +796,8 @@ func (a *expr) genBinOpQuo(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.Quo(r) - a.eval = func() *bignum.Integer { return val } + val := l.Quo(l, r) + a.eval = func() *big.Int { return val } case *floatType: lf := l.asFloat() rf := r.asFloat() @@ -838,8 +838,8 @@ func (a *expr) genBinOpQuo(l, r *expr) { case *idealFloatType: l := l.asIdealFloat()() r := r.asIdealFloat()() - val := l.Quo(r) - a.eval = func() *bignum.Rational { return val } + val := l.Quo(l, r) + a.eval = func() *big.Rat { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } @@ -964,8 +964,8 @@ func (a *expr) genBinOpRem(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.Rem(r) - a.eval = func() *bignum.Integer { return val } + val := l.Rem(l, r) + a.eval = func() *big.Int { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } @@ -1060,8 +1060,8 @@ func (a *expr) genBinOpAnd(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.And(r) - a.eval = func() *bignum.Integer { return val } + val := l.And(l, r) + a.eval = func() *big.Int { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } @@ -1156,8 +1156,8 @@ func (a *expr) genBinOpOr(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.Or(r) - a.eval = func() *bignum.Integer { return val } + val := l.Or(l, r) + a.eval = func() *big.Int { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } @@ -1252,8 +1252,8 @@ func (a *expr) genBinOpXor(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.Xor(r) - a.eval = func() *bignum.Integer { return val } + val := l.Xor(l, r) + a.eval = func() *big.Int { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } @@ -1348,8 +1348,8 @@ func (a *expr) genBinOpAndNot(l, r *expr) { case *idealIntType: l := l.asIdealInt()() r := r.asIdealInt()() - val := l.AndNot(r) - a.eval = func() *bignum.Integer { return val } + val := l.AndNot(l, r) + a.eval = func() *big.Int { return val } default: log.Crashf("unexpected type %v at %v", l.t, a.pos) } diff --git a/src/pkg/exp/eval/expr_test.go b/src/pkg/exp/eval/expr_test.go index b36554183e..0dbce43152 100644 --- a/src/pkg/exp/eval/expr_test.go +++ b/src/pkg/exp/eval/expr_test.go @@ -5,7 +5,7 @@ package eval import ( - "exp/bignum" + "big" "testing" ) @@ -22,7 +22,7 @@ var implLimit = "implementation limit" var mustBeUnsigned = "must be unsigned" var divByZero = "divide by zero" -var hugeInteger = bignum.Int(1).Shl(64) +var hugeInteger = new(big.Int).Lsh(idealOne, 64) var exprTests = []test{ Val("i", 1), @@ -30,9 +30,9 @@ var exprTests = []test{ // TODO(austin) Test variable in constant context //CErr("t", typeAsExpr), - Val("'a'", bignum.Int('a')), - Val("'\\uffff'", bignum.Int('\uffff')), - Val("'\\n'", bignum.Int('\n')), + Val("'a'", big.NewInt('a')), + Val("'\\uffff'", big.NewInt('\uffff')), + Val("'\\n'", big.NewInt('\n')), CErr("''+x", badCharLit), // Produces two parse errors //CErr("'''", ""), @@ -40,10 +40,10 @@ var exprTests = []test{ CErr("'\\z'", unknownEscape), CErr("'ab'", badCharLit), - Val("1.0", bignum.Rat(1, 1)), - Val("1.", bignum.Rat(1, 1)), - Val(".1", bignum.Rat(1, 10)), - Val("1e2", bignum.Rat(100, 1)), + Val("1.0", big.NewRat(1, 1)), + Val("1.", big.NewRat(1, 1)), + Val(".1", big.NewRat(1, 10)), + Val("1e2", big.NewRat(100, 1)), Val("\"abc\"", "abc"), Val("\"\"", ""), @@ -140,12 +140,12 @@ var exprTests = []test{ CErr("&c", badAddrOf), Val("*(&ai[0])", 1), - Val("+1", bignum.Int(+1)), - Val("+1.0", bignum.Rat(1, 1)), - Val("01.5", bignum.Rat(15, 10)), + Val("+1", big.NewInt(+1)), + Val("+1.0", big.NewRat(1, 1)), + Val("01.5", big.NewRat(15, 10)), CErr("+\"x\"", opTypes), - Val("-42", bignum.Int(-42)), + Val("-42", big.NewInt(-42)), Val("-i", -1), Val("-f", -1.0), // 6g bug? @@ -154,8 +154,8 @@ var exprTests = []test{ // TODO(austin) Test unary ! - Val("^2", bignum.Int(^2)), - Val("^(-2)", bignum.Int(^(-2))), + Val("^2", big.NewInt(^2)), + Val("^(-2)", big.NewInt(^(-2))), CErr("^2.0", opTypes), CErr("^2.5", opTypes), Val("^i", ^1), @@ -165,67 +165,66 @@ var exprTests = []test{ Val("1+i", 2), Val("1+u", uint(2)), Val("3.0+i", 4), - Val("1+1", bignum.Int(2)), + Val("1+1", big.NewInt(2)), Val("f+f", 2.0), Val("1+f", 2.0), - Val("1.0+1", bignum.Rat(2, 1)), + Val("1.0+1", big.NewRat(2, 1)), Val("\"abc\" + \"def\"", "abcdef"), CErr("i+u", opTypes), CErr("-1+u", constantUnderflows), // TODO(austin) Test named types - Val("2-1", bignum.Int(1)), - Val("2.0-1", bignum.Rat(1, 1)), + Val("2-1", big.NewInt(1)), + Val("2.0-1", big.NewRat(1, 1)), Val("f-2", -1.0), - // TOOD(austin) bignum can't do negative 0? - //Val("-0.0", XXX), - Val("2*2", bignum.Int(4)), + Val("-0.0", big.NewRat(0, 1)), + Val("2*2", big.NewInt(4)), Val("2*i", 2), - Val("3/2", bignum.Int(1)), + Val("3/2", big.NewInt(1)), Val("3/i", 3), CErr("1/0", divByZero), CErr("1.0/0", divByZero), RErr("i/0", divByZero), - Val("3%2", bignum.Int(1)), + Val("3%2", big.NewInt(1)), Val("i%2", 1), CErr("3%0", divByZero), CErr("3.0%0", opTypes), RErr("i%0", divByZero), // Examples from "Arithmetic operators" - Val("5/3", bignum.Int(1)), + Val("5/3", big.NewInt(1)), Val("(i+4)/(i+2)", 1), - Val("5%3", bignum.Int(2)), + Val("5%3", big.NewInt(2)), Val("(i+4)%(i+2)", 2), - Val("-5/3", bignum.Int(-1)), + Val("-5/3", big.NewInt(-1)), Val("(i-6)/(i+2)", -1), - Val("-5%3", bignum.Int(-2)), + Val("-5%3", big.NewInt(-2)), Val("(i-6)%(i+2)", -2), - Val("5/-3", bignum.Int(-1)), + Val("5/-3", big.NewInt(-1)), Val("(i+4)/(i-4)", -1), - Val("5%-3", bignum.Int(2)), + Val("5%-3", big.NewInt(2)), Val("(i+4)%(i-4)", 2), - Val("-5/-3", bignum.Int(1)), + Val("-5/-3", big.NewInt(1)), Val("(i-6)/(i-4)", 1), - Val("-5%-3", bignum.Int(-2)), + Val("-5%-3", big.NewInt(-2)), Val("(i-6)%(i-4)", -2), // Examples from "Arithmetic operators" - Val("11/4", bignum.Int(2)), + Val("11/4", big.NewInt(2)), Val("(i+10)/4", 2), - Val("11%4", bignum.Int(3)), + Val("11%4", big.NewInt(3)), Val("(i+10)%4", 3), - Val("11>>2", bignum.Int(2)), + Val("11>>2", big.NewInt(2)), Val("(i+10)>>2", 2), - Val("11&3", bignum.Int(3)), + Val("11&3", big.NewInt(3)), Val("(i+10)&3", 3), - Val("-11/4", bignum.Int(-2)), + Val("-11/4", big.NewInt(-2)), Val("(i-12)/4", -2), - Val("-11%4", bignum.Int(-3)), + Val("-11%4", big.NewInt(-3)), Val("(i-12)%4", -3), - Val("-11>>2", bignum.Int(-3)), + Val("-11>>2", big.NewInt(-3)), Val("(i-12)>>2", -3), - Val("-11&3", bignum.Int(1)), + Val("-11&3", big.NewInt(1)), Val("(i-12)&3", 1), // TODO(austin) Test bit ops @@ -234,29 +233,29 @@ var exprTests = []test{ // ideal int, negative ideal int, big ideal int, ideal // fractional float, ideal non-fractional float, int, uint, // and float. - Val("2<<2", bignum.Int(2<<2)), + Val("2<<2", big.NewInt(2<<2)), CErr("2<<(-1)", constantUnderflows), CErr("2<<0x10000000000000000", constantOverflows), CErr("2<<2.5", constantTruncated), - Val("2<<2.0", bignum.Int(2<<2.0)), + Val("2<<2.0", big.NewInt(2<<2.0)), CErr("2<<i", mustBeUnsigned), Val("2<<u", 2<<1), CErr("2<<f", opTypes), - Val("-2<<2", bignum.Int(-2<<2)), + Val("-2<<2", big.NewInt(-2<<2)), CErr("-2<<(-1)", constantUnderflows), CErr("-2<<0x10000000000000000", constantOverflows), CErr("-2<<2.5", constantTruncated), - Val("-2<<2.0", bignum.Int(-2<<2.0)), + Val("-2<<2.0", big.NewInt(-2<<2.0)), CErr("-2<<i", mustBeUnsigned), Val("-2<<u", -2<<1), CErr("-2<<f", opTypes), - Val("0x10000000000000000<<2", hugeInteger.Shl(2)), + Val("0x10000000000000000<<2", new(big.Int).Lsh(hugeInteger, 2)), CErr("0x10000000000000000<<(-1)", constantUnderflows), CErr("0x10000000000000000<<0x10000000000000000", constantOverflows), CErr("0x10000000000000000<<2.5", constantTruncated), - Val("0x10000000000000000<<2.0", hugeInteger.Shl(2)), + Val("0x10000000000000000<<2.0", new(big.Int).Lsh(hugeInteger, 2)), CErr("0x10000000000000000<<i", mustBeUnsigned), CErr("0x10000000000000000<<u", constantOverflows), CErr("0x10000000000000000<<f", opTypes), diff --git a/src/pkg/exp/eval/gen.go b/src/pkg/exp/eval/gen.go index 969d655862..80179c89aa 100644 --- a/src/pkg/exp/eval/gen.go +++ b/src/pkg/exp/eval/gen.go @@ -45,11 +45,11 @@ var ( intType = &Type{Repr: "*intType", Value: "IntValue", Native: "int64", As: "asInt", Sizes: []Size{Size{8, "int8"}, Size{16, "int16"}, Size{32, "int32"}, Size{64, "int64"}, Size{0, "int"}}, } - idealIntType = &Type{Repr: "*idealIntType", Value: "IdealIntValue", Native: "*bignum.Integer", As: "asIdealInt", IsIdeal: true} + idealIntType = &Type{Repr: "*idealIntType", Value: "IdealIntValue", Native: "*big.Int", As: "asIdealInt", IsIdeal: true} floatType = &Type{Repr: "*floatType", Value: "FloatValue", Native: "float64", As: "asFloat", Sizes: []Size{Size{32, "float32"}, Size{64, "float64"}, Size{0, "float"}}, } - idealFloatType = &Type{Repr: "*idealFloatType", Value: "IdealFloatValue", Native: "*bignum.Rational", As: "asIdealFloat", IsIdeal: true} + idealFloatType = &Type{Repr: "*idealFloatType", Value: "IdealFloatValue", Native: "*big.Rat", As: "asIdealFloat", IsIdeal: true} stringType = &Type{Repr: "*stringType", Value: "StringValue", Native: "string", As: "asString"} arrayType = &Type{Repr: "*ArrayType", Value: "ArrayValue", Native: "ArrayValue", As: "asArray", HasAssign: true} structType = &Type{Repr: "*StructType", Value: "StructValue", Native: "StructValue", As: "asStruct", HasAssign: true} @@ -93,33 +93,33 @@ var ( ) var unOps = []Op{ - Op{Name: "Neg", Expr: "-v", ConstExpr: "v.Neg()", Types: numbers}, + Op{Name: "Neg", Expr: "-v", ConstExpr: "val.Neg(val)", Types: numbers}, Op{Name: "Not", Expr: "!v", Types: bools}, - Op{Name: "Xor", Expr: "^v", ConstExpr: "v.Neg().Sub(bignum.Int(1))", Types: integers}, + Op{Name: "Xor", Expr: "^v", ConstExpr: "val.Not(val)", Types: integers}, } var binOps = []Op{ - Op{Name: "Add", Expr: "l + r", ConstExpr: "l.Add(r)", Types: addable}, - Op{Name: "Sub", Expr: "l - r", ConstExpr: "l.Sub(r)", Types: numbers}, - Op{Name: "Mul", Expr: "l * r", ConstExpr: "l.Mul(r)", Types: numbers}, + Op{Name: "Add", Expr: "l + r", ConstExpr: "l.Add(l, r)", Types: addable}, + Op{Name: "Sub", Expr: "l - r", ConstExpr: "l.Sub(l, r)", Types: numbers}, + Op{Name: "Mul", Expr: "l * r", ConstExpr: "l.Mul(l, r)", Types: numbers}, Op{Name: "Quo", Body: "if r == 0 { t.Abort(DivByZeroError{}) }; ret = l / r", - ConstExpr: "l.Quo(r)", + ConstExpr: "l.Quo(l, r)", Types: numbers, }, Op{Name: "Rem", Body: "if r == 0 { t.Abort(DivByZeroError{}) }; ret = l % r", - ConstExpr: "l.Rem(r)", + ConstExpr: "l.Rem(l, r)", Types: integers, }, - Op{Name: "And", Expr: "l & r", ConstExpr: "l.And(r)", Types: integers}, - Op{Name: "Or", Expr: "l | r", ConstExpr: "l.Or(r)", Types: integers}, - Op{Name: "Xor", Expr: "l ^ r", ConstExpr: "l.Xor(r)", Types: integers}, - Op{Name: "AndNot", Expr: "l &^ r", ConstExpr: "l.AndNot(r)", Types: integers}, - Op{Name: "Shl", Expr: "l << r", ConstExpr: "l.Shl(uint(r.Value()))", + Op{Name: "And", Expr: "l & r", ConstExpr: "l.And(l, r)", Types: integers}, + Op{Name: "Or", Expr: "l | r", ConstExpr: "l.Or(l, r)", Types: integers}, + Op{Name: "Xor", Expr: "l ^ r", ConstExpr: "l.Xor(l, r)", Types: integers}, + Op{Name: "AndNot", Expr: "l &^ r", ConstExpr: "l.AndNot(l, r)", Types: integers}, + Op{Name: "Shl", Expr: "l << r", ConstExpr: "l.Lsh(l, uint(r.Value()))", AsRightName: "asUint", Types: shiftable, }, - Op{Name: "Shr", Expr: "l >> r", ConstExpr: "l.Shr(uint(r.Value()))", + Op{Name: "Shr", Expr: "l >> r", ConstExpr: "new(big.Int).Rsh(l, uint(r.Value()))", AsRightName: "asUint", Types: shiftable, }, Op{Name: "Lss", Expr: "l < r", ConstExpr: "l.Cmp(r) < 0", ReturnType: "bool", Types: addable}, @@ -149,8 +149,8 @@ const templateStr = ` package eval import ( - "bignum"; - "log"; + "big" + "log" ) /* @@ -184,9 +184,9 @@ func (a *expr) asInterface() (func(*Thread) interface{}) { «.end» «.end» default: - log.Crashf("unexpected expression node type %T at %v", a.eval, a.pos); + log.Crashf("unexpected expression node type %T at %v", a.eval, a.pos) } - panic("fail"); + panic("fail") } /* @@ -198,19 +198,19 @@ func (a *expr) genConstant(v Value) { «.repeated section Types» case «Repr»: «.section IsIdeal» - val := v.(«Value»).Get(); + val := v.(«Value»).Get() a.eval = func() «Native» { return val } «.or» a.eval = func(t *Thread) «Native» { return v.(«Value»).Get(t) } «.end» «.end» default: - log.Crashf("unexpected constant type %v at %v", a.t, a.pos); + log.Crashf("unexpected constant type %v at %v", a.t, a.pos) } } func (a *expr) genIdentOp(level, index int) { - a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) }; + a.evalAddr = func(t *Thread) Value { return t.f.Get(level, index) } switch a.t.lit().(type) { «.repeated section Types» «.section IsIdeal» @@ -220,12 +220,12 @@ func (a *expr) genIdentOp(level, index int) { «.end» «.end» default: - log.Crashf("unexpected identifier type %v at %v", a.t, a.pos); + log.Crashf("unexpected identifier type %v at %v", a.t, a.pos) } } func (a *expr) genFuncCall(call func(t *Thread) []Value) { - a.exec = func(t *Thread) { call(t)}; + a.exec = func(t *Thread) { call(t)} switch a.t.lit().(type) { «.repeated section Types» «.section IsIdeal» @@ -237,12 +237,12 @@ func (a *expr) genFuncCall(call func(t *Thread) []Value) { case *MultiType: a.eval = func(t *Thread) []Value { return call(t) } default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected result type %v at %v", a.t, a.pos) } } func (a *expr) genValue(vf func(*Thread) Value) { - a.evalAddr = vf; + a.evalAddr = vf switch a.t.lit().(type) { «.repeated section Types» «.section IsIdeal» @@ -252,7 +252,7 @@ func (a *expr) genValue(vf func(*Thread) Value) { «.end» «.end» default: - log.Crashf("unexpected result type %v at %v", a.t, a.pos); + log.Crashf("unexpected result type %v at %v", a.t, a.pos) } } @@ -262,29 +262,29 @@ func (a *expr) genUnaryOp«Name»(v *expr) { «.repeated section Types» case «Repr»: «.section IsIdeal» - v := v.«As»()(); - val := «ConstExpr»; + val := v.«As»()() + «ConstExpr» a.eval = func() «Native» { return val } «.or» - vf := v.«As»(); + vf := v.«As»() a.eval = func(t *Thread) «Native» { v := vf(t); return «Expr» } «.end» «.end» default: - log.Crashf("unexpected type %v at %v", a.t, a.pos); + log.Crashf("unexpected type %v at %v", a.t, a.pos) } } «.end» func (a *expr) genBinOpLogAnd(l, r *expr) { - lf := l.asBool(); - rf := r.asBool(); + lf := l.asBool() + rf := r.asBool() a.eval = func(t *Thread) bool { return lf(t) && rf(t) } } func (a *expr) genBinOpLogOr(l, r *expr) { - lf := l.asBool(); - rf := r.asBool(); + lf := l.asBool() + rf := r.asBool() a.eval = func(t *Thread) bool { return lf(t) || rf(t) } } @@ -294,20 +294,20 @@ func (a *expr) genBinOp«Name»(l, r *expr) { «.repeated section Types» case «Repr»: «.section IsIdeal» - l := l.«As»()(); - r := r.«As»()(); - val := «ConstExpr»; + l := l.«As»()() + r := r.«As»()() + val := «ConstExpr» «.section ReturnType» a.eval = func(t *Thread) «ReturnType» { return val } «.or» a.eval = func() «Native» { return val } «.end» «.or» - lf := l.«As»(); - rf := r.«.section AsRightName»«@»«.or»«As»«.end»(); + lf := l.«As»() + rf := r.«.section AsRightName»«@»«.or»«As»«.end»() «.section ReturnType» a.eval = func(t *Thread) «@» { - l, r := lf(t), rf(t); + l, r := lf(t), rf(t) return «Expr» } «.or» @@ -316,22 +316,22 @@ func (a *expr) genBinOp«Name»(l, r *expr) { «.repeated section @» case «Bits»: a.eval = func(t *Thread) «Native» { - l, r := lf(t), rf(t); - var ret «Native»; + l, r := lf(t), rf(t) + var ret «Native» «.section Body» - «Body»; + «Body» «.or» - ret = «Expr»; + ret = «Expr» «.end» return «Native»(«Sized»(ret)) } «.end» default: - log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos); + log.Crashf("unexpected size %d in type %v at %v", t.Bits, t, a.pos) } «.or» a.eval = func(t *Thread) «Native» { - l, r := lf(t), rf(t); + l, r := lf(t), rf(t) return «Expr» } «.end» @@ -339,7 +339,7 @@ func (a *expr) genBinOp«Name»(l, r *expr) { «.end» «.end» default: - log.Crashf("unexpected type %v at %v", l.t, a.pos); + log.Crashf("unexpected type %v at %v", l.t, a.pos) } } @@ -350,14 +350,14 @@ func genAssign(lt Type, r *expr) (func(lv Value, t *Thread)) { «.section IsIdeal» «.or» case «Repr»: - rf := r.«As»(); + rf := r.«As»() return func(lv Value, t *Thread) { «.section HasAssign»lv.Assign(t, rf(t))«.or»lv.(«Value»).Set(t, rf(t))«.end» } «.end» «.end» default: - log.Crashf("unexpected left operand type %v at %v", lt, r.pos); + log.Crashf("unexpected left operand type %v at %v", lt, r.pos) } - panic("fail"); + panic("fail") } ` diff --git a/src/pkg/exp/eval/stmt.go b/src/pkg/exp/eval/stmt.go index bcd81f04cb..24e9515625 100644 --- a/src/pkg/exp/eval/stmt.go +++ b/src/pkg/exp/eval/stmt.go @@ -5,7 +5,7 @@ package eval import ( - "exp/bignum" + "big" "log" "go/ast" "go/token" @@ -493,7 +493,7 @@ func (a *stmtCompiler) compileIncDecStmt(s *ast.IncDecStmt) { one := l.newExpr(IdealIntType, "constant") one.pos = s.Pos() - one.eval = func() *bignum.Integer { return bignum.Int(1) } + one.eval = func() *big.Int { return big.NewInt(1) } binop := l.compileBinaryExpr(op, l, one) if binop == nil { diff --git a/src/pkg/exp/eval/type.go b/src/pkg/exp/eval/type.go index b0fbe21565..86924494f8 100644 --- a/src/pkg/exp/eval/type.go +++ b/src/pkg/exp/eval/type.go @@ -5,7 +5,7 @@ package eval import ( - "exp/bignum" + "big" "go/ast" "go/token" "log" @@ -60,9 +60,9 @@ type Type interface { type BoundedType interface { Type // minVal returns the smallest value of this type. - minVal() *bignum.Rational + minVal() *big.Rat // maxVal returns the largest value of this type. - maxVal() *bignum.Rational + maxVal() *big.Rat } var universePos = token.Position{"<universe>", 0, 0, 0} @@ -234,9 +234,9 @@ func (t *uintType) Zero() Value { panic("unexpected uint bit count") } -func (t *uintType) minVal() *bignum.Rational { return bignum.Rat(0, 1) } +func (t *uintType) minVal() *big.Rat { return big.NewRat(0, 1) } -func (t *uintType) maxVal() *bignum.Rational { +func (t *uintType) maxVal() *big.Rat { bits := t.Bits if bits == 0 { if t.Ptr { @@ -245,7 +245,10 @@ func (t *uintType) maxVal() *bignum.Rational { bits = uint(8 * unsafe.Sizeof(uint(0))) } } - return bignum.MakeRat(bignum.Int(1).Shl(bits).Add(bignum.Int(-1)), bignum.Nat(1)) + numer := big.NewInt(1) + numer.Lsh(numer, bits) + numer.Sub(numer, idealOne) + return new(big.Rat).SetInt(numer) } /* @@ -307,20 +310,25 @@ func (t *intType) Zero() Value { panic("unexpected int bit count") } -func (t *intType) minVal() *bignum.Rational { +func (t *intType) minVal() *big.Rat { bits := t.Bits if bits == 0 { bits = uint(8 * unsafe.Sizeof(int(0))) } - return bignum.MakeRat(bignum.Int(-1).Shl(bits-1), bignum.Nat(1)) + numer := big.NewInt(-1) + numer.Lsh(numer, bits-1) + return new(big.Rat).SetInt(numer) } -func (t *intType) maxVal() *bignum.Rational { +func (t *intType) maxVal() *big.Rat { bits := t.Bits if bits == 0 { bits = uint(8 * unsafe.Sizeof(int(0))) } - return bignum.MakeRat(bignum.Int(1).Shl(bits-1).Add(bignum.Int(-1)), bignum.Nat(1)) + numer := big.NewInt(1) + numer.Lsh(numer, bits-1) + numer.Sub(numer, idealOne) + return new(big.Rat).SetInt(numer) } /* @@ -346,7 +354,7 @@ func (t *idealIntType) isIdeal() bool { return true } func (t *idealIntType) String() string { return "ideal integer" } -func (t *idealIntType) Zero() Value { return &idealIntV{bignum.Int(0)} } +func (t *idealIntType) Zero() Value { return &idealIntV{idealZero} } /* * Float @@ -393,12 +401,12 @@ func (t *floatType) Zero() Value { panic("unexpected float bit count") } -var maxFloat32Val = bignum.MakeRat(bignum.Int(0xffffff).Shl(127-23), bignum.Nat(1)) -var maxFloat64Val = bignum.MakeRat(bignum.Int(0x1fffffffffffff).Shl(1023-52), bignum.Nat(1)) -var minFloat32Val = maxFloat32Val.Neg() -var minFloat64Val = maxFloat64Val.Neg() +var maxFloat32Val *big.Rat +var maxFloat64Val *big.Rat +var minFloat32Val *big.Rat +var minFloat64Val *big.Rat -func (t *floatType) minVal() *bignum.Rational { +func (t *floatType) minVal() *big.Rat { bits := t.Bits if bits == 0 { bits = uint(8 * unsafe.Sizeof(float(0))) @@ -413,7 +421,7 @@ func (t *floatType) minVal() *bignum.Rational { panic("unreachable") } -func (t *floatType) maxVal() *bignum.Rational { +func (t *floatType) maxVal() *big.Rat { bits := t.Bits if bits == 0 { bits = uint(8 * unsafe.Sizeof(float(0))) @@ -451,7 +459,7 @@ func (t *idealFloatType) isIdeal() bool { return true } func (t *idealFloatType) String() string { return "ideal float" } -func (t *idealFloatType) Zero() Value { return &idealFloatV{bignum.Rat(1, 0)} } +func (t *idealFloatType) Zero() Value { return &idealFloatV{big.NewRat(0, 1)} } /* * String @@ -1221,6 +1229,15 @@ func (t *MultiType) Zero() Value { */ func init() { + numer := big.NewInt(0xffffff) + numer.Lsh(numer, 127-23) + maxFloat32Val = new(big.Rat).SetInt(numer) + numer.SetInt64(0x1fffffffffffff) + numer.Lsh(numer, 1023-52) + maxFloat64Val = new(big.Rat).SetInt(numer) + minFloat32Val = new(big.Rat).Neg(maxFloat32Val) + minFloat64Val = new(big.Rat).Neg(maxFloat64Val) + // To avoid portability issues all numeric types are distinct // except byte, which is an alias for uint8. diff --git a/src/pkg/exp/eval/util.go b/src/pkg/exp/eval/util.go deleted file mode 100644 index ffe13e1702..0000000000 --- a/src/pkg/exp/eval/util.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package eval - -import ( - "exp/bignum" -) - -// TODO(austin): Maybe add to bignum in more general form -func ratToString(rat *bignum.Rational) string { - n, dnat := rat.Value() - d := bignum.MakeInt(false, dnat) - w, frac := n.QuoRem(d) - out := w.String() - if frac.IsZero() { - return out - } - - r := frac.Abs() - r = r.Mul(bignum.Nat(1e6)) - dec, tail := r.DivMod(dnat) - // Round last digit - if tail.Cmp(dnat.Div(bignum.Nat(2))) >= 0 { - dec = dec.Add(bignum.Nat(1)) - } - // Strip zeros - ten := bignum.Nat(10) - for !dec.IsZero() { - dec2, r2 := dec.DivMod(ten) - if !r2.IsZero() { - break - } - dec = dec2 - } - out += "." + dec.String() - return out -} diff --git a/src/pkg/exp/eval/value.go b/src/pkg/exp/eval/value.go index dce4bfcf3d..cace2fd37b 100644 --- a/src/pkg/exp/eval/value.go +++ b/src/pkg/exp/eval/value.go @@ -5,7 +5,7 @@ package eval import ( - "exp/bignum" + "big" "fmt" ) @@ -40,7 +40,7 @@ type IntValue interface { // because ideals are not l-values. type IdealIntValue interface { Value - Get() *bignum.Integer + Get() *big.Int } type FloatValue interface { @@ -51,7 +51,7 @@ type FloatValue interface { type IdealFloatValue interface { Value - Get() *bignum.Rational + Get() *big.Rat } type StringValue interface { @@ -272,7 +272,7 @@ func (v *intV) Set(t *Thread, x int64) { *v = intV(x) } */ type idealIntV struct { - V *bignum.Integer + V *big.Int } func (v *idealIntV) String() string { return v.V.String() } @@ -281,7 +281,7 @@ func (v *idealIntV) Assign(t *Thread, o Value) { v.V = o.(IdealIntValue).Get() } -func (v *idealIntV) Get() *bignum.Integer { return v.V } +func (v *idealIntV) Get() *big.Int { return v.V } /* * Float @@ -322,16 +322,16 @@ func (v *floatV) Set(t *Thread, x float64) { *v = floatV(x) } */ type idealFloatV struct { - V *bignum.Rational + V *big.Rat } -func (v *idealFloatV) String() string { return ratToString(v.V) } +func (v *idealFloatV) String() string { return v.V.FloatString(6) } func (v *idealFloatV) Assign(t *Thread, o Value) { v.V = o.(IdealFloatValue).Get() } -func (v *idealFloatV) Get() *bignum.Rational { return v.V } +func (v *idealFloatV) Get() *big.Rat { return v.V } /* * String @@ -586,8 +586,6 @@ func (v multiV) Assign(t *Thread, o Value) { * Universal constants */ -// TODO(austin) Nothing complains if I accidentally define init with -// arguments. Is this intentional? func init() { s := universe |