void MMOModel::add (string id, bool isDerivative, const ASTNode *value, MMOSectionType type) { MMODeclType t; MMODecl *dec = _declarations.findDec (id); if (dec == NULL) { t = implicit_equation; } else { if (isDerivative) { t = derivative; dec->setType (state); } else { t = algebraic_equation; dec->setType (algebraic); } } if (type == equation) { _parseEquation (id, value, t, type); } else if (type == initial_algorithm) { _parseEquation (id, value, initial_assignment, type); } }
// Parses double value from equation int CEqParserV2::parse(std::string equation, double &aValue) { it = 0; CAbstractEq * eq = _parseEquation(equation, it); int rVal = eq->getValue(aValue); eq->clear(); delete eq; return rVal; }
CFunctionEq* CEqParserV2::_parseFunction(std::string fcnName, std::string &equation, int &it) { //-//-//-//-//-//-//-//-//-//-//-// // Example: 2+func((2+1),3)+42 // ^ //-//-//-//-//-//-//-//-//-//-//-// //std::string fcnName = _parseIdentifier(equation, it); DBOUT("Function name is " << fcnName); CFunctionEq * fcnEq = new CFunctionEq(); // If function parsing failed or function // not found return if (!fcnEq->init(mFcns, fcnName)) { EROUT("Init Function failed, name not found: "<<fcnName); return fcnEq; } // Parse params -> CChain(2,1),CConst(3) // (need subequations...) int paramCount=fcnEq->getParamCount(); DBOUT("Init successful, paramCount is "<<paramCount); std::vector<CAbstractEq*> params; // XXX unneeded?? // skip first parOpen if (paramCount>0) it++; // TODO: Lambda -> paramCount=-1 for (int i = 0; i < paramCount; i++) { std::string paramSubstr = _getFcnParamSubstr(equation, it); DBOUT("Param "<<i<<", substring is: " << paramSubstr); int subIt = 0; CAbstractEq* param = _parseEquation(paramSubstr, subIt); params.push_back(param); fcnEq->addParamValue(param); } return fcnEq; }
CAbstractEq* CEqParserV2::_parseEquation(std::string &equation, int &it) { CChainEq* rVal = new CChainEq(); CAbstractEq* number = NULL; bool hasNum = false; bool hasOp = false; bool inverseNum = false; char chr = equation.at(it); while ((unsigned)it < equation.length()) { //// Fast exit if statement ends //if(cc::isParClose(equation.at(it))) //{ // DBOUT("Called break"); // it+=2; // break; //} chr = equation.at(it); DBOUT("it = " << it << ", char = " << chr); eOpType op = eOpType::NULL_EQ; if (cc::isDecimal(chr)) { DBOUT("Found decimal: " << chr); number = _parseNumber(equation, it); } else if (cc::isParOpen(chr)) { std::string sub = _getEqSubstr(equation, ++it); DBOUT("Found subEquation "<<sub); int subIt = 0; // dummy number = _parseEquation(sub, subIt); } else if (cc::isAlpha(chr)) { DBOUT("Found alpha " << chr); std::string fcnName = _parseIdentifier(equation, it); number = _parseFunction(fcnName,equation, it); } else if (cc::isOperator(chr)) { op = _parseOperator(equation, it); } else { it++; } hasNum = (number != NULL); hasOp = (op != eOpType::NULL_EQ); DBOUT("hasOp = " << hasOp << " hasNum = " << hasNum); if (hasNum) { bool doAdd = false; // Has Number and Operator if (hasOp) { doAdd = true; } // Default Operator "CONST" if finished else if ((unsigned)it >= equation.length()) { op = eOpType::CONST_EQ; doAdd = true; } // Default Operator "MPL" if undefined else { chr = equation.at(it); DBOUT("Try autoadd MPL (203) char is: " << chr); // Subequation e.g. 4(2+3) // ^ ^ doAdd |= cc::isParOpen(chr); // Function e.g. 4x // ^ doAdd |= cc::isAlpha(chr); // Decimal e.g. (2+3)4 // ^ doAdd |= cc::isDecimal(chr); if (doAdd) { op = eOpType::MPL_EQ; } } if (doAdd) { if (inverseNum) number = new CInvEq(number); DBOUT("Adding Operation "<<op); rVal->addOperation(number, op); op = eOpType::NULL_EQ; number = NULL; // hasNum = false; hasOp = false; inverseNum = false; } } // Inverse negative else { if (op == eOpType::SUB_EQ) { DBOUT("Setting inversenum = true"); inverseNum = true; } } } if (hasNum) { if (inverseNum) number = new CInvEq(number); DBOUT("Adding Operation 101"); rVal->addOperation(number, eOpType::CONST_EQ); } DBOUT("Returning equation, it = "<<it); return rVal; }