Merge branch 'testing-uf' into master-uf
[gnucap-felix.git] / lib / m_expression_dump.cc
blob388fb45b8caaf0921c523f48311c8ea0c3074d54
1 /*$Id: m_expression_dump.cc,v 1.1 2009-10-23 12:01:45 felix Exp $ -*- C++ -*-
2 * Copyright (C) 2003 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *------------------------------------------------------------------
22 * Reconstructs an infix expression from the RPN.
24 #include "m_expression.h"
25 /*--------------------------------------------------------------------------*/
26 void Token::dump(std::ostream& out)const
27 {untested();
28 out << _name << ' ';
30 /*--------------------------------------------------------------------------*/
31 template<class S>
32 void Expression::_dump(S& out)const
34 std::vector<const Token*> locals; // a way of faking garbage collection.
35 std::vector<const Token*> stack; // actually use this
36 // The _list is the expression in RPN.
37 // Un-parse it -- back to infix.
38 for (const_iterator i = begin(); i != end(); ++i) {
39 if (dynamic_cast<const Token_STOP*>(*i)) {
40 stack.push_back(*i);
41 }else if (dynamic_cast<const Token_PARLIST*>(*i)) {
42 // pop*n push
43 bool been_here = false;
44 std::string tmp(")");
45 for (;;) {
46 if (stack.empty()) {untested();
47 throw Exception("bad expression");
48 }else{
50 const Token* t = stack.back();
51 stack.pop_back();
52 if (dynamic_cast<const Token_STOP*>(t)) {
53 tmp = "(" + tmp;
54 break;
55 }else if (dynamic_cast<const Token_SYMBOL*>(t)) {
56 if (been_here) {
57 tmp = ", " + tmp;
58 }else{
59 been_here = true;
61 tmp = t->full_name() + tmp;
62 }else{
63 unreachable();
66 Token* t = new Token_PARLIST(tmp);
67 locals.push_back(t);
68 stack.push_back(t);
69 }else if (dynamic_cast<const Token_CONSTANT*>(*i)|| dynamic_cast<const Token_SYMBOL*>(*i)) {
70 if (!stack.empty() && (dynamic_cast<const Token_PARLIST*>(stack.back()))) {
71 // has parameters (table or function)
72 // pop op push
73 const Token* t1 = stack.back();
74 stack.pop_back();
75 Token* t = new Token_SYMBOL((**i).name(), t1->full_name());
76 locals.push_back(t);
77 stack.push_back(t);
78 }else{
79 // has no parameters (scalar)
80 stack.push_back(*i);
82 }else if (dynamic_cast<const Token_BINOP*>(*i)) {
83 // pop pop op push
84 assert(!stack.empty());
85 const Token* t2 = stack.back();
86 stack.pop_back();
87 assert(!stack.empty());
88 const Token* t1 = stack.back();
89 stack.pop_back();
90 std::string tmp('(' + t1->full_name() + ' ' + (**i).name() + ' ' + t2->full_name() + ')');
91 Token* t = new Token_SYMBOL(tmp, "");
92 locals.push_back(t);
93 stack.push_back(t);
94 }else if (dynamic_cast<const Token_UNARY*>(*i)) {
95 // pop op push
96 assert(!stack.empty());
97 const Token* t1 = stack.back();
98 stack.pop_back();
99 std::string tmp('(' + (**i).name() + ' ' + t1->full_name() + ')');
100 Token* t = new Token_SYMBOL(tmp, "");
101 locals.push_back(t);
102 stack.push_back(t);
103 }else{
104 unreachable();
107 if (stack.empty()) {untested();
108 out << "empty";
109 }else{
110 stack.back()->full_dump(out);
111 assert(stack.size() == 1);
113 while (!locals.empty()) {
114 delete locals.back();
115 locals.pop_back();
118 /*--------------------------------------------------------------------------*/
119 /*--------------------------------------------------------------------------*/
120 template void Expression::_dump(OMSTREAM& out)const;
121 template void Expression::_dump(std::ostream& out)const;
122 /*--------------------------------------------------------------------------*/
123 // vim:ts=8:sw=2:noet: