// Copyright 2021 Benjamin Barenblat // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. #include "src/builtin.h" #include #include #include #include "src/language.h" #include "src/language_matchers.h" namespace ec { namespace { using ::testing::ElementsAre; using ::testing::IsEmpty; void PushFive(State& s) { s.stack.push_back(GroundTerm::Make(5)); } TEST(DupTest, UnderflowsOnEmpty) { State s; EXPECT_THROW(BuiltinDup(s), StackUnderflow); } TEST(DupTest, GroundTerm) { State s; s.stack.push_back(GroundTerm::Make(42)); BuiltinDup(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(42), PointsToGroundTerm(42))); } TEST(DropTest, UnderflowsOnEmpty) { State s; EXPECT_THROW(BuiltinDrop(s), StackUnderflow); } TEST(DropTest, GroundTerm) { State s; s.stack.push_back(GroundTerm::Make(42)); BuiltinDrop(s); EXPECT_THAT(s.stack, IsEmpty()); } TEST(SwapTest, Underflow0) { State s; EXPECT_THROW(BuiltinSwap(s), StackUnderflow); } TEST(SwapTest, Underflow1) { State s; s.stack.push_back(GroundTerm::Make(1)); EXPECT_THROW(BuiltinSwap(s), StackUnderflow); } TEST(SwapTest, Swaps) { State s; s.stack.push_back(GroundTerm::Make(1)); s.stack.push_back(GroundTerm::Make(2)); BuiltinSwap(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(2), PointsToGroundTerm(1))); } TEST(UnaryTest, Underflow) { State s; EXPECT_THROW(BuiltinNeg(s), StackUnderflow); } TEST(UnaryTest, ProgramFails) { State s; s.stack.push_back(ForeignProgramTerm::Make(PushFive)); EXPECT_THROW(BuiltinNeg(s), TypeError); } TEST(UnaryBuiltinTest, Neg) { State s; s.stack.push_back(GroundTerm::Make(42)); BuiltinNeg(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(-42))); } TEST(UnaryBuiltinTest, Inv) { State s; s.stack.push_back(GroundTerm::Make(4)); BuiltinInv(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(0.25))); } TEST(UnaryBuiltinTest, Sq) { State s; s.stack.push_back(GroundTerm::Make(4)); BuiltinSq(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(16))); } TEST(UnaryBuiltinTest, Sqrt) { State s; s.stack.push_back(GroundTerm::Make(16)); BuiltinSqrt(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(4))); } TEST(UnaryBuiltinTest, Alog) { State s; s.stack.push_back(GroundTerm::Make(3)); BuiltinAlog(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(1000))); } TEST(UnaryBuiltinTest, Log) { State s; s.stack.push_back(GroundTerm::Make(1000)); BuiltinLog(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(3))); } TEST(UnaryBuiltinTest, Exp) { State s; s.stack.push_back(GroundTerm::Make(2)); BuiltinExp(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(7.38905609893065))); } TEST(UnaryBuiltinTest, Ln) { State s; s.stack.push_back(GroundTerm::Make(2)); BuiltinLn(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(M_LN2))); } TEST(UnaryBuiltinTest, Sin) { State s; s.stack.push_back(GroundTerm::Make(M_PI_2)); BuiltinSin(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(1))); } TEST(UnaryBuiltinTest, Cos) { State s; s.stack.push_back(GroundTerm::Make(M_PI)); BuiltinCos(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(-1))); } TEST(UnaryBuiltinTest, Tan) { State s; s.stack.push_back(GroundTerm::Make(M_PI_4)); BuiltinTan(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(1))); } TEST(UnaryBuiltinTest, Asin) { State s; s.stack.push_back(GroundTerm::Make(1)); BuiltinAsin(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(M_PI_2))); } TEST(UnaryBuiltinTest, Acos) { State s; s.stack.push_back(GroundTerm::Make(-1)); BuiltinAcos(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(M_PI))); } TEST(UnaryBuiltinTest, Atan) { State s; s.stack.push_back(GroundTerm::Make(1)); BuiltinAtan(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(M_PI_4))); } TEST(UnaryBuiltinTest, Abs) { State s; s.stack.push_back(GroundTerm::Make(-42)); BuiltinAbs(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(42))); } TEST(BinaryTest, Underflow0) { State s; EXPECT_THROW(BuiltinAdd(s), StackUnderflow); } TEST(BinaryTest, Underflow1) { State s; s.stack.push_back(GroundTerm::Make(42)); EXPECT_THROW(BuiltinAdd(s), StackUnderflow); } TEST(BinaryTest, ProgramProgramFails) { State s; s.stack.push_back(ForeignProgramTerm::Make(PushFive)); s.stack.push_back(ForeignProgramTerm::Make(PushFive)); EXPECT_THROW(BuiltinAdd(s), TypeError); } TEST(BinaryTest, ProgramGroundFails) { State s; s.stack.push_back(ForeignProgramTerm::Make(PushFive)); s.stack.push_back(GroundTerm::Make(42)); EXPECT_THROW(BuiltinAdd(s), TypeError); } TEST(BinaryTest, GroundProgramFails) { State s; s.stack.push_back(GroundTerm::Make(42)); s.stack.push_back(ForeignProgramTerm::Make(PushFive)); EXPECT_THROW(BuiltinAdd(s), TypeError); } TEST(BinaryBuiltinTest, Add) { State s; s.stack.push_back(GroundTerm::Make(42)); s.stack.push_back(GroundTerm::Make(42)); BuiltinAdd(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(84))); } TEST(BinaryBuiltinTest, Sub) { State s; s.stack.push_back(GroundTerm::Make(42)); s.stack.push_back(GroundTerm::Make(42)); BuiltinSub(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(0))); } TEST(BinaryBuiltinTest, Mul) { State s; s.stack.push_back(GroundTerm::Make(42)); s.stack.push_back(GroundTerm::Make(42)); BuiltinMul(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(1764))); } TEST(BinaryBuiltinTest, Div) { State s; s.stack.push_back(GroundTerm::Make(42)); s.stack.push_back(GroundTerm::Make(42)); BuiltinDiv(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(1))); } TEST(BinaryBuiltinTest, Pow) { State s; s.stack.push_back(GroundTerm::Make(2)); s.stack.push_back(GroundTerm::Make(10)); BuiltinPow(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(1024))); } TEST(BinaryBuiltinTest, Xroot) { State s; s.stack.push_back(GroundTerm::Make(27)); s.stack.push_back(GroundTerm::Make(3)); BuiltinXroot(s); EXPECT_THAT(s.stack, ElementsAre(PointsToGroundTerm(3))); } } // namespace } // namespace ec