102 lines
1.9 KiB
C++
102 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
|
|
extern "C" {
|
|
#include "tree.h"
|
|
#include "parser.h"
|
|
}
|
|
|
|
class Expression {
|
|
std::string m_expr_str;
|
|
struct parser m_parser;
|
|
struct expr_node* m_root;
|
|
|
|
public:
|
|
Expression(const std::string& expr_str) {
|
|
m_root = nullptr;
|
|
SetExpression(expr_str);
|
|
}
|
|
|
|
Expression() : Expression("") {}
|
|
|
|
Expression(const Expression&) = delete;
|
|
Expression& operator=(const Expression&) = delete;
|
|
|
|
Expression(Expression&& other) {
|
|
m_expr_str = std::move(other.m_expr_str);
|
|
m_parser = other.m_parser;
|
|
m_root = other.m_root;
|
|
|
|
other.m_root = nullptr;
|
|
}
|
|
|
|
Expression& operator=(Expression&& other) {
|
|
if (this != &other) {
|
|
if (m_root) {
|
|
node_free(m_root);
|
|
}
|
|
|
|
m_expr_str = std::move(other.m_expr_str);
|
|
m_parser = other.m_parser;
|
|
m_root = other.m_root;
|
|
|
|
other.m_root = nullptr;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
void SetExpression(const std::string& expr_str) {
|
|
if (expr_str == m_expr_str) {
|
|
return;
|
|
}
|
|
|
|
m_expr_str = expr_str;
|
|
|
|
if (m_root) {
|
|
node_free(m_root);
|
|
m_root = nullptr;
|
|
}
|
|
|
|
if (m_expr_str.empty()) {
|
|
return;
|
|
}
|
|
|
|
m_root = parser_parse(&m_parser, m_expr_str.c_str(), "x");
|
|
}
|
|
|
|
bool Evaluate(double x, double& y) const {
|
|
if (!m_root) {
|
|
return false;
|
|
}
|
|
|
|
return node_eval(m_root, x, &y) == EVAL_OK;
|
|
}
|
|
|
|
bool IsValid() const {
|
|
return m_root != nullptr;
|
|
}
|
|
|
|
const char* GetErrorText() const {
|
|
if (parser_get_error(&m_parser) == ERR_NO_ERR) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (m_expr_str.empty()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return parser_get_error_text(&m_parser);
|
|
}
|
|
|
|
~Expression() {
|
|
if (m_root) {
|
|
node_free(m_root);
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
|