-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathevaluator.cpp
More file actions
64 lines (58 loc) · 2.08 KB
/
evaluator.cpp
File metadata and controls
64 lines (58 loc) · 2.08 KB
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
#include "evaluator.h"
#include <stack>
#include <cmath>
#include <stdexcept>
double Evaluator::evaluate(const std::vector<Token>& postfix) {
std::stack<double> stack;
for (const Token& tok : postfix) {
if (tok.type == TokenType::NUMBER) {
stack.push(tok.number);
}
else if (tok.type == TokenType::VARIABLE) {
stack.push(variables.get(tok.value));
}
else if (tok.type == TokenType::OPERATOR) {
if (tok.value == "u-") {
double a = stack.top(); stack.pop();
stack.push(-a);
continue;
}
double b = stack.top(); stack.pop();
double a = stack.top(); stack.pop();
stack.push(applyOp(tok.value, a, b));
}
else if (tok.type == TokenType::FUNCTION) {
double arg = stack.top(); stack.pop();
stack.push(applyFunc(tok.value, arg));
}
}
return stack.top();
}
double Evaluator::applyOp(const std::string& op, double a, double b) const {
if (op == "+") return a + b;
if (op == "-") return a - b;
if (op == "*") return a * b;
if (op == "%") return std::fmod(a, b);
if (op == "^") return std::pow(a, b);
if (op == "/") {
if (b == 0) throw std::runtime_error("division by zero");
return a / b;
}
throw std::runtime_error("unknown operator: " + op);
}
double Evaluator::applyFunc(const std::string& fn, double arg) const {
if (fn == "sqrt") {
if (arg < 0) throw std::runtime_error("sqrt of negative number");
return std::sqrt(arg);
}
if (fn == "sin") return std::sin(arg * M_PI / 180.0);
if (fn == "cos") return std::cos(arg * M_PI / 180.0);
if (fn == "tan") return std::tan(arg * M_PI / 180.0);
if (fn == "log") return std::log10(arg);
if (fn == "log2") return std::log2(arg);
if (fn == "ln") return std::log(arg);
if (fn == "abs") return std::abs(arg);
if (fn == "floor") return std::floor(arg);
if (fn == "ceil") return std::ceil(arg);
throw std::runtime_error("unknown function: " + fn);
}