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)
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
21 *------------------------------------------------------------------
22 * Reconstructs an infix expression from the RPN.
24 #include "m_expression.h"
25 /*--------------------------------------------------------------------------*/
26 void Token::dump(std::ostream
& out
)const
30 /*--------------------------------------------------------------------------*/
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
)) {
41 }else if (dynamic_cast<const Token_PARLIST
*>(*i
)) {
43 bool been_here
= false;
46 if (stack
.empty()) {untested();
47 throw Exception("bad expression");
50 const Token
* t
= stack
.back();
52 if (dynamic_cast<const Token_STOP
*>(t
)) {
55 }else if (dynamic_cast<const Token_SYMBOL
*>(t
)) {
61 tmp
= t
->full_name() + tmp
;
66 Token
* t
= new Token_PARLIST(tmp
);
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)
73 const Token
* t1
= stack
.back();
75 Token
* t
= new Token_SYMBOL((**i
).name(), t1
->full_name());
79 // has no parameters (scalar)
82 }else if (dynamic_cast<const Token_BINOP
*>(*i
)) {
84 assert(!stack
.empty());
85 const Token
* t2
= stack
.back();
87 assert(!stack
.empty());
88 const Token
* t1
= stack
.back();
90 std::string
tmp('(' + t1
->full_name() + ' ' + (**i
).name() + ' ' + t2
->full_name() + ')');
91 Token
* t
= new Token_SYMBOL(tmp
, "");
94 }else if (dynamic_cast<const Token_UNARY
*>(*i
)) {
96 assert(!stack
.empty());
97 const Token
* t1
= stack
.back();
99 std::string
tmp('(' + (**i
).name() + ' ' + t1
->full_name() + ')');
100 Token
* t
= new Token_SYMBOL(tmp
, "");
107 if (stack
.empty()) {untested();
110 stack
.back()->full_dump(out
);
111 assert(stack
.size() == 1);
113 while (!locals
.empty()) {
114 delete locals
.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: