aboutsummaryrefslogtreecommitdiff
path: root/src/nodes.cc
blob: 5432318f46ea1e0dd4c3181f676749157b6351b9 (plain)
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
#include "nodes.h"
#include "utils.h"
#include "tree.h"
#include "exceptions.h"

#include <cmath>
#include <cassert>
#include <sstream>
#include <limits>

namespace SimpleParser {

bool Node::hasChildren() const {
	return false;
}

bool Node::isParentOf(Node*const) const {
	return false;
}

OperandNode::OperandNode(double value):
	value_{value} { }

double OperandNode::solve() const {
	return this->value_;
}

std::string OperandNode::print() const {
	std::stringstream convertStream;
	convertStream.precision(std::numeric_limits<double>::digits10);

	convertStream << this->value_;

	return convertStream.str();
}

OperatorNode::OperatorNode(TokenType token):
	operator_{token} { }

double OperatorNode::solve() const {
	switch ( this->operator_ ) {
		case TokenType::OPERATOR_PLUS: {
			return this->left_->solve() + this->right_->solve();
		}
		case TokenType::OPERATOR_MINUS: {
			return this->left_->solve() - this->right_->solve();
		}
		case TokenType::OPERATOR_MULTIPLY: {
			return this->left_->solve() * this->right_->solve();
		}
		case TokenType::OPERATOR_DIVIDE: {
			return this->left_->solve() / this->right_->solve();
		}
		case TokenType::OPERATOR_POWER: {
			return std::pow(
				this->left_->solve(), this->right_->solve()
			);
		}
		default: {
			throw operator_exception();
		}
	}
}

std::string OperatorNode::print() const {
	switch ( this->operator_ ) {
		case TokenType::OPERATOR_PLUS: {
			return std::string(1, '+');
		}
		case TokenType::OPERATOR_MINUS: {
			return std::string(1, '-');
		}
		case TokenType::OPERATOR_MULTIPLY: {
			return std::string(1, '*');
		}
		case TokenType::OPERATOR_DIVIDE: {
			return std::string(1, '/');
		}
		case TokenType::OPERATOR_POWER: {
			return std::string(1, '^');
		}
		default: {
			throw operator_exception();
		}
	}
}

bool OperatorNode::hasChildren() const {
	return this->right_ != nullptr
	    && this->left_  != nullptr;
}

bool OperatorNode::isParentOf(Node*const node) const {
	return this->right_ == node
	    || this->left_  == node;
}

TokenType OperatorNode::token() const {
	return this->operator_;
}

void OperatorNode::setChildren(Node*const right, Node*const left) {
	assert(right != nullptr && left != nullptr);

	this->right_ = right;
	this->left_  = left;
}

ConstantNode::ConstantNode(
	const std::string& identifier,
	const ConstantMap* constants
):
	identifier_(identifier),
	constants_(constants) { }

double ConstantNode::solve() const {
	if ( this->constants_ != nullptr ) {
		try {
			return this->constants_->at(this->identifier_);
		}
		catch ( std::out_of_range& ) {
			throw identifier_exception();
		}
	} else {
		throw identifier_exception();
	}
}

std::string ConstantNode::print() const {
	return this->identifier_;
}

}