f797dc6b1e9ebd59f1c4e525fa27264c64366709
[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     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     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.compare(numONE()) && coeff.compare(numMINUSONE())) {
150             if (coeff.csgn()==-1)
151                 (numMINUSONE()*coeff).print(os, precedence);
152             else
153                 coeff.print(os, precedence);
154             os << '*';
155         }
156         os << cit->rest;
157     }
158     // print the overall numeric coefficient, if present:
159     if (!overall_coeff.is_zero()) {
160         if (overall_coeff > 0) os << '+';
161         os << overall_coeff;
162     }
163     if (precedence<=upper_precedence) os << ")";
164 }
165
166 void mul::print(ostream & os, unsigned upper_precedence) const
167 {
168     debugmsg("mul print",LOGLEVEL_PRINT);
169     if (precedence<=upper_precedence) os << "(";
170     bool first=true;
171     if (!overall_coeff.is_equal(exONE())) {
172         overall_coeff.print(os,precedence);
173         first=false;
174     }
175     for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
176         if (!first) {
177             os << '*';
178         } else {
179             first=false;
180         }
181         recombine_pair_to_ex(*cit).print(os,precedence);
182     }
183     if (precedence<=upper_precedence) os << ")";
184 }
185
186 void ncmul::print(ostream & os, unsigned upper_precedence) const
187 {
188     debugmsg("ncmul print",LOGLEVEL_PRINT);
189     printseq(os,'(','%',')',precedence,upper_precedence);
190 }
191
192 /*void function::print(ostream & os, unsigned upper_precedence) const
193  *{
194  *    debugmsg("function print",LOGLEVEL_PRINT);
195  *    os << name;
196  *    printseq(os,'(',',',')',exprseq::precedence,function::precedence);
197  *}*/
198
199 void series::print(ostream &os, unsigned upper_precedence) const
200 {
201         debugmsg("symbol print", LOGLEVEL_PRINT);
202         convert_to_poly().print(os, upper_precedence);
203 }
204
205 void relational::print(ostream & os, unsigned upper_precedence) const
206 {
207     debugmsg("relational print",LOGLEVEL_PRINT);
208     if (precedence<=upper_precedence) os << "(";
209     lh.print(os,precedence);
210     switch (o) {
211     case equal:
212         os << "==";
213         break;
214     case not_equal:
215         os << "!=";
216         break;
217     case less:
218         os << "<";
219         break;
220     case less_or_equal:
221         os << "<=";
222         break;
223     case greater:
224         os << ">";
225         break;
226     case greater_or_equal:
227         os << ">=";
228         break;
229     default:
230         os << "(INVALID RELATIONAL OPERATOR)";
231     }
232     rh.print(os,precedence);
233     if (precedence<=upper_precedence) os << ")";
234 }
235
236 void matrix::print(ostream & os, unsigned upper_precedence) const
237 {
238     debugmsg("matrix print",LOGLEVEL_PRINT);
239     os << "[[ ";
240     for (int r=0; r<row-1; ++r) {
241         os << "[[";
242         for (int c=0; c<col-1; ++c) {
243             os << m[r*col+c] << ",";
244         }
245         os << m[col*(r+1)-1] << "]], ";
246     }
247     os << "[[";
248     for (int c=0; c<col-1; ++c) {
249         os << m[(row-1)*col+c] << ",";
250     }
251     os << m[row*col-1] << "]] ]]";
252 }
253
254 } // namespace GiNaC