Skip to content

Commit 4467e73

Browse files
committed
First Commit
0 parents  commit 4467e73

File tree

10 files changed

+1184
-0
lines changed

10 files changed

+1184
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# specific to CodeBlocks IDE
2+
*.layout
3+
*.depend
4+
# generated directories
5+
bin/
6+
obj/
7+
*.exe

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# eval
2+
A tool fot evaluating arithmetic expression from your terminal 😎 🧑🏻‍💻.
3+
4+
No need to open your calculator again for basic calculation. Just type `eval {{expression}}` in your terminal😎. Calculate quickly in your terminal.

color.hpp

Lines changed: 878 additions & 0 deletions
Large diffs are not rendered by default.

eval.cbp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
2+
<CodeBlocks_project_file>
3+
<FileVersion major="1" minor="6" />
4+
<Project>
5+
<Option title="eval" />
6+
<Option pch_mode="2" />
7+
<Option compiler="gcc" />
8+
<Build>
9+
<Target title="Debug">
10+
<Option output="bin/Debug/eval" prefix_auto="1" extension_auto="1" />
11+
<Option object_output="obj/Debug/" />
12+
<Option type="1" />
13+
<Option compiler="gcc" />
14+
<Compiler>
15+
<Add option="-g" />
16+
</Compiler>
17+
</Target>
18+
<Target title="Release">
19+
<Option output="bin/Release/eval" prefix_auto="1" extension_auto="1" />
20+
<Option object_output="obj/Release/" />
21+
<Option type="1" />
22+
<Option compiler="gcc" />
23+
<Compiler>
24+
<Add option="-O2" />
25+
</Compiler>
26+
<Linker>
27+
<Add option="-s" />
28+
</Linker>
29+
</Target>
30+
</Build>
31+
<Compiler>
32+
<Add option="-Wall" />
33+
<Add option="-fexceptions" />
34+
</Compiler>
35+
<Unit filename="main.cpp" />
36+
<Unit filename="resources.rc">
37+
<Option compilerVar="WINDRES" />
38+
</Unit>
39+
<Extensions>
40+
<lib_finder disable_auto="1" />
41+
</Extensions>
42+
</Project>
43+
</CodeBlocks_project_file>

main.cpp

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
#include "color.hpp"
2+
#include "iostream"
3+
#include "math.h"
4+
#include "stack"
5+
#include "string.h"
6+
#include "vector"
7+
#include "conio.h"
8+
using namespace std;
9+
10+
const string VALID_SET("x.0123456789+-*/^()");
11+
12+
double eval(string &);
13+
double eval(string &, double);
14+
double convertToNumber(string &, double);
15+
double operation(double, double, string &);
16+
int precedence(char);
17+
bool isDigit(char);
18+
bool isOperand(string &);
19+
bool isValidCharacter(char);
20+
vector<string> breakIntoTokens(string &);
21+
vector<string> convertToPostfixExp(vector<string> &);
22+
void manageLeadingNegativeSign(vector<string> &);
23+
void manageFirstBracketAfterOperand(vector<string> &);
24+
bool contains_x(string &);
25+
int main(int argc, char **argv) {
26+
string exp;
27+
double x = 0;
28+
29+
if (argc == 1) {
30+
// Manual input
31+
cout << dye::light_blue("Enter the Expression : ");
32+
getline(cin, exp);
33+
34+
if (contains_x(exp)) {
35+
cout << dye::light_blue("Enter value of x : ");
36+
cin >> x;
37+
}
38+
cout << dye::light_green("Eval : ") << eval(exp, x) << endl;
39+
cout << dye::yellow("Press any key to close...") << endl;
40+
getch();
41+
} else {
42+
exp = argv[1];
43+
44+
if (argc == 3) {
45+
string sx = argv[2];
46+
x = convertToNumber(sx, 0);
47+
}
48+
cout << dye::light_green("Eval : ") << eval(exp, x) << endl;
49+
}
50+
return 0;
51+
}
52+
53+
void manageFirstBracketAfterOperand(vector<string> &tokens) {
54+
string multiplySign = "*";
55+
for (int i = 0; i < tokens.size() - 1; i++) {
56+
if (isOperand(tokens[i]) && tokens[i + 1] == "(") {
57+
i++;
58+
tokens.insert(tokens.begin() + i, multiplySign);
59+
}
60+
}
61+
}
62+
void manageLeadingNegativeSign(vector<string> &tokens) {
63+
string openBracket = "(";
64+
string closeBracket = ")";
65+
string zero = "0";
66+
67+
// If the expression starts with '-' sign add '0' before it
68+
if (tokens[0][0] == '-') {
69+
tokens.insert(tokens.begin(), zero);
70+
}
71+
72+
for (int i = 0; i < tokens.size() - 1; i++) {
73+
// If there is '-' sign after any operator "*"
74+
if (!isOperand(tokens[i]) && tokens[i + 1] == "-") {
75+
// if there is '(' after that add the end bracket after matching the
76+
// correct bracket
77+
if (tokens.begin() + i + 2 != tokens.end() &&
78+
tokens[i + 2] == "(") {
79+
tokens.insert(tokens.begin() + ++i, openBracket);
80+
tokens.insert(tokens.begin() + ++i, zero);
81+
i += 2;
82+
int bracesCount = 1;
83+
int j = i + 1;
84+
while (bracesCount != 0 &&
85+
(tokens.begin() + j != tokens.end())) {
86+
char currentCh = tokens[j][0];
87+
if (currentCh == '(')
88+
bracesCount++;
89+
else if (currentCh == ')')
90+
bracesCount--;
91+
j++;
92+
}
93+
tokens.insert(tokens.begin() + j, closeBracket);
94+
} else {
95+
tokens.insert(tokens.begin() + ++i, openBracket);
96+
tokens.insert(tokens.begin() + ++i, zero);
97+
i += 2;
98+
tokens.insert(tokens.begin() + ++i, closeBracket);
99+
}
100+
}
101+
}
102+
}
103+
double eval(string &exp) { return eval(exp, 0); }
104+
105+
double eval(string &exp, double x) {
106+
vector<string> tokens = breakIntoTokens(exp);
107+
manageFirstBracketAfterOperand(tokens);
108+
manageLeadingNegativeSign(tokens);
109+
tokens = convertToPostfixExp(tokens);
110+
stack<double> excStack;
111+
for (auto &token : tokens) {
112+
if (isOperand(token)) {
113+
excStack.push(convertToNumber(token, x));
114+
} else {
115+
double op1 = excStack.top();
116+
excStack.pop();
117+
double op2 = excStack.top();
118+
excStack.pop();
119+
excStack.push(operation(op1, op2, token));
120+
}
121+
}
122+
return excStack.top();
123+
return 0;
124+
}
125+
vector<string> breakIntoTokens(string &exp) {
126+
vector<string> tokens;
127+
string currentToken = "";
128+
129+
for (char &ch : exp) {
130+
if (ch == ' ' || ch == '\n' || ch == '\t') continue;
131+
132+
if (!isValidCharacter(ch)) {
133+
cout << dye::light_red("Invalid Expression");
134+
return tokens;
135+
}
136+
137+
if (isDigit(ch))
138+
currentToken.push_back(ch);
139+
else {
140+
if (currentToken.length() != 0) {
141+
tokens.push_back(currentToken);
142+
currentToken = "";
143+
}
144+
string s = "";
145+
s.push_back(ch);
146+
tokens.push_back(s);
147+
}
148+
}
149+
if (currentToken.length() != 0) tokens.push_back(currentToken);
150+
151+
return tokens;
152+
}
153+
vector<string> convertToPostfixExp(vector<string> &tokens) {
154+
vector<string> postfix;
155+
stack<string> stk;
156+
157+
for (auto &token : tokens) {
158+
if (isOperand(token))
159+
postfix.push_back(token);
160+
161+
else if (token == "(")
162+
stk.push(token);
163+
164+
else if (token == ")") {
165+
while (!stk.empty() && stk.top() != "(") {
166+
postfix.push_back(stk.top());
167+
stk.pop();
168+
}
169+
170+
if (!stk.empty() && stk.top() != "(")
171+
break;
172+
else
173+
stk.pop();
174+
175+
} else {
176+
while (!stk.empty() &&
177+
precedence(token[0]) <= precedence(stk.top()[0])) {
178+
postfix.push_back(stk.top());
179+
stk.pop();
180+
}
181+
stk.push(token);
182+
}
183+
}
184+
185+
while (!stk.empty()) {
186+
postfix.push_back(stk.top());
187+
stk.pop();
188+
}
189+
return postfix;
190+
}
191+
192+
double convertToNumber(string &token, double x) {
193+
if (token == "x") return x;
194+
char num[token.length()];
195+
strcpy(num, token.c_str());
196+
return atof(num);
197+
}
198+
199+
double operation(double op1, double op2, string &token) {
200+
switch (token[0]) {
201+
case '+':
202+
return op2 + op1;
203+
case '-':
204+
return op2 - op1;
205+
case '*':
206+
return op2 * op1;
207+
case '/':
208+
return op2 / op1;
209+
case '^':
210+
return pow(op2, op1);
211+
}
212+
return 0;
213+
}
214+
215+
int precedence(char ch) {
216+
switch (ch) {
217+
case '+':
218+
case '-':
219+
return 1;
220+
221+
case '*':
222+
case '/':
223+
return 2;
224+
225+
case '^':
226+
return 3;
227+
}
228+
return -1;
229+
}
230+
231+
bool isOperand(string &s) {
232+
if (s.length() == 1) {
233+
if (s[0] == 'x') return true;
234+
return isdigit(s[0]);
235+
} else
236+
return true;
237+
}
238+
bool isValidCharacter(char ch) {
239+
string validSet = VALID_SET;
240+
for (auto &c : validSet)
241+
if (ch == c) return true;
242+
return false;
243+
}
244+
245+
bool isDigit(char c) { return c == '.' || (c >= '0' && c <= '9'); }
246+
247+
bool contains_x(string &str) {
248+
for (auto &ch : str)
249+
if (ch == 'x') return true;
250+
return false;
251+
}

media/example.png

132 KB
Loading

media/icon.png

45.6 KB
Loading

media/logo.png

54.5 KB
Loading

resources.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MAIN ICON "./resources/favicon.ico"

resources/favicon.ico

107 KB
Binary file not shown.

0 commit comments

Comments
 (0)