#pragma once #include #include #include #include #include #include #include namespace hex { template class MathEvaluator { public: MathEvaluator() = default; std::optional evaluate(const std::string &input); void registerStandardVariables(); void registerStandardFunctions(); void setVariable(const std::string &name, T value); void setFunction(const std::string &name, const std::function(std::vector)> &function, size_t minNumArgs, size_t maxNumArgs); std::unordered_map &getVariables() { return this->m_variables; } [[nodiscard]] bool hasError() const { return this->m_lastError.has_value(); } [[nodiscard]] std::optional getLastError() const { return this->m_lastError; } private: void setError(const std::string &error) { this->m_lastError = error; } private: enum class TokenType { Number, Variable, Function, Operator, Bracket }; enum class Operator : u16 { Invalid = 0x000, Assign = 0x010, Or = 0x020, Xor = 0x030, And = 0x040, BitwiseOr = 0x050, BitwiseXor = 0x060, BitwiseAnd = 0x070, Equals = 0x080, NotEquals = 0x081, GreaterThan = 0x090, LessThan = 0x091, GreaterThanOrEquals = 0x092, LessThanOrEquals = 0x093, ShiftLeft = 0x0A0, ShiftRight = 0x0A1, Addition = 0x0B0, Subtraction = 0x0B1, Multiplication = 0x0C0, Division = 0x0C1, Modulus = 0x0C2, Exponentiation = 0x1D0, Combine = 0x0E0, BitwiseNot = 0x0F0, Not = 0x0F1 }; enum class BracketType : std::uint8_t { Left, Right }; struct Token { TokenType type; union { T number; Operator op; BracketType bracketType; }; std::string name; std::vector arguments; }; static i16 comparePrecedence(const Operator &a, const Operator &b); static bool isLeftAssociative(const Operator op); static std::pair toOperator(const std::string &input); private: std::optional> parseInput(std::string input); std::optional> toPostfix(std::queue inputQueue); std::optional evaluate(std::queue postfixTokens); std::unordered_map m_variables; std::unordered_map(std::vector)>> m_functions; std::optional m_lastError; }; extern template class MathEvaluator; extern template class MathEvaluator; }