Advertisement
Guest User

=)

a guest
Dec 6th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.24 KB | None | 0 0
  1. Func Program::evaluateExpression(std::string &s) const {
  2.     std::string::const_iterator it = s.begin();
  3.     std::string var;
  4.     std::string buf;
  5.     while (it != s.end()) {
  6.         while (it != s.end() && Utils::isPartIdName(*it)) {
  7.             var += *it;
  8.             ++it;
  9.         }
  10.         if (!var.empty()) {
  11.             if (isFunc(var)) {
  12.                 //reading the function args
  13.                 if (it != s.end() && Utils::isLeftParenthesis(*it)) {
  14.                     //omitting the first '('
  15.                     ++it;
  16.                     std::vector<double> args;
  17.                     std::string argbuf;
  18.                     unsigned parenthesisCount = 1;
  19.                     unsigned partialCount = 1;
  20.  
  21.                     //until the end of the args
  22.                     while (it != s.end() && parenthesisCount != 0) {
  23.                         if (Utils::isRightParenthesis(*it)) {
  24.                             //omitting the last ')'
  25.                             if (--parenthesisCount != 0) {
  26.                                 argbuf += *it;
  27.                             }
  28.                         } else if (Utils::isLeftParenthesis(*it)) {
  29.                             ++parenthesisCount;
  30.                             argbuf += *it;
  31.                         } else if (*it != ',') {
  32.                             argbuf += *it;
  33.                         } else if (!argbuf.empty()) {
  34.                             //if not in a nested func usage ( pow(1,pow(2,3)) )
  35.                             if (parenthesisCount <= 1) {
  36.                                 //placeholder or expression ?
  37.                                 bool isPlaceholder = false;
  38.                                 auto it_argbuf = argbuf.begin();
  39.                                 while(it_argbuf != argbuf.end() && std::isspace(*it_argbuf)) {it_argbuf++;}
  40.                                 if(it_argbuf != argbuf.end()) {
  41.                                     if (*it_argbuf == '_') {
  42.                                         if(it_argbuf+1 != argbuf.end() && *(it_argbuf+1) != ' ') {
  43.                                             std::string number;
  44.                                             ++it_argbuf;
  45.                                             while(it_argbuf != argbuf.end()) {
  46.                                                 if(!std::isspace(*it_argbuf))
  47.                                                     number += *it_argbuf;
  48.                                                 it_argbuf++;
  49.                                             }
  50.                                             if(number == std::to_string(partialCount)) {
  51.                                                     isPlaceholder = true;
  52.                                                     partialCount++;
  53.                                             } else {
  54.                                                     std::cerr << "Wrong number in placeholder, should be " << partialCount << std::endl;
  55.                                                     return nullptr;
  56.                                             }
  57.                                         } else {
  58.                                             std::cerr << "Invalid expression '_', this needs a number [0-9] to be a placeholder" << std::endl;
  59.                                             return nullptr;
  60.                                         }
  61.  
  62.                                     }
  63.                                 }
  64.                                 if(isPlaceholder) {
  65.                                     args.push_back(std::nan(""));
  66.                                 } else {
  67.                                     Func resFunc = evaluateExpression(argbuf);
  68.                                     if (resFunc == nullptr || !resFunc->isComplete()) {
  69.                                         std::cerr << "Expression : '" << argbuf << "' is invalid (used in '" << var
  70.                                                   << "')" << std::endl;
  71.                                         return nullptr;
  72.                                     }
  73.                                     args.push_back(resFunc->eval());
  74.                                 }
  75.                                 argbuf = "";
  76.                             } else {
  77.                                 argbuf += *it;
  78.                             }
  79.                         }
  80.                         ++it;
  81.                     }
  82.  
  83.                     if (!argbuf.empty()) {
  84.                         //placeholder or expression ?
  85.                         bool isPlaceholder = false;
  86.                         auto it_argbuf = argbuf.begin();
  87.                         while(it_argbuf != argbuf.end() && std::isspace(*it_argbuf)) {it_argbuf++;}
  88.                         if(it_argbuf != argbuf.end()) {
  89.                             if (*it_argbuf == '_') {
  90.                                 if(it_argbuf+1 != argbuf.end() && *(it_argbuf+1) != ' ') {
  91.                                     std::string number;
  92.                                     ++it_argbuf;
  93.                                     while(it_argbuf != argbuf.end()) {
  94.                                         if(!std::isspace(*it_argbuf))
  95.                                             number += *it_argbuf;
  96.                                         it_argbuf++;
  97.                                     }
  98.                                     if(number == std::to_string(partialCount)) {
  99.                                         isPlaceholder = true;
  100.                                     } else {
  101.                                         std::cerr << "Wrong number in placeholder, should be " << partialCount << std::endl;
  102.                                         return nullptr;
  103.                                     }
  104.                                 } else {
  105.                                     std::cerr << "Invalid expression '_', this needs a number [0-9] to be a placeholder" << std::endl;
  106.                                     return nullptr;
  107.                                 }
  108.  
  109.                             }
  110.                         }
  111.                         if(isPlaceholder) {
  112.                             args.push_back(std::nan(""));
  113.                         } else {
  114.                             Func resFunc = evaluateExpression(argbuf);
  115.                             if (resFunc == nullptr || !resFunc->isComplete()) {
  116.                                 std::cerr << "Expression : '" << argbuf << "' is invalid (used in '" << var
  117.                                           << "')" << std::endl;
  118.                                 return nullptr;
  119.                             }
  120.                             args.push_back(resFunc->eval());
  121.                         }
  122.                     }
  123.  
  124.                     if (parenthesisCount != 0) {
  125.                         std::cerr << "Misuse (parenthesis missing) of function identifier : '" << var << "'"
  126.                                   << std::endl;
  127.                         return nullptr;
  128.                     }
  129.  
  130.                     Func resFunc = functionMap.at(var)->addArgs(args);
  131.  
  132.                     if (resFunc != nullptr) {
  133.                         if(resFunc->isComplete()) {
  134.                             buf += std::to_string(resFunc->eval());
  135.  
  136.                         //if the function is partial, return the new func
  137.                         } else {
  138.                             //checking if the partial function is the only thing in the expression
  139.                             bool simpleUse = true;
  140.                             //nothing but spaces before
  141.                             for(char c : buf) {
  142.                                 if(!std::isspace(c)) {
  143.                                     simpleUse = false;
  144.                                 }
  145.                             }
  146.                             //nothing but spaces and ';' after
  147.                             while (it != s.end()) {
  148.                                 if(!std::isspace(*it) && *it != ';') {
  149.                                     simpleUse = false;
  150.                                 }
  151.                                 it++;
  152.                             }
  153.                             if (simpleUse) {
  154.                                 return resFunc;
  155.                             } else {
  156.                                 std::cerr << "Invalid use of partial definition in complex expression '" << var << "'"
  157.                                           << std::endl;
  158.                                 return nullptr;
  159.                             }
  160.                         }
  161.                     } else {
  162.                         return nullptr;
  163.                     }
  164.                 } else if (functionMap.find(var) != functionMap.end()) {
  165.                     if(functionMap.at(var)->isComplete()) {
  166.                         buf += std::to_string(functionMap.at(var)->eval());
  167.                     } else {
  168.                         //checking if the partial function is the only thing in the expression
  169.                         bool simpleUse = true;
  170.                         //nothing but spaces before
  171.                         for(char c : buf) {
  172.                             if(!std::isspace(c)) {
  173.                                 simpleUse = false;
  174.                             }
  175.                         }
  176.                         //nothing but spaces and ';' after
  177.                         while (it != s.end()) {
  178.                             if(!std::isspace(*it) && *it != ';') {
  179.                                 simpleUse = false;
  180.                             }
  181.                             it++;
  182.                         }
  183.                         if (simpleUse) {
  184.                             return functionMap.at(var)->addArgs({});
  185.                         } else {
  186.                             std::cerr << "Invalid use of partial definition in complex expression '" << var << "'"
  187.                                       << std::endl;
  188.                             return nullptr;
  189.                         }
  190.                     }
  191.                 }
  192.             } else {
  193.                 std::cerr << "Unknown identifier in expression : '" << var << "'" << std::endl;
  194.                 return nullptr;
  195.             }
  196.         }
  197.         var = "";
  198.         if (it != s.end()) {
  199.             buf += *it;
  200.             ++it;
  201.         }
  202.  
  203.     }
  204.  
  205.     Expr e{buf};
  206.     return std::make_unique<Id>(std::vector {e.eval()});
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement