/////////////////////////////////////////////////////////////////////// // Math Type Library // $Id: printer.tcc,v 1.7 2002/05/05 10:48:24 cparpart Exp $ // (This file contains the expression stream printer specific template members) // // Copyright (c) 2002 by Christian Parpart // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this library; see the file COPYING.LIB. If not, write to // the Free Software Foundation, Inc., 59 Temple Place - Suite 330, // Boston, MA 02111-1307, USA. /////////////////////////////////////////////////////////////////////// #ifndef libmath_printer_h #error You may not include math++/printer.tcc directly; include math++/printer.h instead. #endif #include namespace math { template TPrinter::TPrinter(std::ostream& AOutput) : FStream(AOutput) { } template void TPrinter::printOn(std::ostream& AOutput, const TNode *ANode) { TPrinter printer(AOutput); const_cast *>(ANode)->accept(printer); } template std::string TPrinter::print(const TNode *ANode) { std::stringstream sstr; TPrinter printer(sstr); const_cast *>(ANode)->accept(printer); sstr << std::ends; return sstr.str(); } template void TPrinter::savePrint(const TNode *ANode, const TNode *AParent) { #if 1 // ifndef __ENABLE_DEBUG // just disabled for debugging to see reproduce the node order bool less = ANode->priority() < AParent->priority() || (AParent->nodeType() == TNode::NEG_NODE && (ANode->nodeType() == TNode::PLUS_NODE || ANode->nodeType() == TNode::NEG_NODE)); #else bool less = true;//ANode->priority() < AParent->priority(); #endif if (less) FStream << "("; const_cast *>(ANode)->accept(*this); if (less) FStream << ")"; } template void TPrinter::visit(TNumberNode *ANode) { FStream << ANode->number(); } template void TPrinter::visit(TSymbolNode *ANode) { FStream << ANode->symbol(); } template void TPrinter::visit(TParamNode *ANode) { FStream << "x"; // the parameter is usually x, // so keep this symbol reserved, or override me;) } template void TPrinter::visit(TPlusNode *ANode) { savePrint(ANode->left(), ANode); if (ANode->right()->nodeType() != TNode::NEG_NODE) FStream << "+"; savePrint(ANode->right(), ANode); } template void TPrinter::visit(TNegNode *ANode) { FStream << "-"; savePrint(ANode->node(), ANode); } template void TPrinter::visit(TMulNode *ANode) { savePrint(ANode->left(), ANode); // print 2x isteat of 2*x // print 2(x+y) instead of 2*(x+y) // print (a+b)(c+d) instead of (a+b)*(c+d) //if (!(ANode->left()->nodeType() == TNode::NUMBER_NODE && // (ANode->right()->nodeType() == TNode::SYMBOL_NODE || // ANode->right()->nodeType() == TNode::PARAM_NODE))) FStream << "*"; savePrint(ANode->right(), ANode); } template void TPrinter::visit(TDivNode *ANode) { savePrint(ANode->left(), ANode); FStream << "/"; savePrint(ANode->right(), ANode); } template void TPrinter::visit(TPowNode *ANode) { savePrint(ANode->left(), ANode); FStream << "^"; savePrint(ANode->right(), ANode); } template void TPrinter::visit(TSqrtNode *ANode) { FStream << "sqrt("; ANode->node()->accept(*this); FStream << ")"; } template void TPrinter::visit(TSinNode *ANode) { FStream << "sin("; ANode->node()->accept(*this); FStream << ")"; } template void TPrinter::visit(TCosNode *ANode) { FStream << "cos("; ANode->node()->accept(*this); FStream << ")"; } template void TPrinter::visit(TTanNode *ANode) { FStream << "tan("; ANode->node()->accept(*this); FStream << ")"; } template void TPrinter::visit(TLnNode *ANode) { FStream << "ln("; ANode->node()->accept(*this); FStream << ")"; } template void TPrinter::visit(TFuncNode *ANode) { FStream << ANode->name() << "("; ANode->node()->accept(*this); FStream << ")"; } template void TPrinter::visit(TIfNode *ANode) { FStream << "IF("; ANode->condition()->accept(*this); FStream << ", "; ANode->trueExpr()->accept(*this); FStream << ", "; ANode->falseExpr()->accept(*this); FStream << ")"; } template void TPrinter::visit(TEquNode *ANode) { ANode->left()->accept(*this); FStream << "="; ANode->right()->accept(*this); } template void TPrinter::visit(TUnEquNode *ANode) { ANode->left()->accept(*this); FStream << "<>"; ANode->right()->accept(*this); } template void TPrinter::visit(TGreaterNode *ANode) { ANode->left()->accept(*this); FStream << ">"; ANode->right()->accept(*this); } template void TPrinter::visit(TLessNode *ANode) { ANode->left()->accept(*this); FStream << "<"; ANode->right()->accept(*this); } template void TPrinter::visit(TGreaterEquNode *ANode) { ANode->left()->accept(*this); FStream << ">="; ANode->right()->accept(*this); } template void TPrinter::visit(TLessEquNode *ANode) { ANode->left()->accept(*this); FStream << "<="; ANode->right()->accept(*this); } /*template std::ostream& operator<< (std::ostream& os, const TNode& ANode) { TPrinter::print(os, &ANode); return os; }*/ } // namespace math