A simple scripting language in C++
Ferenc Szontágh
2025-04-18 e2e9e07a9f50dc1f7a967280a3d1d8ef7fcaa153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <memory>
#include <string>
 
#include "ExpressionNode.hpp"
 
namespace Interpreter {
class BinaryExpressionNode : public ExpressionNode {
    std::unique_ptr<ExpressionNode> lhs_;
    std::unique_ptr<ExpressionNode> rhs_;
    std::string                     op_;
 
  public:
    BinaryExpressionNode(std::unique_ptr<ExpressionNode> lhs, std::string op, std::unique_ptr<ExpressionNode> rhs) :
        lhs_(std::move(lhs)),
        rhs_(std::move(rhs)),
        op_(std::move(op)) {}
 
    Symbols::Value evaluate(Interpreter & interpreter) const override {
        auto leftVal  = lhs_->evaluate(interpreter);
        auto rightVal = rhs_->evaluate(interpreter);
        if (leftVal.getType() != rightVal.getType()) {
            throw std::runtime_error(
                "Unsupported types in binary expression: " + Symbols::Variables::TypeToString(leftVal.getType()) +
                " and " + Symbols::Variables::TypeToString(rightVal.getType()) + " " + toString());
        }
 
        if (leftVal.getType() == Symbols::Variables::Type::INTEGER &&
            rightVal.getType() == Symbols::Variables::Type::INTEGER) {
            int l = leftVal.get<int>();
            int r = rightVal.get<int>();
 
            if (op_ == "+") {
                return Symbols::Value(l + r);
            }
            if (op_ == "-") {
                return Symbols::Value(l - r);
            }
            if (op_ == "*") {
                return Symbols::Value(l * r);
            }
            if (op_ == "/") {
                return Symbols::Value(l / r);  // TODO: 0 div
            }
 
            throw std::runtime_error("Unknown operator: " + op_);
        }
 
        if (leftVal.getType() == Symbols::Variables::Type::STRING &&
            rightVal.getType() == Symbols::Variables::Type::STRING) {
            auto l = leftVal.get<std::string>();
            auto r = rightVal.get<std::string>();
 
            if (op_ == "+") {
                return Symbols::Value(l + r);
            }
 
            throw std::runtime_error("Unknown operator: " + op_);
        }
 
        throw std::runtime_error(
            "Unsupported types in binary expression: " + Symbols::Variables::TypeToString(leftVal.getType()) + " and " +
            Symbols::Variables::TypeToString(rightVal.getType()) + " " + toString());
    }
 
    std::string toString() const override { return "(" + lhs_->toString() + " " + op_ + " " + rhs_->toString() + ")"; }
};
 
};  // namespace Interpreter