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