Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Func Program::evaluateExpression(std::string &s) const {
- std::string::const_iterator it = s.begin();
- std::string var;
- std::string buf;
- while (it != s.end()) {
- while (it != s.end() && Utils::isPartIdName(*it)) {
- var += *it;
- ++it;
- }
- if (!var.empty()) {
- if (isFunc(var)) {
- //reading the function args
- if (it != s.end() && Utils::isLeftParenthesis(*it)) {
- //omitting the first '('
- ++it;
- std::vector<double> args;
- std::string argbuf;
- unsigned parenthesisCount = 1;
- unsigned partialCount = 1;
- //until the end of the args
- while (it != s.end() && parenthesisCount != 0) {
- if (Utils::isRightParenthesis(*it)) {
- //omitting the last ')'
- if (--parenthesisCount != 0) {
- argbuf += *it;
- }
- } else if (Utils::isLeftParenthesis(*it)) {
- ++parenthesisCount;
- argbuf += *it;
- } else if (*it != ',') {
- argbuf += *it;
- } else if (!argbuf.empty()) {
- //if not in a nested func usage ( pow(1,pow(2,3)) )
- if (parenthesisCount <= 1) {
- //placeholder or expression ?
- bool isPlaceholder = false;
- auto it_argbuf = argbuf.begin();
- while(it_argbuf != argbuf.end() && std::isspace(*it_argbuf)) {it_argbuf++;}
- if(it_argbuf != argbuf.end()) {
- if (*it_argbuf == '_') {
- if(it_argbuf+1 != argbuf.end() && *(it_argbuf+1) != ' ') {
- std::string number;
- ++it_argbuf;
- while(it_argbuf != argbuf.end()) {
- if(!std::isspace(*it_argbuf))
- number += *it_argbuf;
- it_argbuf++;
- }
- if(number == std::to_string(partialCount)) {
- isPlaceholder = true;
- partialCount++;
- } else {
- std::cerr << "Wrong number in placeholder, should be " << partialCount << std::endl;
- return nullptr;
- }
- } else {
- std::cerr << "Invalid expression '_', this needs a number [0-9] to be a placeholder" << std::endl;
- return nullptr;
- }
- }
- }
- if(isPlaceholder) {
- args.push_back(std::nan(""));
- } else {
- Func resFunc = evaluateExpression(argbuf);
- if (resFunc == nullptr || !resFunc->isComplete()) {
- std::cerr << "Expression : '" << argbuf << "' is invalid (used in '" << var
- << "')" << std::endl;
- return nullptr;
- }
- args.push_back(resFunc->eval());
- }
- argbuf = "";
- } else {
- argbuf += *it;
- }
- }
- ++it;
- }
- if (!argbuf.empty()) {
- //placeholder or expression ?
- bool isPlaceholder = false;
- auto it_argbuf = argbuf.begin();
- while(it_argbuf != argbuf.end() && std::isspace(*it_argbuf)) {it_argbuf++;}
- if(it_argbuf != argbuf.end()) {
- if (*it_argbuf == '_') {
- if(it_argbuf+1 != argbuf.end() && *(it_argbuf+1) != ' ') {
- std::string number;
- ++it_argbuf;
- while(it_argbuf != argbuf.end()) {
- if(!std::isspace(*it_argbuf))
- number += *it_argbuf;
- it_argbuf++;
- }
- if(number == std::to_string(partialCount)) {
- isPlaceholder = true;
- } else {
- std::cerr << "Wrong number in placeholder, should be " << partialCount << std::endl;
- return nullptr;
- }
- } else {
- std::cerr << "Invalid expression '_', this needs a number [0-9] to be a placeholder" << std::endl;
- return nullptr;
- }
- }
- }
- if(isPlaceholder) {
- args.push_back(std::nan(""));
- } else {
- Func resFunc = evaluateExpression(argbuf);
- if (resFunc == nullptr || !resFunc->isComplete()) {
- std::cerr << "Expression : '" << argbuf << "' is invalid (used in '" << var
- << "')" << std::endl;
- return nullptr;
- }
- args.push_back(resFunc->eval());
- }
- }
- if (parenthesisCount != 0) {
- std::cerr << "Misuse (parenthesis missing) of function identifier : '" << var << "'"
- << std::endl;
- return nullptr;
- }
- Func resFunc = functionMap.at(var)->addArgs(args);
- if (resFunc != nullptr) {
- if(resFunc->isComplete()) {
- buf += std::to_string(resFunc->eval());
- //if the function is partial, return the new func
- } else {
- //checking if the partial function is the only thing in the expression
- bool simpleUse = true;
- //nothing but spaces before
- for(char c : buf) {
- if(!std::isspace(c)) {
- simpleUse = false;
- }
- }
- //nothing but spaces and ';' after
- while (it != s.end()) {
- if(!std::isspace(*it) && *it != ';') {
- simpleUse = false;
- }
- it++;
- }
- if (simpleUse) {
- return resFunc;
- } else {
- std::cerr << "Invalid use of partial definition in complex expression '" << var << "'"
- << std::endl;
- return nullptr;
- }
- }
- } else {
- return nullptr;
- }
- } else if (functionMap.find(var) != functionMap.end()) {
- if(functionMap.at(var)->isComplete()) {
- buf += std::to_string(functionMap.at(var)->eval());
- } else {
- //checking if the partial function is the only thing in the expression
- bool simpleUse = true;
- //nothing but spaces before
- for(char c : buf) {
- if(!std::isspace(c)) {
- simpleUse = false;
- }
- }
- //nothing but spaces and ';' after
- while (it != s.end()) {
- if(!std::isspace(*it) && *it != ';') {
- simpleUse = false;
- }
- it++;
- }
- if (simpleUse) {
- return functionMap.at(var)->addArgs({});
- } else {
- std::cerr << "Invalid use of partial definition in complex expression '" << var << "'"
- << std::endl;
- return nullptr;
- }
- }
- }
- } else {
- std::cerr << "Unknown identifier in expression : '" << var << "'" << std::endl;
- return nullptr;
- }
- }
- var = "";
- if (it != s.end()) {
- buf += *it;
- ++it;
- }
- }
- Expr e{buf};
- return std::make_unique<Id>(std::vector {e.eval()});
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement