From 204195838ada34de7e453401fb06810ace2c99b0 Mon Sep 17 00:00:00 2001 From: soronpo Date: Wed, 21 Oct 2020 17:57:09 +0300 Subject: [PATCH] Add bitwise operations --- .../singleton/ops/impl/GeneralMacros.scala | 14 ++++++++++++++ src/main/scala/singleton/ops/impl/OpId.scala | 2 ++ src/main/scala/singleton/ops/package.scala | 2 ++ .../scala/singleton/ops/BitwiseAndSpec.scala | 19 +++++++++++++++++++ .../scala/singleton/ops/BitwiseOrSpec.scala | 19 +++++++++++++++++++ .../scala/singleton/ops/UnsupportedSpec.scala | 2 ++ 6 files changed, 58 insertions(+) create mode 100644 src/test/scala/singleton/ops/BitwiseAndSpec.scala create mode 100644 src/test/scala/singleton/ops/BitwiseOrSpec.scala diff --git a/src/main/scala/singleton/ops/impl/GeneralMacros.scala b/src/main/scala/singleton/ops/impl/GeneralMacros.scala index 6679139b..56fd5578 100644 --- a/src/main/scala/singleton/ops/impl/GeneralMacros.scala +++ b/src/main/scala/singleton/ops/impl/GeneralMacros.scala @@ -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] @@ -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 { @@ -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 diff --git a/src/main/scala/singleton/ops/impl/OpId.scala b/src/main/scala/singleton/ops/impl/OpId.scala index 97f055ff..d3a7ced9 100644 --- a/src/main/scala/singleton/ops/impl/OpId.scala +++ b/src/main/scala/singleton/ops/impl/OpId.scala @@ -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 diff --git a/src/main/scala/singleton/ops/package.scala b/src/main/scala/singleton/ops/package.scala index bdfd8a0d..56d3937c 100644 --- a/src/main/scala/singleton/ops/package.scala +++ b/src/main/scala/singleton/ops/package.scala @@ -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] diff --git a/src/test/scala/singleton/ops/BitwiseAndSpec.scala b/src/test/scala/singleton/ops/BitwiseAndSpec.scala new file mode 100644 index 00000000..112074af --- /dev/null +++ b/src/test/scala/singleton/ops/BitwiseAndSpec.scala @@ -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]] + } +} \ No newline at end of file diff --git a/src/test/scala/singleton/ops/BitwiseOrSpec.scala b/src/test/scala/singleton/ops/BitwiseOrSpec.scala new file mode 100644 index 00000000..8d986f04 --- /dev/null +++ b/src/test/scala/singleton/ops/BitwiseOrSpec.scala @@ -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]] + } +} \ No newline at end of file diff --git a/src/test/scala/singleton/ops/UnsupportedSpec.scala b/src/test/scala/singleton/ops/UnsupportedSpec.scala index 11447e51..cdf45b6f 100644 --- a/src/test/scala/singleton/ops/UnsupportedSpec.scala +++ b/src/test/scala/singleton/ops/UnsupportedSpec.scala @@ -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]]""")}