From dc521999d1d3827b4e0e02280ce096287b3f5a87 Mon Sep 17 00:00:00 2001 From: Matthew McCall Date: Fri, 5 Apr 2024 18:03:49 -0400 Subject: [PATCH] [Feature] Add `UnaryExpression` and `Negate` (#86) --- include/Oasis/Add.hpp | 3 +- include/Oasis/Expression.hpp | 6 ++ include/Oasis/Negate.hpp | 60 ++++++++++++++ include/Oasis/UnaryExpression.hpp | 127 ++++++++++++++++++++++++++++++ src/CMakeLists.txt | 4 + src/Negate.cpp | 8 ++ tests/CMakeLists.txt | 1 + tests/NegateTests.cpp | 19 +++++ 8 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 include/Oasis/Negate.hpp create mode 100644 include/Oasis/UnaryExpression.hpp create mode 100644 src/Negate.cpp create mode 100644 tests/NegateTests.cpp diff --git a/include/Oasis/Add.hpp b/include/Oasis/Add.hpp index 211f1884..fbcb7dfe 100644 --- a/include/Oasis/Add.hpp +++ b/include/Oasis/Add.hpp @@ -30,8 +30,7 @@ class Add< [[nodiscard]] auto ToString() const -> std::string final; - static auto Specialize(const Expression& other) -> std::unique_ptr; - static auto Specialize(const Expression& other, tf::Subflow& subflow) -> std::unique_ptr; + DECL_SPECIALIZE(Add) EXPRESSION_TYPE(Add) EXPRESSION_CATEGORY(Associative | Commutative) diff --git a/include/Oasis/Expression.hpp b/include/Oasis/Expression.hpp index 11d1eb34..fd5a72e9 100644 --- a/include/Oasis/Expression.hpp +++ b/include/Oasis/Expression.hpp @@ -28,6 +28,8 @@ enum class ExpressionType { Divide, Exponent, Log, + Negate, + Sqrt, }; /** @@ -280,6 +282,10 @@ class Expression { return category; \ } +#define DECL_SPECIALIZE(type) \ + static auto Specialize(const Expression& other) -> std::unique_ptr; \ + static auto Specialize(const Expression& other, tf::Subflow&) -> std::unique_ptr; + } // namespace Oasis std::unique_ptr operator+(const std::unique_ptr& lhs, const std::unique_ptr& rhs); diff --git a/include/Oasis/Negate.hpp b/include/Oasis/Negate.hpp new file mode 100644 index 00000000..589eaa92 --- /dev/null +++ b/include/Oasis/Negate.hpp @@ -0,0 +1,60 @@ +// +// Created by Matthew McCall on 3/29/24. +// + +#ifndef NEGATE_HPP +#define NEGATE_HPP + +#include "Multiply.hpp" +#include "fmt/core.h" + +#include "UnaryExpression.hpp" + +namespace Oasis { + +template +class Negate final : public UnaryExpression { +public: + Negate() = default; + Negate(const Negate& other) + : UnaryExpression(other) + { + } + + explicit Negate(const OperandT& operand) + : UnaryExpression(operand) + { + } + + [[nodiscard]] auto Simplify() const -> std::unique_ptr override + { + return Multiply { + Real { -1.0 }, + this->GetOperand() + } + .Simplify(); + } + + auto Simplify(tf::Subflow& subflow) const -> std::unique_ptr override + { + return Multiply { + Real { -1.0 }, + this->GetOperand() + } + .Simplify(subflow); + } + + [[nodiscard]] auto ToString() const -> std::string override + { + return fmt::format("-({})", this->GetOperand().ToString()); + } + + IMPL_SPECIALIZE_UNARYEXPR(Negate, OperandT) + + EXPRESSION_TYPE(Negate) + EXPRESSION_CATEGORY(None) +}; + +} // Oasis + +#endif // NEGATE_HPP diff --git a/include/Oasis/UnaryExpression.hpp b/include/Oasis/UnaryExpression.hpp new file mode 100644 index 00000000..fbdb146d --- /dev/null +++ b/include/Oasis/UnaryExpression.hpp @@ -0,0 +1,127 @@ +// +// Created by Matthew McCall on 3/29/24. +// + +#ifndef UNARYEXPRESSION_HPP +#define UNARYEXPRESSION_HPP + +#include "Expression.hpp" + +namespace Oasis { + +template