#ifndef around namespace GiNaC { }
[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 #ifndef NO_GINAC_NAMESPACE
45 namespace GiNaC {
46 #endif // ndef NO_GINAC_NAMESPACE
47
48 void ex::print(ostream & os, unsigned upper_precedence) const
49 {
50     debugmsg("ex print",LOGLEVEL_PRINT);
51     GINAC_ASSERT(bp!=0);
52     bp->print(os,upper_precedence);
53 }
54
55 void ex::dbgprint(void) const
56 {
57     debugmsg("ex dbgprint",LOGLEVEL_PRINT);
58     GINAC_ASSERT(bp!=0);
59     bp->dbgprint();
60 }
61
62 void basic::print(ostream & os, unsigned upper_precedence) const
63 {
64     debugmsg("basic print",LOGLEVEL_PRINT);
65     os << "[basic object]";
66 }
67
68 void basic::dbgprint(void) const
69 {
70     print(cerr);
71     cerr << endl;
72 }
73
74 void symbol::print(ostream & os, unsigned upper_precedence) const
75 {
76     debugmsg("symbol print",LOGLEVEL_PRINT);
77     os << name;
78 }
79
80 void constant::print(ostream & os, unsigned upper_precedence) const
81 {
82     debugmsg("constant print",LOGLEVEL_PRINT);
83     os << name;
84 }
85
86 void power::print(ostream & os, unsigned upper_precedence) const
87 {
88     debugmsg("power print",LOGLEVEL_PRINT);
89     if (precedence<=upper_precedence) os << "(";
90     basis.print(os,precedence);
91     os << "^";
92     exponent.print(os,precedence);
93     if (precedence<=upper_precedence) os << ")";
94 }
95
96 void fail::print(ostream & os, unsigned upper_precedence) const
97 {
98     debugmsg("fail print",LOGLEVEL_PRINT);
99     os << "FAIL";
100 }
101
102 void expairseq::printpair(ostream & os, expair const & p, unsigned upper_precedence) const
103 {
104     os << "[[";
105     p.rest.bp->print(os,precedence);
106     os << ",";
107     p.coeff.bp->print(os,precedence);
108     os << "]]";
109 }
110
111 void expairseq::printseq(ostream & os, char delim, unsigned this_precedence,
112                          unsigned upper_precedence) const
113 {
114     if (this_precedence<=upper_precedence) os << "(";
115     epvector::const_iterator it,it_last;
116     it_last=seq.end();
117     --it_last;
118     for (it=seq.begin(); it!=it_last; ++it) {
119         printpair(os,*it,this_precedence);
120         os << delim;
121     }
122     printpair(os,*it,this_precedence);
123     if (!overall_coeff.is_equal(default_overall_coeff())) {
124         os << delim << overall_coeff;
125     }
126     if (this_precedence<=upper_precedence) os << ")";
127 }
128     
129 void expairseq::print(ostream & os, unsigned upper_precedence) const
130 {
131     debugmsg("expairseq print",LOGLEVEL_PRINT);
132     os << "[[";
133     printseq(os,',',precedence,upper_precedence);
134     os << "]]";
135 }
136
137 void add::print(ostream & os, unsigned upper_precedence) const
138 {
139     debugmsg("add print",LOGLEVEL_PRINT);
140     if (precedence<=upper_precedence) os << "(";
141     numeric coeff;
142     bool first=true;
143     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
144         coeff = ex_to_numeric(cit->coeff);
145         if (!first) {
146             if (coeff.csgn()==-1) os << '-'; else os << '+';
147         } else {
148             if (coeff.csgn()==-1) os << '-';
149             first=false;
150         }
151         if (!coeff.is_equal(numONE()) &&
152             !coeff.is_equal(numMINUSONE())) {
153             if (coeff.csgn()==-1)
154                 (numMINUSONE()*coeff).print(os, precedence);
155             else
156                 coeff.print(os, precedence);
157             os << '*';
158         }
159         os << cit->rest;
160     }
161     // print the overall numeric coefficient, if present:
162     if (!overall_coeff.is_zero()) {
163         if (overall_coeff > 0) os << '+';
164         os << overall_coeff;
165     }
166     if (precedence<=upper_precedence) os << ")";
167 }
168
169 void mul::print(ostream & os, unsigned upper_precedence) const
170 {
171     debugmsg("mul print",LOGLEVEL_PRINT);
172     if (precedence<=upper_precedence) os << "(";
173     bool first=true;
174     // first print the overall numeric coefficient:
175     if (ex_to_numeric(overall_coeff).csgn()==-1) os << '-';
176     if (!overall_coeff.is_equal(exONE()) &&
177         !overall_coeff.is_equal(exMINUSONE())) {
178         if (ex_to_numeric(overall_coeff).csgn()==-1)
179             (numMINUSONE()*overall_coeff).print(os, precedence);
180         else
181             overall_coeff.print(os, precedence);
182         os << '*';
183     }
184     // then proceed with the remaining factors:
185     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
186         if (!first) {
187             os << '*';
188         } else {
189             first=false;
190         }
191         recombine_pair_to_ex(*cit).print(os,precedence);
192     }
193     if (precedence<=upper_precedence) os << ")";
194 }
195
196 void ncmul::print(ostream & os, unsigned upper_precedence) const
197 {
198     debugmsg("ncmul print",LOGLEVEL_PRINT);
199     printseq(os,'(','%',')',precedence,upper_precedence);
200 }
201
202 /*void function::print(ostream & os, unsigned upper_precedence) const
203  *{
204  *    debugmsg("function print",LOGLEVEL_PRINT);
205  *    os << name;
206  *    printseq(os,'(',',',')',exprseq::precedence,function::precedence);
207  *}*/
208
209 void series::print(ostream &os, unsigned upper_precedence) const
210 {
211         debugmsg("symbol print", LOGLEVEL_PRINT);
212         convert_to_poly().print(os, upper_precedence);
213 }
214
215 void relational::print(ostream & os, unsigned upper_precedence) const
216 {
217     debugmsg("relational print",LOGLEVEL_PRINT);
218     if (precedence<=upper_precedence) os << "(";
219     lh.print(os,precedence);
220     switch (o) {
221     case equal:
222         os << "==";
223         break;
224     case not_equal:
225         os << "!=";
226         break;
227     case less:
228         os << "<";
229         break;
230     case less_or_equal:
231         os << "<=";
232         break;
233     case greater:
234         os << ">";
235         break;
236     case greater_or_equal:
237         os << ">=";
238         break;
239     default:
240         os << "(INVALID RELATIONAL OPERATOR)";
241     }
242     rh.print(os,precedence);
243     if (precedence<=upper_precedence) os << ")";
244 }
245
246 void matrix::print(ostream & os, unsigned upper_precedence) const
247 {
248     debugmsg("matrix print",LOGLEVEL_PRINT);
249     os << "[[ ";
250     for (int r=0; r<row-1; ++r) {
251         os << "[[";
252         for (int c=0; c<col-1; ++c) {
253             os << m[r*col+c] << ",";
254         }
255         os << m[col*(r+1)-1] << "]], ";
256     }
257     os << "[[";
258     for (int c=0; c<col-1; ++c) {
259         os << m[(row-1)*col+c] << ",";
260     }
261     os << m[row*col-1] << "]] ]]";
262 }
263
264 #ifndef NO_GINAC_NAMESPACE
265 } // namespace GiNaC
266 #endif // ndef NO_GINAC_NAMESPACE