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