"go/token"
"go/types"
"io"
+ "math/big"
"sort"
)
val = constant.MakeString(r.string())
case types.IsInteger:
- val = r.mpint(b)
+ var x big.Int
+ r.mpint(&x, b)
+ val = constant.Make(&x)
case types.IsFloat:
val = r.mpfloat(b)
return
}
-func (r *importReader) mpint(b *types.Basic) constant.Value {
- signed, maxBytes := intSize(b)
+func (r *importReader) mpint(x *big.Int, typ *types.Basic) {
+ signed, maxBytes := intSize(typ)
maxSmall := 256 - maxBytes
if signed {
v = ^v
}
}
- return constant.MakeInt64(v)
+ x.SetInt64(v)
+ return
}
v := -n
if v < 1 || uint(v) > maxBytes {
errorf("weird decoding: %v, %v => %v", n, signed, v)
}
-
- buf := make([]byte, v)
- io.ReadFull(&r.declReader, buf)
-
- // convert to little endian
- // TODO(gri) go/constant should have a more direct conversion function
- // (e.g., once it supports a big.Float based implementation)
- for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
- buf[i], buf[j] = buf[j], buf[i]
- }
-
- x := constant.MakeFromBytes(buf)
+ b := make([]byte, v)
+ io.ReadFull(&r.declReader, b)
+ x.SetBytes(b)
if signed && n&1 != 0 {
- x = constant.UnaryOp(token.SUB, x, 0)
+ x.Neg(x)
}
- return x
}
-func (r *importReader) mpfloat(b *types.Basic) constant.Value {
- x := r.mpint(b)
- if constant.Sign(x) == 0 {
- return x
- }
-
- exp := r.int64()
- switch {
- case exp > 0:
- x = constant.Shift(x, token.SHL, uint(exp))
- case exp < 0:
- d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
- x = constant.BinaryOp(x, token.QUO, d)
+func (r *importReader) mpfloat(typ *types.Basic) constant.Value {
+ var mant big.Int
+ r.mpint(&mant, typ)
+ var f big.Float
+ f.SetInt(&mant)
+ if f.Sign() != 0 {
+ f.SetMantExp(&f, int(r.int64()))
}
- return x
+ return constant.Make(&f)
}
func (r *importReader) ident() string {