Skip to content

Commit fa84ac7

Browse files
committed
add compilation
1 parent c6f41be commit fa84ac7

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

include/mathparser.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,7 @@ class MathParser {
6161

6262
bool isConstant(const std::string& symbol);
6363

64-
65-
double evaluateRPN(const std::vector<Token>& RPN); //evaluate Reverse Polish notation
66-
std::vector<Token> toRPN(const std::string& expression); //make Reverse Polish notation
64+
std::vector<Token> toRPN(const std::string& expression);
6765

6866
public:
6967
MathParser();
@@ -72,6 +70,8 @@ class MathParser {
7270
void registerOperator(const std::string& symbol, Operator op);
7371
void registerConstant(const std::string& symbol, double value);
7472
double evaluate(const std::string& expression);
73+
std::vector<Token> compile(const std::string& expression);
74+
double evaluate(const std::vector<Token>& complied);
7575
double tokenToDouble(const Token& token);
7676
double getVariableValue(const std::string& varName);
7777
};

src/mathparser.cpp

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,11 @@ std::vector<MathParser::Token> MathParser::toRPN(const std::string& expression)
281281

282282
}
283283

284-
double MathParser::evaluateRPN(const std::vector<Token>& RPN) {
284+
double MathParser::evaluate(const std::vector<Token>& compiled) {
285285
std::stack<Token> numStack;
286-
for (const Token& token: RPN) {
286+
for (const Token& token: compiled) {
287287
if (token.type == Token::Type::OPERATOR) {
288288
Operator op = operators[std::get<std::string>(token.value)];
289-
if (op.type==Operator::Type::COMMA) continue;
290289
std::vector<Token> operands;
291290
for (int i=0; i<op.operandCount; i++) {
292291
operands.insert(operands.begin(),numStack.top());
@@ -295,17 +294,52 @@ double MathParser::evaluateRPN(const std::vector<Token>& RPN) {
295294
numStack.push(op.evaluate(operands));
296295
}
297296
else {
298-
if (token.type == Token::Type::CONSTANT)
299-
numStack.push(Token{Token::Type::NUMBER, tokenToDouble(token)});
300-
else
301-
numStack.push(token);
297+
numStack.push(token);
302298
}
303299
}
304300
return tokenToDouble(numStack.top());
305301
}
306302

303+
#include <iostream>
307304
double MathParser::evaluate(const std::string& expression) {
308-
return evaluateRPN(toRPN(expression));
305+
auto compiled = compile(expression);
306+
return evaluate(compiled);
307+
}
308+
309+
std::vector<MathParser::Token> MathParser::compile(const std::string& expression) {
310+
auto RPN = toRPN(expression);
311+
std::vector<Token> compiled;
312+
for (const Token& token: RPN) {
313+
if (token.type == Token::Type::OPERATOR) {
314+
Operator op = operators[std::get<std::string>(token.value)];
315+
if (op.type==Operator::Type::COMMA) continue;
316+
bool allConstants = true;
317+
for (int i=0; i<op.operandCount; i++) {
318+
if ((compiled.end()-1-i)->type!=Token::Type::NUMBER) {
319+
allConstants = false;
320+
break;
321+
}
322+
}
323+
if (allConstants) {
324+
std::vector<Token> operands;
325+
for (int i=0; i<op.operandCount; i++) {
326+
operands.insert(operands.begin(),compiled.back());
327+
compiled.pop_back();
328+
}
329+
compiled.push_back(op.evaluate(operands));
330+
}
331+
else {
332+
compiled.push_back(token);
333+
}
334+
}
335+
else {
336+
if (token.type==Token::Type::CONSTANT)
337+
compiled.push_back(Token{Token::Type::NUMBER, constants[std::get<std::string>(token.value)]});
338+
else
339+
compiled.push_back(token);
340+
}
341+
}
342+
return compiled;
309343
}
310344

311345
double MathParser::getVariableValue(const std::string& varName) {

0 commit comments

Comments
 (0)