Skip to content

Commit

Permalink
Merge pull request #157 from soronpo/bitwise
Browse files Browse the repository at this point in the history
Add bitwise operations
  • Loading branch information
Oron Port authored Oct 21, 2020
2 parents 70ab7e8 + 2041958 commit b7f78ef
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/main/scala/singleton/ops/impl/GeneralMacros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ trait GeneralMacros {
val != = symbolOf[OpId.!=]
val && = symbolOf[OpId.&&]
val || = symbolOf[OpId.||]
val BitwiseAnd = symbolOf[OpId.BitwiseAnd]
val BitwiseOr = symbolOf[OpId.BitwiseOr]
val Pow = symbolOf[OpId.Pow]
val Min = symbolOf[OpId.Min]
val Max = symbolOf[OpId.Max]
Expand Down Expand Up @@ -1207,6 +1209,16 @@ trait GeneralMacros {
case _ => unsupported()
}
}
def BitwiseAnd : Calc = (a, b) match {
case (CalcVal(at : Int, att), CalcVal(bt : Int, btt)) => CalcVal(at & bt, q"$att & $btt")
case (CalcVal(at : Long, att), CalcVal(bt : Long, btt)) => CalcVal(at & bt, q"$att & $btt")
case _ => unsupported()
}
def BitwiseOr : Calc = (a, b) match {
case (CalcVal(at : Int, att), CalcVal(bt : Int, btt)) => CalcVal(at | bt, q"$att | $btt")
case (CalcVal(at : Long, att), CalcVal(bt : Long, btt)) => CalcVal(at | bt, q"$att | $btt")
case _ => unsupported()
}
def Or : Calc = a match {
case CalcLit.Boolean(ab) => //`Or` expressions where the LHS is a literal can be inlined
if (!ab) b match {
Expand Down Expand Up @@ -1350,6 +1362,8 @@ trait GeneralMacros {
case funcTypes.!= => Neq
case funcTypes.&& => And
case funcTypes.|| => Or
case funcTypes.BitwiseAnd => BitwiseAnd
case funcTypes.BitwiseOr => BitwiseOr
case funcTypes.Pow => Pow
case funcTypes.Min => Min
case funcTypes.Max => Max
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/singleton/ops/impl/OpId.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ object OpId {
sealed trait != extends OpId
sealed trait || extends OpId
sealed trait && extends OpId
sealed trait BitwiseOr extends OpId
sealed trait BitwiseAnd extends OpId
sealed trait Min extends OpId
sealed trait Max extends OpId
sealed trait Substring extends OpId
Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/singleton/ops/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ package object ops {
type !=[P1, P2] = OpMacro[OpId.!=, P1, P2, NP]
type &&[P1, P2] = OpMacro[OpId.&&, P1, P2, NP]
type ||[P1, P2] = OpMacro[OpId.||, P1, P2, NP]
type BitwiseAnd[P1, P2] = OpMacro[OpId.BitwiseAnd, P1, P2, NP]
type BitwiseOr[P1, P2] = OpMacro[OpId.BitwiseOr, P1, P2, NP]
type SubSequence[S, IBeg, IEnd] = OpMacro[OpId.SubSequence, S, IBeg, IEnd]
type Substring[S, I] = OpMacro[OpId.Substring, S, I, NP]
type StartsWith[S, Prefix] = OpMacro[OpId.StartsWith, S, Prefix, NP]
Expand Down
19 changes: 19 additions & 0 deletions src/test/scala/singleton/ops/BitwiseAndSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package singleton.ops

import org.scalacheck.Properties
import singleton.TestUtils._

class BitwiseAndSpec extends Properties("BitwiseAnd") {
property("Int checks") = wellTyped {
implicitly[Require[(W.`9`.T BitwiseAnd W.`1`.T) == W.`1`.T]]
implicitly[Require[(W.`9`.T BitwiseAnd W.`8`.T) == W.`8`.T]]
implicitly[Require[(W.`9`.T BitwiseAnd W.`9`.T) == W.`9`.T]]
implicitly[Require[(W.`9`.T BitwiseAnd W.`0`.T) == W.`0`.T]]
}
property("Long checks") = wellTyped {
implicitly[Require[(W.`9L`.T BitwiseAnd W.`1L`.T) == W.`1L`.T]]
implicitly[Require[(W.`9L`.T BitwiseAnd W.`8L`.T) == W.`8L`.T]]
implicitly[Require[(W.`9L`.T BitwiseAnd W.`9L`.T) == W.`9L`.T]]
implicitly[Require[(W.`9L`.T BitwiseAnd W.`0L`.T) == W.`0L`.T]]
}
}
19 changes: 19 additions & 0 deletions src/test/scala/singleton/ops/BitwiseOrSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package singleton.ops

import org.scalacheck.Properties
import singleton.TestUtils._

class BitwiseOrSpec extends Properties("BitwiseOr") {
property("Int checks") = wellTyped {
implicitly[Require[(W.`9`.T BitwiseOr W.`1`.T) == W.`9`.T]]
implicitly[Require[(W.`9`.T BitwiseOr W.`8`.T) == W.`9`.T]]
implicitly[Require[(W.`1`.T BitwiseOr W.`8`.T) == W.`9`.T]]
implicitly[Require[(W.`9`.T BitwiseOr W.`0`.T) == W.`9`.T]]
}
property("Long checks") = wellTyped {
implicitly[Require[(W.`9L`.T BitwiseOr W.`1L`.T) == W.`9L`.T]]
implicitly[Require[(W.`9L`.T BitwiseOr W.`8L`.T) == W.`9L`.T]]
implicitly[Require[(W.`1L`.T BitwiseOr W.`8L`.T) == W.`9L`.T]]
implicitly[Require[(W.`9L`.T BitwiseOr W.`0L`.T) == W.`9L`.T]]
}
}
2 changes: 2 additions & 0 deletions src/test/scala/singleton/ops/UnsupportedSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class UnsupportedSpec extends Properties("UnsupportedSpec") {
property("!=") = wellTyped {illTyped("""implicitly[W.`true`.T != W.`2`.T]""")}
property("&&") = wellTyped {illTyped("""implicitly[W.`1`.T && W.`2`.T]""")}
property("||") = wellTyped {illTyped("""implicitly[W.`1`.T || W.`2`.T]""")}
property("BitwiseAnd") = wellTyped {illTyped("""implicitly[W.`1`.T BitwiseAnd W.`true`.T]""")}
property("BitwiseOr") = wellTyped {illTyped("""implicitly[W.`1`.T BitwiseOr W.`true`.T]""")}
property("Pow") = wellTyped {illTyped("""implicitly[Pow[W.`true`.T, W.`2`.T]]""")}
property("Min") = wellTyped {illTyped("""implicitly[Min[W.`true`.T, W.`2`.T]]""")}
property("Max") = wellTyped {illTyped("""implicitly[Max[W.`true`.T, W.`2`.T]]""")}
Expand Down

0 comments on commit b7f78ef

Please sign in to comment.