* Added output-support for Python bindings and LaTeX printing for
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Wed, 19 Dec 2001 19:16:16 +0000 (19:16 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Wed, 19 Dec 2001 19:16:16 +0000 (19:16 +0000)
  indexed objects (Pearu Peterson).
* relational.*: Removed superfluous is_equal_same_type()...
* inifcns_trans.cpp: ...added extern declaration as workaround for
  compiler-bug triggered by changes to relational.*,
* input_parser.yy: added missing namespace specification.

18 files changed:
ginac/add.cpp
ginac/constant.cpp
ginac/container.pl
ginac/idx.cpp
ginac/inifcns_trans.cpp
ginac/input_parser.yy
ginac/matrix.cpp
ginac/mul.cpp
ginac/ncmul.cpp
ginac/numeric.cpp
ginac/power.cpp
ginac/print.cpp
ginac/print.h
ginac/pseries.cpp
ginac/relational.cpp
ginac/relational.h
ginac/symbol.cpp
ginac/wildcard.cpp

index b9eca99..279933d 100644 (file)
@@ -152,10 +152,22 @@ void add::print(const print_context & c, unsigned level) const
                                c.s << '+';
                        overall_coeff.print(c, precedence());
                }
-       
+               
                if (precedence() <= level)
                        c.s << ")";
 
+       } else if (is_a<print_python_repr>(c)) {
+
+               c.s << class_name() << '(';
+               unsigned end = nops();
+               if (end)
+                       op(0).print(c);
+               for (unsigned i=1; i<end; ++i) {
+                       c.s << ',';
+                       op(i).print(c);
+               }
+               c.s << ')';
+
        } else {
 
                if (precedence() <= level) {
index 0cf7c77..beabc96 100644 (file)
@@ -134,9 +134,14 @@ void constant::print(const print_context & c, unsigned level) const
                c.s << std::string(level, ' ') << name << " (" << class_name() << ")"
                    << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
                    << std::endl;
-       } else if (is_a<print_latex>(c))
+       } else if (is_a<print_latex>(c)) {
                c.s << TeX_name;
-       else
+       } else if (is_a<print_python_repr>(c)) {
+               c.s << class_name() << "('" << name << "'";
+               if (TeX_name != "\\mbox{" + name + "}")
+                       c.s << ",TeX_name='" << TeX_name << "'";
+               c.s << ')';
+       } else
                c.s << name;
 }
 
index 5e4837d..4603d3f 100755 (executable)
@@ -430,7 +430,11 @@ void ${CONTAINER}::print(const print_context & c, unsigned level) const
                        ++i;
                }
                c.s << std::string(level + delta_indent,' ') << "=====" << std::endl;
-
+       } else if (is_a<print_python>(c)) {
+               printseq(c, '[', ',', ']', precedence(), precedence()+1);
+       } else if (is_a<print_python_repr>(c)) {
+               c.s << class_name ();
+               printseq(c, '(', ',', ')', precedence(), precedence()+1);
        } else {
                // always print brackets around seq, ignore upper_precedence
                printseq(c, '${open_bracket}', ',', '${close_bracket}', precedence(), precedence()+1);
index 7475402..578b2bf 100644 (file)
@@ -156,7 +156,9 @@ void idx::print(const print_context & c, unsigned level) const
 
        } else {
 
-               if (!is_of_type(c, print_latex))
+               if (is_a<print_latex>(c))
+                       c.s << "_{";
+               else
                        c.s << ".";
                bool need_parens = !(is_ex_exactly_of_type(value, numeric) || is_ex_of_type(value, symbol));
                if (need_parens)
@@ -164,6 +166,8 @@ void idx::print(const print_context & c, unsigned level) const
                value.print(c);
                if (need_parens)
                        c.s << ")";
+               if (is_a<print_latex>(c))
+                       c.s << "}";
        }
 }
 
@@ -180,8 +184,12 @@ void varidx::print(const print_context & c, unsigned level) const
                dim.print(c, level + delta_indent);
 
        } else {
-
-               if (!is_of_type(c, print_latex)) {
+               if (is_a<print_latex>(c)) {
+                       if (covariant)
+                               c.s << "_{";
+                       else
+                               c.s << "^{";
+               } else {
                        if (covariant)
                                c.s << ".";
                        else
@@ -193,6 +201,8 @@ void varidx::print(const print_context & c, unsigned level) const
                value.print(c);
                if (need_parens)
                        c.s << ")";
+               if (is_a<print_latex>(c))
+                       c.s << "}";
        }
 }
 
@@ -212,7 +222,12 @@ void spinidx::print(const print_context & c, unsigned level) const
        } else {
 
                bool is_tex = is_of_type(c, print_latex);
-               if (!is_tex) {
+               if (is_tex) {
+                       if (covariant)
+                               c.s << "_{";
+                       else
+                               c.s << "^{";
+               } else {
                        if (covariant)
                                c.s << ".";
                        else
@@ -232,6 +247,8 @@ void spinidx::print(const print_context & c, unsigned level) const
                        c.s << ")";
                if (is_tex && dotted)
                        c.s << "}";
+               if (is_tex)
+                       c.s << "}";
        }
 }
 
index cbf370d..b092b53 100644 (file)
@@ -141,6 +141,14 @@ static ex log_deriv(const ex & x, unsigned deriv_param)
        return power(x, _ex_1);
 }
 
+// This is a strange workaround for a compiliation problem with the try statement
+// below.  With -O1 the exception is not caucht properly as of GCC-2.95.2, at
+// least on i386.  Version 2.95.4 seems to have fixed this silly problem, though.
+// Funnily, with a simple extern declaration here it mysteriously works again.
+#if defined(__GNUC__) && (__GNUC__==2)
+extern "C" int putchar(int);
+#endif
+
 static ex log_series(const ex &arg,
                      const relational &rel,
                      int order,
index 8ba5bf4..5df99b6 100644 (file)
@@ -94,7 +94,7 @@ exp   : T_NUMBER              {$$ = $1;}
        | T_LITERAL             {$$ = $1;}
        | T_DIGITS              {$$ = $1;}
        | T_SYMBOL '(' exprseq ')' {
-               string n = ex_to<symbol>($1).get_name();
+               std::string n = ex_to<symbol>($1).get_name();
                if (n == "sqrt") {
                        if ($3.nops() != 1)
                                throw (std::runtime_error("too many arguments to sqrt()"));
index 3d735fe..0bedb6b 100644 (file)
@@ -147,6 +147,9 @@ void matrix::print(const print_context & c, unsigned level) const
 
        } else {
 
+               if (is_a<print_python_repr>(c))
+                       c.s << class_name() << '(';
+
                c.s << "[";
                for (unsigned y=0; y<row-1; ++y) {
                        c.s << "[";
@@ -165,6 +168,9 @@ void matrix::print(const print_context & c, unsigned level) const
                m[row*col-1].print(c);
                c.s << "]]";
 
+               if (is_a<print_python_repr>(c))
+                       c.s << ')';
+
        }
 }
 
index 64b090a..47f74f6 100644 (file)
@@ -169,6 +169,16 @@ void mul::print(const print_context & c, unsigned level) const
                if (precedence() <= level)
                        c.s << ")";
 
+       } else if (is_a<print_python_repr>(c)) {
+               c.s << class_name() << '(';
+               unsigned end = nops();
+               if (end)
+                       op(0).print(c);
+               for (unsigned i=1; i<end; ++i) {
+                       c.s << ',';
+                       op(i).print(c);
+               }
+               c.s << ')';
        } else {
 
                if (precedence() <= level) {
index a12fd6f..3f0ec97 100644 (file)
@@ -111,9 +111,9 @@ void ncmul::print(const print_context & c, unsigned level) const
 
                inherited::print(c, level);
 
-       } else if (is_a<print_csrc>(c)) {
+       } else if (is_a<print_csrc>(c) || is_a<print_python_repr>(c)) {
 
-               c.s << "ncmul(";
+               c.s << class_name() << "(";
                exvector::const_iterator it = seq.begin(), itend = seq.end()-1;
                while (it != itend) {
                        it->print(c, precedence());
index fe51c60..01c5845 100644 (file)
@@ -389,6 +389,8 @@ void numeric::print(const print_context & c, unsigned level) const
                const std::string mul_sym   = is_a<print_latex>(c) ? " " : "*";
                const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
                const cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
+               if (is_a<print_python_repr>(c))
+                       c.s << class_name() << "('";
                if (cln::zerop(i)) {
                        // case 1, real:  x  or  -x
                        if ((precedence() <= level) && (!this->is_nonneg_integer())) {
@@ -446,6 +448,8 @@ void numeric::print(const print_context & c, unsigned level) const
                                        c.s << par_close;
                        }
                }
+               if (is_a<print_python_repr>(c))
+                       c.s << "')";
        }
 }
 
index 78c9c96..72ec5aa 100644 (file)
@@ -159,6 +159,14 @@ void power::print(const print_context & c, unsigned level) const
                        c.s << ')';
                }
 
+       } else if (is_a<print_python_repr>(c)) {
+
+               c.s << class_name() << '(';
+               basis.print(c);
+               c.s << ',';
+               exponent.print(c);
+               c.s << ')';
+
        } else {
 
                if (exponent.is_equal(_ex1_2)) {
@@ -179,7 +187,10 @@ void power::print(const print_context & c, unsigned level) const
                                        c.s << "(";
                        }
                        basis.print(c, precedence());
-                       c.s << '^';
+                       if (is_a<print_python>(c))
+                               c.s << "**";
+                       else
+                               c.s << '^';
                        if (is_a<print_latex>(c))
                                c.s << '{';
                        exponent.print(c, precedence());
index bd365cf..2b1e323 100644 (file)
@@ -36,6 +36,16 @@ print_latex::print_latex()
 print_latex::print_latex(std::ostream & os)
        : print_context(os) {}
 
+print_python::print_python()
+       : print_context(std::cout) {}
+print_python::print_python(std::ostream & os)
+       : print_context(os) {}
+
+print_python_repr::print_python_repr()
+       : print_context(std::cout) {}
+print_python_repr::print_python_repr(std::ostream & os)
+       : print_context(os) {}
+
 print_tree::print_tree(unsigned d)
        : print_context(std::cout), delta_indent(d) {}
 print_tree::print_tree(std::ostream & os, unsigned d)
index 1d99639..3e55db5 100644 (file)
@@ -49,6 +49,22 @@ public:
        print_latex(std::ostream &);
 };
 
+/** Context for python pretty-print output. */
+class print_python : public print_context
+{
+public:
+       print_python();
+       print_python(std::ostream &);
+};
+
+/** Context for python-parsable output. */
+class print_python_repr : public print_context
+{
+public:
+       print_python_repr();
+       print_python_repr(std::ostream &);
+};
+
 /** Context for tree-like output for debugging. */
 class print_tree : public print_context
 {
index 8043382..720c4ec 100644 (file)
@@ -134,6 +134,23 @@ void pseries::print(const print_context & c, unsigned level) const
                var.print(c, level + delta_indent);
                point.print(c, level + delta_indent);
 
+       } else if (is_a<print_python_repr>(c)) {
+               c.s << class_name() << "(relational(";
+               var.print(c);
+               c.s << ',';
+               point.print(c);
+               c.s << "),[";
+               unsigned num = seq.size();
+               for (unsigned i=0; i<num; ++i) {
+                       if (i)
+                               c.s << ',';
+                       c.s << '(';
+                       seq[i].rest.print(c);
+                       c.s << ',';
+                       seq[i].coeff.print(c);
+                       c.s << ')';
+               }
+               c.s << "])";
        } else {
 
                if (precedence() <= level)
@@ -174,7 +191,10 @@ void pseries::print(const print_context & c, unsigned level) const
                                        } else
                                                var.print(c);
                                        if (i->coeff.compare(_ex1)) {
-                                               c.s << '^';
+                                               if (is_a<print_python>(c))
+                                                       c.s << "**";
+                                               else
+                                                       c.s << '^';
                                                if (i->coeff.info(info_flags::negative)) {
                                                        c.s << par_open;
                                                        i->coeff.print(c);
index 6936376..484799d 100644 (file)
@@ -95,9 +95,17 @@ void relational::print(const print_context & c, unsigned level) const
 
        } else {
 
-               if (precedence() <= level)
-                       c.s << "(";
-               lh.print(c, precedence());
+               if (is_a<print_python_repr>(c)) {
+                       c.s << class_name() << '(';
+                       lh.print(c);
+                       c.s << ',';
+                       rh.print(c);
+                       c.s << ",'";
+               } else {
+                       if (precedence() <= level)
+                               c.s << "(";
+                       lh.print(c, precedence());
+               }
                switch (o) {
                        case equal:
                                c.s << "==";
@@ -120,9 +128,13 @@ void relational::print(const print_context & c, unsigned level) const
                        default:
                                c.s << "(INVALID RELATIONAL OPERATOR)";
                }
-               rh.print(c, precedence());
-               if (precedence() <= level)
-                       c.s << ")";
+               if (is_a<print_python_repr>(c))
+                       c.s << "')";
+               else {
+                       rh.print(c, precedence());
+                       if (precedence() <= level)
+                               c.s << ")";
+               }
        }
 }
 
@@ -273,39 +285,6 @@ unsigned relational::calchash(void) const
        return v;
 }
 
-bool relational::is_equal_same_type(const basic & other) const
-{
-       GINAC_ASSERT(is_a<relational>(other));
-       const relational &oth = static_cast<const relational &>(other);
-       if (o==oth.o && lh.is_equal(oth.lh) && rh.is_equal(oth.rh))
-               return true;
-       switch (o) {
-               case equal:
-               case not_equal:
-                       if (oth.o!=o)
-                               return false;
-                       break;
-               case less:
-                       if (oth.o!=greater)
-                               return false;
-                       break;
-               case less_or_equal:
-                       if (oth.o!=greater_or_equal)
-                               return false;
-                       break;
-               case greater:
-                       if (oth.o!=less)
-                               return false;
-                       break;
-               case greater_or_equal:
-                       if (oth.o!=less_or_equal)
-                               return false;
-                       break;
-       }
-       return lh.is_equal(oth.rh) && rh.is_equal(oth.lh);
-}
-
-
 //////////
 // new virtual functions which can be overridden by derived classes
 //////////
index 8f2263e..b04d11c 100644 (file)
@@ -63,7 +63,6 @@ protected:
        bool match_same_type(const basic & other) const;
        unsigned return_type(void) const;
        unsigned return_type_tinfo(void) const;
-       bool is_equal_same_type(const basic & other) const;
        unsigned calchash(void) const;
 
        // new virtual functions which can be overridden by derived classes
index 5d2ac8c..39f2335 100644 (file)
@@ -151,9 +151,14 @@ void symbol::print(const print_context & c, unsigned level) const
                    << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
                    << std::endl;
 
-       } else if (is_a<print_latex>(c))
+       } else if (is_a<print_latex>(c)) {
                c.s << TeX_name;
-       else
+       } else if (is_a<print_python_repr>(c)) {
+               c.s << class_name() << "('" << name;
+               if (TeX_name != default_TeX_name())
+                       c.s << "','" << TeX_name;
+               c.s << "')";
+       } else
                c.s << name;
 }
 
index 37e23e9..10aa7e4 100644 (file)
@@ -95,6 +95,8 @@ void wildcard::print(const print_context & c, unsigned level) const
                c.s << std::string(level, ' ') << class_name() << " (" << label << ")"
                    << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
                    << std::endl;
+       } else if (is_a<print_python_repr>(c)) {
+               c.s << class_name() << '(' << label << ')';
        } else
                c.s << "$" << label;
 }