@@ -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>
307304double 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
311345double MathParser::getVariableValue (const std::string& varName) {
0 commit comments