1#include <iostream>
2#include <memory>
3#include <concepts>
4#include <functional>
5
6// Abstract Expression Interface
7template <typename T>
8requires std::is_arithmetic_v<T>
9class ExpressionNode {
10public:
11 virtual ~ExpressionNode() = default;
12 virtual T evaluate() const = 0;
13};
14
15// Concrete Terminal Node: Numeric Constant
16template <typename T>
17requires std::is_arithmetic_v<T>
18class NumericNode : public ExpressionNode<T> {
19private:
20 T m_value;
21public:
22 explicit NumericNode(T val) : m_value(val) {}
23 T evaluate() const override { return m_value; }
24};
25
26// Concrete Binary Operator Node (+, -, *, /)
27template <typename T>
28requires std::is_arithmetic_v<T>
29class BinaryOpNode : public ExpressionNode<T> {
30public:
31 enum class Op { Add, Subtract, Multiply, Divide };
32
33private:
34 std::unique_ptr<ExpressionNode<T>> m_left;
35 std::unique_ptr<ExpressionNode<T>> m_right;
36 Op m_op;
37
38public:
39 BinaryOpNode(Op op, std::unique_ptr<ExpressionNode<T>> left, std::unique_ptr<ExpressionNode<T>> right)
40 : m_op(op), m_left(std::move(left)), m_right(std::move(right)) {}
41
42 T evaluate() const override {
43 T lVal = m_left->evaluate();
44 T rVal = m_right->evaluate();
45
46 switch (m_op) {
47 case Op::Add: return lVal + rVal;
48 case Op::Subtract: return lVal - rVal;
49 case Op::Multiply: return lVal * rVal;
50 case Op::Divide: return (rVal != 0) ? (lVal / rVal) : 0;
51 }
52 return 0;
53 }
54};
55
56int main() {
57 std::cout << "=== MSK Generic AST Expression Evaluator ===\n";
58
59 // Representing: (15 + 5) * (8 - 2)
60 using Op = BinaryOpNode<double>::Op;
61
62 auto expr = std::make_unique<BinaryOpNode<double>>(
63 Op::Multiply,
64 std::make_unique<BinaryOpNode<double>>(
65 Op::Add,
66 std::make_unique<NumericNode<double>>(15.0),
67 std::make_unique<NumericNode<double>>(5.0)
68 ),
69 std::make_unique<BinaryOpNode<double>>(
70 Op::Subtract,
71 std::make_unique<NumericNode<double>>(8.0),
72 std::make_unique<NumericNode<double>>(2.0)
73 )
74 );
75
76 std::cout << "Expression: (15 + 5) * (8 - 2)\n";
77 std::cout << "Evaluated Result: " << expr->evaluate() << "\n"; // Output: 120
78
79 return 0;
80}