void Foam::primitiveEntry::insert ( const tokenList& varTokens, const label posI ) { tokenList& tokens = *this; if (varTokens.empty()) { label end = tokens.size() - 1; for (label j=posI; j<end; j++) { tokens[j] = tokens[j+1]; } tokens.setSize(tokens.size() - 1); } else if (varTokens.size() > 1) { tokens.setSize(tokens.size() + varTokens.size() - 1); label end = tokens.size() - 1; label offset = varTokens.size() - 1; for (label j=end; j>posI; j--) { tokens[j] = tokens[j-offset]; } } forAll(varTokens, j) { tokens[posI + j] = varTokens[j]; } }
void Foam::equationReader::createMap ( const label index, const tokenList& tl, PtrList<equationOperation>& map, labelList& opLvl, labelList& pl ) const { // equation * eqn(&this->operator[](index)); // current parenthesis level - note, a negative parenthesis value indicates // that this is the root level of a function, and therefore ',' is allowed label p(0); forAll(tl, i) { if (tl[i].isNumber()) { // Internal constant. Save to internalScalars and record source opLvl[i] = 0; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stinternalScalar, addInternalScalar(tl[i].number()) + 1, 0, 0, equationOperation::otnone ) ); } else if (tl[i].isWord()) { // could be a variable name, function or mathematical constant // - check for function first - function is [word][punctuation '('] if ( (i < (tl.size() - 1)) && (tl[i + 1].isPunctuation()) && (tl[i + 1].pToken() == token::BEGIN_LIST) ) { // Function detected; function brackets are negative opLvl[i] = 4; p = -mag(p) - 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::findOp(tl[i].wordToken()) ) ); if (map[i].operation() == equationOperation::otnone) { OStringStream description; description << tl[i].wordToken() << " is not a recognized " << "function."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } // Set next token as well (function opening parenthesis) i++; opLvl[i] = 4; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); } else if ( (tl[i].wordToken() == "e_") || (tl[i].wordToken() == "pi_") || (tl[i].wordToken() == "twoPi_") || (tl[i].wordToken() == "piByTwo_") || (tl[i].wordToken() == "GREAT_") || (tl[i].wordToken() == "VGREAT_") || (tl[i].wordToken() == "ROOTVGREAT_") || (tl[i].wordToken() == "SMALL_") || (tl[i].wordToken() == "VSMALL_") || (tl[i].wordToken() == "ROOTVSMALL_") ) { // Mathematical constant if ( findSource(tl[i].wordToken()).sourceType() != equationOperation::stnone ) { // Found a possible conflicting variable name - warn WarningIn("equationReader::createMap") << "Equation for " << operator[](index).name() << ", given by:" << token::NL << token::TAB << operator[](index).rawText() << token:: NL << "refers " << "to '" << tl[i].wordToken() << "'. Although " << "variable " << tl[i].wordToken() << "was found in " << "the data sources, " << tl[i].wordToken() << " is a" << " mathematical constant. The mathematical constant " << "will be used." << endl; } opLvl[i] = 0; pl[i] = p; label internalIndex(0); if (tl[i].wordToken() == "e_") { // MathConstantScope is a hack that allows equationReader // to work in multiple versions of OpenFOAM. See // include/versionSpecific.H internalIndex = addInternalScalar(MathConstantScope::e) + 1; } else if (tl[i].wordToken() == "pi_") { internalIndex = addInternalScalar(MathConstantScope::pi) + 1; } else if (tl[i].wordToken() == "twoPi_") { internalIndex = addInternalScalar(MathConstantScope::twoPi) + 1; } else if (tl[i].wordToken() == "piByTwo_") { internalIndex = addInternalScalar(MathConstantScope::piByTwo) + 1; } else if (tl[i].wordToken() == "GREAT_") { internalIndex = addInternalScalar(GREAT) + 1; } else if (tl[i].wordToken() == "VGREAT_") { internalIndex = addInternalScalar(VGREAT) + 1; } else if (tl[i].wordToken() == "ROOTVGREAT_") { internalIndex = addInternalScalar(ROOTVGREAT) + 1; } else if (tl[i].wordToken() == "SMALL_") { internalIndex = addInternalScalar(SMALL) + 1; } else if (tl[i].wordToken() == "VSMALL_") { internalIndex = addInternalScalar(VSMALL) + 1; } else // tl[i].wordToken() == "ROOTVSMALL_" { internalIndex = addInternalScalar(ROOTVSMALL) + 1; } map.set ( i, new equationOperation ( equationOperation::stinternalScalar, internalIndex, 0, 0, equationOperation::otnone ) ); } else { // Variable name opLvl[i] = 0; pl[i] = p; map.set ( i, new equationOperation(findSource(tl[i].wordToken())) ); if (map[i].sourceIndex() == 0) { OStringStream description; description << "Variable name " << tl[i].wordToken() << " not found in any available sources."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } if (map[i].componentIndex() < 0) { OStringStream description; description << "Variable name " << tl[i].wordToken() << " is interpretted as variablePart.componentPart, " << "and the componentPart is not valid, or is " << "required, but is missing."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } } } else if (tl[i].isPunctuation()) { switch (tl[i].pToken()) { case token::BEGIN_LIST: // ( opLvl[i] = 4; p = mag(p) + 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); break; case token::END_LIST: // ) { opLvl[i] = -4; pl[i] = p; p = mag(p) - 1; if (p < 0) { OStringStream description; description << "Too many ')'."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } // Look for preceding parenthesis change - was it negative? for (label j(i - 1); j >= 0; j--) { if (mag(pl[j]) == p) { if (pl[j] < 0) { p = -p; } break; } } map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); break; } case token::COMMA: // , // , is only accepted in a function level parenthesis if (p < 0) { opLvl[i] = 5; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otnone ) ); } else { OStringStream description; description << "The comma, ',' does not make sense " << "here. Only permitted in the root parenthesis " << "level of a function."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } break; case token::ADD: // + opLvl[i] = 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otplus ) ); break; case token::SUBTRACT: // - opLvl[i] = 1; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otminus ) ); break; case token::MULTIPLY: // * opLvl[i] = 2; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::ottimes ) ); break; case token::DIVIDE: // / opLvl[i] = 2; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otdivide ) ); break; case token::COLON: // :, means ^ { OStringStream description; description << "The '^' operator is not currently " << "supported. Use pow(a,b) instead."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); break; } /* opLvl[i] = 3; pl[i] = p; map.set ( i, new equationOperation ( equationOperation::stnone, 0, 0, 0, equationOperation::otpow ) ); break; */ default: { OStringStream description; description << "Punctuation character '" << tl[i].pToken() << "' is prohibitted."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); break; } } // end punctuation switch } // end if punctuation else { OStringStream description; description << "Unrecognized token: [" << tl[i] << "]."; fatalParseError ( index, tl, i, i, "equationReader::parse", description ); } } // mapping loop if (p) { OStringStream description; description << "Parentheses do not match. Expecting " << mag(p) << " additional ')'s."; fatalParseError ( index, tl, 0, tl.size() - 1, "equationReader::parse", description ); } // Assign negatives (distinguish these from subtraction) // The difference is characterized by the preceding character: // -preceeded by an operator = negative '+' '-' '*' '/' '^' // -preceeded by an open bracket = negative '(' // -preceeded by a comma = negative ',' // -preceeded by a variable = subtract 'word' or 'number' // -preceeded by a close bracket = subtract ')' // Negatives are identified by a negative dictLookupIndex if (map[0].operation() == equationOperation::otminus) { opLvl[0] = 2; map[0].dictLookupIndex() = -1; } for (label i(1); i < map.size(); i++) { if (map[i].operation() == equationOperation::otminus) { if (opLvl[i-1] > 0) { opLvl[i] = 2; map[i].dictLookupIndex() = -1; } } } }