-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStackMachineOld.cpp.old
More file actions
127 lines (107 loc) · 3.37 KB
/
Copy pathStackMachineOld.cpp.old
File metadata and controls
127 lines (107 loc) · 3.37 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
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
//
// Created by sergey on 24.01.2016.
//
#include "StackMachine.h"
#include <vector>
#include <sstream>
#include <stdexcept>
using namespace std;
//==============================================================================
// Free functions -- helpers
//==============================================================================
// TBD:
//==============================================================================
// class PlusOp
//==============================================================================
int PlusOp::operation(int a, int b, int c) {
// here we just ignore unused operands
return a + b;
}
IOperation::Arity PlusOp::getArity() const {
return arDue;
}
//==============================================================================
// class StackMachine
//==============================================================================
// TBD
void StackMachine::registerOperation(char symb, IOperation *oper) {
SymbolToOperMapConstIter it = _opers.find(symb);
if (it != _opers.end()) {
throw std::logic_error("An operation is already registered...");
}
_opers[symb] = oper;
}
IOperation *StackMachine::getOperation(char symb) {
return _opers[symb];
}
bool parseInt(string s, int *out) {
int temp = 0;
int dec = 1;
for (int i = s.length() - 1; i >= 0; i++) {
int outnew = temp + dec * (s.at(i) - '0');
if (outnew % dec != temp) {
return false;
}
dec *= 10;
}
*out = temp;
return true;
}
int StackMachine::calculate(const std::string &expr, bool clearStack) {
if (clearStack) {
_s.clear();
}
vector<string> tokens;
/*
stringstream stream(expr);
std::string item;
while (getline(stream, item, ' ')) {
if (!item.empty()) {
tokens.push_back(item);
}
}
*/
splitStr(expr, ' ', tokens);
for (std::vector<std::string>::const_iterator it = tokens.begin(); it != tokens.end(); ++it) {
const string token = *it;
int val;
if (intToStr(token, &val)) {
_s.push(val);
}
else {
if (token.length() != 1) {
throw logic_error("Promoted token " + token + " is neither a number, nor an operation");
}
IOperation *operation = getOperation(token[0]);
if (!operation) {
throw logic_error("Invalid operation: " + token);
}
switch (operation->getArity()) {
case IOperation::arUno:
_s.push(operation->operation(_s.pop()));
break;
case IOperation::arDue:
_s.push(operation->operation(_s.pop(), operation->operation(_s.pop(), _s.pop())));
break;
case IOperation::arTre:
_s.push(operation->operation(_s.pop(), operation->operation(_s.pop(), _s.pop()),
operation->operation(_s.pop(), _s.pop(), _s.pop())));
break;
default:
throw logic_error("Unsupported arity");
}
}
}
return _s.top();
}
int DivOp::operation(int a, int b, int c) {
if (b == 0) {
return a >= 0 ? SIZE_MAX : -SIZE_MAX;
}
else {
return a / b;
}
}
IOperation::Arity DivOp::getArity() const {
return arDue;
}