54 lines
1.2 KiB
C
54 lines
1.2 KiB
C
|
#ifndef MCALC_NODE_H
|
||
|
#define MCALC_NODE_H
|
||
|
|
||
|
#include <optional>
|
||
|
#include <string>
|
||
|
#include <unordered_set>
|
||
|
#include <memory>
|
||
|
#include <memory_resource>
|
||
|
|
||
|
struct State;
|
||
|
|
||
|
struct Node {
|
||
|
enum class type {
|
||
|
NUM,
|
||
|
VAR,
|
||
|
NEG,
|
||
|
PLUS,
|
||
|
MINUS,
|
||
|
MUL,
|
||
|
DIV,
|
||
|
INVALID
|
||
|
} ty = type::INVALID;
|
||
|
double num = 0;
|
||
|
std::string var{};
|
||
|
std::unique_ptr<Node> a{}, b{};
|
||
|
|
||
|
void used_vars(std::unordered_set<std::string>*) const;
|
||
|
std::optional<double> eval(State*) const;
|
||
|
};
|
||
|
|
||
|
using parser_var_ty = std::variant<double, std::string, Node*>;
|
||
|
|
||
|
template<Node::type ty>
|
||
|
Node *new_node(const parser_var_ty& v) {
|
||
|
auto *node = new Node { .ty = ty };
|
||
|
if constexpr (ty == Node::type::NUM)
|
||
|
node->num = std::get<double>(v);
|
||
|
else if constexpr (ty == Node::type::VAR)
|
||
|
node->var = std::get<std::string>(v);
|
||
|
else
|
||
|
node->a.reset(std::get<Node*>(v));
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
template<Node::type ty>
|
||
|
Node *new_node(const parser_var_ty& a, const parser_var_ty& b) {
|
||
|
auto *node = new Node { .ty = ty };
|
||
|
node->a.reset(std::get<Node*>(a));
|
||
|
node->b.reset(std::get<Node*>(b));
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
#endif //MCALC_NODE_H
|