@@ -169,22 +169,31 @@ bool MathParser::isConstant(const std::string& symbol) {
169169 return constants.find (symbol)!=constants.end ();
170170}
171171
172- double MathParser::tokenToDouble (const MathParser::Token& token) {
173- switch (token.type ) {
174- case Token::Type::NUMBER:
175- return std::get<double >(token.value );
176- case Token::Type::CONSTANT:
177- return constants[std::get<std::string>(token.value )];
178- case Token::Type::VARIABLE: {
179- const std::string& name = std::get<std::string>(token.value );
180- if (variables.find (name) == variables.end ())
181- throw std::runtime_error (" Undefined variable: " + name);
182- return variables[name];
183- }
184- default :
185- throw std::runtime_error (" Cannot convert token to number" );
172+ double MathParser::tokenToDouble (const MathParser::Token& token) const {
173+ switch (token.type ) {
174+ case Token::Type::NUMBER:
175+ return std::get<double >(token.value );
176+
177+ case Token::Type::CONSTANT: {
178+ const auto & name = std::get<std::string>(token.value );
179+ auto it = constants.find (name);
180+ if (it == constants.end ())
181+ throw std::runtime_error (" Unknown constant: " + name);
182+ return it->second ;
183+ }
184+
185+ case Token::Type::VARIABLE: {
186+ const auto & name = std::get<std::string>(token.value );
187+ auto it = variables.find (name);
188+ if (it == variables.end ())
189+ throw std::runtime_error (" Undefined variable: " + name);
190+ return it->second ;
186191 }
192+
193+ default :
194+ throw std::runtime_error (" Cannot convert token to number" );
187195 }
196+ }
188197
189198std::vector<MathParser::Token> MathParser::toRPN (const std::string& expression) {
190199 std::stack<Operator> opStack;
@@ -256,7 +265,10 @@ std::vector<MathParser::Token> MathParser::toRPN(const std::string& expression)
256265 std::string symbol = std::string (1 ,expression[i]);
257266 // if we get - before operand its unary minus
258267 if (symbol==" -" && expectOperand) symbol = " ~" ;
259- Operator curOp = operators[symbol];
268+ auto it = operators.find (symbol);
269+ if (it == operators.end ())
270+ throw std::runtime_error (" Unknown operator: " + symbol);
271+ Operator curOp = it->second ;
260272 while (!opStack.empty () && opStack.top ().type !=Operator::Type::BRACKET) {
261273 Operator topOp = opStack.top ();
262274 if (topOp.type == Operator::Type::COMMA || topOp.type == Operator::Type::FUNCTION) break ;
@@ -284,7 +296,11 @@ double MathParser::evaluate(const std::vector<Token>& compiled) {
284296 std::stack<Token> numStack;
285297 for (const Token& token: compiled) {
286298 if (token.type == Token::Type::OPERATOR) {
287- Operator op = operators[std::get<std::string>(token.value )];
299+ const std::string& opSymbol = std::get<std::string>(token.value );
300+ auto it = operators.find (opSymbol);
301+ if (it == operators.end ())
302+ throw std::runtime_error (" Unknown operator: " + opSymbol);
303+ const Operator& op = it->second ;
288304 std::vector<Token> operands;
289305 for (int i=0 ; i<op.operandCount ; i++) {
290306 operands.insert (operands.begin (),numStack.top ());
@@ -309,7 +325,11 @@ std::vector<MathParser::Token> MathParser::compile(const std::string& expressio
309325 std::vector<Token> compiled;
310326 for (const Token& token: RPN) {
311327 if (token.type == Token::Type::OPERATOR) {
312- Operator op = operators[std::get<std::string>(token.value )];
328+ const std::string& opName = std::get<std::string>(token.value );
329+ auto it = operators.find (opName);
330+ if (it == operators.end ())
331+ throw std::runtime_error (" Unknown operator: " + opName);
332+ Operator op = it->second ;
313333 if (op.type ==Operator::Type::COMMA) continue ;
314334 bool allConstants = true ;
315335 for (int i=0 ; i<op.operandCount ; i++) {
@@ -331,8 +351,13 @@ std::vector<MathParser::Token> MathParser::compile(const std::string& expressio
331351 }
332352 }
333353 else {
334- if (token.type ==Token::Type::CONSTANT)
335- compiled.push_back (Token{Token::Type::NUMBER, constants[std::get<std::string>(token.value )]});
354+ if (token.type ==Token::Type::CONSTANT) {
355+ const std::string& constName = std::get<std::string>(token.value );
356+ auto it = constants.find (constName);
357+ if (it == constants.end ())
358+ throw std::runtime_error (" Unknown constant: " + constName);
359+ compiled.push_back (Token{Token::Type::NUMBER, it->second });
360+ }
336361 else
337362 compiled.push_back (token);
338363 }
0 commit comments