void ASTNaryFunctionNode::reduceOperatorsToBinary() { unsigned int numChildren = getNumChildren(); /* number of children should be greater than 2 */ if (numChildren < 3) return; /* only work with times and plus */ int type = getType(); if (type != AST_TIMES && type != AST_PLUS) return; ASTFunction* op = new ASTFunction( getExtendedType() ); ASTFunction* op2 = new ASTFunction( getExtendedType() ); // add the first two children to the first node op->addChild(getChild(0)); op->addChild(getChild(1)); op2->addChild(op); for (unsigned int n = 2; n < numChildren; n++) { op2->addChild(getChild(n)); } swapChildren(op2); // valgrind says we are leaking a lot of memory here // but we cannot delete op2 since its children are the children of the // current element // neither addChild not swapChildren make copies of things // we could remove the children and delete the object // removeChild does not destroy the object // merely removes it from the mChildren vector unsigned int i = op2->getNumChildren(); while (i > 0) { op2->removeChild(i-1); i--; } delete op2; setReducedToBinary(true); reduceOperatorsToBinary(); }
bool ASTNaryFunctionNode::read(XMLInputStream& stream, const std::string& reqd_prefix) { bool read = false; ASTBase * child = NULL; const XMLToken element = stream.peek (); ASTBase::checkPrefix(stream, reqd_prefix, element); const char* name = element.getName().c_str(); int type = getTypeFromName(name); setType(type); ASTBase::read(stream, reqd_prefix); unsigned int numChildrenAdded = 0; if (getExpectedNumChildren() > 0) { while (stream.isGood() && numChildrenAdded < getExpectedNumChildren()) { stream.skipText(); name = stream.peek().getName().c_str(); if (representsNumber(ASTBase::getTypeFromName(name)) == true) { child = new ASTNumber(); } else { child = new ASTFunction(); } read = child->read(stream, reqd_prefix); stream.skipText(); if (read == true && addChild(child) == LIBSBML_OPERATION_SUCCESS) { numChildrenAdded++; } else { delete child; child = NULL; read = false; break; } } } else { stream.skipPastEnd(element); read = true; } if (read == true && type == AST_FUNCTION_ROOT && getExpectedNumChildren() == 1 && ASTFunctionBase::getChild(0)->getType() != AST_QUALIFIER_DEGREE) { /* HACK TO REPLICATE OLD BEHAVIOUR */ /* we need to add the qualifier child for the degree 2 */ ASTFunction * degree = new ASTFunction(AST_QUALIFIER_DEGREE); ASTNumber * int2 = new ASTNumber(AST_INTEGER); int2->setInteger(2); degree->addChild(int2->deepCopy()); this->prependChild(degree->deepCopy()); delete int2; delete degree; } //if (read == false) //{ // stream.skipPastEnd(element); //} return read; }