Skip to content

Commit de642cf

Browse files
authored
Merge pull request #3 from H5JKey/variable-support
add variables
2 parents 9d55c5f + 42a0765 commit de642cf

File tree

5 files changed

+166
-46
lines changed

5 files changed

+166
-46
lines changed

README.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ A flexible and extensible C++ library for parsing and evaluating mathematical ex
1111
- Parentheses and operator precedence
1212
- Floating-point number support
1313
- Easy to add new operators, functions and constans
14-
- Convertation to RPN and it's evaluation
14+
- Easy to add and use variables
1515

1616
## Quick Start
1717

@@ -28,7 +28,11 @@ int main() {
2828
parser.registerOperator("max", parser::Operator{
2929
parser::Operator::Type::FUNCTION,
3030
4, false, 2,
31-
[](auto args) { return std::max(args[0], args[1]); },
31+
[&](auto args) {
32+
double left = parser.tokenToDouble(args[0]); // this function convert token to double, according of its type
33+
double right = parser.tokenToDouble(args[1]);
34+
return Token{MathParser::Token::Type::NUMBER, std::max(left, right)};
35+
},
3236
"max"
3337
});
3438

@@ -49,7 +53,10 @@ parser.registerOperator("log", parser::Operator{
4953
4, // Precedence
5054
false, // Right associativity
5155
1, // Single argument
52-
[](auto args) { return std::log(args[0]); },
56+
[](auto args) {
57+
double arg = parser.tokenToDouble(args[0]);
58+
return MathParser::Token{MathParser::Token::Type::NUMBER, std::log(arg)};
59+
}, // Evaluating function
5360
"log" // Function name
5461
});
5562
```

include/mathparser.hpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,34 @@
55
#include <functional>
66
#include <cmath>
77
#include <map>
8+
#include <variant>
9+
#include <stdexcept>
810

911
class MathParser {
1012
public:
11-
using EvaluateFunc = std::function<double(const std::vector<double>&)>;
13+
struct Token {
14+
enum class Type {
15+
OPERATOR,
16+
NUMBER,
17+
VARIABLE,
18+
CONSTANT
19+
};
20+
Type type;
21+
std::variant<double, std::string> value;
22+
23+
bool operator<(const Token& other) const {
24+
if (type != other.type)
25+
return static_cast<int>(type) < static_cast<int>(other.type);
26+
27+
switch(type) {
28+
case Type::NUMBER:
29+
return std::get<double>(value) < std::get<double>(other.value);
30+
default:
31+
return std::get<std::string>(value) < std::get<std::string>(other.value);
32+
}
33+
}
34+
};
35+
using EvaluateFunc = std::function<Token(const std::vector<Token>&)>;
1236
struct Operator {
1337
enum class Type {
1438
UNARY,
@@ -23,24 +47,30 @@ class MathParser {
2347
int operandCount;
2448
EvaluateFunc evaluate;
2549
std::string symbol;
26-
};
50+
};
51+
2752
private:
2853
std::unordered_map<std::string, Operator> operators;
2954
std::map<std::string, double> constants;
55+
std::map<std::string, double> variables;
3056
void init();
3157

3258
bool isOperator(const std::string& symbol);
3359
bool isOperator(char symbol);
3460

3561
bool isConstant(const std::string& symbol);
3662

63+
64+
double evaluateRPN(const std::vector<Token>& RPN); //evaluate Reverse Polish notation
65+
std::vector<Token> toRPN(const std::string& expression); //make Reverse Polish notation
66+
3767
public:
3868
MathParser();
3969
~MathParser() = default;
4070

4171
void registerOperator(const std::string& symbol, Operator op);
4272
void registerConstant(const std::string& symbol, double value);
4373
double evaluate(const std::string& expression);
44-
double evaluateRPN(const std::vector<std::string>& RPN); //evaluate Reverse Polish notation
45-
std::vector<std::string> toRPN(const std::string& expression); //make Reverse Polish notation
74+
double tokenToDouble(const Token& token);
75+
double getVariableValue(const std::string& varName);
4676
};

src/main.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
int main() {
1+
#include "mathparser.hpp"
2+
#include <iostream>
23

4+
int main() {
5+
MathParser math;
6+
std::cout<<math.evaluate("x=5")<<'\n';
7+
std::cout<<math.evaluate("y=7")<<'\n';
8+
std::cout<<math.evaluate("x = x+y+1")<<'\n';
9+
std::cout<<math.evaluate("variable = x - y")<<'\n';
10+
std::cout<<math.getVariableValue("variable");
311
return 0;
412
}

0 commit comments

Comments
 (0)