Skip to content

Commit

Permalink
Merge branch 'i1006' of github.com:ScorexFoundation/sigmastate-interp…
Browse files Browse the repository at this point in the history
…reter into i554
  • Loading branch information
kushti committed Sep 12, 2024
2 parents 9a10d17 + 297265f commit 89d4477
Show file tree
Hide file tree
Showing 7 changed files with 1,088 additions and 182 deletions.
42 changes: 20 additions & 22 deletions data/shared/src/main/scala/sigma/ast/methods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,13 @@ trait SNumericTypeMethods extends MonoTypeMethods {

private val subst = Map(tNum -> this.ownerType)

private val v5Methods = {
val v5Methods = {
SNumericTypeMethods.v5Methods.map { m =>
m.copy(stype = applySubst(m.stype, subst).asFunc)
}
}

private val v6Methods = {
val v6Methods = {
SNumericTypeMethods.v6Methods.map { m =>
m.copy(
objType = this, // associate the method with the concrete numeric type
Expand Down Expand Up @@ -314,10 +314,7 @@ object SNumericTypeMethods extends MethodsContainer {
case SBigIntMethods => BigIntIsExactIntegral.bitwiseInverse(obj.asInstanceOf[BigInt])
}
})
.withInfo(PropertyCall,
""" Returns a big-endian representation of this numeric in a collection of Booleans.
| Each boolean corresponds to one bit.
""".stripMargin)
.withInfo(PropertyCall, desc = "Returns bitwise inverse of this numeric. ")

val BitwiseOrMethod: SMethod = SMethod(
this, "bitwiseOr", SFunc(Array(tNum, tNum), tNum), 9, BitwiseInverse_CostKind)
Expand All @@ -331,10 +328,9 @@ object SNumericTypeMethods extends MethodsContainer {
case SBigIntMethods => BigIntIsExactIntegral.bitwiseOr(obj.asInstanceOf[BigInt], other.head.asInstanceOf[BigInt])
}
})
.withInfo(PropertyCall,
""" Returns a big-endian representation of this numeric in a collection of Booleans.
| Each boolean corresponds to one bit.
""".stripMargin)
.withInfo(MethodCall,
""" Returns bitwise or of this numeric and provided one. """.stripMargin,
ArgInfo("that", "A numeric value to calculate or with."))

val BitwiseAndMethod: SMethod = SMethod(
this, "bitwiseAnd", SFunc(Array(tNum, tNum), tNum), 10, BitwiseInverse_CostKind)
Expand All @@ -348,10 +344,9 @@ object SNumericTypeMethods extends MethodsContainer {
case SBigIntMethods => BigIntIsExactIntegral.bitwiseAnd(obj.asInstanceOf[BigInt], other.head.asInstanceOf[BigInt])
}
})
.withInfo(PropertyCall,
""" Returns a big-endian representation of this numeric in a collection of Booleans.
| Each boolean corresponds to one bit.
""".stripMargin)
.withInfo(MethodCall,
""" Returns bitwise and of this numeric and provided one. """.stripMargin,
ArgInfo("that", "A numeric value to calculate and with."))

val BitwiseXorMethod: SMethod = SMethod(
this, "bitwiseXor", SFunc(Array(tNum, tNum), tNum), 11, BitwiseInverse_CostKind)
Expand All @@ -365,10 +360,9 @@ object SNumericTypeMethods extends MethodsContainer {
case SBigIntMethods => BigIntIsExactIntegral.bitwiseXor(obj.asInstanceOf[BigInt], other.head.asInstanceOf[BigInt])
}
})
.withInfo(PropertyCall,
""" Returns a big-endian representation of this numeric in a collection of Booleans.
| Each boolean corresponds to one bit.
""".stripMargin)
.withInfo(MethodCall,
""" Returns bitwise xor of this numeric and provided one. """.stripMargin,
ArgInfo("that", "A numeric value to calculate xor with."))

val ShiftLeftMethod: SMethod = SMethod(
this, "shiftLeft", SFunc(Array(tNum, SInt), tNum), 12, BitwiseInverse_CostKind)
Expand All @@ -382,10 +376,12 @@ object SNumericTypeMethods extends MethodsContainer {
case SBigIntMethods => BigIntIsExactIntegral.shiftLeft(obj.asInstanceOf[BigInt], other.head.asInstanceOf[Int])
}
})
.withInfo(PropertyCall,
.withInfo(MethodCall,
""" Returns a big-endian representation of this numeric in a collection of Booleans.
| Each boolean corresponds to one bit.
""".stripMargin)
""".stripMargin,
ArgInfo("bits", "Number of bit to shift to the left. Note, that bits value must be non-negative and less than " +
"the size of the number in bits (e.g. 64 for Long, 256 for BigInt)"))

val ShiftRightMethod: SMethod = SMethod(
this, "shiftRight", SFunc(Array(tNum, SInt), tNum), 13, BitwiseInverse_CostKind)
Expand All @@ -399,10 +395,12 @@ object SNumericTypeMethods extends MethodsContainer {
case SBigIntMethods => BigIntIsExactIntegral.shiftRight(obj.asInstanceOf[BigInt], other.head.asInstanceOf[Int])
}
})
.withInfo(PropertyCall,
.withInfo(MethodCall,
""" Returns a big-endian representation of this numeric in a collection of Booleans.
| Each boolean corresponds to one bit.
""".stripMargin)
""".stripMargin,
ArgInfo("bits", "Number of bit to shift to the right. Note, that bits value must be non-negative and less than " +
"the size of the number in bits (e.g. 64 for Long, 256 for BigInt)"))

lazy val v5Methods = Array(
ToByteMethod, // see Downcast
Expand Down
18 changes: 15 additions & 3 deletions data/shared/src/main/scala/sigma/data/BigIntegerOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,21 @@ object NumericOps {

override def bitwiseXor(x: BigInt, y: BigInt): BigInt = x.xor(y)

override def shiftLeft(x: BigInt, y: Int): BigInt = x.shiftLeft(y)

override def shiftRight(x: BigInt, y: Int): BigInt = x.shiftRight(y)
override def shiftLeft(x: BigInt, bits: Int): BigInt = {
if (bits < 0 || bits >= 256) {
throw new IllegalArgumentException(s"Wrong argument in BigInt.shiftRight: bits < 0 || bits >= 256 ($bits)")
} else {
x.shiftLeft(bits)
}
}

override def shiftRight(x: BigInt, bits: Int): BigInt = {
if (bits < 0 || bits >= 256) {
throw new IllegalArgumentException(s"Wrong argument in BigInt.shiftRight: bits < 0 || bits >= 256 ($bits)")
} else {
x.shiftRight(bits)
}
}
}

/** The instance of [[scalan.ExactOrdering]] typeclass for [[BigInt]]. */
Expand Down
68 changes: 60 additions & 8 deletions data/shared/src/main/scala/sigma/data/ExactIntegral.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,20 @@ object ExactIntegral {
override def bitwiseOr(x: Byte, y: Byte): Byte = (x | y).toByte
override def bitwiseAnd(x: Byte, y: Byte): Byte = (x & y).toByte
override def bitwiseXor(x: Byte, y: Byte): Byte = (x ^ y).toByte
override def shiftLeft(x: Byte, bits: Int): Byte = (x << bits).toByte
override def shiftRight(x: Byte, bits: Int): Byte = (x >> bits).toByte
override def shiftLeft(x: Byte, bits: Int): Byte = {
if (bits < 0 || bits >= 8) {
throw new IllegalArgumentException(s"Wrong argument in Byte.shiftRight: bits < 0 || bits >= 8 ($bits)")
} else {
(x << bits).toByte
}
}
override def shiftRight(x: Byte, bits: Int): Byte = {
if (bits < 0 || bits >= 8) {
throw new IllegalArgumentException(s"Wrong argument in Byte.shiftRight: bits < 0 || bits >= 8 ($bits)")
} else {
(x >> bits).toByte
}
}
}

implicit object ShortIsExactIntegral extends ExactIntegral[Short] {
Expand All @@ -58,8 +70,20 @@ object ExactIntegral {
override def bitwiseOr(x: Short, y: Short): Short = (x | y).toShort
override def bitwiseAnd(x: Short, y: Short): Short = (x & y).toShort
override def bitwiseXor(x: Short, y: Short): Short = (x ^ y).toShort
override def shiftLeft(x: Short, y: Int): Short = (x << y).toShort
override def shiftRight(x: Short, bits: Int): Short = (x >> bits).toShort
override def shiftLeft(x: Short, bits: Int): Short = {
if (bits < 0 || bits >= 16) {
throw new IllegalArgumentException(s"Wrong argument in Short.shiftRight: bits < 0 || bits >= 16 ($bits)")
} else {
(x << bits).toShort
}
}
override def shiftRight(x: Short, bits: Int): Short = {
if (bits < 0 || bits >= 16){
throw new IllegalArgumentException(s"Wrong argument in Short.shiftRight: bits < 0 || bits >= 16 ($bits)")
} else {
(x >> bits).toShort
}
}
}

implicit object IntIsExactIntegral extends ExactIntegral[Int] {
Expand All @@ -73,8 +97,22 @@ object ExactIntegral {
override def bitwiseOr(x: Int, y: Int): Int = x | y
override def bitwiseAnd(x: Int, y: Int): Int = x & y
override def bitwiseXor(x: Int, y: Int): Int = x ^ y
override def shiftLeft(x: Int, y: Int): Int = x << y
override def shiftRight(x: Int, bits: Int): Int = x >> bits

override def shiftLeft(x: Int, bits: Int): Int = {
if (bits < 0 || bits >= 32) {
throw new IllegalArgumentException(s"Wrong argument in Byte.shiftRight: bits < 0 || bits >= 32 ($bits)")
} else {
x << bits
}
}

override def shiftRight(x: Int, bits: Int): Int = {
if (bits < 0 || bits >= 32) {
throw new IllegalArgumentException(s"Wrong argument in Int.shiftRight: bits < 0 || bits >= 32 ($bits)")
} else {
x >> bits
}
}
}

implicit object LongIsExactIntegral extends ExactIntegral[Long] {
Expand All @@ -88,7 +126,21 @@ object ExactIntegral {
override def bitwiseOr(x: Long, y: Long): Long = x | y
override def bitwiseAnd(x: Long, y: Long): Long = x & y
override def bitwiseXor(x: Long, y: Long): Long = x ^ y
override def shiftLeft(x: Long, y: Int): Long = x << y
override def shiftRight(x: Long, bits: Int): Long = x >> bits

override def shiftLeft(x: Long, bits: Int): Long = {
if (bits < 0 || bits >= 64) {
throw new IllegalArgumentException(s"Wrong argument in Long.shiftRight: bits < 0 || bits >= 64 ($bits)")
} else {
x << bits
}
}

override def shiftRight(x: Long, bits: Int): Long = {
if (bits < 0 || bits >= 64) {
throw new IllegalArgumentException(s"Wrong argument in Long.shiftRight: bits < 0 || bits >= 64 ($bits)")
} else {
x >> bits
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ trait NumericOps extends Base { self: IRContext =>
}
}

/** Descriptor of unary `ToBits` conversion operation. */
/** Descriptor of unary `BitwiseInverse` conversion operation. */
case class NumericBitwiseInverse[T: Elem](n: ExactNumeric[T]) extends UnOp[T, T]("~") {
override def applySeq(x: T): T = n.bitwiseInverse(x)
}
Expand Down
Loading

0 comments on commit 89d4477

Please sign in to comment.