-
Notifications
You must be signed in to change notification settings - Fork 0
/
exp.cpp
112 lines (87 loc) · 2.69 KB
/
exp.cpp
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
#include "exp.h"
#include <utility>
Expression::Expression(){}
/** ---------- ConstantExp---------- */
ConstantExp::ConstantExp(int val) {
value = val;
}
int ConstantExp::eval(const SymbolTable & context) {
return value;
}
std::string ConstantExp::toString() {
return std::to_string(value);
}
ExpressionType ConstantExp::type() {
return CONSTANT;
}
int ConstantExp::getConstantValue() const {
return value;
}
/** ----------IdentifierExp----------- */
IdentifierExp::IdentifierExp(std::string name) :
name(std::move(name)) {}
int IdentifierExp::eval(const SymbolTable & context) {
if (!context.isDefined(name)) {
std::cerr << "Variable " << name << " is not defined." << std::endl;
}
return context.getValue(name);
}
std::string IdentifierExp::toString() {
return name;
}
ExpressionType IdentifierExp::type() {
return IDENTIFIER;
}
std::string IdentifierExp::getIdentifierName() {
return name;
}
/** ------ CompoundExp --------*/
CompoundExp::CompoundExp(std::string op, Expression *lhs, Expression *rhs):
op(std::move(op)) {
std::unique_ptr<Expression> lhs_ptr(lhs);
std::unique_ptr<Expression> rhs_ptr(rhs);
this->lhs = std::move(lhs_ptr);
this->rhs = std::move(rhs_ptr);
}
CompoundExp::~CompoundExp() = default;
int CompoundExp::eval(const SymbolTable & context) {
if (op == "+") {
return lhs->eval(context) + rhs->eval(context);
} else if (op == "-") {
return lhs->eval(context) - rhs->eval(context);
} else if (op == "*") {
return lhs->eval(context) * rhs->eval(context);
} else if (op == "/") {
return lhs->eval(context) / rhs->eval(context);
} else if (op == "MOD") {
/*The MOD operator has the same precedence as * and /.
In the expression LET r = a MOD b,
the absolute value of r should be less than the absolute value of b,
and the sign of r is the same as that of b.
For example, 5 MOD 3 is 2 and 5 MOD (-3) is -1.
*/
return lhs->eval(context) % rhs->eval(context);
} else if (op == "**") {
return static_cast<int>(pow(lhs->eval(context), rhs->eval(context)));
}else {
//TODO: handle error,maybe throw exception
std::cerr << "Unknown operator: " << op << std::endl;
}
return 0;
}
//TODO: Implement the toString method for CompoundExp
std::string CompoundExp::toString() {
return "(" + lhs->toString() + " " + op + " " + rhs->toString() + ")";
}
ExpressionType CompoundExp::type() {
return COMPOUND;
}
std::string CompoundExp::getOperator() {
return op;
}
Expression *CompoundExp::getLHS() {
return lhs.get();
}
Expression *CompoundExp::getRHS() {
return rhs.get();
}