diff --git a/interpreter/value_int.go b/interpreter/value_int.go index 3fab5bfba..cc35e31e4 100644 --- a/interpreter/value_int.go +++ b/interpreter/value_int.go @@ -168,7 +168,7 @@ func (v IntValue) MeteredString(interpreter *Interpreter, _ SeenReferences, _ Lo func (v IntValue) Negate(context NumberValueArithmeticContext, _ LocationRange) NumberValue { return IntValue{ - IntValue: v.IntValue.Negate(context).(values.IntValue), + IntValue: v.IntValue.Negate(context), } } @@ -186,7 +186,7 @@ func (v IntValue) Plus(context NumberValueArithmeticContext, other NumberValue, if err != nil { panic(err) } - return IntValue{IntValue: result.(values.IntValue)} + return IntValue{IntValue: result} } func (v IntValue) SaturatingPlus(context NumberValueArithmeticContext, other NumberValue, locationRange LocationRange) NumberValue { @@ -221,7 +221,7 @@ func (v IntValue) Minus(context NumberValueArithmeticContext, other NumberValue, panic(err) } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -258,7 +258,7 @@ func (v IntValue) Mod(context NumberValueArithmeticContext, other NumberValue, l } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -278,7 +278,7 @@ func (v IntValue) Mul(context NumberValueArithmeticContext, other NumberValue, l panic(err) } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -315,7 +315,7 @@ func (v IntValue) Div(context NumberValueArithmeticContext, other NumberValue, l } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -456,7 +456,7 @@ func (v IntValue) BitwiseOr(context ValueStaticTypeContext, other IntegerValue, } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -477,7 +477,7 @@ func (v IntValue) BitwiseXor(context ValueStaticTypeContext, other IntegerValue, } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -498,7 +498,7 @@ func (v IntValue) BitwiseAnd(context ValueStaticTypeContext, other IntegerValue, } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -519,7 +519,7 @@ func (v IntValue) BitwiseLeftShift(context ValueStaticTypeContext, other Integer } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } @@ -540,7 +540,7 @@ func (v IntValue) BitwiseRightShift(context ValueStaticTypeContext, other Intege } return IntValue{ - IntValue: result.(values.IntValue), + IntValue: result, } } diff --git a/values/value_int.go b/values/value_int.go index 253f521d2..327918aba 100644 --- a/values/value_int.go +++ b/values/value_int.go @@ -69,8 +69,8 @@ func NewUnmeteredIntValueFromBigInt(value *big.Int) IntValue { var _ Value = IntValue{} var _ EquatableValue = IntValue{} var _ ComparableValue = IntValue{} -var _ NumberValue = IntValue{} -var _ IntegerValue = IntValue{} +var _ NumberValue[IntValue] = IntValue{} +var _ IntegerValue[IntValue] = IntValue{} var _ atree.Storable = IntValue{} var _ atree.Value = IntValue{} @@ -80,7 +80,7 @@ func (v IntValue) String() string { return format.BigInt(v.BigInt) } -func (v IntValue) Negate(gauge common.MemoryGauge) NumberValue { +func (v IntValue) Negate(gauge common.MemoryGauge) IntValue { return NewIntValueFromBigInt( gauge, common.NewNegateBigIntMemoryUsage(v.BigInt), @@ -90,109 +90,84 @@ func (v IntValue) Negate(gauge common.MemoryGauge) NumberValue { ) } -func (v IntValue) Plus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) Plus(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return NewIntValueFromBigInt( gauge, - common.NewPlusBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewPlusBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Add(v.BigInt, o.BigInt) + return res.Add(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) SaturatingPlus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { +func (v IntValue) SaturatingPlus(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return v.Plus(gauge, other) } -func (v IntValue) Minus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) Minus(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return NewIntValueFromBigInt( gauge, - common.NewMinusBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewMinusBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Sub(v.BigInt, o.BigInt) + return res.Sub(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) SaturatingMinus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { +func (v IntValue) SaturatingMinus(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return v.Minus(gauge, other) } -func (v IntValue) Mod(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) Mod(gauge common.MemoryGauge, other IntValue) (IntValue, error) { // INT33-C - if o.BigInt.Sign() == 0 { - return nil, DivisionByZeroError{} + if other.BigInt.Sign() == 0 { + return IntValue{}, DivisionByZeroError{} } return NewIntValueFromBigInt( gauge, - common.NewModBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewModBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Rem(v.BigInt, o.BigInt) + return res.Rem(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) Mul(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) Mul(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return NewIntValueFromBigInt( gauge, - common.NewMulBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewMulBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Mul(v.BigInt, o.BigInt) + return res.Mul(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) SaturatingMul(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { +func (v IntValue) SaturatingMul(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return v.Mul(gauge, other) } -func (v IntValue) Div(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) Div(gauge common.MemoryGauge, other IntValue) (IntValue, error) { // INT33-C - if o.BigInt.Sign() == 0 { - return nil, DivisionByZeroError{} + if other.BigInt.Sign() == 0 { + return IntValue{}, DivisionByZeroError{} } return NewIntValueFromBigInt( gauge, - common.NewDivBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewDivBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Div(v.BigInt, o.BigInt) + return res.Div(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) SaturatingDiv(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) { +func (v IntValue) SaturatingDiv(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return v.Div(gauge, other) } @@ -246,98 +221,73 @@ func (v IntValue) Equal(other Value) BoolValue { return cmp == 0 } -func (v IntValue) BitwiseOr(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) BitwiseOr(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return NewIntValueFromBigInt( gauge, - common.NewBitwiseOrBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewBitwiseOrBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Or(v.BigInt, o.BigInt) + return res.Or(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) BitwiseXor(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) BitwiseXor(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return NewIntValueFromBigInt( gauge, - common.NewBitwiseXorBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewBitwiseXorBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Xor(v.BigInt, o.BigInt) + return res.Xor(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) BitwiseAnd(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - +func (v IntValue) BitwiseAnd(gauge common.MemoryGauge, other IntValue) (IntValue, error) { return NewIntValueFromBigInt( gauge, - common.NewBitwiseAndBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewBitwiseAndBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.And(v.BigInt, o.BigInt) + return res.And(v.BigInt, other.BigInt) }, ), nil } -func (v IntValue) BitwiseLeftShift(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - - if o.BigInt.Sign() < 0 { - return nil, NegativeShiftError{} +func (v IntValue) BitwiseLeftShift(gauge common.MemoryGauge, other IntValue) (IntValue, error) { + if other.BigInt.Sign() < 0 { + return IntValue{}, NegativeShiftError{} } - if !o.BigInt.IsUint64() { - return nil, OverflowError{} + if !other.BigInt.IsUint64() { + return IntValue{}, OverflowError{} } return NewIntValueFromBigInt( gauge, - common.NewBitwiseLeftShiftBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewBitwiseLeftShiftBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Lsh(v.BigInt, uint(o.BigInt.Uint64())) + return res.Lsh(v.BigInt, uint(other.BigInt.Uint64())) }, ), nil } -func (v IntValue) BitwiseRightShift(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) { - o, ok := other.(IntValue) - if !ok { - return nil, InvalidOperandsError{} - } - - if o.BigInt.Sign() < 0 { - return nil, NegativeShiftError{} +func (v IntValue) BitwiseRightShift(gauge common.MemoryGauge, other IntValue) (IntValue, error) { + if other.BigInt.Sign() < 0 { + return IntValue{}, NegativeShiftError{} } - if !o.BigInt.IsUint64() { - return nil, OverflowError{} + if !other.BigInt.IsUint64() { + return IntValue{}, OverflowError{} } return NewIntValueFromBigInt( gauge, - common.NewBitwiseRightShiftBigIntMemoryUsage(v.BigInt, o.BigInt), + common.NewBitwiseRightShiftBigIntMemoryUsage(v.BigInt, other.BigInt), func() *big.Int { res := new(big.Int) - return res.Rsh(v.BigInt, uint(o.BigInt.Uint64())) + return res.Rsh(v.BigInt, uint(other.BigInt.Uint64())) }, ), nil } diff --git a/values/value_integer.go b/values/value_integer.go index 4819013d6..ac531ea9f 100644 --- a/values/value_integer.go +++ b/values/value_integer.go @@ -20,11 +20,11 @@ package values import "github.com/onflow/cadence/common" -type IntegerValue interface { - NumberValue - BitwiseOr(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) - BitwiseXor(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) - BitwiseAnd(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) - BitwiseLeftShift(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) - BitwiseRightShift(gauge common.MemoryGauge, other IntegerValue) (IntegerValue, error) +type IntegerValue[T Value] interface { + NumberValue[T] + BitwiseOr(gauge common.MemoryGauge, other T) (T, error) + BitwiseXor(gauge common.MemoryGauge, other T) (T, error) + BitwiseAnd(gauge common.MemoryGauge, other T) (T, error) + BitwiseLeftShift(gauge common.MemoryGauge, other T) (T, error) + BitwiseRightShift(gauge common.MemoryGauge, other T) (T, error) } diff --git a/values/value_number.go b/values/value_number.go index f52c0f9b1..76ca86174 100644 --- a/values/value_number.go +++ b/values/value_number.go @@ -20,18 +20,18 @@ package values import "github.com/onflow/cadence/common" -type NumberValue interface { +type NumberValue[T Value] interface { ComparableValue ToInt() (int, error) - Negate(gauge common.MemoryGauge) NumberValue - Plus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - SaturatingPlus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - Minus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - SaturatingMinus(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - Mod(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - Mul(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - SaturatingMul(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - Div(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) - SaturatingDiv(gauge common.MemoryGauge, other NumberValue) (NumberValue, error) + Negate(gauge common.MemoryGauge) T + Plus(gauge common.MemoryGauge, other T) (T, error) + SaturatingPlus(gauge common.MemoryGauge, other T) (T, error) + Minus(gauge common.MemoryGauge, other T) (T, error) + SaturatingMinus(gauge common.MemoryGauge, other T) (T, error) + Mod(gauge common.MemoryGauge, other T) (T, error) + Mul(gauge common.MemoryGauge, other T) (T, error) + SaturatingMul(gauge common.MemoryGauge, other T) (T, error) + Div(gauge common.MemoryGauge, other T) (T, error) + SaturatingDiv(gauge common.MemoryGauge, other T) (T, error) ToBigEndianBytes() []byte }