]> www.ginac.de Git - ginac.git/blob - ginac/print.cpp
- check program is not built until you say "make check"
[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 "basic.h"
26 #include "ex.h"
27 #include "add.h"
28 #include "constant.h"
29 #include "expairseq.h"
30 #include "fail.h"
31 #include "indexed.h"
32 #include "inifcns.h"
33 #include "matrix.h"
34 #include "mul.h"
35 #include "ncmul.h"
36 #include "numeric.h"
37 #include "power.h"
38 #include "relational.h"
39 #include "series.h"
40 #include "symbol.h"
41
42 void ex::print(ostream & os, unsigned upper_precedence) const
43 {
44     debugmsg("ex print",LOGLEVEL_PRINT);
45     ASSERT(bp!=0);
46     bp->print(os,upper_precedence);
47 }
48
49 void ex::dbgprint(void) const
50 {
51     debugmsg("ex dbgprint",LOGLEVEL_PRINT);
52     ASSERT(bp!=0);
53     bp->dbgprint();
54 }
55
56 void basic::print(ostream & os, unsigned upper_precedence) const
57 {
58     debugmsg("basic print",LOGLEVEL_PRINT);
59     os << "[basic object]";
60 }
61
62 void basic::dbgprint(void) const
63 {
64     print(cerr);
65     cerr << endl;
66 }
67
68 void symbol::print(ostream & os, unsigned upper_precedence) const
69 {
70     debugmsg("symbol print",LOGLEVEL_PRINT);
71     os << name;
72 }
73
74 void constant::print(ostream & os, unsigned upper_precedence) const
75 {
76     debugmsg("constant print",LOGLEVEL_PRINT);
77     os << name;
78 }
79
80 void power::print(ostream & os, unsigned upper_precedence) const
81 {
82     debugmsg("power print",LOGLEVEL_PRINT);
83 #if 1
84     if (precedence<=upper_precedence) os << "(";
85     basis.print(os,precedence);
86     os << "^";
87     exponent.print(os,precedence);
88     if (precedence<=upper_precedence) os << ")";
89 #else
90     os << "pow(" << basis << "," << exponent << ")";
91 #endif
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 /*
110 void expairseq::printseq(ostream & os, char delim, unsigned this_precedence,
111                          unsigned upper_precedence) const
112 {
113     if (this_precedence<=upper_precedence) os << "(";
114     epvector::const_iterator itt,it,it_last,it_start;
115     it_last=seq.end();
116     --it_last;
117     it_start=seq.begin();
118
119     switch (delim) {
120     case '+':
121         for (it=seq.begin(); it!=it_last; ++it) {
122             itt = it +1;
123             expair const & k = *itt;
124             printpair(os,*it, this_precedence);
125             if (((is_ex_of_type(k.rest, numeric)) && (k.coeff*k.rest > 0) ) || ((!is_ex_of_type(k.rest, numeric)) && (k.coeff >0))){
126                 os << "+";
127             }
128         }
129         printpair(os,*it,this_precedence);
130         break;
131         
132     case '*':
133         for (it = it_last ; it!=it_start; --it) {
134             if ((*it).rest.is_equal(exMINUSONE()) &&
135                 (*it).coeff.is_equal(exONE())) {
136                 os << "-";
137             } else {
138                 printpair(os, *it,this_precedence);
139                 os << delim;
140             }
141         }
142         printpair(os,*it,this_precedence);
143         break;
144     default:
145         clog << "Nobody expects the Spanish Inquisition: "
146              << "deliminator unknown!" << endl;
147     }
148     if (this_precedence<=upper_precedence) os << ")";
149 }
150 */
151
152 void expairseq::printseq(ostream & os, char delim, unsigned this_precedence,
153                          unsigned upper_precedence) const
154 {
155     if (this_precedence<=upper_precedence) os << "(";
156     epvector::const_iterator it,it_last;
157     it_last=seq.end();
158     --it_last;
159     for (it=seq.begin(); it!=it_last; ++it) {
160         printpair(os,*it,this_precedence);
161         os << delim;
162     }
163     printpair(os,*it,this_precedence);
164     if (!overall_coeff.is_equal(default_overall_coeff())) {
165         os << delim << overall_coeff;
166     }
167     if (this_precedence<=upper_precedence) os << ")";
168 }
169     
170 void expairseq::print(ostream & os, unsigned upper_precedence) const
171 {
172     debugmsg("expairseq print",LOGLEVEL_PRINT);
173     os << "[[";
174     printseq(os,',',precedence,upper_precedence);
175     os << "]]";
176 }
177
178 void add::printpair(ostream & os, expair const & p, unsigned upper_precedence) const
179 {
180     os << "(";
181     if (p.coeff == -1) {
182         os << "-";
183     } else {
184         if (p.coeff != 1) {
185             os << p.coeff;
186             os << "*";
187         }
188     }
189     os << p.rest;
190     os << ")";
191 }
192     
193 void add::print(ostream & os, unsigned upper_precedence) const
194 {
195     debugmsg("add print",LOGLEVEL_PRINT);
196     if (precedence<=upper_precedence) os << "(";
197     bool first=true;
198     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
199         if (!first) {
200             if (cit->coeff > 0) os << '+';
201         } else {
202             first=false;
203         }
204         if (cit->coeff == -1) {
205             os << "-";
206         } else {
207             if (cit->coeff != 1) {
208                 (cit->coeff).print(os,precedence);
209                 os << "*";
210             }
211         }
212         os << cit->rest;
213     }
214     if (!overall_coeff.is_zero()) {
215         if (overall_coeff > 0) os << '+';
216         os << overall_coeff;
217     }
218     if (precedence<=upper_precedence) os << ")";
219 }
220
221 void mul::printpair(ostream & os, expair const & p, unsigned upper_precedence) const
222 {
223     os << "(";
224     if (p.coeff.compare(exONE())==0) {
225         p.rest.print(os,upper_precedence);
226     } else {
227         // outer parens around ex needed for broken gcc-2.95 parser:
228         (ex(power(p.rest,p.coeff))).print(os,upper_precedence);
229     }
230     os << ")";
231 }
232     
233 void mul::print(ostream & os, unsigned upper_precedence) const
234 {
235     debugmsg("mul print",LOGLEVEL_PRINT);
236     if (precedence<=upper_precedence) os << "(";
237     bool first=true;
238     if (!overall_coeff.is_equal(exONE())) {
239         overall_coeff.print(os,precedence);
240         first=false;
241     }
242     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
243         if (!first) {
244             os << '*';
245         } else {
246             first=false;
247         }
248         recombine_pair_to_ex(*cit).print(os,precedence);
249     }
250     if (precedence<=upper_precedence) os << ")";
251 }
252
253 void ncmul::print(ostream & os, unsigned upper_precedence) const
254 {
255     debugmsg("ncmul print",LOGLEVEL_PRINT);
256     printseq(os,'(','%',')',precedence,upper_precedence);
257 }
258
259 /*void function::print(ostream & os, unsigned upper_precedence) const
260  *{
261  *    debugmsg("function print",LOGLEVEL_PRINT);
262  *    os << name;
263  *    printseq(os,'(',',',')',exprseq::precedence,function::precedence);
264  *}*/
265
266 void series::print(ostream &os, unsigned upper_precedence) const
267 {
268         debugmsg("symbol print", LOGLEVEL_PRINT);
269         convert_to_poly().print(os, upper_precedence);
270 }
271
272 void relational::print(ostream & os, unsigned upper_precedence) const
273 {
274     debugmsg("relational print",LOGLEVEL_PRINT);
275     if (precedence<=upper_precedence) os << "(";
276     lh.print(os,precedence);
277     switch (o) {
278     case equal:
279         os << "==";
280         break;
281     case not_equal:
282         os << "!=";
283         break;
284     case less:
285         os << "<";
286         break;
287     case less_or_equal:
288         os << "<=";
289         break;
290     case greater:
291         os << ">";
292         break;
293     case greater_or_equal:
294         os << ">=";
295         break;
296     default:
297         os << "(INVALID RELATIONAL OPERATOR)";
298     }
299     rh.print(os,precedence);
300     if (precedence<=upper_precedence) os << ")";
301 }
302
303 void matrix::print(ostream & os, unsigned upper_precedence) const
304 {
305     debugmsg("matrix print",LOGLEVEL_PRINT);
306     os << "[[ ";
307     for (int r=0; r<row-1; ++r) {
308         os << "[[";
309         for (int c=0; c<col-1; ++c) {
310             os << m[r*col+c] << ",";
311         }
312         os << m[col*(r+1)-1] << "]], ";
313     }
314     os << "[[";
315     for (int c=0; c<col-1; ++c) {
316         os << m[(row-1)*col+c] << ",";
317     }
318     os << m[row*col-1] << "]] ]]";
319 }