f90a40ce89fa86aa9acb01e3ca15bd37ff70ad47
[ginac.git] / ginac / print.cpp
1 /** @file print.cpp
2  *
3  *  The methods .print() are responsible for the nice default-output of
4  *  objects.  All related helper-functions go in here as well. */
5
6 /*
7  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include <iostream>
25
26 #include "basic.h"
27 #include "ex.h"
28 #include "add.h"
29 #include "constant.h"
30 #include "expairseq.h"
31 #include "fail.h"
32 #include "indexed.h"
33 #include "inifcns.h"
34 #include "matrix.h"
35 #include "mul.h"
36 #include "ncmul.h"
37 #include "numeric.h"
38 #include "power.h"
39 #include "relational.h"
40 #include "series.h"
41 #include "symbol.h"
42 #include "debugmsg.h"
43
44 namespace GiNaC {
45
46 void ex::print(ostream & os, unsigned upper_precedence) const
47 {
48     debugmsg("ex print",LOGLEVEL_PRINT);
49     GINAC_ASSERT(bp!=0);
50     bp->print(os,upper_precedence);
51 }
52
53 void ex::dbgprint(void) const
54 {
55     debugmsg("ex dbgprint",LOGLEVEL_PRINT);
56     GINAC_ASSERT(bp!=0);
57     bp->dbgprint();
58 }
59
60 void basic::print(ostream & os, unsigned upper_precedence) const
61 {
62     debugmsg("basic print",LOGLEVEL_PRINT);
63     os << "[basic object]";
64 }
65
66 void basic::dbgprint(void) const
67 {
68     print(cerr);
69     cerr << endl;
70 }
71
72 void symbol::print(ostream & os, unsigned upper_precedence) const
73 {
74     debugmsg("symbol print",LOGLEVEL_PRINT);
75     os << name;
76 }
77
78 void constant::print(ostream & os, unsigned upper_precedence) const
79 {
80     debugmsg("constant print",LOGLEVEL_PRINT);
81     os << name;
82 }
83
84 void power::print(ostream & os, unsigned upper_precedence) const
85 {
86     debugmsg("power print",LOGLEVEL_PRINT);
87     if (precedence<=upper_precedence) os << "(";
88     basis.print(os,precedence);
89     os << "^";
90     exponent.print(os,precedence);
91     if (precedence<=upper_precedence) os << ")";
92 }
93
94 void fail::print(ostream & os, unsigned upper_precedence) const
95 {
96     debugmsg("fail print",LOGLEVEL_PRINT);
97     os << "FAIL";
98 }
99
100 void expairseq::printpair(ostream & os, expair const & p, unsigned upper_precedence) const
101 {
102     os << "[[";
103     p.rest.bp->print(os,precedence);
104     os << ",";
105     p.coeff.bp->print(os,precedence);
106     os << "]]";
107 }
108
109 void expairseq::printseq(ostream & os, char delim, unsigned this_precedence,
110                          unsigned upper_precedence) const
111 {
112     if (this_precedence<=upper_precedence) os << "(";
113     epvector::const_iterator it,it_last;
114     it_last=seq.end();
115     --it_last;
116     for (it=seq.begin(); it!=it_last; ++it) {
117         printpair(os,*it,this_precedence);
118         os << delim;
119     }
120     printpair(os,*it,this_precedence);
121     if (!overall_coeff.is_equal(default_overall_coeff())) {
122         os << delim << overall_coeff;
123     }
124     if (this_precedence<=upper_precedence) os << ")";
125 }
126     
127 void expairseq::print(ostream & os, unsigned upper_precedence) const
128 {
129     debugmsg("expairseq print",LOGLEVEL_PRINT);
130     os << "[[";
131     printseq(os,',',precedence,upper_precedence);
132     os << "]]";
133 }
134
135 void add::print(ostream & os, unsigned upper_precedence) const
136 {
137     debugmsg("add print",LOGLEVEL_PRINT);
138     if (precedence<=upper_precedence) os << "(";
139     numeric coeff;
140     bool first=true;
141     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
142         coeff = ex_to_numeric(cit->coeff);
143         if (!first) {
144             if (coeff.csgn()==-1) os << '-'; else os << '+';
145         } else {
146             if (coeff.csgn()==-1) os << '-';
147             first=false;
148         }
149         if (!coeff.is_equal(numONE()) &&
150             !coeff.is_equal(numMINUSONE())) {
151             if (coeff.csgn()==-1)
152                 (numMINUSONE()*coeff).print(os, precedence);
153             else
154                 coeff.print(os, precedence);
155             os << '*';
156         }
157         os << cit->rest;
158     }
159     // print the overall numeric coefficient, if present:
160     if (!overall_coeff.is_zero()) {
161         if (overall_coeff > 0) os << '+';
162         os << overall_coeff;
163     }
164     if (precedence<=upper_precedence) os << ")";
165 }
166
167 void mul::print(ostream & os, unsigned upper_precedence) const
168 {
169     debugmsg("mul print",LOGLEVEL_PRINT);
170     if (precedence<=upper_precedence) os << "(";
171     bool first=true;
172     // first print the overall numeric coefficient:
173     if (ex_to_numeric(overall_coeff).csgn()==-1) os << '-';
174     if (!overall_coeff.is_equal(exONE()) &&
175         !overall_coeff.is_equal(exMINUSONE())) {
176         if (ex_to_numeric(overall_coeff).csgn()==-1)
177             (numMINUSONE()*overall_coeff).print(os, precedence);
178         else
179             overall_coeff.print(os, precedence);
180         os << '*';
181     }
182     // then proceed with the remaining factors:
183     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
184         if (!first) {
185             os << '*';
186         } else {
187             first=false;
188         }
189         recombine_pair_to_ex(*cit).print(os,precedence);
190     }
191     if (precedence<=upper_precedence) os << ")";
192 }
193
194 void ncmul::print(ostream & os, unsigned upper_precedence) const
195 {
196     debugmsg("ncmul print",LOGLEVEL_PRINT);
197     printseq(os,'(','%',')',precedence,upper_precedence);
198 }
199
200 /*void function::print(ostream & os, unsigned upper_precedence) const
201  *{
202  *    debugmsg("function print",LOGLEVEL_PRINT);
203  *    os << name;
204  *    printseq(os,'(',',',')',exprseq::precedence,function::precedence);
205  *}*/
206
207 void series::print(ostream &os, unsigned upper_precedence) const
208 {
209         debugmsg("symbol print", LOGLEVEL_PRINT);
210         convert_to_poly().print(os, upper_precedence);
211 }
212
213 void relational::print(ostream & os, unsigned upper_precedence) const
214 {
215     debugmsg("relational print",LOGLEVEL_PRINT);
216     if (precedence<=upper_precedence) os << "(";
217     lh.print(os,precedence);
218     switch (o) {
219     case equal:
220         os << "==";
221         break;
222     case not_equal:
223         os << "!=";
224         break;
225     case less:
226         os << "<";
227         break;
228     case less_or_equal:
229         os << "<=";
230         break;
231     case greater:
232         os << ">";
233         break;
234     case greater_or_equal:
235         os << ">=";
236         break;
237     default:
238         os << "(INVALID RELATIONAL OPERATOR)";
239     }
240     rh.print(os,precedence);
241     if (precedence<=upper_precedence) os << ")";
242 }
243
244 void matrix::print(ostream & os, unsigned upper_precedence) const
245 {
246     debugmsg("matrix print",LOGLEVEL_PRINT);
247     os << "[[ ";
248     for (int r=0; r<row-1; ++r) {
249         os << "[[";
250         for (int c=0; c<col-1; ++c) {
251             os << m[r*col+c] << ",";
252         }
253         os << m[col*(r+1)-1] << "]], ";
254     }
255     os << "[[";
256     for (int c=0; c<col-1; ++c) {
257         os << m[(row-1)*col+c] << ",";
258     }
259     os << m[row*col-1] << "]] ]]";
260 }
261
262 } // namespace GiNaC