-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAbstractSyntaxTree.h
134 lines (115 loc) · 3.81 KB
/
AbstractSyntaxTree.h
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//
// Created by User on 7/10/2024.
//
#ifndef ABSTRACTSYNTAXTREE_H
#define ABSTRACTSYNTAXTREE_H
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <stdexcept>
#include <string>
#include <utility>
class FunctionDefExpression;
class Expression;
using ExpressionPtr = std::shared_ptr<Expression>;
class Expression {
public:
virtual ~Expression() = default;
[[nodiscard]] virtual double evaluate() = 0;
};
class Number final : public Expression {
double value;
public:
explicit Number(double value) : value(value) {}
double evaluate() override {
return value;
}
};
class BinaryExpression final : public Expression {
char op;
ExpressionPtr left;
ExpressionPtr right;
public:
BinaryExpression(char op, ExpressionPtr left, ExpressionPtr right)
:op(op), left(std::move(left)), right(std::move(right)) {}
double evaluate() override {
switch (op) {
case '+': return left->evaluate() + right->evaluate();
case '-': return left->evaluate() - right->evaluate();
case '*': return left->evaluate() * right->evaluate();
case '/': return left->evaluate() / right->evaluate();
default: throw std::runtime_error("Unknown operator");
}
}
};
using FunctionDef = std::function<double(const std::vector<double>&)>;
inline std::map<std::string, FunctionDef> functions;
inline std::map<std::string, std::shared_ptr<FunctionDefExpression>> userFunctions;
inline std::map<std::string, double> variables;
class FunctionDefExpression final : public Expression {
public:
std::string name;
std::vector<std::string> params;
ExpressionPtr body;
FunctionDefExpression(std::string name, std::vector<std::string> params, ExpressionPtr body)
: name(std::move(name)), params(std::move(params)), body(std::move(body)) {}
double evaluate() override { return 0; }
};
class MethodCallExpression final : public Expression {
std::string name;
std::vector<ExpressionPtr> args;
public:
MethodCallExpression(std::string name, std::vector<ExpressionPtr> args) : name(std::move(name)), args(std::move(args)) {}
double evaluate() override {
auto it = userFunctions.find(name);
if (it != userFunctions.end()) {
const auto& funcDef = it->second;
std::map<std::string, double> oldVariables = variables;
for (size_t i = 0; i < funcDef->params.size(); ++i) {
variables[funcDef->params[i]] = args[i]->evaluate();
}
double result = funcDef->body->evaluate();
variables = oldVariables;
return result;
}
std::vector<double> evaluatedArgs;
for (auto& arg : args) {
evaluatedArgs.push_back(arg->evaluate());
}
return functions[name](evaluatedArgs);
}
};
class VariableExpression final : public Expression {
std::string name;
public:
explicit VariableExpression(std::string name) : name(std::move(name)) {}
double evaluate() override {
return variables[name];
}
};
class AssignmentExpression final : public Expression {
std::string name;
ExpressionPtr value;
public:
AssignmentExpression(std::string name, ExpressionPtr value) : name(std::move(name)), value(std::move(value)) {}
double evaluate() override {
variables[name] = value->evaluate();
return variables[name];
}
};
class StatementListExpression final : public Expression {
public:
std::vector<ExpressionPtr> statements;
void addStatement(ExpressionPtr stmt) {
statements.push_back(std::move(stmt));
}
double evaluate() override {
double result = 0;
for (const auto& stmt : statements) {
result = stmt->evaluate();
}
return result;
}
};
#endif //ABSTRACTSYNTAXTREE_H