diff --git a/.gitignore b/.gitignore index 62748f3..9597faf 100644 --- a/.gitignore +++ b/.gitignore @@ -33,5 +33,11 @@ build/ cmake-build-*/ +CMakeUserPresets.json .idea -.vs \ No newline at end of file +.vs + +# Added by the agentic bootstrap: byproducts of the hooks it installs. +__pycache__/ +*.py[cod] +.agents/**/*.bootstrap-tmp diff --git a/CMakeLists.txt b/CMakeLists.txt index 944025a..4c8e283 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,14 @@ cmake_minimum_required(VERSION 3.26) project(cura-formulae-engine) -include(CTest) - find_package(standardprojectsettings REQUIRED) option(ENABLE_TESTS "Build with unit test" ON) option(EXTENSIVE_WARNINGS "Build with all warnings" ON) option(ENABLE_APPS "Build apps example" ON) -if (ENABLE_TESTS AND NOT BUILD_TESTING) - message(STATUS "ENABLE_TESTS is ON, forcing BUILD_TESTING=ON so CTest can discover tests") +if (ENABLE_TESTS) set(BUILD_TESTING ON CACHE BOOL "Enable CTest" FORCE) + include(CTest) endif () find_package(spdlog REQUIRED) diff --git a/LICENSE b/LICENSE index bde60ce..6600f1c 100644 --- a/LICENSE +++ b/LICENSE @@ -162,4 +162,4 @@ General Public License ever published by the Free Software Foundation. whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the -Library. \ No newline at end of file +Library. diff --git a/apps/cmdline_parser/CMakeLists.txt b/apps/cmdline_parser/CMakeLists.txt index 3e1f6f7..c12162e 100644 --- a/apps/cmdline_parser/CMakeLists.txt +++ b/apps/cmdline_parser/CMakeLists.txt @@ -11,4 +11,3 @@ if (${EXTENSIVE_WARNINGS}) endif () target_link_libraries(cmdline_parser PUBLIC cura-formulae-engine foonathan::lexy range-v3::range-v3) - diff --git a/apps/cmdline_parser/cmdline_parser.cpp b/apps/cmdline_parser/cmdline_parser.cpp index 66e4070..e066d33 100644 --- a/apps/cmdline_parser/cmdline_parser.cpp +++ b/apps/cmdline_parser/cmdline_parser.cpp @@ -5,42 +5,37 @@ #include #include -int main(int argc, const char** argv) -{ - spdlog::set_level(spdlog::level::info); - spdlog::info("Formula REPL, type 'exit' to quit."); - - while (true) - { - std::cout << "> "; - std::string command; - std::getline(std::cin, command); - if (command == "exit") - { - break; - } - - const auto input = std::string_view(command.begin(), command.end()); - auto message = CuraFormulaeEngine::parser::parse(input); - - if (!message.has_value()) - { - spdlog::warn("Failed to parse input."); - continue; - } - - const auto& expr = message.value(); - const auto eval_result = expr.evaluate(&CuraFormulaeEngine::env::std_env); - - if (!eval_result.has_value()) - { - spdlog::warn("Expr {} results in eval error", expr.toString()); - continue; - } - - const auto& eval = eval_result.value(); - spdlog::info("{} = {}", expr.toString(), eval.toString()); +int main(int argc, const char **argv) { + spdlog::set_level(spdlog::level::info); + spdlog::info("Formula REPL, type 'exit' to quit."); + + while (true) { + std::cout << "> "; + std::string command; + std::getline(std::cin, command); + if (command == "exit") { + break; } - return 0; + const auto input = std::string_view(command.begin(), command.end()); + auto message = CuraFormulaeEngine::parser::parse(input); + + if (!message.has_value()) { + spdlog::warn("Failed to parse input."); + continue; + } + + const auto &expr = message.value(); + const auto eval_result = expr.evaluate(&CuraFormulaeEngine::env::std_env); + + if (!eval_result.has_value()) { + spdlog::warn("Expr {} results in eval error", expr.toString()); + continue; + } + + const auto &eval = eval_result.value(); + spdlog::info("{} = {}", expr.toString(), eval.toString()); + } + + return 0; } diff --git a/include/cura-formulae-engine/ast/ast.h b/include/cura-formulae-engine/ast/ast.h index 64735a1..d875e45 100644 --- a/include/cura-formulae-engine/ast/ast.h +++ b/include/cura-formulae-engine/ast/ast.h @@ -8,8 +8,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::eval -{ +namespace CuraFormulaeEngine::eval { enum class Error; @@ -19,146 +18,146 @@ using Result = zeus::expected; } // namespace CuraFormulaeEngine::eval -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -class Environment -{ +class Environment { public: - virtual ~Environment() = default; + virtual ~Environment() = default; - [[nodiscard]] virtual std::optional get(const std::string& key) const = 0; - [[nodiscard]] virtual bool has(const std::string& key) const = 0; - [[nodiscard]] virtual std::unordered_map getAll() const = 0; + [[nodiscard]] virtual std::optional + get(const std::string &key) const = 0; + [[nodiscard]] virtual bool has(const std::string &key) const = 0; + [[nodiscard]] virtual std::unordered_map + getAll() const = 0; }; -class EnvironmentMap : public Environment -{ +class EnvironmentMap : public Environment { private: - std::unordered_map environment_ = {}; + std::unordered_map environment_ = {}; public: - EnvironmentMap() = default; - explicit EnvironmentMap(const std::unordered_map& map) - : environment_(map) - { - } - ~EnvironmentMap() override = default; + EnvironmentMap() = default; + explicit EnvironmentMap( + const std::unordered_map &map) + : environment_(map) {} + ~EnvironmentMap() override = default; - [[nodiscard]] std::optional get(const std::string& key) const noexcept override; + [[nodiscard]] std::optional + get(const std::string &key) const noexcept override; - [[nodiscard]] bool has(const std::string& key) const noexcept override; + [[nodiscard]] bool has(const std::string &key) const noexcept override; - [[nodiscard]] std::unordered_map getAll() const noexcept override; + [[nodiscard]] std::unordered_map + getAll() const noexcept override; - bool erase(const std::string& key) noexcept; + bool erase(const std::string &key) noexcept; - void set(const std::string& key, const eval::Value& value) noexcept; + void set(const std::string &key, const eval::Value &value) noexcept; - void add(const std::unordered_map& values); + void add(const std::unordered_map &values); - [[nodiscard]] EnvironmentMap clone() const noexcept; + [[nodiscard]] EnvironmentMap clone() const noexcept; }; -class ChainableEnvironment : public Environment -{ +class ChainableEnvironment : public Environment { private: - const Environment* shadow_environment_{ nullptr }; + const Environment *shadow_environment_{nullptr}; public: - explicit ChainableEnvironment(const Environment* shadow_environment = nullptr) - : shadow_environment_(shadow_environment) - { - } - ~ChainableEnvironment() override = default; + explicit ChainableEnvironment(const Environment *shadow_environment = nullptr) + : shadow_environment_(shadow_environment) {} + ~ChainableEnvironment() override = default; - [[nodiscard]] std::optional get(const std::string& key) const noexcept override final; + [[nodiscard]] std::optional + get(const std::string &key) const noexcept override final; - [[nodiscard]] bool has(const std::string& key) const noexcept override final; + [[nodiscard]] bool has(const std::string &key) const noexcept override final; - [[nodiscard]] std::unordered_map getAll() const noexcept override final; + [[nodiscard]] std::unordered_map + getAll() const noexcept override final; protected: - [[nodiscard]] virtual std::optional getImpl(const std::string& key) const noexcept = 0; + [[nodiscard]] virtual std::optional + getImpl(const std::string &key) const noexcept = 0; - [[nodiscard]] virtual bool hasImpl(const std::string& key) const noexcept = 0; + [[nodiscard]] virtual bool hasImpl(const std::string &key) const noexcept = 0; - [[nodiscard]] virtual std::unordered_map getAllImpl() const noexcept = 0; + [[nodiscard]] virtual std::unordered_map + getAllImpl() const noexcept = 0; }; -class LocalEnvironment : public ChainableEnvironment -{ +class LocalEnvironment : public ChainableEnvironment { private: - EnvironmentMap local_environment_; + EnvironmentMap local_environment_; public: - explicit LocalEnvironment(const Environment* shadow_environment = nullptr) - : ChainableEnvironment(shadow_environment) - { - } - ~LocalEnvironment() override = default; + explicit LocalEnvironment(const Environment *shadow_environment = nullptr) + : ChainableEnvironment(shadow_environment) {} + ~LocalEnvironment() override = default; - [[nodiscard]] std::optional getImpl(const std::string& key) const noexcept override; + [[nodiscard]] std::optional + getImpl(const std::string &key) const noexcept override; - [[nodiscard]] bool hasImpl(const std::string& key) const noexcept override; + [[nodiscard]] bool hasImpl(const std::string &key) const noexcept override; - [[nodiscard]] std::unordered_map getAllImpl() const noexcept override; + [[nodiscard]] std::unordered_map + getAllImpl() const noexcept override; - void set(const std::string& key, const eval::Value& value); + void set(const std::string &key, const eval::Value &value); - void add(const std::unordered_map& values); + void add(const std::unordered_map &values); }; } // namespace CuraFormulaeEngine::env -namespace CuraFormulaeEngine::ast -{ - -struct Expr -{ - Expr() = default; - Expr(const Expr&) = default; - Expr(Expr&&) = default; - Expr& operator=(const Expr&) = default; - Expr& operator=(Expr&&) = default; - virtual ~Expr() = default; - - /** - * @brief Evaluates the expression in the given environment. - * - * @param environment The environment to evaluate the expression in. - * @return eval_result The result of the evaluation. - */ - [[nodiscard]] virtual eval::Result evaluate(const env::Environment* environment) const = 0; - - /** - * @brief Returns the set of free variables in the expression. - * - * @return std::unordered_set The set of free variables. - */ - [[nodiscard]] virtual std::unordered_set freeVariables() const = 0; - - /** - * @brief Returns a string representation of the expression. - * - * @return std::string The string representation. - */ - [[nodiscard]] virtual std::string toString() const = 0; - - /** - * @brief Returns a deep copy of the expression. - * - * @return true if the expressions are equal, false otherwise. - */ - [[nodiscard]] virtual bool deepEq(const Expr& other) const = 0; - - /** - * @brief Traverses the expression tree and applies the visitor function to - * each node. - * - * @param visitor The visitor function to apply to each node. - */ - virtual void visitAll(std::function visitor) const = 0; +namespace CuraFormulaeEngine::ast { + +struct Expr { + Expr() = default; + Expr(const Expr &) = default; + Expr(Expr &&) = default; + Expr &operator=(const Expr &) = default; + Expr &operator=(Expr &&) = default; + virtual ~Expr() = default; + + /** + * @brief Evaluates the expression in the given environment. + * + * @param environment The environment to evaluate the expression in. + * @return eval_result The result of the evaluation. + */ + [[nodiscard]] virtual eval::Result + evaluate(const env::Environment *environment) const = 0; + + /** + * @brief Returns the set of free variables in the expression. + * + * @return std::unordered_set The set of free variables. + */ + [[nodiscard]] virtual std::unordered_set + freeVariables() const = 0; + + /** + * @brief Returns a string representation of the expression. + * + * @return std::string The string representation. + */ + [[nodiscard]] virtual std::string toString() const = 0; + + /** + * @brief Returns a deep copy of the expression. + * + * @return true if the expressions are equal, false otherwise. + */ + [[nodiscard]] virtual bool deepEq(const Expr &other) const = 0; + + /** + * @brief Traverses the expression tree and applies the visitor function to + * each node. + * + * @param visitor The visitor function to apply to each node. + */ + virtual void visitAll(std::function visitor) const = 0; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/binary_expr/add_expr.h b/include/cura-formulae-engine/ast/binary_expr/add_expr.h index 4d1828b..679fb19 100644 --- a/include/cura-formulae-engine/ast/binary_expr/add_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/add_expr.h @@ -6,18 +6,19 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct AddExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct AddExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator+(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator+(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/binary_expr/and_expr.h b/include/cura-formulae-engine/ast/binary_expr/and_expr.h index 42a1775..cf92a77 100644 --- a/include/cura-formulae-engine/ast/binary_expr/and_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/and_expr.h @@ -6,18 +6,19 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct AndExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct AndExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator&&(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator&&(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/binary_expr/binary_expr.h b/include/cura-formulae-engine/ast/binary_expr/binary_expr.h index a608bdf..5b27d02 100644 --- a/include/cura-formulae-engine/ast/binary_expr/binary_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/binary_expr.h @@ -4,13 +4,11 @@ #include "cura-formulae-engine/ast/expr_ptr.h" #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct BinaryExpr : Expr -{ - ExprPtr lhs; - ExprPtr rhs; +struct BinaryExpr : Expr { + ExprPtr lhs; + ExprPtr rhs; BinaryExpr(ExprPtr&& lhs, ExprPtr&& rhs) : lhs(std::move(lhs)) @@ -18,19 +16,21 @@ struct BinaryExpr : Expr { } - [[nodiscard]] virtual std::string getOpIdentifier() const = 0; + [[nodiscard]] virtual std::string getOpIdentifier() const = 0; - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - virtual eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const = 0; + virtual eval::Result evaluate(eval::Value &lhs, eval::Value &rhs) const = 0; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/binary_expr/div_expr.h b/include/cura-formulae-engine/ast/binary_expr/div_expr.h index 73cd3f7..546c410 100644 --- a/include/cura-formulae-engine/ast/binary_expr/div_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/div_expr.h @@ -6,18 +6,19 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct DivExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct DivExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator/(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator/(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/binary_expr/mod_expr.h b/include/cura-formulae-engine/ast/binary_expr/mod_expr.h index 0bf4025..a6943aa 100644 --- a/include/cura-formulae-engine/ast/binary_expr/mod_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/mod_expr.h @@ -6,18 +6,19 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct ModExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct ModExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator%(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator%(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/binary_expr/mul_expr.h b/include/cura-formulae-engine/ast/binary_expr/mul_expr.h index 8d64836..f0d134d 100644 --- a/include/cura-formulae-engine/ast/binary_expr/mul_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/mul_expr.h @@ -6,18 +6,19 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct MulExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct MulExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator*(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator*(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/binary_expr/or_expr.h b/include/cura-formulae-engine/ast/binary_expr/or_expr.h index 293f41d..f1e328e 100644 --- a/include/cura-formulae-engine/ast/binary_expr/or_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/or_expr.h @@ -7,18 +7,19 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct OrExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct OrExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator||(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator||(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/binary_expr/pow_expr.h b/include/cura-formulae-engine/ast/binary_expr/pow_expr.h index 85d757a..39e65fb 100644 --- a/include/cura-formulae-engine/ast/binary_expr/pow_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/pow_expr.h @@ -5,16 +5,15 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct PowExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct PowExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/binary_expr/sub_expr.h b/include/cura-formulae-engine/ast/binary_expr/sub_expr.h index 4c8a319..89d9215 100644 --- a/include/cura-formulae-engine/ast/binary_expr/sub_expr.h +++ b/include/cura-formulae-engine/ast/binary_expr/sub_expr.h @@ -6,18 +6,19 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct SubExpr final : BinaryExpr -{ - using BinaryExpr::BinaryExpr; +struct SubExpr final : BinaryExpr { + using BinaryExpr::BinaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - eval::Result evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept final; + eval::Result evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator-(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator-(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/comp_chain_expr.h b/include/cura-formulae-engine/ast/comp_chain_expr.h index b869e1a..0f6fc3c 100644 --- a/include/cura-formulae-engine/ast/comp_chain_expr.h +++ b/include/cura-formulae-engine/ast/comp_chain_expr.h @@ -3,51 +3,60 @@ #include "cura-formulae-engine/ast/ast.h" #include "expr_ptr.h" -namespace CuraFormulaeEngine::ast -{ - -enum ComparisonOperators -{ - Equals, - NotEquals, - LessThan, - GreaterThan, - LessThenEqual, - GreaterThenEqual, - NotMember, - Member, +namespace CuraFormulaeEngine::ast { + +enum ComparisonOperators { + Equals, + NotEquals, + LessThan, + GreaterThan, + LessThenEqual, + GreaterThenEqual, + NotMember, + Member, }; -struct ComparisonChainExpr final : Expr -{ +struct ComparisonChainExpr final : Expr { - std::vector expressions; - std::vector operators; + std::vector expressions; + std::vector operators; - ComparisonChainExpr() = default; + ComparisonChainExpr() = default; - ComparisonChainExpr(std::vector &&expressions, std::vector &&operators) - : expressions(std::move(expressions)) - , operators(std::move(operators)) - { - } + ComparisonChainExpr(std::vector &&expressions, + std::vector &&operators) + : expressions(std::move(expressions)), operators(std::move(operators)) {} - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator==(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); -CuraFormulaeEngine::ast::ExprPtr operator!=(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); -CuraFormulaeEngine::ast::ExprPtr operator>=(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); -CuraFormulaeEngine::ast::ExprPtr operator>(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); -CuraFormulaeEngine::ast::ExprPtr operator<=(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); -CuraFormulaeEngine::ast::ExprPtr operator<(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator==(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator!=(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator>=(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator>(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator<=(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); +CuraFormulaeEngine::ast::ExprPtr +operator<(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs); diff --git a/include/cura-formulae-engine/ast/condition_expr.h b/include/cura-formulae-engine/ast/condition_expr.h index 4dd3d85..acecaf8 100644 --- a/include/cura-formulae-engine/ast/condition_expr.h +++ b/include/cura-formulae-engine/ast/condition_expr.h @@ -3,14 +3,12 @@ #include "cura-formulae-engine/ast/ast.h" #include "expr_ptr.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct ConditionExpr final : Expr -{ - ExprPtr then_expr; - ExprPtr condition; - ExprPtr else_expr; +struct ConditionExpr final : Expr { + ExprPtr then_expr; + ExprPtr condition; + ExprPtr else_expr; ConditionExpr(ExprPtr&& then_expr, ExprPtr&& condition, ExprPtr&& else_expr) : then_expr(std::move(then_expr)) @@ -19,15 +17,17 @@ struct ConditionExpr final : Expr { } - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/expr_ptr.h b/include/cura-formulae-engine/ast/expr_ptr.h index 54de089..f123fc2 100644 --- a/include/cura-formulae-engine/ast/expr_ptr.h +++ b/include/cura-formulae-engine/ast/expr_ptr.h @@ -2,45 +2,42 @@ #include "cura-formulae-engine/ast/ast.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct ExprPtr final : Expr -{ - ExprPtr() = default; - ExprPtr(const ExprPtr&) = delete; - ExprPtr(ExprPtr&&) = default; - ExprPtr& operator=(const ExprPtr&) = delete; - ExprPtr& operator=(ExprPtr&&) = default; - ~ExprPtr() override = default; +struct ExprPtr final : Expr { + ExprPtr() = default; + ExprPtr(const ExprPtr &) = delete; + ExprPtr(ExprPtr &&) = default; + ExprPtr &operator=(const ExprPtr &) = delete; + ExprPtr &operator=(ExprPtr &&) = default; + ~ExprPtr() override = default; - std::unique_ptr ptr; + std::unique_ptr ptr; ExprPtr(std::unique_ptr&& ptr) : ptr(std::move(ptr)) { } - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; - ExprPtr operator[](ExprPtr other); + ExprPtr operator[](ExprPtr other); - template - ExprPtr operator()(Ts... args); + template ExprPtr operator()(Ts... args); }; -template -ExprPtr make_expr_ptr(Ts... args) -{ - return ExprPtr(std::move(std::make_unique(std::forward(args)...))); +template ExprPtr make_expr_ptr(Ts... args) { + return ExprPtr(std::move(std::make_unique(std::forward(args)...))); } } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/fn_application_expr.h b/include/cura-formulae-engine/ast/fn_application_expr.h index 5473c0b..483310b 100644 --- a/include/cura-formulae-engine/ast/fn_application_expr.h +++ b/include/cura-formulae-engine/ast/fn_application_expr.h @@ -3,8 +3,7 @@ #include "cura-formulae-engine/ast/ast.h" #include "expr_ptr.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { struct FnApplicationExpr final : Expr { @@ -30,23 +29,26 @@ struct FnApplicationExpr final : Expr { } - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -template -CuraFormulaeEngine::ast::ExprPtr CuraFormulaeEngine::ast::ExprPtr::operator()(Ts... args) -{ - std::vector args_vec; - (args_vec.push_back(std::forward(args)), ...); - return make_expr_ptr(std::move(*this), std::move(args_vec)); +template +CuraFormulaeEngine::ast::ExprPtr +CuraFormulaeEngine::ast::ExprPtr::operator()(Ts... args) { + std::vector args_vec; + (args_vec.push_back(std::forward(args)), ...); + return make_expr_ptr(std::move(*this), + std::move(args_vec)); } diff --git a/include/cura-formulae-engine/ast/index_expr.h b/include/cura-formulae-engine/ast/index_expr.h index fdc0f81..d389dc4 100644 --- a/include/cura-formulae-engine/ast/index_expr.h +++ b/include/cura-formulae-engine/ast/index_expr.h @@ -1,8 +1,8 @@ #pragma once #include "cura-formulae-engine/ast/ast.h" -#include "expr_ptr.h" #include "cura-formulae-engine/eval.h" +#include "expr_ptr.h" #include #include @@ -11,13 +11,11 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct IndexExpr final : Expr -{ - ExprPtr array; - ExprPtr index; +struct IndexExpr final : Expr { + ExprPtr array; + ExprPtr index; IndexExpr(ExprPtr&& array, ExprPtr&& index) : array(std::move(array)) @@ -25,15 +23,17 @@ struct IndexExpr final : Expr { } - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/list_comprehension_expr.h b/include/cura-formulae-engine/ast/list_comprehension_expr.h index cf92df8..0f3ed96 100644 --- a/include/cura-formulae-engine/ast/list_comprehension_expr.h +++ b/include/cura-formulae-engine/ast/list_comprehension_expr.h @@ -1,8 +1,8 @@ #pragma once #include "cura-formulae-engine/ast/ast.h" -#include "expr_ptr.h" #include "cura-formulae-engine/eval.h" +#include "expr_ptr.h" #include #include @@ -10,16 +10,13 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct ListComprehensionExpr final : Expr -{ - struct loop - { - ExprPtr iterator_key; - ExprPtr iterable; - std::vector conditions; +struct ListComprehensionExpr final : Expr { + struct loop { + ExprPtr iterator_key; + ExprPtr iterable; + std::vector conditions; loop(ExprPtr&& iterator_key, ExprPtr&& iterable, std::vector&& conditions) : iterator_key(std::move(iterator_key)) @@ -29,8 +26,8 @@ struct ListComprehensionExpr final : Expr } }; - ExprPtr iterator; - std::vector loops; + ExprPtr iterator; + std::vector loops; ListComprehensionExpr(ExprPtr&& iterator, std::vector&& loops) : iterator(std::move(iterator)) @@ -38,18 +35,21 @@ struct ListComprehensionExpr final : Expr { } - [[nodiscard]] std::string toString() const noexcept final; - - std::optional handle_loop(const size_t loop_index, env::LocalEnvironment& local_environment, std::vector& results) const; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + std::optional + handle_loop(const size_t loop_index, env::LocalEnvironment &local_environment, + std::vector &results) const; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - void visitAll(std::function visitor) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/list_expr.h b/include/cura-formulae-engine/ast/list_expr.h index c59c592..bae71a1 100644 --- a/include/cura-formulae-engine/ast/list_expr.h +++ b/include/cura-formulae-engine/ast/list_expr.h @@ -1,40 +1,38 @@ #pragma once #include "cura-formulae-engine/ast/ast.h" -#include "expr_ptr.h" #include "cura-formulae-engine/eval.h" +#include "expr_ptr.h" #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct ListExpr final : Expr -{ - std::vector elements; +struct ListExpr final : Expr { + std::vector elements; ListExpr(std::vector&& elements) : elements(std::move(elements)) { } - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; -template -ExprPtr make_list_expr(Ts&&... elements) -{ - std::vector elements_vec; - (elements_vec.push_back(std::forward(elements)), ...); - return make_expr_ptr(std::move(elements_vec)); +template ExprPtr make_list_expr(Ts &&...elements) { + std::vector elements_vec; + (elements_vec.push_back(std::forward(elements)), ...); + return make_expr_ptr(std::move(elements_vec)); } } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/primary_expr/bool_expr.h b/include/cura-formulae-engine/ast/primary_expr/bool_expr.h index 53563f9..f8cb815 100644 --- a/include/cura-formulae-engine/ast/primary_expr/bool_expr.h +++ b/include/cura-formulae-engine/ast/primary_expr/bool_expr.h @@ -2,12 +2,10 @@ #include "primary_expr.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct BoolExpr final : PrimaryExpr -{ - using PrimaryExpr::PrimaryExpr; +struct BoolExpr final : PrimaryExpr { + using PrimaryExpr::PrimaryExpr; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/primary_expr/float_expr.h b/include/cura-formulae-engine/ast/primary_expr/float_expr.h index 65e8627..37af3dc 100644 --- a/include/cura-formulae-engine/ast/primary_expr/float_expr.h +++ b/include/cura-formulae-engine/ast/primary_expr/float_expr.h @@ -2,12 +2,10 @@ #include "primary_expr.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct FloatExpr final : PrimaryExpr -{ - using PrimaryExpr::PrimaryExpr; +struct FloatExpr final : PrimaryExpr { + using PrimaryExpr::PrimaryExpr; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/primary_expr/int_expr.h b/include/cura-formulae-engine/ast/primary_expr/int_expr.h index 9da9efb..35be8ae 100644 --- a/include/cura-formulae-engine/ast/primary_expr/int_expr.h +++ b/include/cura-formulae-engine/ast/primary_expr/int_expr.h @@ -4,12 +4,10 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct IntExpr final : PrimaryExpr -{ - using PrimaryExpr::PrimaryExpr; +struct IntExpr final : PrimaryExpr { + using PrimaryExpr::PrimaryExpr; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/primary_expr/none_expr.h b/include/cura-formulae-engine/ast/primary_expr/none_expr.h index 0d2ebb4..a16d723 100644 --- a/include/cura-formulae-engine/ast/primary_expr/none_expr.h +++ b/include/cura-formulae-engine/ast/primary_expr/none_expr.h @@ -2,17 +2,12 @@ #include "primary_expr.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct NoneExpr final : PrimaryExpr -{ - NoneExpr() - : PrimaryExpr(nullptr) - { - } +struct NoneExpr final : PrimaryExpr { + NoneExpr() : PrimaryExpr(nullptr) {} - using PrimaryExpr::PrimaryExpr; + using PrimaryExpr::PrimaryExpr; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/primary_expr/primary_expr.h b/include/cura-formulae-engine/ast/primary_expr/primary_expr.h index cb39a48..e5d3a36 100644 --- a/include/cura-formulae-engine/ast/primary_expr/primary_expr.h +++ b/include/cura-formulae-engine/ast/primary_expr/primary_expr.h @@ -9,47 +9,38 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -template -struct PrimaryExpr : public Expr -{ - T value; +template struct PrimaryExpr : public Expr { + T value; - explicit PrimaryExpr(T value) - : value(value) - { - } + explicit PrimaryExpr(T value) : value(value) {} - [[nodiscard]] eval::Result evaluate(const env::Environment*) const noexcept final - { - return value; - } + [[nodiscard]] eval::Result + evaluate(const env::Environment *) const noexcept final { + return value; + } - [[nodiscard]] std::unordered_set freeVariables() const noexcept final - { - return {}; - }; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final { + return {}; + }; - [[nodiscard]] std::string toString() const noexcept override - { - return fmt::format("{}", value); - } + [[nodiscard]] std::string toString() const noexcept override { + return fmt::format("{}", value); + } - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final - { - if (auto other_number = dynamic_cast*>(&other)) - { - return value == other_number->value; - } - return false; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final { + if (auto other_number = dynamic_cast *>(&other)) { + return value == other_number->value; } + return false; + } - void visitAll(std::function visitor) const noexcept final - { - visitor(*this); - } + void + visitAll(std::function visitor) const noexcept final { + visitor(*this); + } }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/primary_expr/string_expr.h b/include/cura-formulae-engine/ast/primary_expr/string_expr.h index 277336c..a175de7 100644 --- a/include/cura-formulae-engine/ast/primary_expr/string_expr.h +++ b/include/cura-formulae-engine/ast/primary_expr/string_expr.h @@ -2,14 +2,12 @@ #include "primary_expr.h" -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct StringExpr final : PrimaryExpr -{ - using PrimaryExpr::PrimaryExpr; +struct StringExpr final : PrimaryExpr { + using PrimaryExpr::PrimaryExpr; - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/slice_expr.h b/include/cura-formulae-engine/ast/slice_expr.h index 7d9495a..18a3b2e 100644 --- a/include/cura-formulae-engine/ast/slice_expr.h +++ b/include/cura-formulae-engine/ast/slice_expr.h @@ -1,8 +1,8 @@ #pragma once #include "cura-formulae-engine/ast/ast.h" -#include "expr_ptr.h" #include "cura-formulae-engine/eval.h" +#include "expr_ptr.h" #include @@ -13,15 +13,13 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct SliceExpr final : Expr -{ - ExprPtr array; - std::optional start_index; - std::optional end_index; - std::optional step_size; +struct SliceExpr final : Expr { + ExprPtr array; + std::optional start_index; + std::optional end_index; + std::optional step_size; SliceExpr(ExprPtr&& array, std::optional&& start_index, std::optional&& end_index, std::optional&& step_size) : array(std::move(array)) @@ -31,16 +29,17 @@ struct SliceExpr final : Expr { } - [[nodiscard]] std::string toString() const noexcept final; - - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - void visitAll(std::function visitor) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/tuple_expr.h b/include/cura-formulae-engine/ast/tuple_expr.h index 57328b6..60618ca 100644 --- a/include/cura-formulae-engine/ast/tuple_expr.h +++ b/include/cura-formulae-engine/ast/tuple_expr.h @@ -8,35 +8,33 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct TupleExpr final : Expr -{ - std::vector elements; +struct TupleExpr final : Expr { + std::vector elements; TupleExpr(std::vector&& elements) : elements(std::move(elements)) { } - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; -template -ExprPtr make_tuple_expr(Ts&&... elements) -{ - std::vector elements_vec; - (elements_vec.push_back(std::forward(elements)), ...); - return make_expr_ptr(std::move(elements_vec)); +template ExprPtr make_tuple_expr(Ts &&...elements) { + std::vector elements_vec; + (elements_vec.push_back(std::forward(elements)), ...); + return make_expr_ptr(std::move(elements_vec)); } } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/unary_expr/neg_expr.h b/include/cura-formulae-engine/ast/unary_expr/neg_expr.h index c1845fc..728c35d 100644 --- a/include/cura-formulae-engine/ast/unary_expr/neg_expr.h +++ b/include/cura-formulae-engine/ast/unary_expr/neg_expr.h @@ -1,23 +1,23 @@ #pragma once #include "cura-formulae-engine/ast/expr_ptr.h" -#include "unary_expr.h" #include "cura-formulae-engine/eval.h" +#include "unary_expr.h" #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct NegExpr final : UnaryExpr -{ - using UnaryExpr::UnaryExpr; +struct NegExpr final : UnaryExpr { + using UnaryExpr::UnaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - [[nodiscard]] eval::Result evaluate(const eval::Value& eval_value) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const eval::Value &eval_value) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator-(CuraFormulaeEngine::ast::ExprPtr operand); +CuraFormulaeEngine::ast::ExprPtr +operator-(CuraFormulaeEngine::ast::ExprPtr operand); diff --git a/include/cura-formulae-engine/ast/unary_expr/not_expr.h b/include/cura-formulae-engine/ast/unary_expr/not_expr.h index d371f9b..5e76745 100644 --- a/include/cura-formulae-engine/ast/unary_expr/not_expr.h +++ b/include/cura-formulae-engine/ast/unary_expr/not_expr.h @@ -1,23 +1,23 @@ #pragma once #include "cura-formulae-engine/ast/expr_ptr.h" -#include "unary_expr.h" #include "cura-formulae-engine/eval.h" +#include "unary_expr.h" #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct NotExpr final : UnaryExpr -{ - using UnaryExpr::UnaryExpr; +struct NotExpr final : UnaryExpr { + using UnaryExpr::UnaryExpr; - [[nodiscard]] std::string getOpIdentifier() const noexcept final; + [[nodiscard]] std::string getOpIdentifier() const noexcept final; - [[nodiscard]] eval::Result evaluate(const eval::Value& eval_value) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const eval::Value &eval_value) const noexcept final; }; } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator!(CuraFormulaeEngine::ast::ExprPtr operand); +CuraFormulaeEngine::ast::ExprPtr +operator!(CuraFormulaeEngine::ast::ExprPtr operand); diff --git a/include/cura-formulae-engine/ast/unary_expr/unary_expr.h b/include/cura-formulae-engine/ast/unary_expr/unary_expr.h index 99fefc2..09ef57c 100644 --- a/include/cura-formulae-engine/ast/unary_expr/unary_expr.h +++ b/include/cura-formulae-engine/ast/unary_expr/unary_expr.h @@ -12,31 +12,32 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct UnaryExpr : Expr -{ - ExprPtr operand; +struct UnaryExpr : Expr { + ExprPtr operand; explicit UnaryExpr(ExprPtr&& operand) : operand(std::move(operand)) { } - [[nodiscard]] virtual std::string getOpIdentifier() const = 0; + [[nodiscard]] virtual std::string getOpIdentifier() const = 0; - [[nodiscard]] std::string toString() const noexcept final; + [[nodiscard]] std::string toString() const noexcept final; - [[nodiscard]] virtual eval::Result evaluate(const eval::Value& eval_value) const = 0; + [[nodiscard]] virtual eval::Result + evaluate(const eval::Value &eval_value) const = 0; - [[nodiscard]] eval::Result evaluate(const env::Environment* environment) const noexcept final; + [[nodiscard]] eval::Result + evaluate(const env::Environment *environment) const noexcept final; - [[nodiscard]] std::unordered_set freeVariables() const noexcept final; + [[nodiscard]] std::unordered_set + freeVariables() const noexcept final; - [[nodiscard]] bool deepEq(const Expr& other) const noexcept final; + [[nodiscard]] bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/ast/variable_expr.h b/include/cura-formulae-engine/ast/variable_expr.h index 58777b4..61a3b02 100644 --- a/include/cura-formulae-engine/ast/variable_expr.h +++ b/include/cura-formulae-engine/ast/variable_expr.h @@ -6,27 +6,26 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -struct VariableExpr final : Expr -{ - std::string name; +struct VariableExpr final : Expr { + std::string name; VariableExpr(std::string&& name) : name(std::move(name)) { } - std::string toString() const noexcept final; + std::string toString() const noexcept final; - eval::Result evaluate(const env::Environment* environment) const noexcept final; + eval::Result + evaluate(const env::Environment *environment) const noexcept final; - std::unordered_set freeVariables() const noexcept final; + std::unordered_set freeVariables() const noexcept final; - bool deepEq(const Expr& other) const noexcept final; + bool deepEq(const Expr &other) const noexcept final; - void visitAll(std::function visitor) const noexcept final; + void visitAll(std::function visitor) const noexcept final; }; } // namespace CuraFormulaeEngine::ast diff --git a/include/cura-formulae-engine/config.h b/include/cura-formulae-engine/config.h index 8651a25..4a81dc2 100644 --- a/include/cura-formulae-engine/config.h +++ b/include/cura-formulae-engine/config.h @@ -1,11 +1,11 @@ #pragma once #ifdef _WIN32 -# ifdef cura_formulae_engine_EXPORTS -# define CURA_FORMULAE_ENGINE_API __declspec(dllexport) -# else -# define CURA_FORMULAE_ENGINE_API __declspec(dllimport) -# endif +#ifdef cura_formulae_engine_EXPORTS +#define CURA_FORMULAE_ENGINE_API __declspec(dllexport) #else -# define CURA_FORMULAE_ENGINE_API +#define CURA_FORMULAE_ENGINE_API __declspec(dllimport) +#endif +#else +#define CURA_FORMULAE_ENGINE_API #endif diff --git a/include/cura-formulae-engine/env/abs.h b/include/cura-formulae-engine/env/abs.h index 76c4d65..c8dd2f9 100644 --- a/include/cura-formulae-engine/env/abs.h +++ b/include/cura-formulae-engine/env/abs.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t abs; diff --git a/include/cura-formulae-engine/env/all.h b/include/cura-formulae-engine/env/all.h index a78f5c4..9066842 100644 --- a/include/cura-formulae-engine/env/all.h +++ b/include/cura-formulae-engine/env/all.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t all; diff --git a/include/cura-formulae-engine/env/any.h b/include/cura-formulae-engine/env/any.h index f60f255..869f04a 100644 --- a/include/cura-formulae-engine/env/any.h +++ b/include/cura-formulae-engine/env/any.h @@ -2,9 +2,8 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { - extern const eval::Value::fn_t any; +extern const eval::Value::fn_t any; } // namespace CuraFormulaeEngine::env diff --git a/include/cura-formulae-engine/env/env.h b/include/cura-formulae-engine/env/env.h index 28169b2..ddbb581 100644 --- a/include/cura-formulae-engine/env/env.h +++ b/include/cura-formulae-engine/env/env.h @@ -3,8 +3,7 @@ #include "cura-formulae-engine/ast/ast.h" #include "cura-formulae-engine/config.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { /** * @brief The standard environment. diff --git a/include/cura-formulae-engine/env/float_fn.h b/include/cura-formulae-engine/env/float_fn.h index e100cf9..564d3d7 100644 --- a/include/cura-formulae-engine/env/float_fn.h +++ b/include/cura-formulae-engine/env/float_fn.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t float_fn; diff --git a/include/cura-formulae-engine/env/len.h b/include/cura-formulae-engine/env/len.h index 1d79c30..9c1afa4 100644 --- a/include/cura-formulae-engine/env/len.h +++ b/include/cura-formulae-engine/env/len.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t len; diff --git a/include/cura-formulae-engine/env/map.h b/include/cura-formulae-engine/env/map.h index cf9b043..b4b2429 100644 --- a/include/cura-formulae-engine/env/map.h +++ b/include/cura-formulae-engine/env/map.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t map; diff --git a/include/cura-formulae-engine/env/math_atan.h b/include/cura-formulae-engine/env/math_atan.h index 443bfc2..729e879 100644 --- a/include/cura-formulae-engine/env/math_atan.h +++ b/include/cura-formulae-engine/env/math_atan.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_atan; diff --git a/include/cura-formulae-engine/env/math_ceil.h b/include/cura-formulae-engine/env/math_ceil.h index cd3fb71..518181f 100644 --- a/include/cura-formulae-engine/env/math_ceil.h +++ b/include/cura-formulae-engine/env/math_ceil.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_ceil; diff --git a/include/cura-formulae-engine/env/math_cos.h b/include/cura-formulae-engine/env/math_cos.h index f2d5388..63ac7c4 100644 --- a/include/cura-formulae-engine/env/math_cos.h +++ b/include/cura-formulae-engine/env/math_cos.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_cos; diff --git a/include/cura-formulae-engine/env/math_degrees.h b/include/cura-formulae-engine/env/math_degrees.h index 7ace2fc..576ff0a 100644 --- a/include/cura-formulae-engine/env/math_degrees.h +++ b/include/cura-formulae-engine/env/math_degrees.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_degrees; diff --git a/include/cura-formulae-engine/env/math_floor.h b/include/cura-formulae-engine/env/math_floor.h index 374ac2a..d1c5b2d 100644 --- a/include/cura-formulae-engine/env/math_floor.h +++ b/include/cura-formulae-engine/env/math_floor.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_floor; diff --git a/include/cura-formulae-engine/env/math_radians.h b/include/cura-formulae-engine/env/math_radians.h index 200c620..d973a2c 100644 --- a/include/cura-formulae-engine/env/math_radians.h +++ b/include/cura-formulae-engine/env/math_radians.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_radians; diff --git a/include/cura-formulae-engine/env/math_sin.h b/include/cura-formulae-engine/env/math_sin.h index 183af7c..d05bf85 100644 --- a/include/cura-formulae-engine/env/math_sin.h +++ b/include/cura-formulae-engine/env/math_sin.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_sin; diff --git a/include/cura-formulae-engine/env/math_sqrt.h b/include/cura-formulae-engine/env/math_sqrt.h index e7c4740..a9459b5 100644 --- a/include/cura-formulae-engine/env/math_sqrt.h +++ b/include/cura-formulae-engine/env/math_sqrt.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_sqrt; diff --git a/include/cura-formulae-engine/env/math_tan.h b/include/cura-formulae-engine/env/math_tan.h index c62bff4..53cfb05 100644 --- a/include/cura-formulae-engine/env/math_tan.h +++ b/include/cura-formulae-engine/env/math_tan.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t math_tan; diff --git a/include/cura-formulae-engine/env/max.h b/include/cura-formulae-engine/env/max.h index 77e7cca..8fed2cd 100644 --- a/include/cura-formulae-engine/env/max.h +++ b/include/cura-formulae-engine/env/max.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t max; diff --git a/include/cura-formulae-engine/env/str.h b/include/cura-formulae-engine/env/str.h index b0a6285..7eee281 100644 --- a/include/cura-formulae-engine/env/str.h +++ b/include/cura-formulae-engine/env/str.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t str; diff --git a/include/cura-formulae-engine/env/sum.h b/include/cura-formulae-engine/env/sum.h index e415c18..57af775 100644 --- a/include/cura-formulae-engine/env/sum.h +++ b/include/cura-formulae-engine/env/sum.h @@ -2,8 +2,7 @@ #include "cura-formulae-engine/eval.h" -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { extern const eval::Value::fn_t sum; diff --git a/include/cura-formulae-engine/eval.h b/include/cura-formulae-engine/eval.h index 2b2adc6..51ed971 100644 --- a/include/cura-formulae-engine/eval.h +++ b/include/cura-formulae-engine/eval.h @@ -17,33 +17,30 @@ #include #include +#include #include #include #include #include #include -#include -namespace CuraFormulaeEngine::eval -{ +namespace CuraFormulaeEngine::eval { struct Value; -enum class Error -{ - TypeMismatch, - UndefinedVariable, - DivisionByZero, - InvalidNumberOfArguments, - IndexOutOfBounds, - ValueError +enum class Error { + TypeMismatch, + UndefinedVariable, + DivisionByZero, + InvalidNumberOfArguments, + IndexOutOfBounds, + ValueError }; using Result = zeus::expected; -struct Value -{ - using fn_t = std::function&)>; +struct Value { + using fn_t = std::function &)>; struct rich_fn_t { @@ -67,37 +64,19 @@ struct Value std::variant, fn_t, rich_fn_t, std::unordered_map, std::nullptr_t> value = nullptr; - Value() noexcept = default; + Value() noexcept = default; - Value(const bool& value) noexcept - : value{ value } - { - } + Value(const bool &value) noexcept : value{value} {} - Value(const double& value) noexcept - : value{ value } - { - } + Value(const double &value) noexcept : value{value} {} - Value(const std::int64_t& value) noexcept - : value{ value } - { - } + Value(const std::int64_t &value) noexcept : value{value} {} - Value(const std::string& value) noexcept - : value{ value } - { - } + Value(const std::string &value) noexcept : value{value} {} - Value(const std::vector& value) noexcept - : value{ value } - { - } + Value(const std::vector &value) noexcept : value{value} {} - Value(const fn_t& value) noexcept - : value{ value } - { - } + Value(const fn_t &value) noexcept : value{value} {} Value(const rich_fn_t& value) noexcept : value{ value } @@ -114,31 +93,28 @@ struct Value { } - static Value none() noexcept - { - return Value(nullptr); - } + static Value none() noexcept { return Value(nullptr); } - ~Value() = default; + ~Value() = default; - Value(Value&& other) noexcept = default; - Value(const Value& other) noexcept = default; - Value& operator=(const Value& other) noexcept = default; - Value& operator=(Value&& other) noexcept = default; + Value(Value &&other) noexcept = default; + Value(const Value &other) noexcept = default; + Value &operator=(const Value &other) noexcept = default; + Value &operator=(Value &&other) noexcept = default; - [[nodiscard]] std::string toString() const noexcept; + [[nodiscard]] std::string toString() const noexcept; - [[nodiscard]] bool deepEq(const Value& other) const noexcept; + [[nodiscard]] bool deepEq(const Value &other) const noexcept; - [[nodiscard]] bool isTruthy() const noexcept; + [[nodiscard]] bool isTruthy() const noexcept; - [[nodiscard]] zeus::expected numeric() const noexcept; + [[nodiscard]] zeus::expected numeric() const noexcept; #ifdef EMSCRIPTEN - [[nodiscard]] emscripten::val toEmscripten() const; + [[nodiscard]] emscripten::val toEmscripten() const; #endif - Result operator[](const Value&) const noexcept; + Result operator[](const Value &) const noexcept; }; /** @@ -149,39 +125,62 @@ struct Value * @param result * @return */ -template -zeus::expected try_get(const Result& result) -{ - if (! result.has_value()) - { - return zeus::unexpected(result.error()); - } - - const auto& type_result = result.value(); - if (! std::holds_alternative(type_result.value)) - { - return zeus::unexpected(Error::TypeMismatch); - } - - return std::get(type_result.value); +template +zeus::expected try_get(const Result &result) { + if (!result.has_value()) { + return zeus::unexpected(result.error()); + } + + const auto &type_result = result.value(); + if (!std::holds_alternative(type_result.value)) { + return zeus::unexpected(Error::TypeMismatch); + } + + return std::get(type_result.value); } -Result pow(const Value& lhs, const Value& rhs); +Result pow(const Value &lhs, const Value &rhs); } // namespace CuraFormulaeEngine::eval -bool operator==(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -bool operator!=(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -zeus::expected operator<(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -zeus::expected operator<=(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -zeus::expected operator>=(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -zeus::expected operator>(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -zeus::expected operator&&(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -zeus::expected operator||(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -CuraFormulaeEngine::eval::Result operator+(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -CuraFormulaeEngine::eval::Result operator-(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -CuraFormulaeEngine::eval::Result operator*(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -CuraFormulaeEngine::eval::Result operator/(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -CuraFormulaeEngine::eval::Result operator%(const CuraFormulaeEngine::eval::Value& lhs, const CuraFormulaeEngine::eval::Value& rhs) noexcept; -CuraFormulaeEngine::eval::Result operator!(const CuraFormulaeEngine::eval::Value& operand) noexcept; -CuraFormulaeEngine::eval::Result operator-(const CuraFormulaeEngine::eval::Value& operand) noexcept; +bool operator==(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +bool operator!=(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +zeus::expected +operator<(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +zeus::expected +operator<=(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +zeus::expected +operator>=(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +zeus::expected +operator>(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +zeus::expected +operator&&(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +zeus::expected +operator||(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +CuraFormulaeEngine::eval::Result +operator+(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +CuraFormulaeEngine::eval::Result +operator-(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +CuraFormulaeEngine::eval::Result +operator*(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +CuraFormulaeEngine::eval::Result +operator/(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +CuraFormulaeEngine::eval::Result +operator%(const CuraFormulaeEngine::eval::Value &lhs, + const CuraFormulaeEngine::eval::Value &rhs) noexcept; +CuraFormulaeEngine::eval::Result +operator!(const CuraFormulaeEngine::eval::Value &operand) noexcept; +CuraFormulaeEngine::eval::Result +operator-(const CuraFormulaeEngine::eval::Value &operand) noexcept; diff --git a/include/cura-formulae-engine/formula.md b/include/cura-formulae-engine/formula.md index 9041ecc..420e46f 100644 --- a/include/cura-formulae-engine/formula.md +++ b/include/cura-formulae-engine/formula.md @@ -122,7 +122,7 @@ int main(int argc, const char** argv) CuraFormulaeEngine::env::LocalEnvironment custom_env { &CuraFormulaeEngine::env::std_env }; custom_env.set("x", CuraFormulaeEngine::eval::Value { 2L }); - + if (!message.has_value()) { spdlog::warn("Parse error"); @@ -131,7 +131,7 @@ int main(int argc, const char** argv) const auto& expr = message.value(); const auto eval_result = expr.evaluate(custom_env); - + if (!eval_result.has_value()) { const auto error = eval_result.error(); diff --git a/include/cura-formulae-engine/parser/bool_grammar.h b/include/cura-formulae-engine/parser/bool_grammar.h index faea851..d8805bb 100644 --- a/include/cura-formulae-engine/parser/bool_grammar.h +++ b/include/cura-formulae-engine/parser/bool_grammar.h @@ -7,25 +7,24 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct BoolGrammar : lexy::token_production -{ - struct TrueGrammar - { - static constexpr auto rule = LEXY_LIT("True"); - static constexpr auto value = lexy::callback([]() { return ast::ExprPtr(std::make_unique(true)); }); - }; +struct BoolGrammar : lexy::token_production { + struct TrueGrammar { + static constexpr auto rule = LEXY_LIT("True"); + static constexpr auto value = lexy::callback( + []() { return ast::ExprPtr(std::make_unique(true)); }); + }; - struct FalseGrammar - { - static constexpr auto rule = LEXY_LIT("False"); - static constexpr auto value = lexy::callback([]() { return ast::ExprPtr(std::make_unique(false)); }); - }; + struct FalseGrammar { + static constexpr auto rule = LEXY_LIT("False"); + static constexpr auto value = lexy::callback( + []() { return ast::ExprPtr(std::make_unique(false)); }); + }; - static constexpr auto rule = lexy::dsl::p | lexy::dsl::p; - static constexpr auto value = lexy::forward; + static constexpr auto rule = + lexy::dsl::p | lexy::dsl::p; + static constexpr auto value = lexy::forward; }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/expr_grammar.h b/include/cura-formulae-engine/parser/expr_grammar.h index 6fcf90a..4497303 100644 --- a/include/cura-formulae-engine/parser/expr_grammar.h +++ b/include/cura-formulae-engine/parser/expr_grammar.h @@ -8,28 +8,29 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct ExprGrammar : lexy::expression_production -{ - static constexpr auto whitespace = lexy::dsl::ascii::space; +struct ExprGrammar : lexy::expression_production { + static constexpr auto whitespace = lexy::dsl::ascii::space; - static constexpr auto atom = lexy::dsl::p; + static constexpr auto atom = lexy::dsl::p; - static constexpr auto op_condition = lexy::dsl::op(LEXY_LIT("if") >> lexy::dsl::p + LEXY_LIT("else")); - struct Condition : lexy::dsl::infix_op_right - { - static constexpr auto op = op_condition; - using operand = lexy::dsl::atom; - }; + static constexpr auto op_condition = lexy::dsl::op( + LEXY_LIT("if") >> lexy::dsl::p + LEXY_LIT("else")); + struct Condition : lexy::dsl::infix_op_right { + static constexpr auto op = op_condition; + using operand = lexy::dsl::atom; + }; - using operation = Condition; + using operation = Condition; - static constexpr auto value = lexy::callback( - lexy::forward, - [](ast::ExprPtr&& lhs, lexy::op, ast::ExprPtr&& condition, ast::ExprPtr&& rhs) - { return ast::ExprPtr(std::make_unique(std::move(lhs), std::move(condition), std::move(rhs))); }); + static constexpr auto value = lexy::callback( + lexy::forward, + [](ast::ExprPtr &&lhs, lexy::op, ast::ExprPtr &&condition, + ast::ExprPtr &&rhs) { + return ast::ExprPtr(std::make_unique( + std::move(lhs), std::move(condition), std::move(rhs))); + }); }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/list_comprehension_grammar.h b/include/cura-formulae-engine/parser/list_comprehension_grammar.h index 4a805c7..647f39e 100644 --- a/include/cura-formulae-engine/parser/list_comprehension_grammar.h +++ b/include/cura-formulae-engine/parser/list_comprehension_grammar.h @@ -10,40 +10,59 @@ #include #include -namespace CuraFormulaeEngine::parser -{ - -struct ListComprehensionGrammar : lexy::token_production -{ - static constexpr auto whitespace = lexy::dsl::ascii::space; - - struct condition_chain : token_production - { - static constexpr auto rule = lexy::dsl::list(LEXY_LIT("if") >> lexy::dsl::whitespace(lexy::dsl::ascii::space) + lexy::dsl::p); - static constexpr auto value = lexy::fold_inplace>( - []() { return std::vector{}; }, - [](auto&& conditions, ast::ExprPtr&& condition) { conditions.emplace_back(std::move(condition)); }); - }; - - struct loop : token_production - { - static constexpr auto rule = lexy::dsl::list( - LEXY_LIT("for") >> lexy::dsl::whitespace(lexy::dsl::ascii::space) + lexy::dsl::p + lexy::dsl::whitespace(lexy::dsl::ascii::space) + LEXY_LIT("in") - + lexy::dsl::whitespace(lexy::dsl::ascii::space) + lexy::dsl::p - + lexy::dsl::whitespace(lexy::dsl::ascii::space) + lexy::dsl::opt(lexy::dsl::p)); - - static constexpr auto value = lexy::fold_inplace>( +namespace CuraFormulaeEngine::parser { + +struct ListComprehensionGrammar : lexy::token_production { + static constexpr auto whitespace = lexy::dsl::ascii::space; + + struct condition_chain : token_production { + static constexpr auto rule = lexy::dsl::list( + LEXY_LIT("if") >> lexy::dsl::whitespace(lexy::dsl::ascii::space) + + lexy::dsl::p); + static constexpr auto value = lexy::fold_inplace>( + []() { return std::vector{}; }, + [](auto &&conditions, ast::ExprPtr &&condition) { + conditions.emplace_back(std::move(condition)); + }); + }; + + struct loop : token_production { + static constexpr auto rule = lexy::dsl::list( + LEXY_LIT("for") >> lexy::dsl::whitespace(lexy::dsl::ascii::space) + + lexy::dsl::p + + lexy::dsl::whitespace(lexy::dsl::ascii::space) + + LEXY_LIT("in") + + lexy::dsl::whitespace(lexy::dsl::ascii::space) + + lexy::dsl::p + + lexy::dsl::whitespace(lexy::dsl::ascii::space) + + lexy::dsl::opt(lexy::dsl::p)); + + static constexpr auto value = + lexy::fold_inplace>( []() { return std::vector{}; }, - [](auto&& loops, ast::ExprPtr&& iterator_key, ast::ExprPtr&& iterable, lexy::nullopt) - { loops.emplace_back(ast::ListComprehensionExpr::loop(std::move(iterator_key), std::move(iterable), std::vector{})); }, - [](auto&& loops, ast::ExprPtr&& iterator_key, ast::ExprPtr&& iterable, std::vector&& conditions) - { loops.emplace_back(ast::ListComprehensionExpr::loop(std::move(iterator_key), std::move(iterable), std::move(conditions))); }); - }; - - static constexpr auto rule = lexy::dsl::p + lexy::dsl::opt(lexy::dsl::p); - static constexpr auto value = lexy::callback( - [](auto&& expr, lexy::nullopt) { return std::move(expr); }, - [](auto&& expr, auto&& loops) { return ast::ExprPtr(std::make_unique(std::move(expr), std::move(loops))); }); + [](auto &&loops, ast::ExprPtr &&iterator_key, + ast::ExprPtr &&iterable, lexy::nullopt) { + loops.emplace_back(ast::ListComprehensionExpr::loop( + std::move(iterator_key), std::move(iterable), + std::vector{})); + }, + [](auto &&loops, ast::ExprPtr &&iterator_key, + ast::ExprPtr &&iterable, + std::vector &&conditions) { + loops.emplace_back(ast::ListComprehensionExpr::loop( + std::move(iterator_key), std::move(iterable), + std::move(conditions))); + }); + }; + + static constexpr auto rule = + lexy::dsl::p + lexy::dsl::opt(lexy::dsl::p); + static constexpr auto value = lexy::callback( + [](auto &&expr, lexy::nullopt) { return std::move(expr); }, + [](auto &&expr, auto &&loops) { + return ast::ExprPtr(std::make_unique( + std::move(expr), std::move(loops))); + }); }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/list_grammar.h b/include/cura-formulae-engine/parser/list_grammar.h index 15ddf4a..9d19eab 100644 --- a/include/cura-formulae-engine/parser/list_grammar.h +++ b/include/cura-formulae-engine/parser/list_grammar.h @@ -8,30 +8,37 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct ListGrammar : lexy::token_production -{ - struct ListGrammarInner : token_production - { - static constexpr auto whitespace = lexy::dsl::ascii::space; - static constexpr auto rule = lexy::dsl::square_bracketed.opt_list(lexy::dsl::p, lexy::dsl::ignore_trailing_sep(lexy::dsl::comma)); - static constexpr auto value = lexy::as_list> >> lexy::callback( - [](std::vector exprs) - { - // special case if the list contains a single list comprehension, we evaluate it and return the result - if (exprs.size() == 1 && dynamic_cast(exprs[0].ptr.get()) != nullptr) - { - return std::move(exprs[0]); - } - return ast::ExprPtr(std::make_unique(std::move(exprs))); - }, - [](lexy::nullopt = {}) { return ast::ExprPtr(std::make_unique(std::vector{})); }); - }; +struct ListGrammar : lexy::token_production { + struct ListGrammarInner : token_production { + static constexpr auto whitespace = lexy::dsl::ascii::space; + static constexpr auto rule = lexy::dsl::square_bracketed.opt_list( + lexy::dsl::p, + lexy::dsl::ignore_trailing_sep(lexy::dsl::comma)); + static constexpr auto + value = lexy::as_list> >> + lexy::callback( + [](std::vector exprs) { + // special case if the list contains a single list + // comprehension, we evaluate it and return the result + if (exprs.size() == 1 && + dynamic_cast( + exprs[0].ptr.get()) != nullptr) { + return std::move(exprs[0]); + } + return ast::ExprPtr( + std::make_unique(std::move(exprs))); + }, + [](lexy::nullopt = {}) { + return ast::ExprPtr(std::make_unique( + std::vector{})); + }); + }; - static constexpr auto rule = lexy::dsl::peek(lexy::dsl::lit_c<'['>) >> lexy::dsl::p; - static constexpr auto value = lexy::forward; + static constexpr auto rule = + lexy::dsl::peek(lexy::dsl::lit_c<'['>) >> lexy::dsl::p; + static constexpr auto value = lexy::forward; }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/math_expr_grammar.h b/include/cura-formulae-engine/parser/math_expr_grammar.h index b43d9a1..a9035c9 100644 --- a/include/cura-formulae-engine/parser/math_expr_grammar.h +++ b/include/cura-formulae-engine/parser/math_expr_grammar.h @@ -1,5 +1,6 @@ #pragma once +#include "bool_grammar.h" #include "cura-formulae-engine/ast/binary_expr/add_expr.h" #include "cura-formulae-engine/ast/binary_expr/and_expr.h" #include "cura-formulae-engine/ast/binary_expr/div_expr.h" @@ -12,6 +13,11 @@ #include "cura-formulae-engine/ast/expr_ptr.h" #include "cura-formulae-engine/ast/unary_expr/neg_expr.h" #include "cura-formulae-engine/ast/unary_expr/not_expr.h" +#include "list_grammar.h" +#include "none_grammar.h" +#include "number_grammar.h" +#include "parens_grammar.h" +#include "string_grammar.h" #include "variable_or_fn_application_grammar_or_array_indexing_grammar.h" #include @@ -20,89 +26,79 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct MathExprGrammar : lexy::expression_production -{ - static constexpr auto whitespace = lexy::dsl::ascii::space; +struct MathExprGrammar : lexy::expression_production { + static constexpr auto whitespace = lexy::dsl::ascii::space; - // clang-format off + // clang-format off static constexpr auto atom = lexy::dsl::p; // clang-format on - static constexpr auto op_pow = lexy::dsl::op(LEXY_LIT("**")); - struct number_power : lexy::dsl::infix_op_right - { - static constexpr auto op = op_pow; - using operand = lexy::dsl::atom; - }; - - static constexpr auto op_neg = lexy::dsl::op(LEXY_LIT("-")); - struct number_prefix : lexy::dsl::prefix_op - { - static constexpr auto op = op_neg; - using operand = number_power; - }; - - static constexpr auto op_mul = lexy::dsl::op(LEXY_LIT("*")); - static constexpr auto op_div = lexy::dsl::op(LEXY_LIT("/")); - static constexpr auto op_mod = lexy::dsl::op(LEXY_LIT("%")); - struct number_product : lexy::dsl::infix_op_left - { - using operand = number_prefix; - static constexpr auto op = op_mul / op_div / op_mod; - }; - - - static constexpr auto op_add = lexy::dsl::op(LEXY_LIT("+")); - static constexpr auto op_sub = lexy::dsl::op(LEXY_LIT("-")); - struct number_sum : lexy::dsl::infix_op_left - { - using operand = number_product; - static constexpr auto op = op_add / op_sub; - }; - - static constexpr auto op_eq = lexy::dsl::op(LEXY_LIT("==")); - static constexpr auto op_neq = lexy::dsl::op(LEXY_LIT("!=")); - static constexpr auto op_lt = lexy::dsl::op(LEXY_LIT("<")); - static constexpr auto op_gt = lexy::dsl::op(LEXY_LIT(">")); - static constexpr auto op_leq = lexy::dsl::op(LEXY_LIT("<=")); - static constexpr auto op_geq = lexy::dsl::op(LEXY_LIT(">=")); - static constexpr auto op_not_member = lexy::dsl::op(LEXY_LIT("not in")); - static constexpr auto op_member = lexy::dsl::op(LEXY_LIT("in")); - - struct number_compare : lexy::dsl::infix_op_list - { - using operand = number_sum; - static constexpr auto op = op_eq / op_neq / op_lt / op_gt / op_leq / op_geq / op_not_member / op_member; - }; - - static constexpr auto op_not = lexy::dsl::op(LEXY_LIT("not")); - struct bool_prefix : lexy::dsl::prefix_op - { - static constexpr auto op = op_not; - using operand = number_compare; - }; - - static constexpr auto op_and = lexy::dsl::op(LEXY_LIT("and")); - struct bool_and : lexy::dsl::infix_op_left - { - static constexpr auto op = op_and; - using operand = bool_prefix; - }; - - static constexpr auto op_or = lexy::dsl::op(LEXY_LIT("or")); - struct bool_or : lexy::dsl::infix_op_left - { - static constexpr auto op = op_or; - using operand = bool_and; - }; - - using operation = bool_or; - - // clang-format off + static constexpr auto op_pow = lexy::dsl::op(LEXY_LIT("**")); + struct number_power : lexy::dsl::infix_op_right { + static constexpr auto op = op_pow; + using operand = lexy::dsl::atom; + }; + + static constexpr auto op_neg = lexy::dsl::op(LEXY_LIT("-")); + struct number_prefix : lexy::dsl::prefix_op { + static constexpr auto op = op_neg; + using operand = number_power; + }; + + static constexpr auto op_mul = lexy::dsl::op(LEXY_LIT("*")); + static constexpr auto op_div = lexy::dsl::op(LEXY_LIT("/")); + static constexpr auto op_mod = lexy::dsl::op(LEXY_LIT("%")); + struct number_product : lexy::dsl::infix_op_left { + using operand = number_prefix; + static constexpr auto op = op_mul / op_div / op_mod; + }; + + static constexpr auto op_add = lexy::dsl::op(LEXY_LIT("+")); + static constexpr auto op_sub = lexy::dsl::op(LEXY_LIT("-")); + struct number_sum : lexy::dsl::infix_op_left { + using operand = number_product; + static constexpr auto op = op_add / op_sub; + }; + + static constexpr auto op_eq = lexy::dsl::op(LEXY_LIT("==")); + static constexpr auto op_neq = lexy::dsl::op(LEXY_LIT("!=")); + static constexpr auto op_lt = lexy::dsl::op(LEXY_LIT("<")); + static constexpr auto op_gt = lexy::dsl::op(LEXY_LIT(">")); + static constexpr auto op_leq = lexy::dsl::op(LEXY_LIT("<=")); + static constexpr auto op_geq = lexy::dsl::op(LEXY_LIT(">=")); + static constexpr auto op_not_member = lexy::dsl::op(LEXY_LIT("not in")); + static constexpr auto op_member = lexy::dsl::op(LEXY_LIT("in")); + + struct number_compare : lexy::dsl::infix_op_list { + using operand = number_sum; + static constexpr auto op = op_eq / op_neq / op_lt / op_gt / op_leq / + op_geq / op_not_member / op_member; + }; + + static constexpr auto op_not = lexy::dsl::op(LEXY_LIT("not")); + struct bool_prefix : lexy::dsl::prefix_op { + static constexpr auto op = op_not; + using operand = number_compare; + }; + + static constexpr auto op_and = lexy::dsl::op(LEXY_LIT("and")); + struct bool_and : lexy::dsl::infix_op_left { + static constexpr auto op = op_and; + using operand = bool_prefix; + }; + + static constexpr auto op_or = lexy::dsl::op(LEXY_LIT("or")); + struct bool_or : lexy::dsl::infix_op_left { + static constexpr auto op = op_or; + using operand = bool_and; + }; + + using operation = bool_or; + + // clang-format off static constexpr auto value = lexy::fold_inplace>( [] { return std::make_unique(); }, [](auto&& node, lexy::op) { node->operators.emplace_back(CuraFormulaeEngine::ast::ComparisonOperators::Equals); }, @@ -127,7 +123,7 @@ struct MathExprGrammar : lexy::expression_production [](ast::ExprPtr&& lhs, lexy::op, ast::ExprPtr&& rhs) { return std::move(lhs) && std::move(rhs); }, [](ast::ExprPtr&& lhs, lexy::op, ast::ExprPtr&& rhs) { return std::move(lhs) || std::move(rhs); } ); - // clang-format on + // clang-format on }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/nested_grammar.h b/include/cura-formulae-engine/parser/nested_grammar.h index 1c5ffca..7e9bdaf 100644 --- a/include/cura-formulae-engine/parser/nested_grammar.h +++ b/include/cura-formulae-engine/parser/nested_grammar.h @@ -5,15 +5,13 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { // for recursive grammars, equivalent to `struct expr_grammar` but // written with a forward declaration -struct NestedGrammar : lexy::transparent_production -{ - static constexpr auto rule = lexy::dsl::recurse; - static constexpr auto value = lexy::forward; +struct NestedGrammar : lexy::transparent_production { + static constexpr auto rule = lexy::dsl::recurse; + static constexpr auto value = lexy::forward; }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/none_grammar.h b/include/cura-formulae-engine/parser/none_grammar.h index 503ac15..c8f7f20 100644 --- a/include/cura-formulae-engine/parser/none_grammar.h +++ b/include/cura-formulae-engine/parser/none_grammar.h @@ -6,13 +6,12 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct NoneGrammar -{ - static constexpr auto rule = LEXY_LIT("None"); - static constexpr auto value = lexy::callback([]() { return ast::ExprPtr(std::make_unique()); }); +struct NoneGrammar { + static constexpr auto rule = LEXY_LIT("None"); + static constexpr auto value = lexy::callback( + []() { return ast::ExprPtr(std::make_unique()); }); }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/number_grammar.h b/include/cura-formulae-engine/parser/number_grammar.h index 1059ee8..75250b6 100644 --- a/include/cura-formulae-engine/parser/number_grammar.h +++ b/include/cura-formulae-engine/parser/number_grammar.h @@ -9,22 +9,21 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct NumberGrammar : lexy::token_production -{ - static constexpr auto rule = lexy::dsl::identifier(lexy::dsl::ascii::digit / lexy::dsl::lit_c<'.'>); - static constexpr auto value = lexy::callback( - [](const auto number) - { - const auto number_str = std::string(number.begin(), number.end()); - if (number_str.find('.') != std::string::npos) - { - return static_cast(std::make_unique(std::stod(number_str))); - } - return static_cast(std::make_unique(std::stod(number_str))); - }); +struct NumberGrammar : lexy::token_production { + static constexpr auto rule = + lexy::dsl::identifier(lexy::dsl::ascii::digit / lexy::dsl::lit_c<'.'>); + static constexpr auto value = + lexy::callback([](const auto number) { + const auto number_str = std::string(number.begin(), number.end()); + if (number_str.find('.') != std::string::npos) { + return static_cast( + std::make_unique(std::stod(number_str))); + } + return static_cast( + std::make_unique(std::stod(number_str))); + }); }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/parens_grammar.h b/include/cura-formulae-engine/parser/parens_grammar.h index d9c579c..b285d1a 100644 --- a/include/cura-formulae-engine/parser/parens_grammar.h +++ b/include/cura-formulae-engine/parser/parens_grammar.h @@ -9,23 +9,27 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct ParensGrammar : lexy::token_production -{ - static constexpr auto rule - = lexy::dsl::round_bracketed.opt_list(lexy::dsl::p, lexy::dsl::ignore_trailing_sep(lexy::dsl::comma >> lexy::dsl::whitespace(lexy::dsl::ascii::space))); - static constexpr auto value = lexy::as_list> >> lexy::callback( - [](std::vector exprs) - { - if (exprs.size() == 1) - { - return std::move(exprs[0]); - } - return ast::ExprPtr(std::make_unique(std::move(exprs))); - }, - [](lexy::nullopt = {}) { return ast::ExprPtr(std::make_unique(std::vector{})); }); +struct ParensGrammar : lexy::token_production { + static constexpr auto rule = lexy::dsl::round_bracketed.opt_list( + lexy::dsl::p, + lexy::dsl::ignore_trailing_sep( + lexy::dsl::comma >> lexy::dsl::whitespace(lexy::dsl::ascii::space))); + static constexpr auto + value = lexy::as_list> >> + lexy::callback( + [](std::vector exprs) { + if (exprs.size() == 1) { + return std::move(exprs[0]); + } + return ast::ExprPtr( + std::make_unique(std::move(exprs))); + }, + [](lexy::nullopt = {}) { + return ast::ExprPtr(std::make_unique( + std::vector{})); + }); }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/parser.h b/include/cura-formulae-engine/parser/parser.h index 118e541..bc3a62a 100644 --- a/include/cura-formulae-engine/parser/parser.h +++ b/include/cura-formulae-engine/parser/parser.h @@ -15,13 +15,11 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct Grammar : public lexy::token_production -{ - static constexpr auto rule = lexy::dsl::p + lexy::dsl::eof; - static constexpr auto value = lexy::forward; +struct Grammar : public lexy::token_production { + static constexpr auto rule = lexy::dsl::p + lexy::dsl::eof; + static constexpr auto value = lexy::forward; }; using error_t = typename lexy::validate_result::error_type; diff --git a/include/cura-formulae-engine/parser/string_grammar.h b/include/cura-formulae-engine/parser/string_grammar.h index 9ca02b0..d8026f4 100644 --- a/include/cura-formulae-engine/parser/string_grammar.h +++ b/include/cura-formulae-engine/parser/string_grammar.h @@ -11,51 +11,49 @@ #include #include -namespace CuraFormulaeEngine::parser -{ - -struct StringGrammar : lexy::token_production -{ - static constexpr auto InnerStrGrammar - = lexy::dsl::ascii::alpha_digit_underscore - / lexy::dsl::lit_c<' '> - / lexy::dsl::lit_c<','> - / lexy::dsl::lit_c<'/'> - / lexy::dsl::lit_c<'.'> - / lexy::dsl::lit_c<'_'> - / lexy::dsl::lit_c<'-'> - / lexy::dsl::lit_c<'+'> - / lexy::dsl::lit_c<'('> - / lexy::dsl::lit_c<')'> - / lexy::dsl::lit_c<';'> - / lexy::dsl::lit_c<'\\'> - / lexy::dsl::lit_c<'\n'> - / lexy::dsl::lit_c<'='> - / lexy::dsl::lit_c<'{'> - / lexy::dsl::lit_c<'}'> - / lexy::dsl::lit_c<'>'> - / lexy::dsl::lit_c<'<'> - / lexy::dsl::lit_c<':'> - / lexy::dsl::lit_c<'/'> - / lexy::dsl::lit_c<'!'>; - // clang-format on - - struct DoubleQuoteStringGrammar : token_production - { - static constexpr auto rule = lexy::dsl::lit_c<'\"'> >> lexy::dsl::opt(lexy::dsl::identifier(InnerStrGrammar / lexy::dsl::lit_c<'\''>)) >> lexy::dsl::lit_c<'\"'>; - static constexpr auto value = lexy::as_string; - }; - - struct SingleQuoteStringGrammar : token_production - { - static constexpr auto rule = lexy::dsl::lit_c<'\''> >> lexy::dsl::opt(lexy::dsl::identifier(InnerStrGrammar / lexy::dsl::lit_c<'\"'>)) >> lexy::dsl::lit_c<'\''>; - static constexpr auto value = lexy::as_string; - }; - - static constexpr auto rule = DoubleQuoteStringGrammar::rule | SingleQuoteStringGrammar::rule; - static constexpr auto value = lexy::callback( - [](lexy::nullopt = {}) { return CuraFormulaeEngine::ast::make_expr_ptr(std::string("")); }, - [](const auto& str) { return CuraFormulaeEngine::ast::make_expr_ptr(std::string(str.begin(), str.end())); }); +namespace CuraFormulaeEngine::parser { + +struct StringGrammar : lexy::token_production { + static constexpr auto InnerStrGrammar = + lexy::dsl::ascii::alpha_digit_underscore / lexy::dsl::lit_c<' '> / + lexy::dsl::lit_c<','> / lexy::dsl::lit_c<'/'> / lexy::dsl::lit_c<'.'> / + lexy::dsl::lit_c<'_'> / lexy::dsl::lit_c<'-'> / lexy::dsl::lit_c<'+'> / + lexy::dsl::lit_c<'('> / lexy::dsl::lit_c<')'> / lexy::dsl::lit_c<';'> / + lexy::dsl::lit_c<'\\'> / lexy::dsl::lit_c<'\n'> / lexy::dsl::lit_c<'='> / + lexy::dsl::lit_c<'{'> / lexy::dsl::lit_c<'}'> / lexy::dsl::lit_c<'>'> / + lexy::dsl::lit_c<'<'> / lexy::dsl::lit_c<':'> / lexy::dsl::lit_c<'/'> / + lexy::dsl::lit_c<'!'>; + // clang-format on + + struct DoubleQuoteStringGrammar : token_production { + static constexpr auto + rule = lexy::dsl::lit_c<'\"'> >> + lexy::dsl::opt(lexy::dsl::identifier(InnerStrGrammar / + lexy::dsl::lit_c<'\''>)) >> + lexy::dsl::lit_c<'\"'>; + static constexpr auto value = lexy::as_string; + }; + + struct SingleQuoteStringGrammar : token_production { + static constexpr auto + rule = lexy::dsl::lit_c<'\''> >> + lexy::dsl::opt(lexy::dsl::identifier(InnerStrGrammar / + lexy::dsl::lit_c<'\"'>)) >> + lexy::dsl::lit_c<'\''>; + static constexpr auto value = lexy::as_string; + }; + + static constexpr auto rule = + DoubleQuoteStringGrammar::rule | SingleQuoteStringGrammar::rule; + static constexpr auto value = lexy::callback( + [](lexy::nullopt = {}) { + return CuraFormulaeEngine::ast::make_expr_ptr( + std::string("")); + }, + [](const auto &str) { + return CuraFormulaeEngine::ast::make_expr_ptr( + std::string(str.begin(), str.end())); + }); }; } // namespace CuraFormulaeEngine::parser diff --git a/include/cura-formulae-engine/parser/variable_grammar.h b/include/cura-formulae-engine/parser/variable_grammar.h index 82d1885..61d5630 100644 --- a/include/cura-formulae-engine/parser/variable_grammar.h +++ b/include/cura-formulae-engine/parser/variable_grammar.h @@ -6,8 +6,7 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { struct VariableGrammar : lexy::token_production { diff --git a/include/cura-formulae-engine/parser/variable_or_fn_application_grammar_or_array_indexing_grammar.h b/include/cura-formulae-engine/parser/variable_or_fn_application_grammar_or_array_indexing_grammar.h index 98d3f77..412aac0 100644 --- a/include/cura-formulae-engine/parser/variable_or_fn_application_grammar_or_array_indexing_grammar.h +++ b/include/cura-formulae-engine/parser/variable_or_fn_application_grammar_or_array_indexing_grammar.h @@ -24,54 +24,49 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -struct ApplyExpr -{ - ApplyExpr() = default; - ApplyExpr(const ApplyExpr&) = default; - ApplyExpr(ApplyExpr&&) = default; - ApplyExpr& operator=(const ApplyExpr&) = default; - ApplyExpr& operator=(ApplyExpr&&) = default; - - virtual ~ApplyExpr() = default; - virtual ast::ExprPtr apply(ast::ExprPtr&&) = 0; +struct ApplyExpr { + ApplyExpr() = default; + ApplyExpr(const ApplyExpr &) = default; + ApplyExpr(ApplyExpr &&) = default; + ApplyExpr &operator=(const ApplyExpr &) = default; + ApplyExpr &operator=(ApplyExpr &&) = default; + + virtual ~ApplyExpr() = default; + virtual ast::ExprPtr apply(ast::ExprPtr &&) = 0; }; -struct IndexExpr final : ApplyExpr -{ - IndexExpr() = default; +struct IndexExpr final : ApplyExpr { + IndexExpr() = default; - IndexExpr(std::optional&& index) - : index(std::move(index)) - { - } + IndexExpr(std::optional &&index) : index(std::move(index)) {} - std::optional index; + std::optional index; - ast::ExprPtr apply(ast::ExprPtr&& array) override { return std::move(array)[std::move(index.value())]; } + ast::ExprPtr apply(ast::ExprPtr &&array) override { + return std::move(array)[std::move(index.value())]; + } }; -struct ApplySliceExpr final : ApplyExpr -{ - ApplySliceExpr() = default; +struct ApplySliceExpr final : ApplyExpr { + ApplySliceExpr() = default; - ApplySliceExpr(std::optional&& start_index, std::optional&& end_index, std::optional&& step) - : start_index(std::move(start_index)) - , end_index(std::move(end_index)) - , step(std::move(step)) - { - } + ApplySliceExpr(std::optional &&start_index, + std::optional &&end_index, + std::optional &&step) + : start_index(std::move(start_index)), end_index(std::move(end_index)), + step(std::move(step)) {} - std::optional start_index; - std::optional end_index; - std::optional step; + std::optional start_index; + std::optional end_index; + std::optional step; - ast::ExprPtr apply(ast::ExprPtr&& array) override - { - return { std::make_unique(std::move(array), std::move(start_index), std::move(end_index), std::move(step)) }; - } + ast::ExprPtr apply(ast::ExprPtr &&array) override { + return {std::make_unique( + std::move(array), std::move(start_index), std::move(end_index), + std::move(step))}; + } }; struct ApplyFnApplicationExpr final : ApplyExpr @@ -80,10 +75,8 @@ struct ApplyFnApplicationExpr final : ApplyExpr ApplyFnApplicationExpr() = default; - ApplyFnApplicationExpr(std::vector&& args) - : args(std::move(args)) - { - } + ApplyFnApplicationExpr(std::vector &&args) + : args(std::move(args)) {} ApplyFnApplicationExpr(std::vector&& arg_elements) { @@ -126,19 +119,22 @@ struct ApplyPropertyAccessExpr final : ApplyExpr } }; -struct VariableOrFnApplicationGrammarOrArrayIndexingGrammar : lexy::token_production -{ - struct SliceElementColon : token_production - { - static constexpr auto rule = lexy::dsl::if_(lexy::dsl::peek_not(lexy::dsl::colon) >> lexy::dsl::p); - static constexpr auto value = lexy::callback>([](ast::ExprPtr expr) { return expr; }, []() { return std::nullopt; }); - }; - - struct SliceElementColonOrBracket : token_production - { - static constexpr auto rule = lexy::dsl::if_(lexy::dsl::peek_not(lexy::dsl::colon | lexy::dsl::lit_c<']'>) >> lexy::dsl::p); - static constexpr auto value = lexy::callback>([](ast::ExprPtr expr) { return expr; }, []() { return std::nullopt; }); - }; +struct VariableOrFnApplicationGrammarOrArrayIndexingGrammar + : lexy::token_production { + struct SliceElementColon : token_production { + static constexpr auto rule = lexy::dsl::if_( + lexy::dsl::peek_not(lexy::dsl::colon) >> lexy::dsl::p); + static constexpr auto value = lexy::callback>( + [](ast::ExprPtr expr) { return expr; }, []() { return std::nullopt; }); + }; + + struct SliceElementColonOrBracket : token_production { + static constexpr auto rule = lexy::dsl::if_( + lexy::dsl::peek_not(lexy::dsl::colon | lexy::dsl::lit_c<']'>) >> + lexy::dsl::p); + static constexpr auto value = lexy::callback>( + [](ast::ExprPtr expr) { return expr; }, []() { return std::nullopt; }); + }; struct FnApplicationGrammar : token_production { diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index 9b775e2..6d990f0 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -1,99 +1,89 @@ #include "cura-formulae-engine/ast/ast.h" -namespace CuraFormulaeEngine::env -{ - -std::optional EnvironmentMap::get(const std::string& key) const noexcept -{ - auto iterator = environment_.find(key); - if (iterator == environment_.end()) - { - return std::nullopt; - } - return iterator->second; +namespace CuraFormulaeEngine::env { + +std::optional +EnvironmentMap::get(const std::string &key) const noexcept { + auto iterator = environment_.find(key); + if (iterator == environment_.end()) { + return std::nullopt; + } + return iterator->second; } -bool EnvironmentMap::has(const std::string& key) const noexcept -{ - return environment_.find(key) != environment_.end(); +bool EnvironmentMap::has(const std::string &key) const noexcept { + return environment_.find(key) != environment_.end(); } -std::unordered_map EnvironmentMap::getAll() const noexcept -{ - return environment_; +std::unordered_map +EnvironmentMap::getAll() const noexcept { + return environment_; } -bool EnvironmentMap::erase(const std::string& key) noexcept -{ - return environment_.erase(key) > 0; +bool EnvironmentMap::erase(const std::string &key) noexcept { + return environment_.erase(key) > 0; } -void EnvironmentMap::set(const std::string& key, const eval::Value& value) noexcept -{ - environment_.insert_or_assign(key, value); +void EnvironmentMap::set(const std::string &key, + const eval::Value &value) noexcept { + environment_.insert_or_assign(key, value); } -void EnvironmentMap::add(const std::unordered_map& values) -{ - environment_.insert(values.begin(), values.end()); +void EnvironmentMap::add( + const std::unordered_map &values) { + environment_.insert(values.begin(), values.end()); } -EnvironmentMap EnvironmentMap::clone() const noexcept -{ - return EnvironmentMap{ environment_ }; +EnvironmentMap EnvironmentMap::clone() const noexcept { + return EnvironmentMap{environment_}; } -std::optional LocalEnvironment::getImpl(const std::string& key) const noexcept -{ - return local_environment_.get(key); +std::optional +LocalEnvironment::getImpl(const std::string &key) const noexcept { + return local_environment_.get(key); } -bool LocalEnvironment::hasImpl(const std::string& key) const noexcept -{ - return local_environment_.has(key); +bool LocalEnvironment::hasImpl(const std::string &key) const noexcept { + return local_environment_.has(key); } -std::unordered_map LocalEnvironment::getAllImpl() const noexcept -{ - return local_environment_.getAll(); +std::unordered_map +LocalEnvironment::getAllImpl() const noexcept { + return local_environment_.getAll(); } -void LocalEnvironment::set(const std::string& key, const eval::Value& value) -{ - local_environment_.set(key, value); +void LocalEnvironment::set(const std::string &key, const eval::Value &value) { + local_environment_.set(key, value); } -void LocalEnvironment::add(const std::unordered_map& values) -{ - local_environment_.add(values); +void LocalEnvironment::add( + const std::unordered_map &values) { + local_environment_.add(values); } -std::optional ChainableEnvironment::get(const std::string& key) const noexcept -{ - std::optional value = getImpl(key); - if (! value.has_value() && shadow_environment_) - { - value = shadow_environment_->get(key); - } - return value; +std::optional +ChainableEnvironment::get(const std::string &key) const noexcept { + std::optional value = getImpl(key); + if (!value.has_value() && shadow_environment_) { + value = shadow_environment_->get(key); + } + return value; } -bool ChainableEnvironment::has(const std::string& key) const noexcept -{ - return hasImpl(key) || (shadow_environment_ && shadow_environment_->has(key)); +bool ChainableEnvironment::has(const std::string &key) const noexcept { + return hasImpl(key) || (shadow_environment_ && shadow_environment_->has(key)); } -std::unordered_map ChainableEnvironment::getAll() const noexcept -{ - std::unordered_map all; - if (shadow_environment_) - { - all = shadow_environment_->getAll(); - } - - auto scoped = getAllImpl(); - all.insert(scoped.begin(), scoped.end()); - return all; +std::unordered_map +ChainableEnvironment::getAll() const noexcept { + std::unordered_map all; + if (shadow_environment_) { + all = shadow_environment_->getAll(); + } + + auto scoped = getAllImpl(); + all.insert(scoped.begin(), scoped.end()); + return all; } } // namespace CuraFormulaeEngine::env diff --git a/src/ast/binary_expr/add_expr.cpp b/src/ast/binary_expr/add_expr.cpp index b8348e4..815a09e 100644 --- a/src/ast/binary_expr/add_expr.cpp +++ b/src/ast/binary_expr/add_expr.cpp @@ -4,22 +4,22 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string AddExpr::getOpIdentifier() const noexcept -{ - return "+"; +[[nodiscard]] std::string AddExpr::getOpIdentifier() const noexcept { + return "+"; } -eval::Result AddExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return lhs + rhs; +eval::Result AddExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return lhs + rhs; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator+(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(lhs), std::move(rhs)); +CuraFormulaeEngine::ast::ExprPtr +operator+(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::AddExpr>(std::move(lhs), std::move(rhs)); } diff --git a/src/ast/binary_expr/and_expr.cpp b/src/ast/binary_expr/and_expr.cpp index 5a8c588..39f1629 100644 --- a/src/ast/binary_expr/and_expr.cpp +++ b/src/ast/binary_expr/and_expr.cpp @@ -5,22 +5,22 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string AndExpr::getOpIdentifier() const noexcept -{ - return "and"; +[[nodiscard]] std::string AndExpr::getOpIdentifier() const noexcept { + return "and"; } -eval::Result AndExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return lhs && rhs; +eval::Result AndExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return lhs && rhs; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator&&(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(lhs), std::move(rhs)); +CuraFormulaeEngine::ast::ExprPtr +operator&&(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::AndExpr>(std::move(lhs), std::move(rhs)); } diff --git a/src/ast/binary_expr/binary_expr.cpp b/src/ast/binary_expr/binary_expr.cpp index e7f0b41..790f6b0 100644 --- a/src/ast/binary_expr/binary_expr.cpp +++ b/src/ast/binary_expr/binary_expr.cpp @@ -7,57 +7,53 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string BinaryExpr::toString() const noexcept -{ - return fmt::format("({} {} {})", lhs.toString(), getOpIdentifier(), rhs.toString()); +[[nodiscard]] std::string BinaryExpr::toString() const noexcept { + return fmt::format("({} {} {})", lhs.toString(), getOpIdentifier(), + rhs.toString()); } -[[nodiscard]] eval::Result BinaryExpr::evaluate(const env::Environment* environment) const noexcept -{ - const auto lhs_result = lhs.evaluate(environment); - if (! lhs_result.has_value()) - { - return zeus::unexpected(lhs_result.error()); - } - auto lhs_eval = lhs_result.value(); - - const auto rhs_result = rhs.evaluate(environment); - if (! rhs_result.has_value()) - { - return zeus::unexpected(rhs_result.error()); - } - auto rhs_eval = rhs_result.value(); - - return evaluate(lhs_eval, rhs_eval); +[[nodiscard]] eval::Result +BinaryExpr::evaluate(const env::Environment *environment) const noexcept { + const auto lhs_result = lhs.evaluate(environment); + if (!lhs_result.has_value()) { + return zeus::unexpected(lhs_result.error()); + } + auto lhs_eval = lhs_result.value(); + + const auto rhs_result = rhs.evaluate(environment); + if (!rhs_result.has_value()) { + return zeus::unexpected(rhs_result.error()); + } + auto rhs_eval = rhs_result.value(); + + return evaluate(lhs_eval, rhs_eval); } -[[nodiscard]] std::unordered_set BinaryExpr::freeVariables() const noexcept -{ - auto lhs_free_variables = lhs.freeVariables(); - auto rhs_free_variables = rhs.freeVariables(); - lhs_free_variables.insert(rhs_free_variables.begin(), rhs_free_variables.end()); - return lhs_free_variables; +[[nodiscard]] std::unordered_set +BinaryExpr::freeVariables() const noexcept { + auto lhs_free_variables = lhs.freeVariables(); + auto rhs_free_variables = rhs.freeVariables(); + lhs_free_variables.insert(rhs_free_variables.begin(), + rhs_free_variables.end()); + return lhs_free_variables; } -[[nodiscard]] bool BinaryExpr::deepEq(const Expr& other) const noexcept -{ - if (typeid(*this) != typeid(other)) - { - return false; - } - const auto& other_binary_expr = static_cast(other); - return lhs.deepEq(other_binary_expr.lhs) && rhs.deepEq(other_binary_expr.rhs); +[[nodiscard]] bool BinaryExpr::deepEq(const Expr &other) const noexcept { + if (typeid(*this) != typeid(other)) { + return false; + } + const auto &other_binary_expr = static_cast(other); + return lhs.deepEq(other_binary_expr.lhs) && rhs.deepEq(other_binary_expr.rhs); } -void BinaryExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void BinaryExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); - lhs.visitAll(visitor); - rhs.visitAll(visitor); + lhs.visitAll(visitor); + rhs.visitAll(visitor); } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/binary_expr/div_expr.cpp b/src/ast/binary_expr/div_expr.cpp index 8250b16..0196c78 100644 --- a/src/ast/binary_expr/div_expr.cpp +++ b/src/ast/binary_expr/div_expr.cpp @@ -4,22 +4,22 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string DivExpr::getOpIdentifier() const noexcept -{ - return "/"; +[[nodiscard]] std::string DivExpr::getOpIdentifier() const noexcept { + return "/"; } -eval::Result DivExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return lhs / rhs; +eval::Result DivExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return lhs / rhs; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator/(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(lhs), std::move(rhs)); +CuraFormulaeEngine::ast::ExprPtr +operator/(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::DivExpr>(std::move(lhs), std::move(rhs)); } diff --git a/src/ast/binary_expr/mod_expr.cpp b/src/ast/binary_expr/mod_expr.cpp index 7c51e96..d0bbae8 100644 --- a/src/ast/binary_expr/mod_expr.cpp +++ b/src/ast/binary_expr/mod_expr.cpp @@ -4,22 +4,22 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string ModExpr::getOpIdentifier() const noexcept -{ - return "%"; +[[nodiscard]] std::string ModExpr::getOpIdentifier() const noexcept { + return "%"; } -eval::Result ModExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return lhs % rhs; +eval::Result ModExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return lhs % rhs; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator%(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(lhs), std::move(rhs)); +CuraFormulaeEngine::ast::ExprPtr +operator%(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::ModExpr>(std::move(lhs), std::move(rhs)); } diff --git a/src/ast/binary_expr/mul_expr.cpp b/src/ast/binary_expr/mul_expr.cpp index 1a71d95..2a9bc0d 100644 --- a/src/ast/binary_expr/mul_expr.cpp +++ b/src/ast/binary_expr/mul_expr.cpp @@ -3,22 +3,22 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string MulExpr::getOpIdentifier() const noexcept -{ - return "*"; +[[nodiscard]] std::string MulExpr::getOpIdentifier() const noexcept { + return "*"; } -eval::Result MulExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return lhs * rhs; +eval::Result MulExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return lhs * rhs; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator*(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(lhs), std::move(rhs)); +CuraFormulaeEngine::ast::ExprPtr +operator*(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::MulExpr>(std::move(lhs), std::move(rhs)); } diff --git a/src/ast/binary_expr/or_expr.cpp b/src/ast/binary_expr/or_expr.cpp index b778dc6..3d78343 100644 --- a/src/ast/binary_expr/or_expr.cpp +++ b/src/ast/binary_expr/or_expr.cpp @@ -4,22 +4,22 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string OrExpr::getOpIdentifier() const noexcept -{ - return "or"; +[[nodiscard]] std::string OrExpr::getOpIdentifier() const noexcept { + return "or"; } -eval::Result OrExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return lhs || rhs; +eval::Result OrExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return lhs || rhs; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator||(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(lhs), std::move(rhs)); +CuraFormulaeEngine::ast::ExprPtr +operator||(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::OrExpr>(std::move(lhs), std::move(rhs)); } diff --git a/src/ast/binary_expr/pow_expr.cpp b/src/ast/binary_expr/pow_expr.cpp index c84cd25..8e58d41 100644 --- a/src/ast/binary_expr/pow_expr.cpp +++ b/src/ast/binary_expr/pow_expr.cpp @@ -3,17 +3,15 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string PowExpr::getOpIdentifier() const noexcept -{ - return "**"; +[[nodiscard]] std::string PowExpr::getOpIdentifier() const noexcept { + return "**"; } -eval::Result PowExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return eval::pow(lhs, rhs); +eval::Result PowExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return eval::pow(lhs, rhs); } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/binary_expr/sub_expr.cpp b/src/ast/binary_expr/sub_expr.cpp index 4df0cd7..0e3235f 100644 --- a/src/ast/binary_expr/sub_expr.cpp +++ b/src/ast/binary_expr/sub_expr.cpp @@ -3,22 +3,22 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string SubExpr::getOpIdentifier() const noexcept -{ - return "-"; +[[nodiscard]] std::string SubExpr::getOpIdentifier() const noexcept { + return "-"; } -eval::Result SubExpr::evaluate(eval::Value& lhs, eval::Value& rhs) const noexcept -{ - return lhs - rhs; +eval::Result SubExpr::evaluate(eval::Value &lhs, + eval::Value &rhs) const noexcept { + return lhs - rhs; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator-(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(lhs), std::move(rhs)); +CuraFormulaeEngine::ast::ExprPtr +operator-(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::SubExpr>(std::move(lhs), std::move(rhs)); } diff --git a/src/ast/comp_chain_expr.cpp b/src/ast/comp_chain_expr.cpp index 4afefb3..6387b45 100644 --- a/src/ast/comp_chain_expr.cpp +++ b/src/ast/comp_chain_expr.cpp @@ -7,244 +7,224 @@ #include #include -namespace CuraFormulaeEngine::ast -{ - -[[nodiscard]] std::string ComparisonChainExpr::toString() const noexcept -{ - std::string result; - for (size_t i = 0; i < operators.size(); ++i) - { - result += expressions[i].toString(); - switch (operators[i]) - { - case Equals: - result += " == "; - break; - case NotEquals: - result += " != "; - break; - case LessThan: - result += " < "; - break; - case GreaterThan: - result += " > "; - break; - case LessThenEqual: - result += " <= "; - break; - case GreaterThenEqual: - result += " >= "; - break; - case NotMember: - result += " not in "; - break; - case Member: - result += " in "; - break; - } +namespace CuraFormulaeEngine::ast { + +[[nodiscard]] std::string ComparisonChainExpr::toString() const noexcept { + std::string result; + for (size_t i = 0; i < operators.size(); ++i) { + result += expressions[i].toString(); + switch (operators[i]) { + case Equals: + result += " == "; + break; + case NotEquals: + result += " != "; + break; + case LessThan: + result += " < "; + break; + case GreaterThan: + result += " > "; + break; + case LessThenEqual: + result += " <= "; + break; + case GreaterThenEqual: + result += " >= "; + break; + case NotMember: + result += " not in "; + break; + case Member: + result += " in "; + break; } - result += expressions.back().toString(); - return result; + } + result += expressions.back().toString(); + return result; } -[[nodiscard]] eval::Result ComparisonChainExpr::evaluate(const env::Environment* environment) const noexcept -{ - assert(expressions.size() == operators.size() + 1); +[[nodiscard]] eval::Result ComparisonChainExpr::evaluate( + const env::Environment *environment) const noexcept { + assert(expressions.size() == operators.size() + 1); - const auto left_value_result = expressions[0].evaluate(environment); - if (!left_value_result.has_value()) - { - return zeus::unexpected(left_value_result.error()); - } - auto left_value = left_value_result.value(); - - for (size_t i = 0; i < operators.size(); i ++) - { - const auto right_value_result = expressions[i + 1].evaluate(environment); - if (!right_value_result.has_value()) - { - return zeus::unexpected(right_value_result.error()); - } - const auto& right_value = right_value_result.value(); - - eval::Result comparison_result; - switch (operators[i]) - { - case Equals: - comparison_result = left_value == right_value; - break; - case NotEquals: - comparison_result = !(left_value == right_value); - break; - case LessThan: - comparison_result = left_value < right_value; - break; - case GreaterThan: - comparison_result = left_value > right_value; - break; - case LessThenEqual: - comparison_result = left_value_result.value() <= right_value_result.value(); - break; - case GreaterThenEqual: - comparison_result = left_value_result.value() >= right_value_result.value(); - break; - case Member: - case NotMember: - { - bool found = false; - if (std::holds_alternative(right_value.value)) - { - if (!std::holds_alternative(left_value.value)) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - const auto& haystack = std::get(right_value.value); - const auto& needle = std::get(left_value.value); - found = haystack.find(needle) != std::string::npos; - } - else if (std::holds_alternative>(right_value.value)) - { - const auto& list = std::get>(right_value.value); - found = std::ranges::any_of(list, [&](const eval::Value& item) { return left_value == item; }); - } - else - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - comparison_result = (operators[i] == Member) ? found : !found; - break; - } - } + const auto left_value_result = expressions[0].evaluate(environment); + if (!left_value_result.has_value()) { + return zeus::unexpected(left_value_result.error()); + } + auto left_value = left_value_result.value(); - if (!comparison_result.has_value()) - { - return zeus::unexpected(comparison_result.error()); + for (size_t i = 0; i < operators.size(); i++) { + const auto right_value_result = expressions[i + 1].evaluate(environment); + if (!right_value_result.has_value()) { + return zeus::unexpected(right_value_result.error()); + } + const auto &right_value = right_value_result.value(); + + eval::Result comparison_result; + switch (operators[i]) { + case Equals: + comparison_result = left_value == right_value; + break; + case NotEquals: + comparison_result = !(left_value == right_value); + break; + case LessThan: + comparison_result = left_value < right_value; + break; + case GreaterThan: + comparison_result = left_value > right_value; + break; + case LessThenEqual: + comparison_result = left_value <= right_value; + break; + case GreaterThenEqual: + comparison_result = left_value >= right_value; + break; + case Member: + case NotMember: { + bool found = false; + if (std::holds_alternative(right_value.value)) { + if (!std::holds_alternative(left_value.value)) { + return zeus::unexpected(eval::Error::TypeMismatch); } + const auto &haystack = std::get(right_value.value); + const auto &needle = std::get(left_value.value); + found = haystack.find(needle) != std::string::npos; + } else if (std::holds_alternative>(right_value.value)) { + const auto &list = std::get>(right_value.value); + found = std::ranges::any_of(list, [&](const eval::Value &item) { return left_value == item; }); + } else { + return zeus::unexpected(eval::Error::TypeMismatch); + } + comparison_result = (operators[i] == Member) ? found : !found; + break; + } + } - if (!comparison_result.value().isTruthy()) - { - return false; - } + if (!comparison_result.has_value()) { + return zeus::unexpected(comparison_result.error()); + } - left_value = right_value; + if (!comparison_result.value().isTruthy()) { + return false; } - return true; + left_value = right_value; + } + + return true; } -[[nodiscard]] std::unordered_set ComparisonChainExpr::freeVariables() const noexcept -{ - std::unordered_set free_vars; - for (const auto& expr : expressions) - { - const auto expr_free_vars = expr.freeVariables(); - free_vars.insert(expr_free_vars.begin(), expr_free_vars.end()); - } - return free_vars; +[[nodiscard]] std::unordered_set +ComparisonChainExpr::freeVariables() const noexcept { + std::unordered_set free_vars; + for (const auto &expr : expressions) { + const auto expr_free_vars = expr.freeVariables(); + free_vars.insert(expr_free_vars.begin(), expr_free_vars.end()); + } + return free_vars; } -[[nodiscard]] bool ComparisonChainExpr::deepEq(const Expr& other) const noexcept -{ - if (const auto other_comp_chain_expr = dynamic_cast(&other)) - { - if (operators.size() != other_comp_chain_expr->operators.size() || expressions.size() != other_comp_chain_expr->expressions.size()) - { - return false; - } - for (size_t i = 0; i < operators.size(); ++i) - { - if (operators[i] != other_comp_chain_expr->operators[i]) - { - return false; - } - } - for (size_t i = 0; i < expressions.size(); ++i) - { - if (!expressions[i].deepEq(other_comp_chain_expr->expressions[i])) - { - return false; - } - } - return true; +[[nodiscard]] bool +ComparisonChainExpr::deepEq(const Expr &other) const noexcept { + if (const auto other_comp_chain_expr = + dynamic_cast(&other)) { + if (operators.size() != other_comp_chain_expr->operators.size() || + expressions.size() != other_comp_chain_expr->expressions.size()) { + return false; + } + for (size_t i = 0; i < operators.size(); ++i) { + if (operators[i] != other_comp_chain_expr->operators[i]) { + return false; + } + } + for (size_t i = 0; i < expressions.size(); ++i) { + if (!expressions[i].deepEq(other_comp_chain_expr->expressions[i])) { + return false; + } } - return false; + return true; + } + return false; } -void ComparisonChainExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void ComparisonChainExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); - for (const auto& expr : expressions) - { - expr.visitAll(visitor); - } + for (const auto &expr : expressions) { + expr.visitAll(visitor); + } } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator==(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - std::vector expressions; - expressions.push_back(std::move(lhs)); - expressions.push_back(std::move(rhs)); - return CuraFormulaeEngine::ast::make_expr_ptr( - std::move(expressions), - std::vector{ CuraFormulaeEngine::ast::Equals } - ); +CuraFormulaeEngine::ast::ExprPtr +operator==(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + std::vector expressions; + expressions.push_back(std::move(lhs)); + expressions.push_back(std::move(rhs)); + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::ComparisonChainExpr>( + std::move(expressions), std::vector{CuraFormulaeEngine::ast::Equals}); } -CuraFormulaeEngine::ast::ExprPtr operator!=(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - std::vector expressions; - expressions.push_back(std::move(lhs)); - expressions.push_back(std::move(rhs)); - return CuraFormulaeEngine::ast::make_expr_ptr( - std::move(expressions), - std::vector{ CuraFormulaeEngine::ast::NotEquals } - ); +CuraFormulaeEngine::ast::ExprPtr +operator!=(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + std::vector expressions; + expressions.push_back(std::move(lhs)); + expressions.push_back(std::move(rhs)); + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::ComparisonChainExpr>( + std::move(expressions), std::vector{CuraFormulaeEngine::ast::NotEquals}); } -CuraFormulaeEngine::ast::ExprPtr operator>=(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - std::vector expressions; - expressions.push_back(std::move(lhs)); - expressions.push_back(std::move(rhs)); - return CuraFormulaeEngine::ast::make_expr_ptr( - std::move(expressions), - std::vector{ CuraFormulaeEngine::ast::GreaterThenEqual } - ); +CuraFormulaeEngine::ast::ExprPtr +operator>=(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + std::vector expressions; + expressions.push_back(std::move(lhs)); + expressions.push_back(std::move(rhs)); + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::ComparisonChainExpr>( + std::move(expressions), + std::vector{CuraFormulaeEngine::ast::GreaterThenEqual}); } -CuraFormulaeEngine::ast::ExprPtr operator>(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - std::vector expressions; - expressions.push_back(std::move(lhs)); - expressions.push_back(std::move(rhs)); - return CuraFormulaeEngine::ast::make_expr_ptr( - std::move(expressions), - std::vector{ CuraFormulaeEngine::ast::GreaterThan } - ); +CuraFormulaeEngine::ast::ExprPtr +operator>(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + std::vector expressions; + expressions.push_back(std::move(lhs)); + expressions.push_back(std::move(rhs)); + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::ComparisonChainExpr>( + std::move(expressions), + std::vector{CuraFormulaeEngine::ast::GreaterThan}); } -CuraFormulaeEngine::ast::ExprPtr operator<=(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - std::vector expressions; - expressions.push_back(std::move(lhs)); - expressions.push_back(std::move(rhs)); - return CuraFormulaeEngine::ast::make_expr_ptr( - std::move(expressions), - std::vector{ CuraFormulaeEngine::ast::LessThenEqual } - ); +CuraFormulaeEngine::ast::ExprPtr +operator<=(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + std::vector expressions; + expressions.push_back(std::move(lhs)); + expressions.push_back(std::move(rhs)); + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::ComparisonChainExpr>( + std::move(expressions), + std::vector{CuraFormulaeEngine::ast::LessThenEqual}); } -CuraFormulaeEngine::ast::ExprPtr operator<(CuraFormulaeEngine::ast::ExprPtr lhs, CuraFormulaeEngine::ast::ExprPtr rhs) -{ - std::vector expressions; - expressions.push_back(std::move(lhs)); - expressions.push_back(std::move(rhs)); - return CuraFormulaeEngine::ast::make_expr_ptr( - std::move(expressions), - std::vector{ CuraFormulaeEngine::ast::LessThan } - ); +CuraFormulaeEngine::ast::ExprPtr +operator<(CuraFormulaeEngine::ast::ExprPtr lhs, + CuraFormulaeEngine::ast::ExprPtr rhs) { + std::vector expressions; + expressions.push_back(std::move(lhs)); + expressions.push_back(std::move(rhs)); + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::ComparisonChainExpr>( + std::move(expressions), std::vector{CuraFormulaeEngine::ast::LessThan}); } diff --git a/src/ast/condition_expr.cpp b/src/ast/condition_expr.cpp index da10614..61bee50 100644 --- a/src/ast/condition_expr.cpp +++ b/src/ast/condition_expr.cpp @@ -7,60 +7,56 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string ConditionExpr::toString() const noexcept -{ - return fmt::format("({} if {} else {})", then_expr.toString(), condition.toString(), else_expr.toString()); +[[nodiscard]] std::string ConditionExpr::toString() const noexcept { + return fmt::format("({} if {} else {})", then_expr.toString(), + condition.toString(), else_expr.toString()); } -[[nodiscard]] eval::Result ConditionExpr::evaluate(const env::Environment* environment) const noexcept -{ - const auto condition_result = condition.evaluate(environment); - if (! condition_result.has_value()) - { - return zeus::unexpected(condition_result.error()); - } - const auto& condition_value = condition_result.value(); - - if (condition_value.isTruthy()) - { - return then_expr.evaluate(environment); - } - return else_expr.evaluate(environment); +[[nodiscard]] eval::Result +ConditionExpr::evaluate(const env::Environment *environment) const noexcept { + const auto condition_result = condition.evaluate(environment); + if (!condition_result.has_value()) { + return zeus::unexpected(condition_result.error()); + } + const auto &condition_value = condition_result.value(); + + if (condition_value.isTruthy()) { + return then_expr.evaluate(environment); + } + return else_expr.evaluate(environment); } -[[nodiscard]] std::unordered_set ConditionExpr::freeVariables() const noexcept -{ - auto condition_vars = condition.freeVariables(); - auto then_vars = then_expr.freeVariables(); - auto else_vars = else_expr.freeVariables(); - condition_vars.insert(then_vars.begin(), then_vars.end()); - condition_vars.insert(else_vars.begin(), else_vars.end()); - return condition_vars; +[[nodiscard]] std::unordered_set +ConditionExpr::freeVariables() const noexcept { + auto condition_vars = condition.freeVariables(); + auto then_vars = then_expr.freeVariables(); + auto else_vars = else_expr.freeVariables(); + condition_vars.insert(then_vars.begin(), then_vars.end()); + condition_vars.insert(else_vars.begin(), else_vars.end()); + return condition_vars; } -[[nodiscard]] bool ConditionExpr::deepEq(const Expr& other) const noexcept -{ - if (const auto other_condition_expr = dynamic_cast(&other)) - { - // clang-format off +[[nodiscard]] bool ConditionExpr::deepEq(const Expr &other) const noexcept { + if (const auto other_condition_expr = + dynamic_cast(&other)) { + // clang-format off return then_expr.deepEq(other_condition_expr->then_expr) && condition.deepEq(other_condition_expr->condition) && else_expr.deepEq(other_condition_expr->else_expr); - // clang-format on - } - return false; + // clang-format on + } + return false; } -void ConditionExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void ConditionExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); - then_expr.visitAll(visitor); - condition.visitAll(visitor); - else_expr.visitAll(visitor); + then_expr.visitAll(visitor); + condition.visitAll(visitor); + else_expr.visitAll(visitor); } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/expr_ptr.cpp b/src/ast/expr_ptr.cpp index 2a7e8eb..aae0ce3 100644 --- a/src/ast/expr_ptr.cpp +++ b/src/ast/expr_ptr.cpp @@ -4,42 +4,36 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -eval::Result ExprPtr::evaluate(const env::Environment* environment) const noexcept -{ - return ptr->evaluate(environment); +eval::Result +ExprPtr::evaluate(const env::Environment *environment) const noexcept { + return ptr->evaluate(environment); } -std::unordered_set ExprPtr::freeVariables() const noexcept -{ - return ptr->freeVariables(); +std::unordered_set ExprPtr::freeVariables() const noexcept { + return ptr->freeVariables(); } -std::string ExprPtr::toString() const noexcept -{ - return ptr->toString(); -} +std::string ExprPtr::toString() const noexcept { return ptr->toString(); } -bool ExprPtr::deepEq(const Expr& other) const noexcept -{ - if (const auto& other_ptr = dynamic_cast(&other)) - { - return ptr->deepEq(*other_ptr->ptr); - } - return false; +bool ExprPtr::deepEq(const Expr &other) const noexcept { + if (const auto &other_ptr = dynamic_cast(&other)) { + return ptr->deepEq(*other_ptr->ptr); + } + return false; } -void ExprPtr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); - ptr->visitAll(visitor); +void ExprPtr::visitAll( + std::function visitor) const noexcept { + visitor(*this); + ptr->visitAll(visitor); } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr CuraFormulaeEngine::ast::ExprPtr::operator[](ExprPtr other) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(*this), std::move(other)); +CuraFormulaeEngine::ast::ExprPtr +CuraFormulaeEngine::ast::ExprPtr::operator[](ExprPtr other) { + return CuraFormulaeEngine::ast::make_expr_ptr(std::move(*this), + std::move(other)); } diff --git a/src/ast/fn_application_expr.cpp b/src/ast/fn_application_expr.cpp index cc84cee..24f912b 100644 --- a/src/ast/fn_application_expr.cpp +++ b/src/ast/fn_application_expr.cpp @@ -97,11 +97,10 @@ zeus::expected, eval::Error> bindKeywordArguments( auto args_str = all_args | ranges::views::join(ranges::views::c_str(", ")) | ranges::to(); - if (const auto& variable = dynamic_cast(fn.ptr.get())) - { - return fmt::format("({}({}))", variable->name, args_str); - } - return fmt::format("(({})({}))", fn.toString(), args_str); + if (const auto &variable = dynamic_cast(fn.ptr.get())) { + return fmt::format("({}({}))", variable->name, args_str); + } + return fmt::format("(({})({}))", fn.toString(), args_str); } [[nodiscard]] eval::Result FnApplicationExpr::evaluate(const env::Environment* environment) const noexcept @@ -228,9 +227,9 @@ zeus::expected, eval::Error> bindKeywordArguments( return false; } -void FnApplicationExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void FnApplicationExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); fn.visitAll(visitor); for (const auto& arg : args) diff --git a/src/ast/index_expr.cpp b/src/ast/index_expr.cpp index 99f8669..0673498 100644 --- a/src/ast/index_expr.cpp +++ b/src/ast/index_expr.cpp @@ -10,55 +10,50 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string IndexExpr::toString() const noexcept -{ - return fmt::format("{}[{}]", array.toString(), index.toString()); +[[nodiscard]] std::string IndexExpr::toString() const noexcept { + return fmt::format("{}[{}]", array.toString(), index.toString()); } -[[nodiscard]] eval::Result IndexExpr::evaluate(const env::Environment* environment) const noexcept -{ - const auto array_result = array.evaluate(environment); - if (! array_result.has_value()) - { - return zeus::unexpected(array_result.error()); - } - const auto& array_value = array_result.value(); - - const auto index_result = index.evaluate(environment); - if (! index_result.has_value()) - { - return zeus::unexpected(index_result.error()); - } - const auto& index_value = index_result.value(); - - return array_value[index_value]; +[[nodiscard]] eval::Result +IndexExpr::evaluate(const env::Environment *environment) const noexcept { + const auto array_result = array.evaluate(environment); + if (!array_result.has_value()) { + return zeus::unexpected(array_result.error()); + } + const auto &array_value = array_result.value(); + + const auto index_result = index.evaluate(environment); + if (!index_result.has_value()) { + return zeus::unexpected(index_result.error()); + } + const auto &index_value = index_result.value(); + + return array_value[index_value]; } -[[nodiscard]] std::unordered_set IndexExpr::freeVariables() const noexcept -{ - auto array_vars = array.freeVariables(); - auto index_vars = index.freeVariables(); - array_vars.insert(index_vars.begin(), index_vars.end()); - return array_vars; +[[nodiscard]] std::unordered_set +IndexExpr::freeVariables() const noexcept { + auto array_vars = array.freeVariables(); + auto index_vars = index.freeVariables(); + array_vars.insert(index_vars.begin(), index_vars.end()); + return array_vars; } -[[nodiscard]] bool IndexExpr::deepEq(const Expr& other) const noexcept -{ - if (const auto other_index_expr = dynamic_cast(&other)) - { - return array.deepEq(other_index_expr->array) && index.deepEq(other_index_expr->index); - } - return false; +[[nodiscard]] bool IndexExpr::deepEq(const Expr &other) const noexcept { + if (const auto other_index_expr = dynamic_cast(&other)) { + return array.deepEq(other_index_expr->array) && + index.deepEq(other_index_expr->index); + } + return false; } -void IndexExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); - array.visitAll(visitor); - index.visitAll(visitor); +void IndexExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); + array.visitAll(visitor); + index.visitAll(visitor); } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/list_comprehension_expr.cpp b/src/ast/list_comprehension_expr.cpp index 14e509a..7fb564a 100644 --- a/src/ast/list_comprehension_expr.cpp +++ b/src/ast/list_comprehension_expr.cpp @@ -15,193 +15,171 @@ #include #include -namespace CuraFormulaeEngine::ast -{ - -[[nodiscard]] std::string ListComprehensionExpr::toString() const noexcept -{ - const auto loops_str = loops - | ranges::views::transform( - [](const auto& loop) - { - if (loop.conditions.empty()) - { - return fmt::format("for {} in {}", loop.iterator_key.toString(), loop.iterable.toString()); - } - const auto conditions_str = loop.conditions - | ranges::views::transform([](const auto& condition) { return fmt::format("if {}", condition.toString()); }) - | ranges::views::join(ranges::views::c_str(" ")) | ranges::to(); - return fmt::format("for {} in {} {}", loop.iterator_key.toString(), loop.iterable.toString(), conditions_str); - }) - | ranges::views::join(ranges::views::c_str(" ")) | ranges::to(); - - return fmt::format("({} {})", iterator.toString(), loops_str); +namespace CuraFormulaeEngine::ast { + +[[nodiscard]] std::string ListComprehensionExpr::toString() const noexcept { + const auto loops_str = + loops | ranges::views::transform([](const auto &loop) { + if (loop.conditions.empty()) { + return fmt::format("for {} in {}", loop.iterator_key.toString(), + loop.iterable.toString()); + } + const auto conditions_str = + loop.conditions | + ranges::views::transform([](const auto &condition) { + return fmt::format("if {}", condition.toString()); + }) | + ranges::views::join(ranges::views::c_str(" ")) | + ranges::to(); + return fmt::format("for {} in {} {}", loop.iterator_key.toString(), + loop.iterable.toString(), conditions_str); + }) | + ranges::views::join(ranges::views::c_str(" ")) | + ranges::to(); + + return fmt::format("({} {})", iterator.toString(), loops_str); } -std::optional ListComprehensionExpr::handle_loop(const size_t loop_index, env::LocalEnvironment& local_environment, std::vector& results) const -{ - if (loop_index >= loops.size()) - { - assert(loops.size() == 0 && "loops in list comprehension cannot be empty"); - throw std::runtime_error("loops in list comprehension cannot be empty"); +std::optional +ListComprehensionExpr::handle_loop(const size_t loop_index, + env::LocalEnvironment &local_environment, + std::vector &results) const { + if (loop_index >= loops.size()) { + assert(loops.size() == 0 && "loops in list comprehension cannot be empty"); + throw std::runtime_error("loops in list comprehension cannot be empty"); + } + + const auto &loop = loops[loop_index]; + const auto iterable_result = try_get>( + loop.iterable.evaluate(&local_environment)); + if (!iterable_result.has_value()) { + return iterable_result.error(); + } + const auto iterable_value = iterable_result.value(); + + for (const auto &element : iterable_value) { + for (const auto &key : loop.iterator_key.freeVariables()) { + local_environment.set(key, element); } - const auto& loop = loops[loop_index]; - const auto iterable_result = try_get>(loop.iterable.evaluate(&local_environment)); - if (! iterable_result.has_value()) - { - return iterable_result.error(); + auto exit_loop = false; + for (const auto &condition : loop.conditions) { + const auto condition_result = condition.evaluate(&local_environment); + if (!condition_result.has_value()) { + return condition_result.error(); + } + const auto &condition_value = condition_result.value(); + + if (!condition_value.isTruthy()) { + exit_loop = true; + break; + } } - const auto iterable_value = iterable_result.value(); - - for (const auto& element : iterable_value) - { - for (const auto& key : loop.iterator_key.freeVariables()) - { - local_environment.set(key, element); - } - - auto exit_loop = false; - for (const auto& condition : loop.conditions) - { - const auto condition_result = condition.evaluate(&local_environment); - if (! condition_result.has_value()) - { - return condition_result.error(); - } - const auto& condition_value = condition_result.value(); - - if (! condition_value.isTruthy()) - { - exit_loop = true; - break; - } - } - if (exit_loop) - { - continue; - } + if (exit_loop) { + continue; + } - if (loop_index + 1 == loops.size()) - { - const auto iterator_result = iterator.evaluate(&local_environment); - if (! iterator_result.has_value()) - { - return iterator_result.error(); - } - results.push_back(iterator_result.value()); - } - else - { - const auto loop_err = handle_loop(loop_index + 1, local_environment, results); - if (loop_err.has_value()) - { - return loop_err.value(); - } - } + if (loop_index + 1 == loops.size()) { + const auto iterator_result = iterator.evaluate(&local_environment); + if (!iterator_result.has_value()) { + return iterator_result.error(); + } + results.push_back(iterator_result.value()); + } else { + const auto loop_err = + handle_loop(loop_index + 1, local_environment, results); + if (loop_err.has_value()) { + return loop_err.value(); + } } + } - return std::nullopt; + return std::nullopt; } -[[nodiscard]] eval::Result ListComprehensionExpr::evaluate(const env::Environment* environment) const noexcept -{ - env::LocalEnvironment local_environment { environment }; - std::vector results; - const auto loop_err = handle_loop(0, local_environment, results); - if (loop_err.has_value()) - { - return zeus::unexpected(loop_err.value()); - } - return eval::Value{ results }; +[[nodiscard]] eval::Result ListComprehensionExpr::evaluate( + const env::Environment *environment) const noexcept { + env::LocalEnvironment local_environment{environment}; + std::vector results; + const auto loop_err = handle_loop(0, local_environment, results); + if (loop_err.has_value()) { + return zeus::unexpected(loop_err.value()); + } + return eval::Value{results}; } -[[nodiscard]] std::unordered_set ListComprehensionExpr::freeVariables() const noexcept -{ - std::unordered_set free_variables = {}; - std::unordered_set local_variables = {}; - for (const auto& loop : loops) - { - for (const auto& key : loop.iterable.freeVariables()) - { - if (local_variables.contains(key)) - { - continue; - } - free_variables.insert(key); - } - for (const auto& condition : loop.conditions) - { - for (const auto& key : condition.freeVariables()) - { - if (local_variables.contains(key)) - { - continue; - } - free_variables.insert(key); - } - } - for (const auto& key : loop.iterator_key.freeVariables()) - { - local_variables.insert(key); +[[nodiscard]] std::unordered_set +ListComprehensionExpr::freeVariables() const noexcept { + std::unordered_set free_variables = {}; + std::unordered_set local_variables = {}; + for (const auto &loop : loops) { + for (const auto &key : loop.iterable.freeVariables()) { + if (local_variables.contains(key)) { + continue; + } + free_variables.insert(key); + } + for (const auto &condition : loop.conditions) { + for (const auto &key : condition.freeVariables()) { + if (local_variables.contains(key)) { + continue; } + free_variables.insert(key); + } } - return free_variables; + for (const auto &key : loop.iterator_key.freeVariables()) { + local_variables.insert(key); + } + } + return free_variables; } -[[nodiscard]] bool ListComprehensionExpr::deepEq(const Expr& other) const noexcept -{ - if (const auto other_list_comprehension = dynamic_cast(&other)) - { - if (loops.size() != other_list_comprehension->loops.size()) - { - return false; - } +[[nodiscard]] bool +ListComprehensionExpr::deepEq(const Expr &other) const noexcept { + if (const auto other_list_comprehension = + dynamic_cast(&other)) { + if (loops.size() != other_list_comprehension->loops.size()) { + return false; + } - for (const auto [loop, other_loop] : ranges::views::zip(loops, other_list_comprehension->loops)) - { - if (! loop.iterator_key.deepEq(other_loop.iterator_key)) - { - return false; - } - if (! loop.iterable.deepEq(other_loop.iterable)) - { - return false; - } - if (loop.conditions.size() != other_loop.conditions.size()) - { - return false; - } - for (const auto [condition, other_condition] : ranges::views::zip(loop.conditions, other_loop.conditions)) - { - if (! condition.deepEq(other_condition)) - { - return false; - } - } + for (const auto [loop, other_loop] : + ranges::views::zip(loops, other_list_comprehension->loops)) { + if (!loop.iterator_key.deepEq(other_loop.iterator_key)) { + return false; + } + if (!loop.iterable.deepEq(other_loop.iterable)) { + return false; + } + if (loop.conditions.size() != other_loop.conditions.size()) { + return false; + } + for (const auto [condition, other_condition] : + ranges::views::zip(loop.conditions, other_loop.conditions)) { + if (!condition.deepEq(other_condition)) { + return false; } - - return iterator.deepEq(other_list_comprehension->iterator); + } } - return false; + + return iterator.deepEq(other_list_comprehension->iterator); + } + return false; } -void ListComprehensionExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void ListComprehensionExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); - iterator.visitAll(visitor); + iterator.visitAll(visitor); - for (const auto& loop : loops) - { - loop.iterator_key.visitAll(visitor); - loop.iterable.visitAll(visitor); - for (const auto& condition : loop.conditions) - { - condition.visitAll(visitor); - } + for (const auto &loop : loops) { + loop.iterator_key.visitAll(visitor); + loop.iterable.visitAll(visitor); + for (const auto &condition : loop.conditions) { + condition.visitAll(visitor); } + } } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/list_expr.cpp b/src/ast/list_expr.cpp index 8cb4280..4bfaa26 100644 --- a/src/ast/list_expr.cpp +++ b/src/ast/list_expr.cpp @@ -14,73 +14,66 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { +[[nodiscard]] std::string ListExpr::toString() const noexcept { + auto elements_str = elements | + ranges::views::transform([](const auto &element) { + return element.toString(); + }) | + ranges::views::join(ranges::views::c_str(", ")) | + ranges::to(); -[[nodiscard]] std::string ListExpr::toString() const noexcept -{ - auto elements_str = elements | ranges::views::transform([](const auto& element) { return element.toString(); }) | ranges::views::join(ranges::views::c_str(", ")) - | ranges::to(); - - return fmt::format("[{}]", elements_str); + return fmt::format("[{}]", elements_str); } -[[nodiscard]] eval::Result ListExpr::evaluate(const env::Environment* environment) const noexcept -{ - std::vector results; - for (const auto& element : elements) - { - const auto result = element.evaluate(environment); - if (! result.has_value()) - { - return zeus::unexpected(result.error()); - } - results.push_back(result.value()); +[[nodiscard]] eval::Result +ListExpr::evaluate(const env::Environment *environment) const noexcept { + std::vector results; + for (const auto &element : elements) { + const auto result = element.evaluate(environment); + if (!result.has_value()) { + return zeus::unexpected(result.error()); } - return std::move(results); + results.push_back(result.value()); + } + return std::move(results); } -[[nodiscard]] std::unordered_set ListExpr::freeVariables() const noexcept -{ - std::unordered_set result; - for (const auto& element : elements) - { - const auto element_vars = element.freeVariables(); - result.insert(element_vars.begin(), element_vars.end()); - } - return result; +[[nodiscard]] std::unordered_set +ListExpr::freeVariables() const noexcept { + std::unordered_set result; + for (const auto &element : elements) { + const auto element_vars = element.freeVariables(); + result.insert(element_vars.begin(), element_vars.end()); + } + return result; } -[[nodiscard]] bool ListExpr::deepEq(const Expr& other) const noexcept -{ - if (auto other_list_expr = dynamic_cast(&other)) - { - if (elements.size() != other_list_expr->elements.size()) - { - return false; - } +[[nodiscard]] bool ListExpr::deepEq(const Expr &other) const noexcept { + if (auto other_list_expr = dynamic_cast(&other)) { + if (elements.size() != other_list_expr->elements.size()) { + return false; + } - for (const auto [element, other_element] : ranges::views::zip(elements, other_list_expr->elements)) - { - if (! element.deepEq(other_element)) - { - return false; - } - } - return true; + for (const auto [element, other_element] : + ranges::views::zip(elements, other_list_expr->elements)) { + if (!element.deepEq(other_element)) { + return false; + } } - return false; + return true; + } + return false; } -void ListExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void ListExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); - for (const auto& element : elements) - { - element.visitAll(visitor); - } + for (const auto &element : elements) { + element.visitAll(visitor); + } } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/primary_expr/string_expr.cpp b/src/ast/primary_expr/string_expr.cpp index 60e12fc..9fc1ae3 100644 --- a/src/ast/primary_expr/string_expr.cpp +++ b/src/ast/primary_expr/string_expr.cpp @@ -4,12 +4,10 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -std::string StringExpr::toString() const noexcept -{ - return fmt::format("\"{}\"", value); +std::string StringExpr::toString() const noexcept { + return fmt::format("\"{}\"", value); } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/slice_expr.cpp b/src/ast/slice_expr.cpp index dc1df12..0c80d2f 100644 --- a/src/ast/slice_expr.cpp +++ b/src/ast/slice_expr.cpp @@ -1,7 +1,7 @@ +#include "cura-formulae-engine/ast/slice_expr.h" #include "cura-formulae-engine/ast/ast.h" #include "cura-formulae-engine/ast/expr_ptr.h" #include "cura-formulae-engine/eval.h" -#include "cura-formulae-engine/ast/slice_expr.h" #include @@ -11,157 +11,159 @@ #include #include -namespace CuraFormulaeEngine::ast -{ - -[[nodiscard]] std::string SliceExpr::toString() const noexcept -{ - const auto start_index_str = start_index.has_value() ? start_index.value().toString() : ""; - const auto end_index_str = end_index.has_value() ? end_index.value().toString() : ""; - const auto step_size_str = step_size.has_value() ? step_size.value().toString() : ""; - return fmt::format("{}[{}:{}:{}]", array.toString(), start_index_str, end_index_str, step_size_str); +namespace CuraFormulaeEngine::ast { + +[[nodiscard]] std::string SliceExpr::toString() const noexcept { + const auto start_index_str = + start_index.has_value() ? start_index.value().toString() : ""; + const auto end_index_str = + end_index.has_value() ? end_index.value().toString() : ""; + const auto step_size_str = + step_size.has_value() ? step_size.value().toString() : ""; + return fmt::format("{}[{}:{}:{}]", array.toString(), start_index_str, + end_index_str, step_size_str); } -[[nodiscard]] eval::Result SliceExpr::evaluate(const env::Environment* environment) const noexcept -{ - std::int64_t step_size_value = int64_t(1); - if (step_size.has_value()) - { - const auto end_index_result = try_get(step_size.value().evaluate(environment)); - if (! end_index_result.has_value()) - { - return zeus::unexpected(end_index_result.error()); - } - step_size_value = end_index_result.value(); - - if (step_size_value == int64_t(0)) - { - return zeus::unexpected(eval::Error::ValueError); - } +[[nodiscard]] eval::Result +SliceExpr::evaluate(const env::Environment *environment) const noexcept { + std::int64_t step_size_value = int64_t(1); + if (step_size.has_value()) { + const auto end_index_result = + try_get(step_size.value().evaluate(environment)); + if (!end_index_result.has_value()) { + return zeus::unexpected(end_index_result.error()); } + step_size_value = end_index_result.value(); - const auto array_result = try_get>(array.evaluate(environment)); - if (! array_result.has_value()) - { - return zeus::unexpected(array_result.error()); + if (step_size_value == int64_t(0)) { + return zeus::unexpected(eval::Error::ValueError); } - const auto& array_value = array_result.value(); - - std::int64_t start_index_absolute_value = step_size_value > 0 ? 0 : int64_t(array_value.size()) - 1; - if (start_index.has_value()) - { - const auto start_index_result = try_get(start_index.value().evaluate(environment)); - if (! start_index_result.has_value()) - { - return zeus::unexpected(start_index_result.error()); - } - const auto start_index_value = start_index_result.value(); - - if (start_index_value < int64_t(0)) - { - start_index_absolute_value = int64_t(array_value.size()) - -start_index_value - int64_t(1); - start_index_absolute_value = std::max(start_index_absolute_value, int64_t(0)); - } - else - { - start_index_absolute_value = start_index_value; - start_index_absolute_value = std::min(start_index_absolute_value, static_cast(array_value.size()) - int64_t(1)); - } - start_index_absolute_value = std::min(start_index_absolute_value, static_cast(array_value.size()) - int64_t(1)); + } + + const auto array_result = + try_get>(array.evaluate(environment)); + if (!array_result.has_value()) { + return zeus::unexpected(array_result.error()); + } + const auto &array_value = array_result.value(); + + std::int64_t start_index_absolute_value = + step_size_value > 0 ? 0 : int64_t(array_value.size()) - 1; + if (start_index.has_value()) { + const auto start_index_result = + try_get(start_index.value().evaluate(environment)); + if (!start_index_result.has_value()) { + return zeus::unexpected(start_index_result.error()); } - - std::int64_t end_index_absolute_value = step_size_value > int64_t(0) ? static_cast(array_value.size()) - int64_t(1) : int64_t(0); - if (end_index.has_value()) - { - const auto end_index_result = try_get(end_index.value().evaluate(environment)); - if (! end_index_result.has_value()) - { - return zeus::unexpected(end_index_result.error()); - } - const auto end_index_value = end_index_result.value(); - - if (end_index_value < int64_t(0)) - { - end_index_absolute_value = int64_t(array_value.size()) - -end_index_value - int64_t(1); - end_index_absolute_value = std::max(end_index_absolute_value, int64_t(0)); - } - else - { - end_index_absolute_value = end_index_value; - end_index_absolute_value = std::min(end_index_absolute_value, static_cast(array_value.size()) - int64_t(1)); - } + const auto start_index_value = start_index_result.value(); + + if (start_index_value < int64_t(0)) { + start_index_absolute_value = + int64_t(array_value.size()) - -start_index_value - int64_t(1); + start_index_absolute_value = + std::max(start_index_absolute_value, int64_t(0)); + } else { + start_index_absolute_value = start_index_value; + start_index_absolute_value = + std::min(start_index_absolute_value, + static_cast(array_value.size()) - int64_t(1)); } - - std::vector result; - - if (step_size_value > 0) - { - for (std::int64_t i = start_index_absolute_value; i <= end_index_absolute_value; i += step_size_value) - { - result.push_back(array_value[size_t(i)]); - } + start_index_absolute_value = + std::min(start_index_absolute_value, + static_cast(array_value.size()) - int64_t(1)); + } + + std::int64_t end_index_absolute_value = + step_size_value > int64_t(0) + ? static_cast(array_value.size()) - int64_t(1) + : int64_t(0); + if (end_index.has_value()) { + const auto end_index_result = + try_get(end_index.value().evaluate(environment)); + if (!end_index_result.has_value()) { + return zeus::unexpected(end_index_result.error()); } - else - { - for (std::int64_t i = start_index_absolute_value; i >= end_index_absolute_value; i += step_size_value) - { - result.push_back(array_value[size_t(i)]); - } + const auto end_index_value = end_index_result.value(); + + if (end_index_value < int64_t(0)) { + end_index_absolute_value = + int64_t(array_value.size()) - -end_index_value - int64_t(1); + end_index_absolute_value = std::max(end_index_absolute_value, int64_t(0)); + } else { + end_index_absolute_value = end_index_value; + end_index_absolute_value = + std::min(end_index_absolute_value, + static_cast(array_value.size()) - int64_t(1)); } + } - return result; -} + std::vector result; -[[nodiscard]] std::unordered_set SliceExpr::freeVariables() const noexcept -{ - auto free_vars = array.freeVariables(); - if (start_index.has_value()) - { - const auto start_index_vars = start_index.value().freeVariables(); - free_vars.insert(start_index_vars.begin(), start_index_vars.end()); + if (step_size_value > 0) { + for (std::int64_t i = start_index_absolute_value; + i <= end_index_absolute_value; i += step_size_value) { + result.push_back(array_value[size_t(i)]); } - if (end_index.has_value()) - { - const auto end_index_vars = end_index.value().freeVariables(); - free_vars.insert(end_index_vars.begin(), end_index_vars.end()); + } else { + for (std::int64_t i = start_index_absolute_value; + i >= end_index_absolute_value; i += step_size_value) { + result.push_back(array_value[size_t(i)]); } - if (step_size.has_value()) - { - const auto step_size_vars = step_size.value().freeVariables(); - free_vars.insert(step_size_vars.begin(), step_size_vars.end()); - } - return free_vars; + } + + return result; } -[[nodiscard]] bool SliceExpr::deepEq(const Expr& other) const noexcept -{ - if (const auto other_slice_expr = dynamic_cast(&other)) - { - return array.deepEq(other_slice_expr->array) && start_index.has_value() == other_slice_expr->start_index.has_value() - && (! start_index.has_value() || start_index.value().deepEq(other_slice_expr->start_index.value())) - && end_index.has_value() == other_slice_expr->end_index.has_value() && (! end_index.has_value() || end_index.value().deepEq(other_slice_expr->end_index.value())) - && step_size.has_value() == other_slice_expr->step_size.has_value() && (! step_size.has_value() || step_size.value().deepEq(other_slice_expr->step_size.value())); - } - return false; +[[nodiscard]] std::unordered_set +SliceExpr::freeVariables() const noexcept { + auto free_vars = array.freeVariables(); + if (start_index.has_value()) { + const auto start_index_vars = start_index.value().freeVariables(); + free_vars.insert(start_index_vars.begin(), start_index_vars.end()); + } + if (end_index.has_value()) { + const auto end_index_vars = end_index.value().freeVariables(); + free_vars.insert(end_index_vars.begin(), end_index_vars.end()); + } + if (step_size.has_value()) { + const auto step_size_vars = step_size.value().freeVariables(); + free_vars.insert(step_size_vars.begin(), step_size_vars.end()); + } + return free_vars; } -void SliceExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +[[nodiscard]] bool SliceExpr::deepEq(const Expr &other) const noexcept { + if (const auto other_slice_expr = dynamic_cast(&other)) { + return array.deepEq(other_slice_expr->array) && + start_index.has_value() == + other_slice_expr->start_index.has_value() && + (!start_index.has_value() || + start_index.value().deepEq( + other_slice_expr->start_index.value())) && + end_index.has_value() == other_slice_expr->end_index.has_value() && + (!end_index.has_value() || + end_index.value().deepEq(other_slice_expr->end_index.value())) && + step_size.has_value() == other_slice_expr->step_size.has_value() && + (!step_size.has_value() || + step_size.value().deepEq(other_slice_expr->step_size.value())); + } + return false; +} - array.visitAll(visitor); - if (start_index.has_value()) - { - start_index.value().visitAll(visitor); - } - if (end_index.has_value()) - { - end_index.value().visitAll(visitor); - } - if (step_size.has_value()) - { - step_size.value().visitAll(visitor); - } +void SliceExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); + + array.visitAll(visitor); + if (start_index.has_value()) { + start_index.value().visitAll(visitor); + } + if (end_index.has_value()) { + end_index.value().visitAll(visitor); + } + if (step_size.has_value()) { + step_size.value().visitAll(visitor); + } } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/tuple_expr.cpp b/src/ast/tuple_expr.cpp index 3008b3c..608d7fc 100644 --- a/src/ast/tuple_expr.cpp +++ b/src/ast/tuple_expr.cpp @@ -14,72 +14,65 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { +[[nodiscard]] std::string TupleExpr::toString() const noexcept { + auto elements_str = elements | + ranges::views::transform([](const auto &element) { + return element.toString(); + }) | + ranges::views::join(ranges::views::c_str(", ")) | + ranges::to(); -[[nodiscard]] std::string TupleExpr::toString() const noexcept -{ - auto elements_str = elements | ranges::views::transform([](const auto& element) { return element.toString(); }) | ranges::views::join(ranges::views::c_str(", ")) - | ranges::to(); - - return fmt::format("({})", elements_str); + return fmt::format("({})", elements_str); } -[[nodiscard]] eval::Result TupleExpr::evaluate(const env::Environment* environment) const noexcept -{ - std::vector results; - for (const auto& element : elements) - { - auto result = element.evaluate(environment); - if (! result.has_value()) - { - return zeus::unexpected(result.error()); - } - results.push_back(result.value()); +[[nodiscard]] eval::Result +TupleExpr::evaluate(const env::Environment *environment) const noexcept { + std::vector results; + for (const auto &element : elements) { + auto result = element.evaluate(environment); + if (!result.has_value()) { + return zeus::unexpected(result.error()); } - return std::move(results); + results.push_back(result.value()); + } + return std::move(results); } -[[nodiscard]] std::unordered_set TupleExpr::freeVariables() const noexcept -{ - std::unordered_set result; - for (const auto& element : elements) - { - auto element_vars = element.freeVariables(); - result.insert(element_vars.begin(), element_vars.end()); - } - return result; +[[nodiscard]] std::unordered_set +TupleExpr::freeVariables() const noexcept { + std::unordered_set result; + for (const auto &element : elements) { + auto element_vars = element.freeVariables(); + result.insert(element_vars.begin(), element_vars.end()); + } + return result; } -[[nodiscard]] bool TupleExpr::deepEq(const Expr& other) const noexcept -{ - if (const auto* other_tuple_expr = dynamic_cast(&other)) - { - if (elements.size() != other_tuple_expr->elements.size()) - { - return false; - } - for (const auto [element, other_element] : ranges::views::zip(elements, other_tuple_expr->elements)) - { - if (! element.deepEq(other_element)) - { - return false; - } - } - return true; +[[nodiscard]] bool TupleExpr::deepEq(const Expr &other) const noexcept { + if (const auto *other_tuple_expr = dynamic_cast(&other)) { + if (elements.size() != other_tuple_expr->elements.size()) { + return false; } - return false; + for (const auto [element, other_element] : + ranges::views::zip(elements, other_tuple_expr->elements)) { + if (!element.deepEq(other_element)) { + return false; + } + } + return true; + } + return false; } -void TupleExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void TupleExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); - for (const auto& element : elements) - { - element.visitAll(visitor); - } + for (const auto &element : elements) { + element.visitAll(visitor); + } } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/unary_expr/neg_expr.cpp b/src/ast/unary_expr/neg_expr.cpp index f90cc35..090d55f 100644 --- a/src/ast/unary_expr/neg_expr.cpp +++ b/src/ast/unary_expr/neg_expr.cpp @@ -2,22 +2,21 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string NegExpr::getOpIdentifier() const noexcept -{ - return "-"; +[[nodiscard]] std::string NegExpr::getOpIdentifier() const noexcept { + return "-"; } -[[nodiscard]] eval::Result NegExpr::evaluate(const eval::Value& eval_value) const noexcept -{ - return -eval_value; +[[nodiscard]] eval::Result +NegExpr::evaluate(const eval::Value &eval_value) const noexcept { + return -eval_value; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator-(CuraFormulaeEngine::ast::ExprPtr operand) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(operand)); +CuraFormulaeEngine::ast::ExprPtr +operator-(CuraFormulaeEngine::ast::ExprPtr operand) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::NegExpr>(std::move(operand)); } diff --git a/src/ast/unary_expr/not_expr.cpp b/src/ast/unary_expr/not_expr.cpp index 6f18cc3..8461fcb 100644 --- a/src/ast/unary_expr/not_expr.cpp +++ b/src/ast/unary_expr/not_expr.cpp @@ -2,22 +2,21 @@ #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string NotExpr::getOpIdentifier() const noexcept -{ - return "not"; +[[nodiscard]] std::string NotExpr::getOpIdentifier() const noexcept { + return "not"; } -[[nodiscard]] eval::Result NotExpr::evaluate(const eval::Value& eval_value) const noexcept -{ - return ! eval_value; +[[nodiscard]] eval::Result +NotExpr::evaluate(const eval::Value &eval_value) const noexcept { + return !eval_value; } } // namespace CuraFormulaeEngine::ast -CuraFormulaeEngine::ast::ExprPtr operator!(CuraFormulaeEngine::ast::ExprPtr operand) -{ - return CuraFormulaeEngine::ast::make_expr_ptr(std::move(operand)); +CuraFormulaeEngine::ast::ExprPtr +operator!(CuraFormulaeEngine::ast::ExprPtr operand) { + return CuraFormulaeEngine::ast::make_expr_ptr< + CuraFormulaeEngine::ast::NotExpr>(std::move(operand)); } diff --git a/src/ast/unary_expr/unary_expr.cpp b/src/ast/unary_expr/unary_expr.cpp index 2819ae5..312c3e9 100644 --- a/src/ast/unary_expr/unary_expr.cpp +++ b/src/ast/unary_expr/unary_expr.cpp @@ -6,44 +6,39 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -[[nodiscard]] std::string UnaryExpr::toString() const noexcept -{ - return fmt::format("({} {})", getOpIdentifier(), operand.toString()); +[[nodiscard]] std::string UnaryExpr::toString() const noexcept { + return fmt::format("({} {})", getOpIdentifier(), operand.toString()); } -[[nodiscard]] eval::Result UnaryExpr::evaluate(const env::Environment* environment) const noexcept -{ - const auto operand_result = operand.evaluate(environment); - if (! operand_result.has_value()) - { - return zeus::unexpected(operand_result.error()); - } - const auto operand_value = operand_result.value(); - return evaluate(operand_value); +[[nodiscard]] eval::Result +UnaryExpr::evaluate(const env::Environment *environment) const noexcept { + const auto operand_result = operand.evaluate(environment); + if (!operand_result.has_value()) { + return zeus::unexpected(operand_result.error()); + } + const auto operand_value = operand_result.value(); + return evaluate(operand_value); } -[[nodiscard]] std::unordered_set UnaryExpr::freeVariables() const noexcept -{ - return operand.freeVariables(); +[[nodiscard]] std::unordered_set +UnaryExpr::freeVariables() const noexcept { + return operand.freeVariables(); } -[[nodiscard]] bool UnaryExpr::deepEq(const Expr& other) const noexcept -{ - if (typeid(*this) != typeid(other)) - { - return false; - } - const auto& other_UnaryExpr = static_cast(other); - return operand.deepEq(other_UnaryExpr.operand); +[[nodiscard]] bool UnaryExpr::deepEq(const Expr &other) const noexcept { + if (typeid(*this) != typeid(other)) { + return false; + } + const auto &other_UnaryExpr = static_cast(other); + return operand.deepEq(other_UnaryExpr.operand); } -void UnaryExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); - operand.visitAll(visitor); +void UnaryExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); + operand.visitAll(visitor); } } // namespace CuraFormulaeEngine::ast diff --git a/src/ast/variable_expr.cpp b/src/ast/variable_expr.cpp index 3ac4479..853e31a 100644 --- a/src/ast/variable_expr.cpp +++ b/src/ast/variable_expr.cpp @@ -7,40 +7,32 @@ #include #include -namespace CuraFormulaeEngine::ast -{ +namespace CuraFormulaeEngine::ast { -std::string VariableExpr::toString() const noexcept -{ - return name; -} +std::string VariableExpr::toString() const noexcept { return name; } -eval::Result VariableExpr::evaluate(const env::Environment* environment) const noexcept -{ - if (const auto value = environment->get(name); value.has_value()) - { - return value.value(); - } - return zeus::unexpected(eval::Error::UndefinedVariable); +eval::Result +VariableExpr::evaluate(const env::Environment *environment) const noexcept { + if (const auto value = environment->get(name); value.has_value()) { + return value.value(); + } + return zeus::unexpected(eval::Error::UndefinedVariable); } -std::unordered_set VariableExpr::freeVariables() const noexcept -{ - return { name }; +std::unordered_set VariableExpr::freeVariables() const noexcept { + return {name}; } -bool VariableExpr::deepEq(const Expr& other) const noexcept -{ - if (const auto* other_variable = dynamic_cast(&other)) - { - return name == other_variable->name; - } - return false; +bool VariableExpr::deepEq(const Expr &other) const noexcept { + if (const auto *other_variable = dynamic_cast(&other)) { + return name == other_variable->name; + } + return false; } -void VariableExpr::visitAll(std::function visitor) const noexcept -{ - visitor(*this); +void VariableExpr::visitAll( + std::function visitor) const noexcept { + visitor(*this); } } // namespace CuraFormulaeEngine::ast diff --git a/src/env/abs.cpp b/src/env/abs.cpp index 00499ae..e190cfd 100644 --- a/src/env/abs.cpp +++ b/src/env/abs.cpp @@ -8,29 +8,25 @@ namespace CuraFormulaeEngine::env { -const eval::Value::fn_t abs = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - - const auto &value = args[0]; - if (std::holds_alternative(value.value)) - { - return std::get(value.value) ? eval::Value(int64_t(1)) : eval::Value(int64_t(0)); - } - if (std::holds_alternative(value.value)) - { - return std::abs(std::get(value.value)); - } - if (std::holds_alternative(value.value)) - { - return std::abs(std::get(value.value)); - } - - - return zeus::unexpected(eval::Error::TypeMismatch); +const eval::Value::fn_t abs = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + + const auto &value = args[0]; + if (std::holds_alternative(value.value)) { + return std::get(value.value) ? eval::Value(int64_t(1)) + : eval::Value(int64_t(0)); + } + if (std::holds_alternative(value.value)) { + return std::abs(std::get(value.value)); + } + if (std::holds_alternative(value.value)) { + return std::abs(std::get(value.value)); + } + + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/all.cpp b/src/env/all.cpp index 61c1e3d..4a0c91e 100644 --- a/src/env/all.cpp +++ b/src/env/all.cpp @@ -6,21 +6,19 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t all = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - if (! std::holds_alternative>(args[0].value)) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - const auto& elements = std::get>(args[0].value); - return ranges::all_of(elements, [](const auto& element) { return element.isTruthy(); }); +const eval::Value::fn_t all = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + if (!std::holds_alternative>(args[0].value)) { + return zeus::unexpected(eval::Error::TypeMismatch); + } + const auto &elements = std::get>(args[0].value); + return ranges::all_of(elements, + [](const auto &element) { return element.isTruthy(); }); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/any.cpp b/src/env/any.cpp index 44c06d4..e820b08 100644 --- a/src/env/any.cpp +++ b/src/env/any.cpp @@ -6,21 +6,19 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t any = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - if (! std::holds_alternative>(args[0].value)) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - const auto& elements = std::get>(args[0].value); - return ranges::any_of(elements, [](const auto& element) { return element.isTruthy(); }); +const eval::Value::fn_t any = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + if (!std::holds_alternative>(args[0].value)) { + return zeus::unexpected(eval::Error::TypeMismatch); + } + const auto &elements = std::get>(args[0].value); + return ranges::any_of(elements, + [](const auto &element) { return element.isTruthy(); }); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/env.cpp b/src/env/env.cpp index 08644e7..fdf4b1a 100644 --- a/src/env/env.cpp +++ b/src/env/env.cpp @@ -29,15 +29,13 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { /** * @brief The standard environment. */ -CURA_FORMULAE_ENGINE_API const EnvironmentMap std_env = []() -{ - EnvironmentMap env; +CURA_FORMULAE_ENGINE_API const EnvironmentMap std_env = []() { + EnvironmentMap env; env.set("abs", eval::Value(abs)); env.set("all", eval::Value(all)); @@ -69,7 +67,7 @@ CURA_FORMULAE_ENGINE_API const EnvironmentMap std_env = []() math_props["tau"] = eval::Value(std::numbers::pi * 2.0); math_props["radians"] = eval::Value(math_radians); math_props["sqrt"] = eval::Value(math_sqrt); - + env.set("math", eval::Value(math_props)); return env; diff --git a/src/env/float_fn.cpp b/src/env/float_fn.cpp index 5a6f0ea..90af474 100644 --- a/src/env/float_fn.cpp +++ b/src/env/float_fn.cpp @@ -6,34 +6,28 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t float_fn = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } +const eval::Value::fn_t float_fn = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } - const auto& value = args[0]; - if (std::holds_alternative(value.value)) - { - return std::get(value.value); - } - if (std::holds_alternative(value.value)) - { - return { std::get(value.value) }; - } - if (std::holds_alternative(value.value)) - { - return std::stod(std::get(value.value)); - } - if (std::holds_alternative(value.value)) - { - return std::get(value.value) ? 1.0 : 0.0; - } - return zeus::unexpected(eval::Error::TypeMismatch); + const auto &value = args[0]; + if (std::holds_alternative(value.value)) { + return std::get(value.value); + } + if (std::holds_alternative(value.value)) { + return {std::get(value.value)}; + } + if (std::holds_alternative(value.value)) { + return std::stod(std::get(value.value)); + } + if (std::holds_alternative(value.value)) { + return std::get(value.value) ? 1.0 : 0.0; + } + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/int_fn.cpp b/src/env/int_fn.cpp index 668c95f..ae7ce50 100644 --- a/src/env/int_fn.cpp +++ b/src/env/int_fn.cpp @@ -7,8 +7,7 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { [[nodiscard]] eval::Result IntFunction::operator()(const std::vector &args) const noexcept { diff --git a/src/env/len.cpp b/src/env/len.cpp index 7160fd9..b0a9c8f 100644 --- a/src/env/len.cpp +++ b/src/env/len.cpp @@ -5,21 +5,18 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t len = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - if (! std::holds_alternative>(args[0].value)) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - const auto& elements = std::get>(args[0].value); - return eval::Value{ static_cast(elements.size()) }; +const eval::Value::fn_t len = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + if (!std::holds_alternative>(args[0].value)) { + return zeus::unexpected(eval::Error::TypeMismatch); + } + const auto &elements = std::get>(args[0].value); + return eval::Value{static_cast(elements.size())}; }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/map.cpp b/src/env/map.cpp index cc73ea2..9e6459f 100644 --- a/src/env/map.cpp +++ b/src/env/map.cpp @@ -5,15 +5,13 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t map = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 2) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } +const eval::Value::fn_t map = + [](const std::vector &args) -> eval::Result { + if (args.size() != 2) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } if (! std::holds_alternative>(args[1].value)) { @@ -36,17 +34,15 @@ const eval::Value::fn_t map = [](const std::vector &args) -> eval:: const auto list = std::get>(args[1].value); - std::vector result; - for (const auto& element : list) - { - const auto mapped = fn({ element }); - if (! mapped.has_value()) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - result.push_back(mapped.value()); + std::vector result; + for (const auto &element : list) { + const auto mapped = fn({element}); + if (!mapped.has_value()) { + return zeus::unexpected(eval::Error::TypeMismatch); } - return result; + result.push_back(mapped.value()); + } + return result; }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_atan.cpp b/src/env/math_atan.cpp index 567481a..0f1283f 100644 --- a/src/env/math_atan.cpp +++ b/src/env/math_atan.cpp @@ -5,26 +5,22 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t math_atan = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } +const eval::Value::fn_t math_atan = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } - const auto& value = args[0]; - if (std::holds_alternative(value.value)) - { - return std::atan(std::get(value.value)); - } - if (std::holds_alternative(value.value)) - { - return std::atan(std::get(value.value)); - } - return zeus::unexpected(eval::Error::TypeMismatch); + const auto &value = args[0]; + if (std::holds_alternative(value.value)) { + return std::atan(std::get(value.value)); + } + if (std::holds_alternative(value.value)) { + return std::atan(std::get(value.value)); + } + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_ceil.cpp b/src/env/math_ceil.cpp index a021e50..8d35991 100644 --- a/src/env/math_ceil.cpp +++ b/src/env/math_ceil.cpp @@ -5,31 +5,26 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t math_ceil = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } +const eval::Value::fn_t math_ceil = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } - const auto& value = args[0]; + const auto &value = args[0]; - if (std::holds_alternative(value.value)) - { - return eval::Value(std::ceil(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::ceil(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::ceil(std::get(value.value))); - } - return zeus::unexpected(eval::Error::TypeMismatch); + if (std::holds_alternative(value.value)) { + return eval::Value(std::ceil(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::ceil(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::ceil(std::get(value.value))); + } + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_cos.cpp b/src/env/math_cos.cpp index d360d70..aea4f7f 100644 --- a/src/env/math_cos.cpp +++ b/src/env/math_cos.cpp @@ -5,26 +5,22 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t math_cos = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } +const eval::Value::fn_t math_cos = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } - const auto& value = args[0]; - if (std::holds_alternative(value.value)) - { - return std::cos(std::get(value.value)); - } - if (std::holds_alternative(value.value)) - { - return std::cos(std::get(value.value)); - } - return zeus::unexpected(eval::Error::TypeMismatch); + const auto &value = args[0]; + if (std::holds_alternative(value.value)) { + return std::cos(std::get(value.value)); + } + if (std::holds_alternative(value.value)) { + return std::cos(std::get(value.value)); + } + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_degrees.cpp b/src/env/math_degrees.cpp index 6191b50..dbe6d6f 100644 --- a/src/env/math_degrees.cpp +++ b/src/env/math_degrees.cpp @@ -4,16 +4,14 @@ #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t math_degrees = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - return args[0] * eval::Value(180.0 / std::numbers::pi); +const eval::Value::fn_t math_degrees = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + return args[0] * eval::Value(180.0 / std::numbers::pi); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_floor.cpp b/src/env/math_floor.cpp index 665cafe..c0beee6 100644 --- a/src/env/math_floor.cpp +++ b/src/env/math_floor.cpp @@ -5,32 +5,27 @@ #include #include -namespace CuraFormulaeEngine::env -{ - -const eval::Value::fn_t math_floor = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - - const auto& value = args[0]; - - if (std::holds_alternative(value.value)) - { - return eval::Value(std::floor(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::floor(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::floor(std::get(value.value))); - } - - return zeus::unexpected(eval::Error::TypeMismatch); +namespace CuraFormulaeEngine::env { + +const eval::Value::fn_t math_floor = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + + const auto &value = args[0]; + + if (std::holds_alternative(value.value)) { + return eval::Value(std::floor(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::floor(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::floor(std::get(value.value))); + } + + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_log.cpp b/src/env/math_log.cpp index 80da9ca..1861658 100644 --- a/src/env/math_log.cpp +++ b/src/env/math_log.cpp @@ -10,7 +10,7 @@ namespace CuraFormulaeEngine::env { -[[nodiscard]] eval::Result MathLogFunction::operator()(const std::vector &args) const noexcept +[[nodiscard]] eval::Result MathLogFunction::operator()(const std::vector& args) const noexcept { if (args.empty() || args.size() > 2) { diff --git a/src/env/math_radians.cpp b/src/env/math_radians.cpp index e63a73a..88a7be6 100644 --- a/src/env/math_radians.cpp +++ b/src/env/math_radians.cpp @@ -4,16 +4,14 @@ #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t math_radians = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - return args[0] * eval::Value(std::numbers::pi / 180.0); +const eval::Value::fn_t math_radians = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + return args[0] * eval::Value(std::numbers::pi / 180.0); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_sin.cpp b/src/env/math_sin.cpp index cc585f2..4a60d3f 100644 --- a/src/env/math_sin.cpp +++ b/src/env/math_sin.cpp @@ -6,32 +6,27 @@ #include #include -namespace CuraFormulaeEngine::env -{ - -const eval::Value::fn_t math_sin = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - - const auto& value = args[0]; - - if (std::holds_alternative(value.value)) - { - return eval::Value(std::sin(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::sin(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::sin(std::get(value.value))); - } - - return zeus::unexpected(eval::Error::TypeMismatch); +namespace CuraFormulaeEngine::env { + +const eval::Value::fn_t math_sin = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + + const auto &value = args[0]; + + if (std::holds_alternative(value.value)) { + return eval::Value(std::sin(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::sin(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::sin(std::get(value.value))); + } + + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_sqrt.cpp b/src/env/math_sqrt.cpp index 13918da..1795266 100644 --- a/src/env/math_sqrt.cpp +++ b/src/env/math_sqrt.cpp @@ -6,32 +6,27 @@ #include #include -namespace CuraFormulaeEngine::env -{ - -const eval::Value::fn_t math_sqrt = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - - const auto& value = args[0]; - - if (std::holds_alternative(value.value)) - { - return eval::Value(std::sqrt(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::sqrt(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::sqrt(std::get(value.value))); - } - - return zeus::unexpected(eval::Error::TypeMismatch); +namespace CuraFormulaeEngine::env { + +const eval::Value::fn_t math_sqrt = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + + const auto &value = args[0]; + + if (std::holds_alternative(value.value)) { + return eval::Value(std::sqrt(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::sqrt(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::sqrt(std::get(value.value))); + } + + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/math_tan.cpp b/src/env/math_tan.cpp index 819679c..799c736 100644 --- a/src/env/math_tan.cpp +++ b/src/env/math_tan.cpp @@ -6,32 +6,27 @@ #include #include -namespace CuraFormulaeEngine::env -{ - -const eval::Value::fn_t math_tan = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - - const auto& value = args[0]; - - if (std::holds_alternative(value.value)) - { - return eval::Value(std::tan(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::tan(std::get(value.value))); - } - if (std::holds_alternative(value.value)) - { - return eval::Value(std::tan(std::get(value.value))); - } - - return zeus::unexpected(eval::Error::TypeMismatch); +namespace CuraFormulaeEngine::env { + +const eval::Value::fn_t math_tan = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + + const auto &value = args[0]; + + if (std::holds_alternative(value.value)) { + return eval::Value(std::tan(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::tan(std::get(value.value))); + } + if (std::holds_alternative(value.value)) { + return eval::Value(std::tan(std::get(value.value))); + } + + return zeus::unexpected(eval::Error::TypeMismatch); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/max.cpp b/src/env/max.cpp index 2ca6f47..621d344 100644 --- a/src/env/max.cpp +++ b/src/env/max.cpp @@ -6,40 +6,35 @@ #include #include -namespace CuraFormulaeEngine::env -{ - -const eval::Value::fn_t max = [](const std::vector &args) -> eval::Result -{ - if (args.empty()) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); +namespace CuraFormulaeEngine::env { + +const eval::Value::fn_t max = + [](const std::vector &args) -> eval::Result { + if (args.empty()) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + + const auto find_max = + [](const std::vector &vec) -> eval::Result { + auto max = vec[0]; + for (const auto &arg : vec | ranges::views::drop(1)) { + const auto cmp = arg > max; + if (!cmp.has_value()) { + return zeus::unexpected(eval::Error::TypeMismatch); + } + + if (cmp.value()) { + max = arg; + } } - - const auto find_max = [](const std::vector& vec) -> eval::Result - { - auto max = vec[0]; - for (const auto& arg : vec | ranges::views::drop(1)) - { - const auto cmp = arg > max; - if (! cmp.has_value()) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - - if (cmp.value()) - { - max = arg; - } - } - return max; - }; - - if (args.size() == 1 && std::holds_alternative>(args[0].value)) - { - return find_max(std::get>(args[0].value)); - } - return find_max(args); + return max; + }; + + if (args.size() == 1 && + std::holds_alternative>(args[0].value)) { + return find_max(std::get>(args[0].value)); + } + return find_max(args); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/min.cpp b/src/env/min.cpp index 94bf9dc..33089fb 100644 --- a/src/env/min.cpp +++ b/src/env/min.cpp @@ -6,8 +6,7 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { [[nodiscard]] eval::Result MinFunction::operator()(const std::vector &args) const noexcept { @@ -90,7 +89,7 @@ namespace CuraFormulaeEngine::env { return find_min(std::get>(args[0].value)); } - + if (args.size() == 2) { const bool second_arg_is_callable = std::holds_alternative(args[1].value) diff --git a/src/env/round.cpp b/src/env/round.cpp index 86fe965..1495320 100644 --- a/src/env/round.cpp +++ b/src/env/round.cpp @@ -7,8 +7,7 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { [[nodiscard]] eval::Result RoundFunction::operator()(const std::vector &args) const noexcept { @@ -17,35 +16,29 @@ namespace CuraFormulaeEngine::env return zeus::unexpected(eval::Error::InvalidNumberOfArguments); } - auto base = 0LL; - if (args.size() == 2) - { - const auto& base_arg = args[1]; - if (! std::holds_alternative(base_arg.value)) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } - base = std::get(base_arg.value); + auto base = 0LL; + if (args.size() == 2) { + const auto &base_arg = args[1]; + if (!std::holds_alternative(base_arg.value)) { + return zeus::unexpected(eval::Error::TypeMismatch); } + base = std::get(base_arg.value); + } - const auto& x = args[0]; - const auto initialize = [](const auto& value) -> double - { - if (std::holds_alternative(value.value)) - { - return static_cast(std::get(value.value)); - } - if (std::holds_alternative(value.value)) - { - return std::get(value.value); - } - return std::numeric_limits::quiet_NaN(); - }; - double value = initialize(x); - if (std::isnan(value)) - { - return zeus::unexpected(eval::Error::TypeMismatch); + const auto &x = args[0]; + const auto initialize = [](const auto &value) -> double { + if (std::holds_alternative(value.value)) { + return static_cast(std::get(value.value)); + } + if (std::holds_alternative(value.value)) { + return std::get(value.value); } + return std::numeric_limits::quiet_NaN(); + }; + double value = initialize(x); + if (std::isnan(value)) { + return zeus::unexpected(eval::Error::TypeMismatch); + } const auto base_exponent = std::pow(10, base); value = std::round(value * base_exponent) / base_exponent; diff --git a/src/env/str.cpp b/src/env/str.cpp index a060ced..dfbe2e8 100644 --- a/src/env/str.cpp +++ b/src/env/str.cpp @@ -6,36 +6,31 @@ #include #include -namespace CuraFormulaeEngine::env -{ - -const eval::Value::fn_t str = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } - - if (std::holds_alternative(args[0].value)) - { - return std::get(args[0].value); - } - - if (std::holds_alternative(args[0].value)) - { - return std::to_string(std::get(args[0].value)); - } - - if (std::holds_alternative(args[0].value)) - { - return std::to_string(std::get(args[0].value)); - } - - if (std::holds_alternative(args[0].value)) - { - return std::get(args[0].value) ? std::string("True") : std::string("False"); - } - throw std::runtime_error("Unimplemented"); +namespace CuraFormulaeEngine::env { + +const eval::Value::fn_t str = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } + + if (std::holds_alternative(args[0].value)) { + return std::get(args[0].value); + } + + if (std::holds_alternative(args[0].value)) { + return std::to_string(std::get(args[0].value)); + } + + if (std::holds_alternative(args[0].value)) { + return std::to_string(std::get(args[0].value)); + } + + if (std::holds_alternative(args[0].value)) { + return std::get(args[0].value) ? std::string("True") + : std::string("False"); + } + throw std::runtime_error("Unimplemented"); }; } // namespace CuraFormulaeEngine::env diff --git a/src/env/sum.cpp b/src/env/sum.cpp index 8b9f097..1dd0947 100644 --- a/src/env/sum.cpp +++ b/src/env/sum.cpp @@ -5,33 +5,28 @@ #include #include -namespace CuraFormulaeEngine::env -{ +namespace CuraFormulaeEngine::env { -const eval::Value::fn_t sum = [](const std::vector &args) -> eval::Result -{ - if (args.size() != 1) - { - return zeus::unexpected(eval::Error::InvalidNumberOfArguments); - } +const eval::Value::fn_t sum = + [](const std::vector &args) -> eval::Result { + if (args.size() != 1) { + return zeus::unexpected(eval::Error::InvalidNumberOfArguments); + } - if (! std::holds_alternative>(args[0].value)) - { - return zeus::unexpected(eval::Error::TypeMismatch); - } + if (!std::holds_alternative>(args[0].value)) { + return zeus::unexpected(eval::Error::TypeMismatch); + } - auto result = eval::Value{ int64_t(0) }; - const auto list = std::get>(args[0].value); - for (const auto& arg : list) - { - const auto sum = result + arg; - if (! sum.has_value()) - { - return zeus::unexpected(sum.error()); - } - result = sum.value(); + auto result = eval::Value{int64_t(0)}; + const auto list = std::get>(args[0].value); + for (const auto &arg : list) { + const auto sum = result + arg; + if (!sum.has_value()) { + return zeus::unexpected(sum.error()); } - return result; + result = sum.value(); + } + return result; }; } // namespace CuraFormulaeEngine::env diff --git a/src/eval.cpp b/src/eval.cpp index ca41c8c..269636d 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -221,11 +221,11 @@ namespace CuraFormulaeEngine::eval { } if (std::holds_alternative(value)) { - throw std::runtime_error("Cannot convert function to emscripten"); + return emscripten::val::undefined(); } if (std::holds_alternative(value)) { - throw std::runtime_error("Cannot convert function to emscripten"); + return emscripten::val::undefined(); } if (std::holds_alternative>(value)) { @@ -238,7 +238,7 @@ namespace CuraFormulaeEngine::eval { return obj; } - throw std::runtime_error("Unknown type in `Value::toEmscripten`"); + return emscripten::val::undefined(); } #endif diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 2110a9e..e0f4e7f 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -1,5 +1,5 @@ -#include "cura-formulae-engine/ast/expr_ptr.h" #include "cura-formulae-engine/parser/parser.h" +#include "cura-formulae-engine/ast/expr_ptr.h" #include @@ -9,17 +9,17 @@ #include #include -namespace CuraFormulaeEngine::parser -{ +namespace CuraFormulaeEngine::parser { -zeus::expected parse(std::string_view input) -{ - auto parse_result = lexy::parse(lexy::string_input(input), lexy::noop); - if (parse_result.is_success()) - { - return static_cast&&>(parse_result).value(); - } - return zeus::unexpected(parse_result.errors()); +zeus::expected parse(std::string_view input) { + auto parse_result = lexy::parse( + lexy::string_input(input), lexy::noop); + if (parse_result.is_success()) { + return static_cast &&>( + parse_result) + .value(); + } + return zeus::unexpected(parse_result.errors()); } } // namespace CuraFormulaeEngine::parser diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e116eee..b0d761e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,4 +29,4 @@ catch_discover_tests(tests OUTPUT_PREFIX "unittests." OUTPUT_SUFFIX - .xml) \ No newline at end of file + .xml) diff --git a/tests/parser.cpp b/tests/parser.cpp index f3cb89f..d456937 100644 --- a/tests/parser.cpp +++ b/tests/parser.cpp @@ -13,491 +13,464 @@ using namespace std::string_view_literals; using namespace CuraFormulaeEngine::ast; -TEST_CASE("constant single digit", "[parser, constant]") -{ - auto input = "1"sv; - const auto expected_ast = make_expr_ptr(1); - const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(1)); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("constant multi digit", "[parser, constant]") -{ - auto input = "12345"sv; - const auto expected_ast = make_expr_ptr(12345); - const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(12345)); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("float", "[parser, constant]") -{ - auto input = "3.14"sv; - const auto expected_ast = make_expr_ptr(3.14); - const auto expected_eval = CuraFormulaeEngine::eval::Value(3.14); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("float no integer", "[parser, constant]") -{ - auto input = ".0"sv; - const auto expected_ast = make_expr_ptr(0.0); - const auto expected_eval = CuraFormulaeEngine::eval::Value(0.0); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("float no decimal", "[parser, constant]") -{ - auto input = "0."sv; - const auto expected_ast = make_expr_ptr(0.0); - const auto expected_eval = CuraFormulaeEngine::eval::Value(0.0); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("int scientific", "[.][parser, constant]") -{ - auto input = "3e10"sv; - const auto expected_ast = make_expr_ptr(3e10); - const auto expected_eval = CuraFormulaeEngine::eval::Value(3e10); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("int scientific plus", "[.][parser, constant]") -{ - auto input = "3e+10"sv; - const auto expected_ast = make_expr_ptr(3e+10); - const auto expected_eval = CuraFormulaeEngine::eval::Value(3e+10); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("int scientific minus", "[.][parser, constant]") -{ - auto input = "3e-10"sv; - const auto expected_ast = make_expr_ptr(3e-10); - const auto expected_eval = CuraFormulaeEngine::eval::Value(3e-10); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("float scientific", "[.][parser, constant]") -{ - auto input = "2.7e10"sv; - const auto expected_ast = make_expr_ptr(2.7e10); - const auto expected_eval = CuraFormulaeEngine::eval::Value(2.7e10); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("float scientific plus", "[.][parser, constant]") -{ - auto input = "2.7e+10"sv; - const auto expected_ast = make_expr_ptr(2.7e+10); - const auto expected_eval = CuraFormulaeEngine::eval::Value(2.7e+10); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("float scientific minus", "[.][parser, constant]") -{ - auto input = "2.7e-10"sv; - const auto expected_ast = make_expr_ptr(2.7e-10); - const auto expected_eval = CuraFormulaeEngine::eval::Value(2.7e-10); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("constant boolean True", "[parser, constant]") -{ - auto input = "True"sv; - const auto expected_ast = make_expr_ptr(true); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("constant boolean", "[parser, constant]") -{ - auto input = "False"sv; - const auto expected_ast = make_expr_ptr(false); - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("negate int", "[parser, neg]") -{ - auto input = "-1"sv; - const auto expected_ast = -make_expr_ptr(1); - const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(-1)); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("negate float", "[parser, neg]") -{ - auto input = "-1.0"sv; - const auto expected_ast = -make_expr_ptr(1.0); - const auto expected_eval = CuraFormulaeEngine::eval::Value(-1.0); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("negate bool false", "[parser, neg]") -{ - auto input = "-False"sv; - const auto expected_ast = -make_expr_ptr(false); - const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(0)); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("negate bool true", "[parser, neg]") -{ - auto input = "-[]"sv; - const auto expected_ast = -make_list_expr(); - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE_FALSE(eval.has_value()); +TEST_CASE("constant single digit", "[parser, constant]") { + auto input = "1"sv; + const auto expected_ast = make_expr_ptr(1); + const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(1)); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("constant multi digit", "[parser, constant]") { + auto input = "12345"sv; + const auto expected_ast = make_expr_ptr(12345); + const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(12345)); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("float", "[parser, constant]") { + auto input = "3.14"sv; + const auto expected_ast = make_expr_ptr(3.14); + const auto expected_eval = CuraFormulaeEngine::eval::Value(3.14); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("float no integer", "[parser, constant]") { + auto input = ".0"sv; + const auto expected_ast = make_expr_ptr(0.0); + const auto expected_eval = CuraFormulaeEngine::eval::Value(0.0); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("float no decimal", "[parser, constant]") { + auto input = "0."sv; + const auto expected_ast = make_expr_ptr(0.0); + const auto expected_eval = CuraFormulaeEngine::eval::Value(0.0); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("int scientific", "[.][parser, constant]") { + auto input = "3e10"sv; + const auto expected_ast = make_expr_ptr(3e10); + const auto expected_eval = CuraFormulaeEngine::eval::Value(3e10); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("int scientific plus", "[.][parser, constant]") { + auto input = "3e+10"sv; + const auto expected_ast = make_expr_ptr(3e+10); + const auto expected_eval = CuraFormulaeEngine::eval::Value(3e+10); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("int scientific minus", "[.][parser, constant]") { + auto input = "3e-10"sv; + const auto expected_ast = make_expr_ptr(3e-10); + const auto expected_eval = CuraFormulaeEngine::eval::Value(3e-10); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("float scientific", "[.][parser, constant]") { + auto input = "2.7e10"sv; + const auto expected_ast = make_expr_ptr(2.7e10); + const auto expected_eval = CuraFormulaeEngine::eval::Value(2.7e10); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("float scientific plus", "[.][parser, constant]") { + auto input = "2.7e+10"sv; + const auto expected_ast = make_expr_ptr(2.7e+10); + const auto expected_eval = CuraFormulaeEngine::eval::Value(2.7e+10); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("float scientific minus", "[.][parser, constant]") { + auto input = "2.7e-10"sv; + const auto expected_ast = make_expr_ptr(2.7e-10); + const auto expected_eval = CuraFormulaeEngine::eval::Value(2.7e-10); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("constant boolean True", "[parser, constant]") { + auto input = "True"sv; + const auto expected_ast = make_expr_ptr(true); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("constant boolean", "[parser, constant]") { + auto input = "False"sv; + const auto expected_ast = make_expr_ptr(false); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("negate int", "[parser, neg]") { + auto input = "-1"sv; + const auto expected_ast = -make_expr_ptr(1); + const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(-1)); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("negate float", "[parser, neg]") { + auto input = "-1.0"sv; + const auto expected_ast = -make_expr_ptr(1.0); + const auto expected_eval = CuraFormulaeEngine::eval::Value(-1.0); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("negate bool false", "[parser, neg]") { + auto input = "-False"sv; + const auto expected_ast = -make_expr_ptr(false); + const auto expected_eval = CuraFormulaeEngine::eval::Value(int64_t(0)); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("negate bool true", "[parser, neg]") { + auto input = "-[]"sv; + const auto expected_ast = -make_list_expr(); + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE_FALSE(eval.has_value()); +} + +TEST_CASE("inverse int 1", "[parser, not]") { + auto input = "not 1"sv; + const auto expected_ast = !make_expr_ptr(1); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse float 1", "[parser, not]") { + auto input = "not 1.0"sv; + const auto expected_ast = !make_expr_ptr(1.0); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse int 0", "[parser, not]") { + auto input = "not 0"sv; + const auto expected_ast = !make_expr_ptr(0); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse float 0", "[parser, not]") { + auto input = "not 0.0"sv; + const auto expected_ast = !make_expr_ptr(0.0); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse bool false", "[parser, not]") { + auto input = "not False"sv; + const auto expected_ast = !make_expr_ptr(false); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse bool true", "[parser, not]") { + auto input = "not True"sv; + const auto expected_ast = !make_expr_ptr(true); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse empty string", "[parser, not]") { + auto input = "not \"\""sv; + const auto expected_ast = !make_expr_ptr(""); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse string", "[parser, not]") { + auto input = "not \"foo\""sv; + const auto expected_ast = !make_expr_ptr("foo"); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); +} + +TEST_CASE("inverse bool empty list", "[parser, not]") { + auto input = "not []"sv; + const auto expected_ast = !make_list_expr(); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); } -TEST_CASE("inverse int 1", "[parser, not]") -{ - auto input = "not 1"sv; - const auto expected_ast = !make_expr_ptr(1); - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); +TEST_CASE("inverse bool list", "[parser, not]") { + auto input = "not [1]"sv; + const auto expected_ast = !make_list_expr(make_expr_ptr(int64_t(1))); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); } -TEST_CASE("inverse float 1", "[parser, not]") -{ - auto input = "not 1.0"sv; - const auto expected_ast = !make_expr_ptr(1.0); - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); +TEST_CASE("member empty list", "[parser, member]") { + auto input = "1 in []"sv; - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} + std::vector numbers; + numbers.push_back(make_expr_ptr(int64_t(1))); + numbers.push_back(make_list_expr()); + const auto expected_ast = make_expr_ptr( + std::move(numbers), std::vector{ComparisonOperators::Member}); -TEST_CASE("inverse int 0", "[parser, not]") -{ - auto input = "not 0"sv; - const auto expected_ast = !make_expr_ptr(0); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); } -TEST_CASE("inverse float 0", "[parser, not]") -{ - auto input = "not 0.0"sv; - const auto expected_ast = !make_expr_ptr(0.0); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); +TEST_CASE("member list", "[parser, member]") { + auto input = "1 in [1]"sv; - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} + std::vector expressions; + expressions.push_back(make_expr_ptr(int64_t(1))); + std::vector numbers; + numbers.push_back(make_expr_ptr(int64_t(1))); + expressions.push_back(make_list_expr(make_expr_ptr(int64_t(1)))); -TEST_CASE("inverse bool false", "[parser, not]") -{ - auto input = "not False"sv; - const auto expected_ast = !make_expr_ptr(false); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + std::vector operators = {ComparisonOperators::Member}; - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} + const auto expected_ast = make_expr_ptr( + std::move(expressions), std::move(operators)); -TEST_CASE("inverse bool true", "[parser, not]") -{ - auto input = "not True"sv; - const auto expected_ast = !make_expr_ptr(true); - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); } -TEST_CASE("inverse empty string", "[parser, not]") -{ - auto input = "not \"\""sv; - const auto expected_ast = !make_expr_ptr(""); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); +TEST_CASE("not member empty list", "[parser, member]") { + auto input = "1 not in []"sv; - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} + std::vector numbers; + numbers.push_back(make_expr_ptr(int64_t(1))); -TEST_CASE("inverse string", "[parser, not]") -{ - auto input = "not \"foo\""sv; - const auto expected_ast = !make_expr_ptr("foo"); - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); + numbers.push_back(make_list_expr()); - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("inverse bool empty list", "[parser, not]") -{ - auto input = "not []"sv; - const auto expected_ast = !make_list_expr(); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("inverse bool list", "[parser, not]") -{ - auto input = "not [1]"sv; - const auto expected_ast = !make_list_expr(make_expr_ptr(int64_t(1))); - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("member empty list", "[parser, member]") -{ - auto input = "1 in []"sv; - - std::vector numbers; - numbers.push_back(make_expr_ptr(int64_t(1))); - numbers.push_back(make_list_expr()); - const auto expected_ast = make_expr_ptr(std::move(numbers), std::vector{ComparisonOperators::Member}); - - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} - -TEST_CASE("member list", "[parser, member]") -{ - auto input = "1 in [1]"sv; - - std::vector expressions; - expressions.push_back(make_expr_ptr(int64_t(1))); - std::vector numbers; - numbers.push_back(make_expr_ptr(int64_t(1))); - expressions.push_back(make_list_expr(make_expr_ptr(int64_t(1)))); - - std::vector operators = {ComparisonOperators::Member}; + const auto expected_ast = make_expr_ptr( + std::move(numbers), std::vector{ComparisonOperators::NotMember}); - const auto expected_ast = make_expr_ptr(std::move(expressions), std::move(operators)); + const auto expected_eval = CuraFormulaeEngine::eval::Value(true); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); - - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); + const auto message = CuraFormulaeEngine::parser::parse(input); + REQUIRE(message.has_value()); + const auto &ast = message.value(); + REQUIRE(ast.deepEq(expected_ast)); + const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); + REQUIRE(eval.has_value()); + REQUIRE(eval.value().deepEq(expected_eval)); } -TEST_CASE("not member empty list", "[parser, member]") -{ - auto input = "1 not in []"sv; +TEST_CASE("not member list", "[parser, member]") { + auto input = "1 not in [1]"sv; - std::vector numbers; - numbers.push_back(make_expr_ptr(int64_t(1))); - - numbers.push_back(make_list_expr()); + std::vector expressions; + expressions.push_back(make_expr_ptr(int64_t(1))); - const auto expected_ast = make_expr_ptr(std::move(numbers), std::vector{ComparisonOperators::NotMember}); + std::vector numbers; + numbers.push_back(make_expr_ptr(int64_t(1))); + expressions.push_back(make_list_expr(make_expr_ptr(int64_t(1)))); - const auto expected_eval = CuraFormulaeEngine::eval::Value(true); + std::vector operators = {ComparisonOperators::NotMember}; - const auto message = CuraFormulaeEngine::parser::parse(input); - REQUIRE(message.has_value()); - const auto &ast = message.value(); - REQUIRE(ast.deepEq(expected_ast)); - const auto eval = ast.evaluate(&CuraFormulaeEngine::env::std_env); - REQUIRE(eval.has_value()); - REQUIRE(eval.value().deepEq(expected_eval)); -} + const auto expected_ast = make_expr_ptr( + std::move(expressions), std::move(operators)); -TEST_CASE("not member list", "[parser, member]") -{ - auto input = "1 not in [1]"sv; - - std::vector expressions; - expressions.push_back(make_expr_ptr(int64_t(1))); - - std::vector numbers; - numbers.push_back(make_expr_ptr(int64_t(1))); - expressions.push_back(make_list_expr(make_expr_ptr(int64_t(1)))); - - std::vector operators = {ComparisonOperators::NotMember}; - - const auto expected_ast = make_expr_ptr(std::move(expressions), std::move(operators)); - - const auto expected_eval = CuraFormulaeEngine::eval::Value(false); + const auto expected_eval = CuraFormulaeEngine::eval::Value(false); const auto message = CuraFormulaeEngine::parser::parse(input); REQUIRE(message.has_value());