From a4635fb95235ba4bf077bd59957da0626fc5ba72 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Tue, 14 Dec 2021 12:34:06 -0500 Subject: EC, a terminal-based RPN calculator --- src/builtin_test.cc | 274 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 src/builtin_test.cc (limited to 'src/builtin_test.cc') diff --git a/src/builtin_test.cc b/src/builtin_test.cc new file mode 100644 index 0000000..0197c99 --- /dev/null +++ b/src/builtin_test.cc @@ -0,0 +1,274 @@ +// 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 -- cgit v1.2.3